Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://mooseframework.inl.gov 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #pragma once 11 : 12 : #include "Assembly.h" 13 : #include "Coupleable.h" 14 : #include "InputParameters.h" 15 : #include "MooseVariableFE.h" 16 : #include "MooseObject.h" 17 : 18 : /** 19 : * Users of this template class must specify the type of shape functions that 20 : * will be used in the Jacobian calculation. Current options are for volume 21 : * shape functions (specified with ShapeType::Element, accessed with _assembly.phi()) 22 : * and for surface shape functions (specified with ShapeType::Side, accessed with 23 : * _assembly.phiFace()) 24 : */ 25 : 26 : enum class ShapeType 27 : { 28 : Element, 29 : Side 30 : }; 31 : 32 : /** 33 : * UserObject template class in which the _phi and _grad_phi shape function data 34 : * is available and correctly initialized on EXEC_NONLINEAR (the Jacobian calculation). 35 : * This enables the calculation of Jacobian matrix contributions inside a UO. 36 : * 37 : * \warning It is up to the user to ensure _fe_problem.currentlyComputingJacobian() 38 : * returns true before utilizing the shape functions. 39 : */ 40 : template <typename T> 41 : class ShapeUserObject : public T 42 : { 43 : public: 44 : static InputParameters validParams(); 45 : 46 : ShapeUserObject(const InputParameters & parameters, ShapeType type); 47 : 48 : /// check if jacobian is to be computed in user objects 49 122 : const bool & computeJacobianFlag() const { return _compute_jacobians; } 50 : 51 : /** 52 : * Returns the set of variables a Jacobian has been requested for 53 : */ 54 122 : const std::set<const MooseVariableFEBase *> & jacobianMooseVariables() const 55 : { 56 122 : return _jacobian_moose_variables; 57 : } 58 : 59 : /** 60 : * This function will be called with the shape functions for jvar initialized. It 61 : * can be used to compute Jacobian contributions of the by implementing executeJacobian. 62 : */ 63 : virtual void executeJacobianWrapper(unsigned int jvar, 64 : const std::vector<dof_id_type> & dof_indices); 65 : 66 : protected: 67 : /** 68 : * Implement this function to compute Jacobian terms for this UserObject. The 69 : * shape function index _j and its corrsponding global DOF index _j_global 70 : * will be provided. 71 : */ 72 : virtual void executeJacobian(unsigned int /*jvar*/) = 0; 73 : 74 : /** 75 : * Returns the index for a coupled variable by name and requests the computation 76 : * of a Jacobian w.r.t. to this variable i.e. the call to executeJacobian() with 77 : * shapefunctions initialized for this variable. 78 : */ 79 : virtual unsigned int coupled(const std::string & var_name, unsigned int comp = 0) const override; 80 : 81 : /// shape function values 82 : const VariablePhiValue & _phi; 83 : 84 : /// shape function gradients 85 : const VariablePhiGradient & _grad_phi; 86 : 87 : /// j-th index for enumerating the shape functions 88 : unsigned int _j; 89 : 90 : /// global DOF ID corresponding to _j 91 : dof_id_type _j_global; 92 : 93 : private: 94 : const bool _compute_jacobians; 95 : mutable std::set<const MooseVariableFEBase *> _jacobian_moose_variables; 96 : }; 97 : 98 : template <typename T> 99 122 : ShapeUserObject<T>::ShapeUserObject(const InputParameters & parameters, ShapeType type) 100 : : T(parameters), 101 122 : _phi(type == ShapeType::Element ? this->_assembly.phi() : this->_assembly.phiFace()), 102 122 : _grad_phi(type == ShapeType::Element ? this->_assembly.gradPhi() 103 68 : : this->_assembly.gradPhiFace()), 104 244 : _compute_jacobians(MooseObject::getParam<bool>("compute_jacobians")) 105 : { 106 122 : mooseWarning("Jacobian calculation in UserObjects is an experimental capability with a " 107 : "potentially unstable interface."); 108 122 : } 109 : 110 : template <typename T> 111 : InputParameters 112 71559 : ShapeUserObject<T>::validParams() 113 : { 114 71559 : InputParameters params = emptyInputParameters(); 115 71559 : params.addParam<bool>("compute_jacobians", true, "Compute Jacobians for coupled variables"); 116 71559 : params.addParamNamesToGroup("compute_jacobians", "Advanced"); 117 71559 : return params; 118 0 : } 119 : 120 : template <typename T> 121 : unsigned int 122 166 : ShapeUserObject<T>::coupled(const std::string & var_name, unsigned int comp) const 123 : { 124 166 : const auto * var = this->template getVarHelper<MooseVariable>(var_name, comp); 125 : 126 : // add to the set of variables for which executeJacobian will be called 127 166 : if (_compute_jacobians && var->kind() == Moose::VAR_SOLVER) 128 166 : _jacobian_moose_variables.insert(var); 129 : 130 : // return the variable number 131 166 : return T::coupled(var_name, comp); 132 : } 133 : 134 : template <typename T> 135 : void 136 2804 : ShapeUserObject<T>::executeJacobianWrapper(unsigned int jvar, 137 : const std::vector<dof_id_type> & dof_indices) 138 : { 139 22332 : for (_j = 0; _j < _phi.size(); ++_j) 140 : { 141 19528 : _j_global = dof_indices[_j]; 142 19528 : executeJacobian(jvar); 143 : } 144 2804 : }