32 #include "libmesh/libmesh_logging.h" 33 #include "libmesh/sparse_matrix.h" 34 #include "libmesh/numeric_vector.h" 35 #include "libmesh/linear_solver.h" 36 #include "libmesh/petsc_matrix.h" 37 #include "libmesh/enum_norm_type.h" 38 #include "libmesh/dof_map.h" 47 _use_eigenvalue_stabilization (true),
48 _assemble_mass (false),
85 libmesh_assert_greater(
max_amp, 0.);
91 LOG_SCOPE(
"sensitivity_solve()",
"StabilizedSensitivity");
97 libMesh::SparseMatrix<Real>
103 std::unique_ptr<libMesh::SparseMatrix<Real>>
104 M0(libMesh::SparseMatrix<Real>::build(sys.comm()).release());
105 sys.get_dof_map().attach_matrix(*M0);
112 libMesh::NumericVector<Real>
116 &rhs = sys.add_sensitivity_rhs();
118 std::unique_ptr<libMesh::NumericVector<Real>>
119 f_int(rhs.zero_clone().release()),
120 vec1(rhs.zero_clone().release());
135 sys.time += this->
dt;
142 while (continue_it) {
145 std::ostringstream oss;
153 J_int.add(this->
dt, M1);
158 Mat M_avg_mat =
dynamic_cast<libMesh::PetscMatrix<Real>&
>(M_avg).mat();
159 PetscErrorCode ierr = MatScale(M_avg_mat, (sys.time -
_t0 - this->dt)/(sys.time -
_t0));
160 CHKERRABORT(sys.comm().get(), ierr);
161 M_avg.add(this->
dt/(sys.time -
_t0), M1);
170 f_int->add(this->
dt, rhs);
173 M_avg.vector_mult(rhs, dsol0);
185 M1.add(this->
beta, J_int);
190 M0->add(-(1.-this->
beta), J_int);
197 std::pair<unsigned int, Real>
201 libMesh::SparseMatrix<Real> * pc = sys.request_matrix(
"Preconditioner");
203 std::pair<unsigned int, Real> rval =
207 solver_params.second,
208 solver_params.first);
211 #ifdef LIBMESH_ENABLE_CONSTRAINTS 212 sys.get_dof_map().enforce_constraints_exactly (sys, &dsol1,
true);
215 M_avg.vector_mult(*vec1, dsol1);
233 libMesh::out <<
"accepting sol" << std::endl;
235 dsol0.add(1., dsol1);
241 dsol1.add(1., dsol0);
244 libMesh::out <<
"reached final step. Rjecting solution" << std::endl;
250 sys.time += this->
dt;
273 libMesh::NumericVector<Real>
278 std::unique_ptr<libMesh::NumericVector<Real>>
279 dx(dx0.zero_clone().release());
286 std::ostringstream oss;
293 eta = (sys.time-
_t0)/(t1-
_t0);
296 dx->add(1.-eta, dx0);
314 const std::vector<libMesh::NumericVector<Real>*>& sols) {
316 libmesh_assert_equal_to(sols.size(), 2);
318 const unsigned int n_dofs = (
unsigned int)dof_indices.size();
323 sol = RealVectorX::Zero(n_dofs),
324 vel = RealVectorX::Zero(n_dofs);
327 const libMesh::NumericVector<Real>
328 &sol_global = *sols[0],
329 &vel_global = *sols[1];
333 for (
unsigned int i=0; i<n_dofs; i++) {
335 sol(i) = sol_global(dof_indices[i]);
336 vel(i) = vel_global(dof_indices[i]);
339 _assembly_ops->set_elem_solution(sol);
340 _assembly_ops->set_elem_velocity(vel);
348 const std::vector<libMesh::NumericVector<Real>*>& sols,
349 std::vector<RealVectorX>& local_sols) {
351 libmesh_assert_equal_to(sols.size(), 2);
353 const unsigned int n_dofs = (
unsigned int)dof_indices.size();
355 local_sols.resize(2);
358 &sol = local_sols[0],
359 &vel = local_sols[1];
361 sol = RealVectorX::Zero(n_dofs);
362 vel = RealVectorX::Zero(n_dofs);
364 const libMesh::NumericVector<Real>
365 &sol_global = *sols[0],
366 &vel_global = *sols[1];
370 for (
unsigned int i=0; i<n_dofs; i++) {
372 sol(i) = sol_global(dof_indices[i]);
373 vel(i) = vel_global(dof_indices[i]);
382 const libMesh::NumericVector<Real>& sol) {
384 const libMesh::NumericVector<Real>
390 vec.add(-1., prev_sol);
402 const libMesh::NumericVector<Real>& sol) {
404 const libMesh::NumericVector<Real>
410 vec.add(-1., prev_sol);
426 libmesh_assert(_assembly_ops);
427 unsigned int n_dofs = (
unsigned int)vec.size();
430 f_x = RealVectorX::Zero(n_dofs),
431 f_m = RealVectorX::Zero(n_dofs);
434 f_m_jac_xdot = RealMatrixX::Zero(n_dofs, n_dofs),
435 f_m_jac = RealMatrixX::Zero(n_dofs, n_dofs),
436 f_x_jac = RealMatrixX::Zero(n_dofs, n_dofs);
439 _assembly_ops->elem_calculations(if_jac,
449 mat = f_m_jac + f_x_jac;
460 libmesh_assert(_assembly_ops);
461 unsigned int n_dofs = (
unsigned int)vec.size();
464 f_x = RealVectorX::Zero(n_dofs),
465 f_m = RealVectorX::Zero(n_dofs);
468 _assembly_ops->elem_sensitivity_calculations(f,
491 const libMesh::NumericVector<Real>& sol1) {
506 var_norm = RealVectorX::Zero(n_vars);
508 for (
unsigned int i=0; i<n_vars; i++) {
510 norm0 = sys.calculate_norm(sol0, i, libMesh::L2);
511 norm1 = sys.calculate_norm(sol1, i, libMesh::L2);
514 var_norm(i) = norm1/norm0;
517 libMesh::out <<
"amp coeffs: " << var_norm.transpose() << std::endl;
518 return var_norm.maxCoeff();
525 libMesh::SparseMatrix<Real>& B) {
532 std::unique_ptr<MAST::SlepcEigenSolver>
535 if (libMesh::on_command_line(
"--solver_system_names")) {
537 EPS
eps = eigen_solver.get()->eps();
538 std::string nm = sys.name() +
"_";
539 EPSSetOptionsPrefix(eps, nm.c_str());
542 eigen_solver->set_position_of_spectrum(libMesh::LARGEST_MAGNITUDE);
543 eigen_solver->init();
547 std::pair<unsigned int, unsigned int>
548 solve_data = eigen_solver->solve_generalized (A, B,
555 libmesh_assert(solve_data.first);
557 std::pair<Real, Real> pair = eigen_solver->get_eigenvalue(0);
558 std::complex<Real> eig(pair.first, pair.second);
559 Real amp = std::abs(eig);
561 libMesh::out <<
"amp coeffs: " << amp << std::endl;
const MAST::NonlinearSystem & system() const
MAST::NonlinearSystem & system()
virtual ~StabilizedFirstOrderNewmarkTransientSensitivitySolver()
void set_nolinear_solution_location(std::string &file_root, std::string &dir)
sets the directory where the nonlinear solutions are stored.
void read_in_vector(libMesh::NumericVector< Real > &vec, const std::string &directory_name, const std::string &data_name, const bool read_binary_vectors)
reads the specified vector with the specified name in a directory.
This class implements a system for solution of nonlinear systems.
virtual void elem_sensitivity_calculations(const MAST::FunctionBase &f, RealVectorX &vec)
performs the element sensitivity calculations over elem, and returns the element residual sensitivity...
virtual void clear_elem_operation_object()
clears the association of this object with the assembly element operation object. ...
void set_eigenvalue_stabilization(bool f)
sets if the eigenvalue-based stabilization will be used.
This provides the base class for definitin of element level contribution of output quantity in an ana...
std::string _sol_name_root
libMesh::NumericVector< Real > & solution(unsigned int prev_iter=0) const
virtual void set_elem_operation_object(MAST::AssemblyElemOperations &elem_ops)
attaches a element operation to this object, and associated this with the element operation object...
This class inherits from libMesh::SlepcEigenSolver<Real> and implements a method for retriving the re...
void set_eigenproblem_type(libMesh::EigenProblemType ept)
Sets the type of the current eigen problem.
unsigned int n_vars() const
libMesh::NumericVector< Real > & solution_sensitivity(unsigned int prev_iter=0) const
bool _use_eigenvalue_stabilization
virtual void sensitivity_solve(MAST::AssemblyBase &assembly, const MAST::FunctionBase &f)
solvers the current time step for sensitivity wrt f
virtual void update_sensitivity_velocity(libMesh::NumericVector< Real > &vec, const libMesh::NumericVector< Real > &sol)
update the transient sensitivity velocity based on the current sensitivity solution ...
Real _compute_eig_amplification_factor(libMesh::SparseMatrix< Real > &A, libMesh::SparseMatrix< Real > &B)
libMesh::SparseMatrix< Real > * matrix_A
The system matrix for standard eigenvalue problems.
Matrix< Real, Dynamic, Dynamic > RealMatrixX
libMesh::NumericVector< Real > & velocity(unsigned int prev_iter=0) const
Real max_amp
parameter used by this solver.
virtual std::pair< unsigned int, Real > get_linear_solve_parameters()
calls NonlinearImplicitSystem::set_solver_parameters() before accessing the values.
virtual void set_element_data(const std::vector< libMesh::dof_id_type > &dof_indices, const std::vector< libMesh::NumericVector< Real > *> &sols)
Matrix< Real, Dynamic, 1 > RealVectorX
virtual Real output_sensitivity_total(const MAST::FunctionBase &p)=0
virtual void elem_sensitivity_contribution_previous_timestep(const std::vector< RealVectorX > &prev_sols, RealVectorX &vec)
virtual void calculate_output_direct_sensitivity(const libMesh::NumericVector< Real > &X, bool if_localize_sol, const libMesh::NumericVector< Real > *dXdp, bool if_localize_sol_sens, const MAST::FunctionBase &p, MAST::OutputAssemblyElemOperations &output)
evaluates the sensitivity of the outputs in the attached discipline with respect to the parametrs in ...
libMesh::SparseMatrix< Real > * matrix_B
A second system matrix for generalized eigenvalue problems.
Real _compute_norm_amplification_factor(const libMesh::NumericVector< Real > &sol0, const libMesh::NumericVector< Real > &sol1)
virtual void zero_for_analysis()=0
zeroes the output quantity values stored inside this object so that assembly process can begin...
virtual void extract_element_sensitivity_data(const std::vector< libMesh::dof_id_type > &dof_indices, const std::vector< libMesh::NumericVector< Real > *> &sols, std::vector< RealVectorX > &local_sols)
std::unique_ptr< libMesh::LinearSolver< Real > > linear_solver
The LinearSolver for solution of the linear equations.
virtual void residual_and_jacobian(const libMesh::NumericVector< Real > &X, libMesh::NumericVector< Real > *R, libMesh::SparseMatrix< Real > *J, libMesh::NonlinearImplicitSystem &S)
function that assembles the matrices and vectors quantities for nonlinear solution ...
unsigned int max_index
index of solution that is used for current linearization
virtual void elem_calculations(bool if_jac, RealVectorX &vec, RealMatrixX &mat)
performs the element calculations over elem, and returns the element vector and matrix quantities in ...
libMesh::NumericVector< Real > & velocity_sensitivity(unsigned int prev_iter=0) const
virtual Real evaluate_q_sens_for_previous_interval(MAST::AssemblyBase &assembly, const MAST::FunctionBase &p, MAST::OutputAssemblyElemOperations &output)
StabilizedFirstOrderNewmarkTransientSensitivitySolver()
virtual bool sensitivity_assemble(const libMesh::NumericVector< Real > &X, bool if_localize_sol, const MAST::FunctionBase &f, libMesh::NumericVector< Real > &sensitivity_rhs, bool close_vector=true)
Assembly function.
virtual void update_velocity(libMesh::NumericVector< Real > &vel, const libMesh::NumericVector< Real > &sol)
update the transient velocity based on the current solution
MAST::SystemInitialization * _system