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 : #include "DerivativeFunctionMaterialBase.h" 11 : 12 : #include "libmesh/quadrature.h" 13 : 14 : template <bool is_ad> 15 : InputParameters 16 29212 : DerivativeFunctionMaterialBaseTempl<is_ad>::validParams() 17 : { 18 : 19 29212 : InputParameters params = FunctionMaterialBase<is_ad>::validParams(); 20 29212 : params.addClassDescription("Material to provide a function (such as a free energy) and its " 21 : "derivatives w.r.t. the coupled variables"); 22 29212 : params.addDeprecatedParam<bool>("third_derivatives", 23 : "Flag to indicate if third derivatives are needed", 24 : "Use derivative_order instead."); 25 87636 : params.addRangeCheckedParam<unsigned int>("derivative_order", 26 58424 : 3, 27 : "derivative_order>=2 & derivative_order<=3", 28 : "Maximum order of derivatives taken (2 or 3)"); 29 29212 : return params; 30 0 : } 31 : 32 : template <bool is_ad> 33 522 : DerivativeFunctionMaterialBaseTempl<is_ad>::DerivativeFunctionMaterialBaseTempl( 34 : const InputParameters & parameters) 35 : : FunctionMaterialBase<is_ad>(parameters), 36 522 : _third_derivatives(this->template getParam<unsigned int>("derivative_order") == 3) 37 : { 38 : // reserve space for material properties and explicitly initialize to NULL 39 522 : _prop_dF.resize(_nargs, NULL); 40 522 : _prop_d2F.resize(_nargs); 41 522 : _prop_d3F.resize(_nargs); 42 1044 : for (unsigned int i = 0; i < _nargs; ++i) 43 : { 44 522 : _prop_d2F[i].resize(_nargs, NULL); 45 : 46 522 : if (_third_derivatives) 47 : { 48 132 : _prop_d3F[i].resize(_nargs); 49 : 50 264 : for (unsigned int j = 0; j < _nargs; ++j) 51 132 : _prop_d3F[i][j].resize(_nargs, NULL); 52 : } 53 : } 54 : 55 : // initialize derivatives 56 1044 : for (unsigned int i = 0; i < _nargs; ++i) 57 : { 58 522 : if (!Coupleable::isCoupledConstant(_arg_names[i])) 59 522 : _prop_dF[i] = &this->template declarePropertyDerivative<Real, is_ad>(_F_name, _arg_names[i]); 60 : 61 : // second derivatives 62 1044 : for (unsigned int j = i; j < _nargs; ++j) 63 : { 64 522 : if (!Coupleable::isCoupledConstant(_arg_names[i])) 65 1044 : _prop_d2F[i][j] = _prop_d2F[j][i] = &this->template declarePropertyDerivative<Real, is_ad>( 66 522 : _F_name, _arg_names[i], _arg_names[j]); 67 : 68 : // third derivatives 69 522 : if (_third_derivatives) 70 : { 71 264 : for (unsigned int k = j; k < _nargs; ++k) 72 : { 73 : // filling all permutations does not cost us much and simplifies access 74 : // (no need to check i<=j<=k) 75 132 : if (!Coupleable::isCoupledConstant(_arg_names[i])) 76 132 : _prop_d3F[i][j][k] = _prop_d3F[k][i][j] = _prop_d3F[j][k][i] = _prop_d3F[k][j][i] = 77 132 : _prop_d3F[j][i][k] = _prop_d3F[i][k][j] = 78 132 : &this->template declarePropertyDerivative<Real, is_ad>( 79 132 : _F_name, _arg_names[i], _arg_names[j], _arg_names[k]); 80 : } 81 : } 82 : } 83 : } 84 522 : } 85 : 86 : template <bool is_ad> 87 : void 88 0 : DerivativeFunctionMaterialBaseTempl<is_ad>::initialSetup() 89 : { 90 : // set the _prop_* pointers of all material properties that are not beeing used back to NULL 91 0 : bool needs_third_derivatives = false; 92 : 93 0 : if (!this->_fe_problem.isMatPropRequested(_F_name)) 94 0 : _prop_F = NULL; 95 : 96 0 : for (unsigned int i = 0; i < _nargs; ++i) 97 : { 98 0 : if (!this->_fe_problem.isMatPropRequested( 99 0 : this->derivativePropertyNameFirst(_F_name, _arg_names[i]))) 100 0 : _prop_dF[i] = NULL; 101 : 102 : // second derivatives 103 0 : for (unsigned int j = i; j < _nargs; ++j) 104 : { 105 0 : if (!this->_fe_problem.isMatPropRequested( 106 0 : this->derivativePropertyNameSecond(_F_name, _arg_names[i], _arg_names[j]))) 107 0 : _prop_d2F[i][j] = _prop_d2F[j][i] = NULL; 108 : 109 : // third derivatives 110 0 : if (_third_derivatives) 111 : { 112 0 : for (unsigned int k = j; k < _nargs; ++k) 113 : { 114 0 : if (!this->_fe_problem.isMatPropRequested(this->derivativePropertyNameThird( 115 0 : _F_name, _arg_names[i], _arg_names[j], _arg_names[k]))) 116 0 : _prop_d3F[i][j][k] = _prop_d3F[k][i][j] = _prop_d3F[j][k][i] = _prop_d3F[k][j][i] = 117 0 : _prop_d3F[j][i][k] = _prop_d3F[i][k][j] = NULL; 118 : else 119 0 : needs_third_derivatives = true; 120 : } 121 : 122 0 : if (!needs_third_derivatives) 123 0 : mooseWarning("This simulation does not actually need the third derivatives of " 124 : "DerivativeFunctionMaterialBaseTempl " + 125 0 : name()); 126 : } 127 : } 128 : } 129 0 : } 130 : 131 : template <bool is_ad> 132 : void 133 0 : DerivativeFunctionMaterialBaseTempl<is_ad>::computeProperties() 134 : { 135 0 : for (_qp = 0; _qp < _qrule->n_points(); _qp++) 136 : { 137 : // set function value 138 0 : if (_prop_F) 139 0 : (*_prop_F)[_qp] = computeF(); 140 : 141 0 : for (unsigned int i = 0; i < _nargs; ++i) 142 : { 143 : // set first derivatives 144 0 : if (_prop_dF[i]) 145 0 : (*_prop_dF[i])[_qp] = computeDF(_arg_numbers[i]); 146 : 147 : // second derivatives 148 0 : for (unsigned int j = i; j < _nargs; ++j) 149 : { 150 0 : if (_prop_d2F[i][j]) 151 0 : (*_prop_d2F[i][j])[_qp] = computeD2F(_arg_numbers[i], _arg_numbers[j]); 152 : 153 : // third derivatives 154 0 : if (_third_derivatives) 155 : { 156 0 : for (unsigned int k = j; k < _nargs; ++k) 157 0 : if (_prop_d3F[i][j][k]) 158 0 : (*_prop_d3F[i][j][k])[_qp] = 159 0 : computeD3F(_arg_numbers[i], _arg_numbers[j], _arg_numbers[k]); 160 : } 161 : } 162 : } 163 : } 164 0 : } 165 : 166 : // explicit instantiation 167 : template class DerivativeFunctionMaterialBaseTempl<true>; 168 : template class DerivativeFunctionMaterialBaseTempl<false>;