https://mooseframework.inl.gov
Loading...
Searching...
No Matches
FunctionMaterialPropertyDescriptor.C
Go to the documentation of this file.
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
12#include "Material.h"
13#include "Kernel.h"
14#include <algorithm>
15
16template <bool is_ad>
18 const std::string & expression, MooseObject * parent, bool required)
19 : _state(PropertyState::CURRENT),
20 _dependent_symbols(),
21 _derivative_symbols(),
22 _value(nullptr),
23 _old_older_value(nullptr),
24 _parent(parent),
25 _required(required)
26{
27 auto define = expression.find_last_of(":=");
28
29 // expression contains a ':='
30 if (define != std::string::npos)
31 {
32 // section before ':=' is the name used in the function expression
33 _fparser_name = expression.substr(0, define - 1);
34
35 // parse right hand side
36 parseDerivative(expression.substr(define + 1));
37 }
38 else
39 {
40 // parse entire expression and use natural material property base name
41 // for D(x(t),t,t) this would simply be 'x'!
42 parseDerivative(expression);
44 }
45
47}
48
49template <bool is_ad>
52 : _state(rhs._state),
53 _fparser_name(rhs._fparser_name),
54 _base_name(rhs._base_name),
55 _dependent_symbols(rhs._dependent_symbols),
56 _derivative_symbols(rhs._derivative_symbols),
57 _value(nullptr),
58 _old_older_value(nullptr),
59 _parent(rhs._parent),
60 _property_name(rhs._property_name),
61 _required(false)
62{
63}
64
65template <bool is_ad>
68 : _state(rhs._state),
69 _fparser_name(rhs._fparser_name),
70 _base_name(rhs._base_name),
71 _dependent_symbols(rhs._dependent_symbols),
72 _derivative_symbols(rhs._derivative_symbols),
73 _value(nullptr),
74 _old_older_value(nullptr),
75 _parent(parent),
76 _property_name(rhs._property_name),
77 _required(false)
78{
79}
80
81template <bool is_ad>
82std::vector<FunctionMaterialPropertyDescriptor<is_ad>>
84 const std::vector<std::string> & expression_list, MooseObject * parent)
85{
86 std::vector<FunctionMaterialPropertyDescriptor> fmpds;
87 for (auto & ex : expression_list)
88 fmpds.push_back(FunctionMaterialPropertyDescriptor(ex, parent));
89 return fmpds;
90}
91
92template <bool is_ad>
93void
95{
96 _derivative_symbols.push_back(var);
97 _value = nullptr;
98 updatePropertyName();
99}
100
101template <bool is_ad>
102bool
104{
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();
109}
110
111template <bool is_ad>
112std::vector<DerivativeMaterialPropertyNameInterface::SymbolName>
114{
115 std::set<SymbolName> all(_dependent_symbols.begin(), _dependent_symbols.end());
116 all.insert(_derivative_symbols.begin(), _derivative_symbols.end());
117
118 return std::vector<SymbolName>(all.begin(), all.end());
119}
120
121template <bool is_ad>
122void
124{
125 auto open = expression.find_first_of("[");
126 auto close = expression.find_last_of("]");
127
128 if (open == std::string::npos && close == std::string::npos)
129 {
130 // no derivative requested
131 parseDependentSymbols(expression);
132
133 return;
134 }
135 if (open != std::string::npos && close != std::string::npos)
136 {
137 if (expression.substr(0, open) == "Old")
138 {
139 _base_name = expression.substr(open + 1, close - open - 1);
140 _dependent_symbols.clear();
141 _state = PropertyState::OLD;
142 return;
143 }
144 if (expression.substr(0, open) == "Older")
145 {
146 _base_name = expression.substr(open + 1, close - open - 1);
147 _dependent_symbols.clear();
148 _state = PropertyState::OLDER;
149 return;
150 }
151 else if (expression.substr(0, open) == "D")
152 {
153 auto arguments = expression.substr(open + 1, close - open - 1);
154 auto close2 = arguments.find_last_of(")");
155
156 if (close2 == std::string::npos)
157 {
158 // rest of argument list 0 is the function and 1,.. are the variable to take the derivative
159 // w.r.t.
160 MooseUtils::tokenize(arguments, _derivative_symbols, 0, ",");
161
162 // check for empty [] brackets
163 if (_derivative_symbols.size() > 0)
164 {
165 // parse argument zero of D[] as the function material property
166 parseDependentSymbols(_derivative_symbols[0]);
167
168 // remove function from the _derivative_symbols vector
169 _derivative_symbols.erase(_derivative_symbols.begin());
170 updatePropertyName();
171
172 return;
173 }
174 }
175 else
176 {
177 parseDependentSymbols(arguments.substr(0, close2 + 1));
178 MooseUtils::tokenize(arguments.substr(close2 + 2), _derivative_symbols, 0, ",");
179 updatePropertyName();
180 return;
181 }
182 }
183 }
184
185 mooseError("Malformed material_properties expression '", expression, "'");
186}
187
188template <bool is_ad>
189void
191{
192 auto open = expression.find_first_of("(");
193 auto close = expression.find_last_of(")");
194
195 if (open == std::string::npos && close == std::string::npos)
196 {
197 // material property name without arguments
198 _base_name = expression;
199 }
200 else if (open != std::string::npos && close != std::string::npos)
201 {
202 // take material property name before bracket
203 _base_name = expression.substr(0, open);
204
205 // parse argument list
206 MooseUtils::tokenize(expression.substr(open + 1, close - open - 1), _dependent_symbols, 0, ",");
207
208 // remove duplicates from dependent variable list
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());
212 }
213 else
214 mooseError("Malformed material_properties expression '", expression, "'");
215}
216
217template <bool is_ad>
218void
220{
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';
228}
229
230template <bool is_ad>
233{
234 // current property
235 if (_state == PropertyState::CURRENT)
236 {
237 if (_value == nullptr)
238 {
239 DerivativeMaterialInterface<Material> * _material_parent =
240 dynamic_cast<DerivativeMaterialInterface<Material> *>(_parent);
241 DerivativeMaterialInterface<Kernel> * _kernel_parent =
242 dynamic_cast<DerivativeMaterialInterface<Kernel> *>(_parent);
243
244 // property name
245 auto name = derivativePropertyName(_base_name, _derivative_symbols);
246
247 // get the material property reference
248 if (_material_parent)
249 _value = _required ? &(_material_parent->getGenericMaterialProperty<Real, is_ad>(name))
250 : &(_material_parent->getGenericZeroMaterialProperty<Real, is_ad>(name));
251 else if (_kernel_parent)
252 _value = _required ? &(_kernel_parent->getGenericMaterialProperty<Real, is_ad>(name))
253 : &(_kernel_parent->getGenericZeroMaterialProperty<Real, is_ad>(name));
254 else
255 mooseError("A FunctionMaterialPropertyDescriptor must be owned by either a Material or a "
256 "Kernel object.");
257 }
258
259 return qp != libMesh::invalid_uint ? (*_value)[qp] : 0.0;
260 }
261
262 // old or older property
263 if (_old_older_value == nullptr)
264 {
265 mooseAssert(_derivative_symbols.empty(), "Don't take derivatives of old/older properties.");
266
267 DerivativeMaterialInterface<Material> * _material_parent =
268 dynamic_cast<DerivativeMaterialInterface<Material> *>(_parent);
269 DerivativeMaterialInterface<Kernel> * _kernel_parent =
270 dynamic_cast<DerivativeMaterialInterface<Kernel> *>(_parent);
271
272 // get the material property reference
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));
281 else
282 mooseError("A FunctionMaterialPropertyDescriptor must be owned by either a Material or a "
283 "Kernel object.");
284 }
285
286 return qp != libMesh::invalid_uint ? (*_old_older_value)[qp] : 0.0;
287}
288
289template <bool is_ad>
290void
292{
293 _property_name = derivativePropertyName(_base_name, _derivative_symbols);
294}
295
296// explicit instantiation
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
Moose::GenericType< Real, is_ad > GenericReal
Definition MooseTypes.h:698
Interface class ("Veneer") to provide generator methods for derivative material property names.
Material properties get fully described using this structure, including their dependent variables and...
std::string _base_name
function material property base name
bool dependsOn(const SymbolName &symbol) const
Check if a material property depends on a given FParser symbol.
FunctionMaterialPropertyDescriptor()=delete
no default constructor
void printDebug()
output the internal state of this descriptor for debugging purposes
std::string _fparser_name
name used in function expression
GenericReal< is_ad > value(unsigned int qp=libMesh::invalid_uint) const
get the property value at the given quadrature point
static std::vector< FunctionMaterialPropertyDescriptor > parseVector(const std::vector< std::string > &, MooseObject *)
construct a vector of FunctionMaterialPropertyDescriptors from a vector of strings
void updatePropertyName()
update the cached _property_name member
std::vector< SymbolName > getDependentSymbols()
builds a list of dependent symbols (exactly all symbols for which depends on returns true)
void addDerivative(const SymbolName &symbol)
take another derivative
Every object that can be built by the factory should be derived from this class.
Definition MooseObject.h:31
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 ...
const unsigned int invalid_uint