https://mooseframework.inl.gov
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 
16 template <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 
49 template <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 
65 template <bool is_ad>
67  const FunctionMaterialPropertyDescriptor & rhs, MooseObject * parent)
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 
81 template <bool is_ad>
82 std::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 
92 template <bool is_ad>
93 void
95 {
96  _derivative_symbols.push_back(var);
97  _value = nullptr;
98  updatePropertyName();
99 }
100 
101 template <bool is_ad>
102 bool
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 
111 template <bool is_ad>
112 std::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 
121 template <bool is_ad>
122 void
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 
188 template <bool is_ad>
189 void
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 
217 template <bool is_ad>
218 void
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 
230 template <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 
289 template <bool is_ad>
290 void
292 {
293  _property_name = derivativePropertyName(_base_name, _derivative_symbols);
294 }
295 
296 // explicit instantiation
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...
Definition: MaterialBase.h:448
Moose::GenericType< Real, is_ad > GenericReal
Definition: MooseTypes.h:648
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
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...
Definition: MooseError.h:302
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
Every object that can be built by the factory should be derived from this class.
Definition: MooseObject.h:28
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...
Definition: Material.h:263