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 : 19 : #include "libmesh/diff_context.h" 20 : #include "libmesh/diff_physics.h" 21 : #include "libmesh/system.h" 22 : #include "libmesh/variable.h" 23 : 24 : namespace libMesh 25 : { 26 : 27 72671 : DifferentiablePhysics::~DifferentiablePhysics() = default; 28 : 29 0 : void DifferentiablePhysics::clear_physics () 30 : { 31 0 : _time_evolving.resize(0); 32 0 : } 33 : 34 : 35 : 36 5967 : void DifferentiablePhysics::init_physics (const System & sys) 37 : { 38 : // give us flags for every variable that might be time evolving 39 5967 : _time_evolving.resize(sys.n_vars(), false); 40 5967 : } 41 : 42 7166 : void DifferentiablePhysics::time_evolving (unsigned int var, 43 : unsigned int order) 44 : { 45 7166 : libmesh_error_msg_if(order != 1 && order != 2, "Input order must be 1 or 2!"); 46 : 47 7378 : if (_time_evolving.size() <= var) 48 6430 : _time_evolving.resize(var+1, 0); 49 : 50 7166 : _time_evolving[var] = order; 51 : 52 7166 : if (order == 1) 53 4884 : _first_order_vars.insert(var); 54 : else 55 2070 : _second_order_vars.insert(var); 56 7166 : } 57 : 58 0 : bool DifferentiablePhysics::nonlocal_mass_residual(bool request_jacobian, 59 : DiffContext & c) 60 : { 61 0 : FEMContext & context = cast_ref<FEMContext &>(c); 62 : 63 0 : for (auto var : make_range(context.n_vars())) 64 : { 65 0 : if (!this->is_time_evolving(var)) 66 0 : continue; 67 : 68 0 : if (c.get_system().variable(var).type().family != SCALAR) 69 0 : continue; 70 : 71 : const std::vector<dof_id_type> & dof_indices = 72 0 : context.get_dof_indices(var); 73 : 74 : const unsigned int n_dofs = cast_int<unsigned int> 75 0 : (dof_indices.size()); 76 : 77 0 : DenseSubVector<Number> & Fs = context.get_elem_residual(var); 78 0 : DenseSubMatrix<Number> & Kss = context.get_elem_jacobian( var, var ); 79 : 80 : const libMesh::DenseSubVector<libMesh::Number> & Us = 81 0 : context.get_elem_solution(var); 82 : 83 0 : for (unsigned int i=0; i != n_dofs; ++i) 84 : { 85 0 : Fs(i) -= Us(i); 86 : 87 0 : if (request_jacobian) 88 0 : Kss(i,i) -= context.elem_solution_rate_derivative; 89 : } 90 : } 91 : 92 0 : return request_jacobian; 93 : } 94 : 95 : 96 : 97 20563472 : bool DifferentiablePhysics::_eulerian_time_deriv (bool request_jacobian, 98 : DiffContext & context) 99 : { 100 : // For any problem we need time derivative terms 101 : request_jacobian = 102 20563472 : this->element_time_derivative(request_jacobian, context); 103 : 104 : // For a moving mesh problem we may need the pseudoconvection term too 105 20563472 : return this->eulerian_residual(request_jacobian, context) && 106 20563472 : request_jacobian; 107 : } 108 : 109 : } // namespace libMesh