MAST
transient_solver_base.cpp
Go to the documentation of this file.
1 /*
2  * MAST: Multidisciplinary-design Adaptation and Sensitivity Toolkit
3  * Copyright (C) 2013-2019 Manav Bhatia
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 // MAST includes
23 #include "base/assembly_base.h"
25 #include "base/nonlinear_system.h"
27 
28 // libMesh includes
29 #include "libmesh/numeric_vector.h"
30 #include "libmesh/dof_map.h"
31 #include "libmesh/sparse_matrix.h"
32 #include "libmesh/linear_solver.h"
33 
34 
35 
37  unsigned int n):
39 dt (0.),
40 _first_step (true),
41 _first_sensitivity_step (true),
42 _ode_order (o),
43 _n_iters_to_store (n),
44 _assembly_ops (nullptr),
45 _if_highest_derivative_solution (false) {
46 
47 }
48 
49 
50 
51 
53 
55 }
56 
57 
58 
59 void
61 
62  libmesh_assert(_assembly_ops);
64  _assembly_ops->set_assembly(assembly);
65 }
66 
67 
68 void
70 
72  if (_assembly_ops)
73  _assembly_ops->clear_assembly();
74 }
75 
76 
79 
80  libmesh_assert(_assembly_ops);
81 
82  return *_assembly_ops;
83 }
84 
85 
86 void
89 
90  libmesh_assert(_system);
91  libmesh_assert(_discipline);
92 
94  &sys = _system->system();
95 
96  // make sure that the previous assembly association has been cleared
98 
99  _assembly_ops = &assembly_ops;
100 
101  // now, add the vectors
102  std::string nm;
103  for (unsigned int i=0; i<_n_iters_to_store; i++) {
104  std::ostringstream iter;
105  iter << i;
106 
107  // add the solution only for previous iterations. The current
108  // solution is obtained from system->solution
109  if (i>0) {
110 
111  nm = "transient_solution_";
112  nm += iter.str();
113  sys.add_vector(nm, true, libMesh::GHOSTED);
114 
115  nm = "transient_solution_sensitivity_";
116  nm += iter.str();
117  sys.add_vector(nm, true, libMesh::GHOSTED);
118  }
119 
120  // add the velocity
121  nm = "transient_velocity_";
122  nm += iter.str();
123  sys.add_vector(nm, true, libMesh::GHOSTED);
124  nm = "transient_velocity_sensitivity_";
125  nm += iter.str();
126  sys.add_vector(nm, true, libMesh::GHOSTED);
127 
128  if (_ode_order > 1) {
129  // add the acceleration
130  nm = "transient_acceleration_";
131  nm += iter.str();
132  sys.add_vector(nm, true, libMesh::GHOSTED);
133  nm = "transient_acceleration_sensitivity_";
134  nm += iter.str();
135  sys.add_vector(nm, true, libMesh::GHOSTED);
136  }
137  }
138 
139  _first_step = true;
140 }
141 
142 
143 
144 void
146 
147  // if no system has been set so far, nothing needs to be done
148  if (!_system)
149  return;
150 
152  &sys = _system->system();
153 
154  // clear the transient solutions stored in system for solution
155  // number of time steps to store
156  std::string nm;
157  for (unsigned int i=0; i<_n_iters_to_store; i++) {
158  std::ostringstream iter;
159  iter << i;
160 
161  // remove the solution
162  nm = "transient_solution_";
163  nm += iter.str();
164  if (sys.have_vector(nm)) sys.remove_vector(nm);
165  nm = "transient_solution_sensitivity_";
166  nm += iter.str();
167  if (sys.have_vector(nm)) sys.remove_vector(nm);
168 
169  // remove the velocity
170  nm = "transient_velocity_";
171  nm += iter.str();
172  if (sys.have_vector(nm)) sys.remove_vector(nm);
173  nm = "transient_velocity_sensitivity_";
174  nm += iter.str();
175  if (sys.have_vector(nm)) sys.remove_vector(nm);
176 
177  if (_ode_order > 1) {
178  // remove the acceleration
179  nm = "transient_acceleration_";
180  nm += iter.str();
181  if (sys.have_vector(nm)) sys.remove_vector(nm);
182  nm = "transient_acceleration_sensitivity_";
183  nm += iter.str();
184  if (sys.have_vector(nm)) sys.remove_vector(nm);
185 
186  }
187  }
188 
189  _assembly_ops = nullptr;
190  _first_step = true;
191 }
192 
193 
194 
195 
196 libMesh::NumericVector<Real>&
197 MAST::TransientSolverBase::solution(unsigned int prev_iter) const {
198 
199  // make sura that prev_iter is within acceptable bounds
200  libmesh_assert_less(prev_iter, _n_iters_to_store);
201 
202  // make sure that the vectors have been initialized
203  std::ostringstream oss;
204  oss << prev_iter;
205 
206  if (prev_iter) {
207  // get references to the solution
208  std::string
209  nm = "transient_solution_" + oss.str();
210 
211  return _system->system().get_vector(nm);
212  }
213  else
214  return *_system->system().current_local_solution;
215 }
216 
217 
218 
219 libMesh::NumericVector<Real>&
220 MAST::TransientSolverBase::solution_sensitivity(unsigned int prev_iter) const {
221 
222  // make sura that prev_iter is within acceptable bounds
223  libmesh_assert_less(prev_iter, _n_iters_to_store);
224 
225  // make sure that the vectors have been initialized
226  std::ostringstream oss;
227  oss << prev_iter;
228 
229  if (prev_iter) {
230  // get references to the solution
231  std::string
232  nm = "transient_solution_sensitivity_" + oss.str();
233 
234  return _system->system().get_vector(nm);
235  }
236  else
237  return _system->system().add_sensitivity_solution();
238 }
239 
240 
241 
242 libMesh::NumericVector<Real>&
243 MAST::TransientSolverBase::velocity(unsigned int prev_iter) const {
244 
245  // make sura that prev_iter is within acceptable bounds
246  libmesh_assert_less(prev_iter, _n_iters_to_store);
247 
248  // make sure that the vectors have been initialized
249  std::ostringstream oss;
250  oss << prev_iter;
251 
252  // get references to the solution
253  std::string
254  nm = "transient_velocity_" + oss.str();
255 
256  return _system->system().get_vector(nm);
257 }
258 
259 
260 
261 libMesh::NumericVector<Real>&
262 MAST::TransientSolverBase::velocity_sensitivity(unsigned int prev_iter) const {
263 
264  // make sura that prev_iter is within acceptable bounds
265  libmesh_assert_less(prev_iter, _n_iters_to_store);
266 
267  // make sure that the vectors have been initialized
268  std::ostringstream oss;
269  oss << prev_iter;
270 
271  // get references to the solution
272  std::string
273  nm = "transient_velocity_sensitivity_" + oss.str();
274 
275  return _system->system().get_vector(nm);
276 }
277 
278 
279 
280 
281 libMesh::NumericVector<Real>&
282 MAST::TransientSolverBase::acceleration(unsigned int prev_iter) const {
283 
284  // make sura that prev_iter is within acceptable bounds
285  libmesh_assert_less(prev_iter, _n_iters_to_store);
286 
287  // make sure that the vectors have been initialized
288  std::ostringstream oss;
289  oss << prev_iter;
290 
291  // get references to the solution
292  std::string
293  nm = "transient_acceleration_" + oss.str();
294 
295  return _system->system().get_vector(nm);
296 }
297 
298 
299 
300 libMesh::NumericVector<Real>&
302 
303  // make sura that prev_iter is within acceptable bounds
304  libmesh_assert_less(prev_iter, _n_iters_to_store);
305 
306  // make sure that the vectors have been initialized
307  std::ostringstream oss;
308  oss << prev_iter;
309 
310  // get references to the solution
311  std::string
312  nm = "transient_acceleration_sensitivity_" + oss.str();
313 
314  return _system->system().get_vector(nm);
315 }
316 
317 
318 
319 void
321 
322  // make sure that the system has been specified
323  libmesh_assert_msg(_system, "System pointer is nullptr.");
324 
325  // ask the Newton solver to solve for the system solution
326  _system->system().solve(*this, assembly);
327 
328 }
329 
330 
331 
332 void
334  const MAST::FunctionBase& f) {
335 
336  // make sure that the system has been specified
337  libmesh_assert_msg(_system, "System pointer is nullptr.");
338 
339  // ask the Newton solver to solve for the system solution
340  _system->system().sensitivity_solve(*this, assembly, f);
341 }
342 
343 
344 
345 void
348 
349  libmesh_assert(_first_step);
350  libmesh_assert(_system);
351  libmesh_assert(_discipline);
352  libmesh_assert(!_assembly);
353 
354  // tell the solver that the current solution being obtained is for the
355  // highest time derivative
356  _if_highest_derivative_solution = true;
357 
359  &sys = _system->system();
360 
361  // Build the residual and Jacobian
362  assembly.set_elem_operation_object(*this);
363  assembly.residual_and_jacobian(*sys.solution, sys.rhs, sys.matrix, sys);
364  assembly.clear_elem_operation_object();
365 
366  // reset the solution flag
367  _if_highest_derivative_solution = false;
368 
369  std::pair<unsigned int, Real>
370  solver_params = sys.get_linear_solve_parameters();
371 
372  // Solve the linear system.
373  libMesh::SparseMatrix<Real> *
374  pc = sys.request_matrix("Preconditioner");
375 
376  std::unique_ptr<libMesh::NumericVector<Real> >
377  dvec(velocity().zero_clone().release());
378 
379  sys.linear_solver->solve (*sys.matrix, pc,
380  *dvec,
381  *sys.rhs,
382  solver_params.second,
383  solver_params.first);
384 
385  libMesh::NumericVector<Real> *vec = nullptr;
386 
387  switch (_ode_order) {
388 
389  case 1:
390  vec = &velocity();
391  break;
392 
393  case 2:
394  vec = &acceleration();
395  break;
396 
397  default:
398  // higher than 2 derivative not implemented yet.
399  libmesh_error();
400  }
401 
402  vec->add(-1., *dvec);
403 
404  // The linear solver may not have fit our constraints exactly
405 #ifdef LIBMESH_ENABLE_CONSTRAINTS
406  sys.get_dof_map().enforce_constraints_exactly(sys, vec, /* homogeneous = */ true);
407 #endif
408 
409  sys.update();
410 
411  // next, move all the solutions and velocities into older
412  // time step locations
413  for (unsigned int i=_n_iters_to_store-1; i>0; i--) {
414  this->solution(i).zero();
415  this->solution(i).add(1., this->solution(i-1));
416  this->solution(i).close();
417 
418  this->velocity(i).zero();
419  this->velocity(i).add(1., this->velocity(i-1));
420  this->velocity(i).close();
421 
422  if (_ode_order > 1) {
423 
424  this->acceleration(i).zero();
425  this->acceleration(i).add(1., this->acceleration(i-1));
426  this->acceleration(i).close();
427  }
428  }
429 
430  // finally, update the system time
431  sys.time += dt;
432  _first_step = false;
433 }
434 
435 
436 
437 
438 void
441  const MAST::FunctionBase& f) {
442 
443  libmesh_assert(_first_sensitivity_step);
444  libmesh_assert(_system);
445  libmesh_assert(_discipline);
446  libmesh_assert(!_assembly);
447 
448  // tell the solver that the current solution being obtained is for the
449  // highest time derivative
450  _if_highest_derivative_solution = true;
451 
453  &sys = _system->system();
454 
455  // Build the Jacobian
456  assembly.set_elem_operation_object(*this);
457  assembly.residual_and_jacobian(*sys.solution, nullptr, sys.matrix, sys);
458  // this should assembl the sensitivity of the residual
459  assembly.sensitivity_assemble(f, *sys.rhs);
460  assembly.clear_elem_operation_object();
461 
462  // reset the solution flag
463  _if_highest_derivative_solution = false;
464 
465  std::pair<unsigned int, Real>
466  solver_params = sys.get_linear_solve_parameters();
467 
468  // Solve the linear system.
469  libMesh::SparseMatrix<Real> *
470  pc = sys.request_matrix("Preconditioner");
471 
472  std::unique_ptr<libMesh::NumericVector<Real> >
473  dvec(velocity().zero_clone().release());
474 
475  sys.linear_solver->solve (*sys.matrix, pc,
476  *dvec,
477  *sys.rhs,
478  solver_params.second,
479  solver_params.first);
480 
481  libMesh::NumericVector<Real> *vec = nullptr;
482 
483  switch (_ode_order) {
484 
485  case 1:
486  vec = &velocity_sensitivity();
487  break;
488 
489  case 2:
490  vec = &acceleration_sensitivity();
491  break;
492 
493  default:
494  // higher than 2 derivative not implemented yet.
495  libmesh_error();
496  }
497 
498  vec->add(-1., *dvec);
499 
500  // The linear solver may not have fit our constraints exactly
501 #ifdef LIBMESH_ENABLE_CONSTRAINTS
502  sys.get_dof_map().enforce_constraints_exactly(sys, vec, /* homogeneous = */ true);
503 #endif
504 
505  // next, move all the solutions and velocities into older
506  // time step locations
507  for (unsigned int i=_n_iters_to_store-1; i>0; i--) {
508 
509  this->solution_sensitivity(i).zero();
510  this->solution_sensitivity(i).add(1., this->solution_sensitivity(i-1));
511  this->solution_sensitivity(i).close();
512 
513  this->velocity_sensitivity(i).zero();
514  this->velocity_sensitivity(i).add(1., this->velocity_sensitivity(i-1));
515  this->velocity_sensitivity(i).close();
516 
517  if (_ode_order > 1) {
518 
519  this->acceleration_sensitivity(i).zero();
520  this->acceleration_sensitivity(i).add(1., this->acceleration_sensitivity(i-1));
521  this->acceleration_sensitivity(i).close();
522  }
523  }
524 
525  // finally, update the system time
526  sys.time += dt;
527  _first_sensitivity_step = false;
528 }
529 
530 
531 
532 void
534 build_local_quantities(const libMesh::NumericVector<Real>& current_sol,
535  std::vector<libMesh::NumericVector<Real>*>& sol) {
536 
537  // make sure that the system has been specified
538  libmesh_assert(_system);
539 
541  &sys = _system->system();
542 
543  // make sure there are no solutions in sol
544  libmesh_assert(!sol.size());
545 
546  // resize the vector to store the quantities
547  sol.resize(_ode_order+1);
548 
549  const std::vector<libMesh::dof_id_type>&
550  send_list = sys.get_dof_map().get_send_list();
551 
552 
553  for ( unsigned int i=0; i<=_ode_order; i++) {
554 
555  sol[i] = libMesh::NumericVector<Real>::build(sys.comm()).release();
556  sol[i]->init(sys.n_dofs(),
557  sys.n_local_dofs(),
558  send_list,
559  false,
560  libMesh::GHOSTED);
561 
562  switch (i) {
563 
564  case 0: {
565 
566  if (!_if_highest_derivative_solution)
567  // copy the solution to this
568  current_sol.localize(*sol[i], send_list);
569  else
570  solution().localize(*sol[i], send_list);
571  }
572  break;
573 
574  case 1: {
575 
576  // update the current local velocity vector
577  libMesh::NumericVector<Real>& vel = this->velocity();
578 
579  if (!_if_highest_derivative_solution)
580  // calculate the velocity and localize it
581  update_velocity(vel, current_sol);
582 
583  vel.localize(*sol[i], send_list);
584  }
585  break;
586 
587  case 2: {
588 
589  // update the current local acceleration vector
590  libMesh::NumericVector<Real>& acc = this->acceleration();
591 
592  if (!_if_highest_derivative_solution)
593  // calculate the acceleration and localize it
594  update_acceleration(acc, current_sol);
595 
596  acc.localize(*sol[i], send_list);
597  }
598  break;
599 
600  default:
601  // should not get here
602  libmesh_error();
603  break;
604  }
605  }
606 }
607 
608 
609 
610 void
612 build_sensitivity_local_quantities(unsigned int prev_iter,
613  std::vector<libMesh::NumericVector<Real>*>& sol) {
614 
615  // make sure that the system has been specified
616  libmesh_assert(_system);
617  libmesh_assert_less_equal(prev_iter, _n_iters_to_store);
618 
620  &sys = _system->system();
621 
622  // make sure there are no solutions in sol
623  libmesh_assert(!sol.size());
624 
625  // resize the vector to store the quantities
626  sol.resize(_ode_order+1);
627 
628  const std::vector<libMesh::dof_id_type>&
629  send_list = sys.get_dof_map().get_send_list();
630 
631 
632  for ( unsigned int i=0; i<=_ode_order; i++) {
633 
634  sol[i] = libMesh::NumericVector<Real>::build(sys.comm()).release();
635  sol[i]->init(sys.n_dofs(),
636  sys.n_local_dofs(),
637  send_list,
638  false,
639  libMesh::GHOSTED);
640 
641  switch (i) {
642 
643  case 0:
644  solution_sensitivity(prev_iter).localize(*sol[i], send_list);
645  break;
646 
647  case 1:
648  velocity_sensitivity(prev_iter).localize(*sol[i], send_list);
649  break;
650 
651  case 2:
652  acceleration_sensitivity(prev_iter).localize(*sol[i], send_list);
653  break;
654 
655  default:
656  // should not get here
657  libmesh_error();
658  break;
659  }
660  }
661 }
662 
663 
664 
665 
666 
667 void
668 MAST::TransientSolverBase::
669 build_perturbed_local_quantities(const libMesh::NumericVector<Real>& current_dsol,
670  std::vector<libMesh::NumericVector<Real>*>& sol) {
671 
672  // make sure that the system has been specified
673  libmesh_assert(_system);
674 
676  &sys = _system->system();
677 
678  // make sure there are no solutions in sol
679  libmesh_assert(!sol.size());
680 
681  // resize the vector to store the quantities
682  sol.resize(_ode_order+1);
683 
684  const std::vector<libMesh::dof_id_type>&
685  send_list = sys.get_dof_map().get_send_list();
686 
687 
688  std::unique_ptr<libMesh::NumericVector<Real> >
689  tmp(this->solution().zero_clone().release());
690 
691  for ( unsigned int i=0; i<=_ode_order; i++) {
692 
693  sol[i] = libMesh::NumericVector<Real>::build(sys.comm()).release();
694  sol[i]->init(sys.n_dofs(),
695  sys.n_local_dofs(),
696  send_list,
697  false,
698  libMesh::GHOSTED);
699 
700  switch (i) {
701 
702  case 0: {
703 
704  current_dsol.localize(*sol[i], send_list);
705  if (_if_highest_derivative_solution)
706  // only the highest derivative is perturbed since
707  // all lower derivative quantities are known
708  sol[i]->zero();
709  }
710  break;
711 
712  case 1: {
713 
714  if (_ode_order == 1 && _if_highest_derivative_solution)
715  // the provided solution is the current velocity increment
716  current_dsol.localize(*sol[i], send_list);
717  else if (_if_highest_derivative_solution)
718  sol[i]->zero();
719  else {
720  update_delta_velocity(*tmp, current_dsol);
721  tmp->localize(*sol[i], send_list);
722  }
723  }
724  break;
725 
726  case 2: {
727 
728  if (_ode_order == 2 && _if_highest_derivative_solution)
729  // the provided solution is the current velocity increment
730  current_dsol.localize(*sol[i], send_list);
731  else if (_if_highest_derivative_solution)
732  sol[i]->zero();
733  else {
734  update_delta_acceleration(*tmp, current_dsol);
735  tmp->localize(*sol[i], send_list);
736  }
737  }
738  break;
739 
740  default:
741  // should not get here
742  libmesh_error();
743  break;
744  }
745  }
746 }
747 
748 
749 
750 
751 void
753 
754  libmesh_assert(_system);
755  libmesh_assert(_discipline);
756 
758  &sys = _system->system();
759 
760  // first ask the solver to update the velocity and acceleration vector
761  sys.update();
762  update_velocity(this->velocity(), *sys.current_local_solution);
763 
764  if (_ode_order > 1)
765  update_acceleration(this->acceleration(), *sys.current_local_solution);
766 
767  // next, move all the solutions and velocities into older
768  // time step locations
769  for (unsigned int i=_n_iters_to_store-1; i>0; i--) {
770  this->solution(i).zero();
771  this->solution(i).add(1., this->solution(i-1));
772  this->solution(i).close();
773 
774  this->velocity(i).zero();
775  this->velocity(i).add(1., this->velocity(i-1));
776  this->velocity(i).close();
777 
778  if (_ode_order > 1) {
779 
780  this->acceleration(i).zero();
781  this->acceleration(i).add(1., this->acceleration(i-1));
782  this->acceleration(i).close();
783  }
784  }
785 
786  // finally, update the system time
787  sys.time += dt;
788  _first_step = false;
789 }
790 
791 
792 
793 void
795 
797  &sys = _system->system();
798 
799  // first ask the solver to update the velocity and acceleration vector
801 
802  if (_ode_order > 1)
804 
805  // next, move all the solutions and velocities into older
806  // time step locations
807  for (unsigned int i=_n_iters_to_store-1; i>0; i--) {
808  this->solution_sensitivity(i).zero();
809  this->solution_sensitivity(i).add(1., this->solution_sensitivity(i-1));
810  this->solution_sensitivity(i).close();
811 
812  this->velocity_sensitivity(i).zero();
813  this->velocity_sensitivity(i).add(1., this->velocity_sensitivity(i-1));
814  this->velocity_sensitivity(i).close();
815 
816  if (_ode_order > 1) {
817 
818  this->acceleration_sensitivity(i).zero();
819  this->acceleration_sensitivity(i).add(1., this->acceleration_sensitivity(i-1));
820  this->acceleration_sensitivity(i).close();
821  }
822  }
823 
824  // finally, update the system time
825  sys.time += dt;
826  _first_sensitivity_step = false;
827 }
828 
829 
830 
831 void
833  const libMesh::Elem& ref_elem,
834  MAST::GeomElem &elem) const {
835 
836  libmesh_assert(_assembly_ops);
837  _assembly_ops->set_elem_data(dim, ref_elem, elem);
838 }
839 
840 
841 void
843 
844  libmesh_assert(_assembly_ops);
845  _assembly_ops->init(elem);
846 }
847 
848 
849 
850 
851 void
853 
854  libmesh_assert(_assembly_ops);
855  _assembly_ops->clear_elem();
856 }
857 
858 
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 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 > &current_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...
Definition: geom_elem.h:59
virtual void solve(MAST::AssemblyBase &assembly)
solves the current time step for solution and velocity
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