18 const std::string & expression,
MooseObject * parent,
bool required)
21 _derivative_symbols(),
23 _old_older_value(nullptr),
27 auto define = expression.find_last_of(
":=");
30 if (define != std::string::npos)
53 _fparser_name(rhs._fparser_name),
54 _base_name(rhs._base_name),
55 _dependent_symbols(rhs._dependent_symbols),
56 _derivative_symbols(rhs._derivative_symbols),
58 _old_older_value(nullptr),
60 _property_name(rhs._property_name),
69 _fparser_name(rhs._fparser_name),
70 _base_name(rhs._base_name),
71 _dependent_symbols(rhs._dependent_symbols),
72 _derivative_symbols(rhs._derivative_symbols),
74 _old_older_value(nullptr),
76 _property_name(rhs._property_name),
82 std::vector<FunctionMaterialPropertyDescriptor<is_ad>>
84 const std::vector<std::string> & expression_list,
MooseObject * parent)
86 std::vector<FunctionMaterialPropertyDescriptor> fmpds;
87 for (
auto & ex : expression_list)
96 _derivative_symbols.push_back(var);
101 template <
bool is_ad>
105 return std::find(_dependent_symbols.begin(), _dependent_symbols.end(), var) !=
106 _dependent_symbols.end() ||
107 std::find(_derivative_symbols.begin(), _derivative_symbols.end(), var) !=
108 _derivative_symbols.end();
111 template <
bool is_ad>
112 std::vector<DerivativeMaterialPropertyNameInterface::SymbolName>
115 std::set<SymbolName> all(_dependent_symbols.begin(), _dependent_symbols.end());
116 all.insert(_derivative_symbols.begin(), _derivative_symbols.end());
118 return std::vector<SymbolName>(all.begin(), all.end());
121 template <
bool is_ad>
125 auto open = expression.find_first_of(
"[");
126 auto close = expression.find_last_of(
"]");
128 if (open == std::string::npos && close == std::string::npos)
131 parseDependentSymbols(expression);
135 if (open != std::string::npos && close != std::string::npos)
137 if (expression.substr(0, open) ==
"Old")
139 _base_name = expression.substr(open + 1, close - open - 1);
140 _dependent_symbols.clear();
141 _state = PropertyState::OLD;
144 if (expression.substr(0, open) ==
"Older")
146 _base_name = expression.substr(open + 1, close - open - 1);
147 _dependent_symbols.clear();
148 _state = PropertyState::OLDER;
151 else if (expression.substr(0, open) ==
"D")
153 auto arguments = expression.substr(open + 1, close - open - 1);
154 auto close2 = arguments.find_last_of(
")");
156 if (close2 == std::string::npos)
163 if (_derivative_symbols.size() > 0)
166 parseDependentSymbols(_derivative_symbols[0]);
169 _derivative_symbols.erase(_derivative_symbols.begin());
170 updatePropertyName();
177 parseDependentSymbols(arguments.substr(0, close2 + 1));
179 updatePropertyName();
185 mooseError(
"Malformed material_properties expression '", expression,
"'");
188 template <
bool is_ad>
192 auto open = expression.find_first_of(
"(");
193 auto close = expression.find_last_of(
")");
195 if (open == std::string::npos && close == std::string::npos)
198 _base_name = expression;
200 else if (open != std::string::npos && close != std::string::npos)
203 _base_name = expression.substr(0, open);
206 MooseUtils::tokenize(expression.substr(open + 1, close - open - 1), _dependent_symbols, 0,
",");
209 std::sort(_dependent_symbols.begin(), _dependent_symbols.end());
210 _dependent_symbols.erase(std::unique(_dependent_symbols.begin(), _dependent_symbols.end()),
211 _dependent_symbols.end());
214 mooseError(
"Malformed material_properties expression '", expression,
"'");
217 template <
bool is_ad>
221 Moose::out <<
"MPD: " << _fparser_name <<
' ' << _base_name <<
" deriv = [";
222 for (
auto & dv : _derivative_symbols)
223 Moose::out << dv <<
' ';
224 Moose::out <<
"] dep = [";
225 for (
auto & dv : _dependent_symbols)
226 Moose::out << dv <<
' ';
227 Moose::out <<
"] " << getPropertyName() <<
'\n';
230 template <
bool is_ad>
235 if (_state == PropertyState::CURRENT)
237 if (_value ==
nullptr)
245 auto name = derivativePropertyName(_base_name, _derivative_symbols);
248 if (_material_parent)
251 else if (_kernel_parent)
252 _value = _required ? &(_kernel_parent->getGenericMaterialProperty<
Real, is_ad>(
name))
253 : &(_kernel_parent->getGenericZeroMaterialProperty<
Real, is_ad>(
name));
255 mooseError(
"A FunctionMaterialPropertyDescriptor must be owned by either a Material or a " 263 if (_old_older_value ==
nullptr)
265 mooseAssert(_derivative_symbols.empty(),
"Don't take derivatives of old/older properties.");
273 if (_material_parent)
274 _old_older_value = (_state == PropertyState::OLD)
275 ? &(_material_parent->getMaterialPropertyOld<
Real>(_base_name))
276 : &(_material_parent->getMaterialPropertyOlder<
Real>(_base_name));
277 else if (_kernel_parent)
278 _old_older_value = (_state == PropertyState::OLD)
279 ? &(_kernel_parent->getMaterialPropertyOld<
Real>(_base_name))
280 : &(_kernel_parent->getMaterialPropertyOlder<
Real>(_base_name));
282 mooseError(
"A FunctionMaterialPropertyDescriptor must be owned by either a Material or a " 289 template <
bool is_ad>
293 _property_name = derivativePropertyName(_base_name, _derivative_symbols);
std::string name(const ElemQuality q)
const GenericMaterialProperty< T, is_ad > & getGenericZeroMaterialProperty(const std::string &name)
Return a material property that is initialized to zero by default and does not need to (but can) be d...
Moose::GenericType< Real, is_ad > GenericReal
GenericReal< is_ad > value(unsigned int qp=libMesh::invalid_uint) const
get the property value at the given quadrature point
void tokenize(const std::string &str, std::vector< T > &elements, unsigned int min_len=1, const std::string &delims="/")
This function will split the passed in string on a set of delimiters appending the substrings to the ...
std::string _base_name
function material property base name
const unsigned int invalid_uint
void parseDependentSymbols(const std::string &)
Material properties get fully described using this structure, including their dependent variables and...
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
void printDebug()
output the internal state of this descriptor for debugging purposes
void addDerivative(const SymbolName &symbol)
take another derivative
FunctionMaterialPropertyDescriptor()=delete
no default constructor
PropertyState
property state
Every object that can be built by the factory should be derived from this class.
void parseDerivative(const std::string &)
static std::vector< FunctionMaterialPropertyDescriptor > parseVector(const std::vector< std::string > &, MooseObject *)
construct a vector of FunctionMaterialPropertyDescriptors from a vector of strings ...
std::string _fparser_name
name used in function expression
void updatePropertyName()
update the cached _property_name member
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
bool dependsOn(const SymbolName &symbol) const
Check if a material property depends on a given FParser symbol.
std::vector< SymbolName > getDependentSymbols()
builds a list of dependent symbols (exactly all symbols for which depends on returns true) ...
const GenericMaterialProperty< T, is_ad > & getGenericMaterialProperty(const std::string &name, const unsigned int state=0)
Retrieve the property through a given input parameter key with a fallback to getting it by name...