Line data Source code
1 : // The libMesh Finite Element Library. 2 : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 3 : 4 : // This library is free software; you can redistribute it and/or 5 : // modify it under the terms of the GNU Lesser General Public 6 : // License as published by the Free Software Foundation; either 7 : // version 2.1 of the License, or (at your option) any later version. 8 : 9 : // This library is distributed in the hope that it will be useful, 10 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 : // Lesser General Public License for more details. 13 : 14 : // You should have received a copy of the GNU Lesser General Public 15 : // License along with this library; if not, write to the Free Software 16 : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 : 18 : #ifndef LIBMESH_FIRST_ORDER_UNSTEADY_SOLVER_H 19 : #define LIBMESH_FIRST_ORDER_UNSTEADY_SOLVER_H 20 : 21 : #include "libmesh/unsteady_solver.h" 22 : 23 : namespace libMesh 24 : { 25 : /** 26 : * Generic class from which first order UnsteadySolvers should subclass. 27 : * 28 : * Subclasses of this class are meant to solve problems of the form 29 : * \f[ M(u)\dot{u} = F(u)\f] 30 : * 31 : * There is also infrastructure for subclasses to support solving second 32 : * order-in-time systems (or both first order and second order). 33 : * In particular, consider the second system 34 : * \f[ M(u)\ddot{u} + C(u)\dot{u} + F(u) = 0 \f] 35 : * If we introduce the equation \f$\dot{u} = v\f$, then, we have the 36 : * following first order system: 37 : * \f{eqnarray}{ \dot{u} &=& v \\ M(u)\dot{v} + C(u)v + F(u) &=& 0\f} 38 : * Such systems are supported by the user specifying that the time order 39 : * of the variable \f$u\f$ is 2 when adding the variable using 40 : * FEMSystem::time_evolving. This class will then add the \f$v\f$ variables 41 : * to the FEMSystem (named "dot_u" if the second order variable name is "u"). 42 : * Subclasses will then need to make sure to use the function 43 : * FirstOrderUnsteadySolver::prepare_accel() to prepare data structures for the 44 : * users to use from FEMContext. Furthermore, subclasses will need to appropriately 45 : * call damping_residual functions. Finally, subclasses will call 46 : * FirstOrderUnsteadySolver::compute_second_order_eqns() to actually assemble 47 : * residual and Jacobians for the \f$ \dot{u} = v\f$ equations. These aspects 48 : * should be invisible ot users during their element assembly. 49 : * 50 : * Unfortunately, complete usage of the feature of treating second order 51 : * equations as a system of first order equations is not completely invisible 52 : * to the user. The user must assemble their residual in the correct equation. 53 : * In particular, the residual must go in the \f$v\f$ residual equation, i.e. 54 : * \f$ M(u)\dot{v} + C(u)v + F(u) = 0 \f$, and, 55 : * subsequently, they must also be careful to populate to the correct Jacobian 56 : * blocks. The function to help facilitate this is get_second_order_dot_var. 57 : * If you have a second order variable, you pass that variable index and 58 : * get_second_order_dot_var will return the index of the corresponding velocity 59 : * variable, \f$v\f$ in the notation above. Then, the user knows what blocks to 60 : * populate. 61 : * 62 : * \note The API is designed so that if the user codes to this 63 : * paradigm, the TimeSolver will be interchangeable for those element 64 : * kernels. That is, they'll be able to use either a 65 : * FirstOrderUnsteadySolver or a SecondOrderUnsteadySolver. 66 : * 67 : * This class is part of the new DifferentiableSystem framework, 68 : * which is still experimental. Users of this framework should 69 : * beware of bugs and future API changes. 70 : * 71 : * \author Paul T. Bauman 72 : * \date 2015 73 : */ 74 : class FirstOrderUnsteadySolver : public UnsteadySolver 75 : { 76 : public: 77 : /** 78 : * Constructor. Requires a reference to the system 79 : * to be solved. 80 : */ 81 : explicit 82 76 : FirstOrderUnsteadySolver (sys_type & s) 83 2673 : : UnsteadySolver(s) {} 84 : 85 : /** 86 : * Destructor. 87 : */ 88 2673 : virtual ~FirstOrderUnsteadySolver () = default; 89 : 90 86467762 : virtual unsigned int time_order() const override 91 86467762 : { return 1; } 92 : 93 : virtual void integrate_qoi_timestep() override = 0; 94 : 95 : #ifdef LIBMESH_ENABLE_AMR 96 : virtual void integrate_adjoint_refinement_error_estimate(AdjointRefinementEstimator & adjoint_refinement_error_estimator, ErrorVector & QoI_elementwise_error) override = 0; 97 : #endif // LIBMESH_ENABLE_AMR 98 : 99 : protected: 100 : 101 : /** 102 : * If there are second order variables in the system, 103 : * then we also prepare the accel for those variables 104 : * so the user can treat them as such. 105 : */ 106 : void prepare_accel(DiffContext & context); 107 : 108 : /** 109 : * If there are second order variables, then we need to compute their residual equations 110 : * and corresponding Jacobian. The residual equation will simply be 111 : * \f$ \dot{u} - v = 0 \f$, where \f$ u \f$ is the second order variable add 112 : * by the user and \f$ v \f$ is the variable added by the time-solver as the 113 : * "velocity" variable. 114 : */ 115 : bool compute_second_order_eqns(bool compute_jacobian, DiffContext & c); 116 : 117 : }; 118 : 119 : } // end namespace libMesh 120 : 121 : #endif // LIBMESH_FIRST_ORDER_UNSTEADY_SOLVER_H