29 #include "libmesh/numeric_vector.h" 30 #include "libmesh/dof_map.h" 31 #include "libmesh/sparse_matrix.h" 32 #include "libmesh/linear_solver.h" 41 _first_sensitivity_step (true),
43 _n_iters_to_store (n),
44 _assembly_ops (nullptr),
45 _if_highest_derivative_solution (false) {
62 libmesh_assert(_assembly_ops);
64 _assembly_ops->set_assembly(assembly);
73 _assembly_ops->clear_assembly();
80 libmesh_assert(_assembly_ops);
82 return *_assembly_ops;
99 _assembly_ops = &assembly_ops;
103 for (
unsigned int i=0; i<_n_iters_to_store; i++) {
104 std::ostringstream iter;
111 nm =
"transient_solution_";
113 sys.add_vector(nm,
true, libMesh::GHOSTED);
115 nm =
"transient_solution_sensitivity_";
117 sys.add_vector(nm,
true, libMesh::GHOSTED);
121 nm =
"transient_velocity_";
123 sys.add_vector(nm,
true, libMesh::GHOSTED);
124 nm =
"transient_velocity_sensitivity_";
126 sys.add_vector(nm,
true, libMesh::GHOSTED);
128 if (_ode_order > 1) {
130 nm =
"transient_acceleration_";
132 sys.add_vector(nm,
true, libMesh::GHOSTED);
133 nm =
"transient_acceleration_sensitivity_";
135 sys.add_vector(nm,
true, libMesh::GHOSTED);
157 for (
unsigned int i=0; i<_n_iters_to_store; i++) {
158 std::ostringstream iter;
162 nm =
"transient_solution_";
164 if (sys.have_vector(nm)) sys.remove_vector(nm);
165 nm =
"transient_solution_sensitivity_";
167 if (sys.have_vector(nm)) sys.remove_vector(nm);
170 nm =
"transient_velocity_";
172 if (sys.have_vector(nm)) sys.remove_vector(nm);
173 nm =
"transient_velocity_sensitivity_";
175 if (sys.have_vector(nm)) sys.remove_vector(nm);
177 if (_ode_order > 1) {
179 nm =
"transient_acceleration_";
181 if (sys.have_vector(nm)) sys.remove_vector(nm);
182 nm =
"transient_acceleration_sensitivity_";
184 if (sys.have_vector(nm)) sys.remove_vector(nm);
189 _assembly_ops =
nullptr;
196 libMesh::NumericVector<Real>&
200 libmesh_assert_less(prev_iter, _n_iters_to_store);
203 std::ostringstream oss;
209 nm =
"transient_solution_" + oss.str();
219 libMesh::NumericVector<Real>&
223 libmesh_assert_less(prev_iter, _n_iters_to_store);
226 std::ostringstream oss;
232 nm =
"transient_solution_sensitivity_" + oss.str();
242 libMesh::NumericVector<Real>&
246 libmesh_assert_less(prev_iter, _n_iters_to_store);
249 std::ostringstream oss;
254 nm =
"transient_velocity_" + oss.str();
261 libMesh::NumericVector<Real>&
265 libmesh_assert_less(prev_iter, _n_iters_to_store);
268 std::ostringstream oss;
273 nm =
"transient_velocity_sensitivity_" + oss.str();
281 libMesh::NumericVector<Real>&
285 libmesh_assert_less(prev_iter, _n_iters_to_store);
288 std::ostringstream oss;
293 nm =
"transient_acceleration_" + oss.str();
300 libMesh::NumericVector<Real>&
304 libmesh_assert_less(prev_iter, _n_iters_to_store);
307 std::ostringstream oss;
312 nm =
"transient_acceleration_sensitivity_" + oss.str();
323 libmesh_assert_msg(
_system,
"System pointer is nullptr.");
337 libmesh_assert_msg(
_system,
"System pointer is nullptr.");
349 libmesh_assert(_first_step);
356 _if_highest_derivative_solution =
true;
367 _if_highest_derivative_solution =
false;
369 std::pair<unsigned int, Real>
373 libMesh::SparseMatrix<Real> *
374 pc = sys.request_matrix(
"Preconditioner");
376 std::unique_ptr<libMesh::NumericVector<Real> >
377 dvec(
velocity().zero_clone().release());
382 solver_params.second,
383 solver_params.first);
385 libMesh::NumericVector<Real> *vec =
nullptr;
387 switch (_ode_order) {
402 vec->add(-1., *dvec);
405 #ifdef LIBMESH_ENABLE_CONSTRAINTS 406 sys.get_dof_map().enforce_constraints_exactly(sys, vec,
true);
413 for (
unsigned int i=_n_iters_to_store-1; i>0; i--) {
422 if (_ode_order > 1) {
443 libmesh_assert(_first_sensitivity_step);
450 _if_highest_derivative_solution =
true;
463 _if_highest_derivative_solution =
false;
465 std::pair<unsigned int, Real>
469 libMesh::SparseMatrix<Real> *
470 pc = sys.request_matrix(
"Preconditioner");
472 std::unique_ptr<libMesh::NumericVector<Real> >
473 dvec(
velocity().zero_clone().release());
478 solver_params.second,
479 solver_params.first);
481 libMesh::NumericVector<Real> *vec =
nullptr;
483 switch (_ode_order) {
498 vec->add(-1., *dvec);
501 #ifdef LIBMESH_ENABLE_CONSTRAINTS 502 sys.get_dof_map().enforce_constraints_exactly(sys, vec,
true);
507 for (
unsigned int i=_n_iters_to_store-1; i>0; i--) {
517 if (_ode_order > 1) {
527 _first_sensitivity_step =
false;
535 std::vector<libMesh::NumericVector<Real>*>& sol) {
544 libmesh_assert(!sol.size());
547 sol.resize(_ode_order+1);
549 const std::vector<libMesh::dof_id_type>&
550 send_list = sys.get_dof_map().get_send_list();
553 for (
unsigned int i=0; i<=_ode_order; i++) {
555 sol[i] = libMesh::NumericVector<Real>::build(sys.comm()).release();
556 sol[i]->init(sys.n_dofs(),
566 if (!_if_highest_derivative_solution)
568 current_sol.localize(*sol[i], send_list);
570 solution().localize(*sol[i], send_list);
577 libMesh::NumericVector<Real>& vel = this->
velocity();
579 if (!_if_highest_derivative_solution)
583 vel.localize(*sol[i], send_list);
590 libMesh::NumericVector<Real>& acc = this->
acceleration();
592 if (!_if_highest_derivative_solution)
596 acc.localize(*sol[i], send_list);
613 std::vector<libMesh::NumericVector<Real>*>& sol) {
617 libmesh_assert_less_equal(prev_iter, _n_iters_to_store);
623 libmesh_assert(!sol.size());
626 sol.resize(_ode_order+1);
628 const std::vector<libMesh::dof_id_type>&
629 send_list = sys.get_dof_map().get_send_list();
632 for (
unsigned int i=0; i<=_ode_order; i++) {
634 sol[i] = libMesh::NumericVector<Real>::build(sys.comm()).release();
635 sol[i]->init(sys.n_dofs(),
668 MAST::TransientSolverBase::
669 build_perturbed_local_quantities(
const libMesh::NumericVector<Real>& current_dsol,
670 std::vector<libMesh::NumericVector<Real>*>& sol) {
679 libmesh_assert(!sol.size());
682 sol.resize(_ode_order+1);
684 const std::vector<libMesh::dof_id_type>&
685 send_list = sys.get_dof_map().get_send_list();
688 std::unique_ptr<libMesh::NumericVector<Real> >
689 tmp(this->
solution().zero_clone().release());
691 for (
unsigned int i=0; i<=_ode_order; i++) {
693 sol[i] = libMesh::NumericVector<Real>::build(sys.comm()).release();
694 sol[i]->init(sys.n_dofs(),
704 current_dsol.localize(*sol[i], send_list);
705 if (_if_highest_derivative_solution)
714 if (_ode_order == 1 && _if_highest_derivative_solution)
716 current_dsol.localize(*sol[i], send_list);
717 else if (_if_highest_derivative_solution)
721 tmp->localize(*sol[i], send_list);
728 if (_ode_order == 2 && _if_highest_derivative_solution)
730 current_dsol.localize(*sol[i], send_list);
731 else if (_if_highest_derivative_solution)
735 tmp->localize(*sol[i], send_list);
769 for (
unsigned int i=_n_iters_to_store-1; i>0; i--) {
778 if (_ode_order > 1) {
807 for (
unsigned int i=_n_iters_to_store-1; i>0; i--) {
816 if (_ode_order > 1) {
826 _first_sensitivity_step =
false;
833 const libMesh::Elem& ref_elem,
836 libmesh_assert(_assembly_ops);
837 _assembly_ops->set_elem_data(dim, ref_elem, elem);
844 libmesh_assert(_assembly_ops);
845 _assembly_ops->init(elem);
854 libmesh_assert(_assembly_ops);
855 _assembly_ops->clear_elem();
virtual void sensitivity_solve(MAST::AssemblyElemOperations &elem_ops, MAST::AssemblyBase &assembly, const MAST::FunctionBase &p, bool if_assemble_jacobian=true)
Solves the sensitivity problem for the provided parameter.
MAST::NonlinearSystem & system()
virtual void advance_time_step_with_sensitivity()
advances the time step and copies the current sensitivity solution to old sensitivity solution...
virtual void advance_time_step()
advances the time step and copies the current solution to old solution, and so on.
void solve_highest_derivative_and_advance_time_step(MAST::AssemblyBase &assembly)
To be used only for initial conditions.
virtual void sensitivity_solve(MAST::AssemblyBase &assembly, const MAST::FunctionBase &f)
solvers the current time step for sensitivity wrt f
virtual void update_sensitivity_acceleration(libMesh::NumericVector< Real > &acc, const libMesh::NumericVector< Real > &sol)=0
update the transient sensitivity acceleration based on the current sensitivity solution ...
This class implements a system for solution of nonlinear systems.
virtual void set_assembly(MAST::AssemblyBase &assembly)
sets the assembly object
virtual MAST::TransientAssemblyElemOperations & get_elem_operation_object()
virtual void clear_elem_operation_object()
clears the association of this object with the assembly element operation object. ...
virtual bool sensitivity_assemble(const MAST::FunctionBase &f, libMesh::NumericVector< Real > &sensitivity_rhs)
Assembly function.
virtual void update_delta_acceleration(libMesh::NumericVector< Real > &acc, const libMesh::NumericVector< Real > &sol)=0
update the perturbation in transient acceleration based on the current perturbed solution ...
virtual void set_assembly(MAST::AssemblyBase &assembly)
sets the assembly object
virtual void update_delta_velocity(libMesh::NumericVector< Real > &vel, const libMesh::NumericVector< Real > &sol)=0
update the perturbation in transient velocity based on the current perturbed solution ...
virtual ~TransientSolverBase()
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...
MAST::PhysicsDisciplineBase * _discipline
virtual void set_elem_operation_object(MAST::TransientAssemblyElemOperations &elem_ops)
Attaches the assembly elem operations object that provides the x_dot, M and J quantities for the elem...
libMesh::NumericVector< Real > & solution_sensitivity(unsigned int prev_iter=0) const
libMesh::NumericVector< Real > & velocity(unsigned int prev_iter=0) const
virtual void set_elem_data(unsigned int dim, const libMesh::Elem &ref_elem, MAST::GeomElem &elem) const =0
some analyses may want to set additional element data before initialization of the GeomElem...
virtual void update_velocity(libMesh::NumericVector< Real > &vel, const libMesh::NumericVector< Real > &sol)=0
update the transient velocity based on the current solution
virtual void clear_assembly()
clears the assembly object
virtual void build_local_quantities(const libMesh::NumericVector< Real > ¤t_sol, std::vector< libMesh::NumericVector< Real > * > &qtys)
localizes the relevant solutions for system assembly.
virtual void build_sensitivity_local_quantities(unsigned int prev_iter, std::vector< libMesh::NumericVector< Real > * > &qtys)
localizes the relevant solutions for system assembly.
libMesh::NumericVector< Real > & velocity_sensitivity(unsigned int prev_iter=0) const
virtual std::pair< unsigned int, Real > get_linear_solve_parameters()
calls NonlinearImplicitSystem::set_solver_parameters() before accessing the values.
virtual void init(const MAST::GeomElem &elem)=0
initializes the object for calculation of element quantities for the specified elem.
virtual void update_acceleration(libMesh::NumericVector< Real > &acc, const libMesh::NumericVector< Real > &sol)=0
update the transient acceleration based on the current solution
libMesh::NumericVector< Real > & acceleration_sensitivity(unsigned int prev_iter=0) const
virtual void clear_assembly()
clears the assembly object
libMesh::NumericVector< Real > & solution(unsigned int prev_iter=0) const
This class acts as a wrapper around libMesh::Elem for the purpose of providing a uniform interface fo...
virtual void solve(MAST::AssemblyBase &assembly)
solves the current time step for solution and velocity
MAST::AssemblyBase * _assembly
std::unique_ptr< libMesh::LinearSolver< Real > > linear_solver
The LinearSolver for solution of the linear equations.
virtual void clear_elem()
clears the element initialization
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 ...
TransientSolverBase(unsigned int o, unsigned int n)
constructor requires the number of iterations to store for the derived solver.
virtual void update_sensitivity_velocity(libMesh::NumericVector< Real > &vel, const libMesh::NumericVector< Real > &sol)=0
update the transient sensitivity velocity based on the current sensitivity solution ...
void solve_highest_derivative_and_advance_time_step_with_sensitivity(MAST::AssemblyBase &assembly, const MAST::FunctionBase &f)
solves for the sensitivity of highest derivative and advances the time-step.
virtual void clear_elem_operation_object()
Clears the assembly elem operations object.
libMesh::NumericVector< Real > & acceleration(unsigned int prev_iter=0) const
virtual void solve(MAST::AssemblyElemOperations &elem_ops, MAST::AssemblyBase &assembly)
solves the nonlinear problem with the specified assembly operation object
MAST::SystemInitialization * _system