www.mooseframework.org
DerivativeMaterialInterface.h
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 "AuxiliarySystem.h"
13 #include "BlockRestrictable.h"
14 #include "BoundaryRestrictable.h"
16 #include "KernelBase.h"
17 #include "BoundaryCondition.h"
18 #include "Material.h"
19 #include "MooseVariableFE.h"
20 #include "NonlinearSystem.h"
21 
22 // Forward declarations
23 class FEProblemBase;
24 template <typename>
26 
31 template <class T>
33 {
34 public:
36 
37  DerivativeMaterialInterface(const InputParameters & parameters);
38 
43  template <typename U, bool is_ad = false>
44  const GenericMaterialProperty<U, is_ad> & getDefaultMaterialProperty(const std::string & name);
45 
47  template <typename U, bool is_ad = false>
49  getDefaultMaterialPropertyByName(const std::string & name);
50 
52 
58  template <typename U, bool is_ad = false>
60  declarePropertyDerivative(const std::string & base, const std::vector<VariableName> & c);
61 
62  template <typename U, bool is_ad = false>
64  const std::vector<SymbolName> & c);
65 
66  template <typename U, bool is_ad = false>
68  const SymbolName & c1,
69  const SymbolName & c2 = "",
70  const SymbolName & c3 = "");
72 
74 
80  template <typename U, bool is_ad = false>
82  getMaterialPropertyDerivative(const std::string & base, const std::vector<VariableName> & c);
83 
84  template <typename U, bool is_ad = false>
86  getMaterialPropertyDerivative(const std::string & base, const std::vector<SymbolName> & c);
87 
88  template <typename U, bool is_ad = false>
90  getMaterialPropertyDerivative(const std::string & base,
91  const SymbolName & c1,
92  const SymbolName & c2 = "",
93  const SymbolName & c3 = "");
95 
101  template <typename U, bool is_ad = false>
103  getMaterialPropertyDerivative(const std::string & base,
104  const SymbolName & c1,
105  unsigned int v2,
106  unsigned int v3 = libMesh::invalid_uint);
107 
108  template <typename U, bool is_ad = false>
110  getMaterialPropertyDerivative(const std::string & base,
111  unsigned int v1,
112  unsigned int v2 = libMesh::invalid_uint,
113  unsigned int v3 = libMesh::invalid_uint);
115 
117 
123  template <typename U, bool is_ad = false>
125  getMaterialPropertyDerivativeByName(const MaterialPropertyName & base,
126  const std::vector<VariableName> & c);
127 
128  template <typename U, bool is_ad = false>
130  getMaterialPropertyDerivativeByName(const MaterialPropertyName & base,
131  const std::vector<SymbolName> & c);
132 
133  template <typename U, bool is_ad = false>
135  getMaterialPropertyDerivativeByName(const MaterialPropertyName & base,
136  const SymbolName & c1,
137  const SymbolName & c2 = "",
138  const SymbolName & c3 = "");
140 
142 
146  template <typename U, bool is_ad = false>
147  void validateCoupling(const MaterialPropertyName & base,
148  const std::vector<VariableName> & c,
149  bool validate_aux = true);
150 
151  template <typename U, bool is_ad = false>
152  void validateCoupling(const MaterialPropertyName & base,
153  const VariableName & c1 = "",
154  const VariableName & c2 = "",
155  const VariableName & c3 = "");
156 
157  template <typename U, bool is_ad = false>
158  void validateNonlinearCoupling(const MaterialPropertyName & base,
159  const VariableName & c1 = "",
160  const VariableName & c2 = "",
161  const VariableName & c3 = "");
163 
170  template <typename U, bool is_ad = false>
171  void validateDerivativeMaterialPropertyBase(const std::string & base);
172 
173 private:
175  template <typename U, bool is_ad = false>
176  bool haveMaterialProperty(const std::string & prop_name);
177 
179  std::vector<VariableName>
180  buildVariableVector(const VariableName & c1, const VariableName & c2, const VariableName & c3);
181 
183  template <typename U, bool is_ad = false>
184  void validateCouplingHelper(const MaterialPropertyName & base,
185  const std::vector<VariableName> & c,
186  const System & system,
187  std::vector<VariableName> & missing);
188 
189  // check if the specified variable name is not the variable this kernel is acting on (always true
190  // for any other type of object)
191  bool isNotObjectVariable(const VariableName & name);
192 
195 };
196 
197 template <class T>
199  : T(parameters),
200  _dmi_fe_problem(*parameters.getCheckedPointerParam<FEProblemBase *>("_fe_problem_base"))
201 {
202 }
203 
204 template <>
205 template <typename U, bool is_ad>
206 bool
208 {
209  return ((this->boundaryRestricted() &&
210  this->template hasBoundaryMaterialProperty<U, is_ad>(prop_name)) ||
211  (this->template hasBlockMaterialProperty<U, is_ad>(prop_name)));
212 }
213 
214 template <class T>
215 template <typename U, bool is_ad>
216 bool
218 {
219  // Call the correct method to test for material property declarations
220  BlockRestrictable * blk = dynamic_cast<BlockRestrictable *>(this);
221  BoundaryRestrictable * bnd = dynamic_cast<BoundaryRestrictable *>(this);
222  return ((bnd && bnd->boundaryRestricted() &&
223  bnd->template hasBoundaryMaterialProperty<U, is_ad>(prop_name)) ||
224  (blk && blk->template hasBlockMaterialProperty<U, is_ad>(prop_name)) ||
225  (this->template hasGenericMaterialProperty<U, is_ad>(prop_name)));
226 }
227 
228 template <class T>
229 template <typename U, bool is_ad>
232 {
233  // get the base property name
234  std::string prop_name = this->getMaterialPropertyName(name);
235 
236  // Check if it's just a constant
237  const auto * default_property =
238  this->template defaultGenericMaterialProperty<U, is_ad>(prop_name);
239  if (default_property)
240  return *default_property;
241 
242  // if found return the requested property
243  return this->template getGenericZeroMaterialPropertyByName<U, is_ad>(prop_name);
244 }
245 
246 template <class T>
247 template <typename U, bool is_ad>
250 {
251  // TODO: deprecate this
252  return this->template getGenericZeroMaterialPropertyByName<U, is_ad>(prop_name);
253 }
254 
255 template <class T>
256 template <typename U, bool is_ad>
259  const std::vector<VariableName> & c)
260 {
261  std::vector<SymbolName> symbol_vector(c.begin(), c.end());
262  return declarePropertyDerivative<U, is_ad>(base, symbol_vector);
263 }
264 
265 template <class T>
266 template <typename U, bool is_ad>
269  const std::vector<SymbolName> & c)
270 {
271  return this->template declareGenericProperty<U, is_ad>(derivativePropertyName(base, c));
272 }
273 
274 template <class T>
275 template <typename U, bool is_ad>
278  const SymbolName & c1,
279  const SymbolName & c2,
280  const SymbolName & c3)
281 {
282  if (c3 != "")
283  return this->template declareGenericProperty<U, is_ad>(
284  derivativePropertyNameThird(base, c1, c2, c3));
285  if (c2 != "")
286  return this->template declareGenericProperty<U, is_ad>(
287  derivativePropertyNameSecond(base, c1, c2));
288  return this->template declareGenericProperty<U, is_ad>(derivativePropertyNameFirst(base, c1));
289 }
290 
291 template <class T>
292 template <typename U, bool is_ad>
295  const std::vector<VariableName> & c)
296 {
297  std::vector<SymbolName> symbol_vector(c.begin(), c.end());
298  return getMaterialPropertyDerivative(base, symbol_vector);
299 }
300 
301 template <class T>
302 template <typename U, bool is_ad>
305  const std::vector<SymbolName> & c)
306 {
307  // get the base property name
308  std::string prop_name = this->getMaterialPropertyName(base);
309 
314  if (this->template defaultGenericMaterialProperty<U, is_ad>(prop_name))
315  return this->template getGenericZeroMaterialProperty<U, is_ad>();
316 
317  return this->template getGenericZeroMaterialPropertyByName<U, is_ad>(
318  derivativePropertyName(prop_name, c));
319 }
320 
321 template <class T>
322 template <typename U, bool is_ad>
325  const SymbolName & c1,
326  const SymbolName & c2,
327  const SymbolName & c3)
328 {
329  // get the base property name
330  std::string prop_name = this->getMaterialPropertyName(base);
331 
336  if (this->template defaultGenericMaterialProperty<U, is_ad>(prop_name))
337  return this->template getGenericZeroMaterialProperty<U, is_ad>();
338 
339  if (c3 != "")
340  return this->template getGenericZeroMaterialPropertyByName<U, is_ad>(
341  derivativePropertyNameThird(prop_name, c1, c2, c3));
342  if (c2 != "")
343  return this->template getGenericZeroMaterialPropertyByName<U, is_ad>(
344  derivativePropertyNameSecond(prop_name, c1, c2));
345  return this->template getGenericZeroMaterialPropertyByName<U, is_ad>(
346  derivativePropertyNameFirst(prop_name, c1));
347 }
348 
349 template <class T>
350 template <typename U, bool is_ad>
353  const SymbolName & c1,
354  unsigned int v2,
355  unsigned int v3)
356 {
357  return getMaterialPropertyDerivative<U, is_ad>(
358  base,
359  c1,
360  this->_coupled_standard_moose_vars[v2]->name(),
361  v3 == libMesh::invalid_uint ? "" : this->_coupled_standard_moose_vars[v3]->name());
362 }
363 
364 template <class T>
365 template <typename U, bool is_ad>
368  unsigned int v1,
369  unsigned int v2,
370  unsigned int v3)
371 {
372  return getMaterialPropertyDerivative<U, is_ad>(
373  base,
374  this->_coupled_standard_moose_vars[v1]->name(),
375  v2 == libMesh::invalid_uint ? "" : this->_coupled_standard_moose_vars[v2]->name(),
376  v3 == libMesh::invalid_uint ? "" : this->_coupled_standard_moose_vars[v3]->name());
377 }
378 
379 template <class T>
380 template <typename U, bool is_ad>
383  const MaterialPropertyName & base, const std::vector<VariableName> & c)
384 {
385  std::vector<SymbolName> symbol_vector(c.begin(), c.end());
386  return getMaterialPropertyDerivativeByName(base, symbol_vector);
387 }
388 
389 template <class T>
390 template <typename U, bool is_ad>
393  const MaterialPropertyName & base, const std::vector<SymbolName> & c)
394 {
395  return this->template getGenericZeroMaterialPropertyByName<U, is_ad>(
396  derivativePropertyName(base, c));
397 }
398 
399 template <class T>
400 template <typename U, bool is_ad>
403  const MaterialPropertyName & base,
404  const SymbolName & c1,
405  const SymbolName & c2,
406  const SymbolName & c3)
407 {
408  if (c3 != "")
409  return this->template getGenericZeroMaterialPropertyByName<U, is_ad>(
410  derivativePropertyNameThird(base, c1, c2, c3));
411  if (c2 != "")
412  return this->template getGenericZeroMaterialPropertyByName<U, is_ad>(
413  derivativePropertyNameSecond(base, c1, c2));
414  return this->template getGenericZeroMaterialPropertyByName<U, is_ad>(
415  derivativePropertyNameFirst(base, c1));
416 }
417 
418 template <class T>
419 template <typename U, bool is_ad>
420 void
422  const std::vector<VariableName> & c,
423  const System & system,
424  std::vector<VariableName> & missing)
425 {
426  unsigned int ncoupled = this->_coupled_standard_moose_vars.size();
427 
428  // iterate over all variables in the current system (in groups)
429  for (unsigned int i = 0; i < system.n_variable_groups(); ++i)
430  {
431  const VariableGroup & vg = system.variable_group(i);
432  for (unsigned int j = 0; j < vg.n_variables(); ++j)
433  {
434  std::vector<SymbolName> cj(c.begin(), c.end());
435  SymbolName jname = vg.name(j);
436  cj.push_back(jname);
437 
438  // if the derivative exists make sure the variable is coupled
439  if (haveMaterialProperty<U, is_ad>(derivativePropertyName(base, cj)))
440  {
441  // kernels and BCs to not have the variable they are acting on in coupled_moose_vars
442  bool is_missing = isNotObjectVariable(jname);
443 
444  for (unsigned int k = 0; k < ncoupled; ++k)
445  if (this->_coupled_standard_moose_vars[k]->name() == jname)
446  {
447  is_missing = false;
448  break;
449  }
450 
451  if (is_missing)
452  missing.push_back(jname);
453  }
454  }
455  }
456 }
457 
458 template <class T>
459 template <typename U, bool is_ad>
460 void
461 DerivativeMaterialInterface<T>::validateCoupling(const MaterialPropertyName & base,
462  const std::vector<VariableName> & c,
463  bool validate_aux)
464 {
465  // get the base property name
466  std::string prop_name = this->getMaterialPropertyName(base);
467  // list of potentially missing coupled variables
468  std::vector<VariableName> missing;
469 
470  // iterate over all variables in the both the non-linear and auxiliary system (optional)
471  validateCouplingHelper<U, is_ad>(
472  prop_name, c, _dmi_fe_problem.getNonlinearSystemBase(/*nl_sys=*/0).system(), missing);
473  if (validate_aux)
474  validateCouplingHelper<U, is_ad>(
475  prop_name, c, _dmi_fe_problem.getAuxiliarySystem().system(), missing);
476 
477  if (missing.size() > 0)
478  {
479  // join list of missing variable names
480  std::string list = missing[0];
481  for (unsigned int i = 1; i < missing.size(); ++i)
482  list += ", " + missing[i];
483 
484  mooseWarning("Missing coupled variables {",
485  list,
486  "} (add them to coupled_variables parameter of ",
487  this->name(),
488  ")");
489  }
490 }
491 
492 template <class T>
493 std::vector<VariableName>
495  const VariableName & c2,
496  const VariableName & c3)
497 {
498  std::vector<VariableName> c;
499  if (c1 != "")
500  {
501  c.push_back(c1);
502  if (c2 != "")
503  {
504  c.push_back(c2);
505  if (c3 != "")
506  c.push_back(c3);
507  }
508  }
509  return c;
510 }
511 
512 template <class T>
513 template <typename U, bool is_ad>
514 void
515 DerivativeMaterialInterface<T>::validateCoupling(const MaterialPropertyName & base,
516  const VariableName & c1,
517  const VariableName & c2,
518  const VariableName & c3)
519 {
520  validateCoupling<U, is_ad>(base, buildVariableVector(c1, c2, c3), true);
521 }
522 
523 template <class T>
524 template <typename U, bool is_ad>
525 void
527  const VariableName & c1,
528  const VariableName & c2,
529  const VariableName & c3)
530 {
531  validateCoupling<U, is_ad>(base, buildVariableVector(c1, c2, c3), false);
532 }
533 
534 template <class T>
535 template <typename U, bool is_ad>
536 void
538 {
539  // resolve the input parameter name base to the actual material property name
540  const MaterialPropertyName prop_name = this->template getParam<MaterialPropertyName>(base);
541 
542  // check if the material property does not exist on the blocks of the current object,
543  // and check if it is not a plain number in the input file
544  if (!haveMaterialProperty<U, is_ad>(prop_name) &&
545  this->template defaultGenericMaterialProperty<U, is_ad>(prop_name) == 0)
546  mooseWarning("The material property '",
547  prop_name,
548  "' does not exist. The kernel '",
549  this->name(),
550  "' only needs its derivatives, but this may indicate a typo in the input file.");
551 }
552 
553 template <class T>
554 inline bool
556 {
557  // try to cast this to a Kernel pointer
558  KernelBase * kernel_ptr = dynamic_cast<KernelBase *>(this);
559  if (kernel_ptr != nullptr)
560  return kernel_ptr->variable().name() != name;
561 
562  // try to cast this to a BoundaryCondition pointer
563  BoundaryCondition * bc_ptr = dynamic_cast<BoundaryCondition *>(this);
564  if (bc_ptr != nullptr)
565  return bc_ptr->variable().name() != name;
566 
567  // This interface is not templated on a class derived from either Kernel or BC
568  return true;
569 }
std::string name(const ElemQuality q)
DerivativeMaterialInterface(const InputParameters &parameters)
const unsigned int invalid_uint
std::vector< VariableName > buildVariableVector(const VariableName &c1, const VariableName &c2, const VariableName &c3)
helper method to combine multiple VariableNames into a vector (if they are != "") ...
virtual bool boundaryRestricted() const
Returns true if this object has been restricted to a boundary.
GenericMaterialProperty< U, is_ad > & declarePropertyDerivative(const std::string &base, const std::vector< VariableName > &c)
Methods for declaring derivative material properties.
void validateNonlinearCoupling(const MaterialPropertyName &base, const VariableName &c1="", const VariableName &c2="", const VariableName &c3="")
void mooseWarning(Args &&... args)
Emit a warning message with the given stringified, concatenated args.
Definition: MooseError.h:296
const std::string & name() const override
Get the variable name.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
void validateCoupling(const MaterialPropertyName &base, const std::vector< VariableName > &c, bool validate_aux=true)
check if derivatives of the passed in material property exist w.r.t a variable that is not coupled in...
/class BoundaryRestrictable /brief Provides functionality for limiting the object to certain boundary...
const GenericMaterialProperty< U, is_ad > & getDefaultMaterialProperty(const std::string &name)
Fetch a material property if it exists, otherwise return getZeroMaterialProperty. ...
void validateCouplingHelper(const MaterialPropertyName &base, const std::vector< VariableName > &c, const System &system, std::vector< VariableName > &missing)
helper method to compile list of missing coupled variables for a given system
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivative(const std::string &base, const std::vector< VariableName > &c)
Methods for retrieving derivative material properties.
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivativeByName(const MaterialPropertyName &base, const std::vector< VariableName > &c)
Methods for retrieving derivative material properties.
This is the common base class for the three main kernel types implemented in MOOSE, Kernel, VectorKernel and ArrayKernel.
Definition: KernelBase.h:22
const GenericMaterialProperty< U, is_ad > & getDefaultMaterialPropertyByName(const std::string &name)
Fetch a material property by name if it exists, otherwise return getZeroMaterialProperty.
typename GenericMaterialPropertyStruct< T, is_ad >::type GenericMaterialProperty
bool haveMaterialProperty(const std::string &prop_name)
Check if a material property is present with the applicable restrictions.
FEProblemBase & _dmi_fe_problem
Reference to FEProblemBase.
DerivativeMaterialPropertyNameInterface::SymbolName SymbolName
Base class for creating new types of boundary conditions.
Interface class ("Veneer") to provide generator methods for derivative material property names...
An interface that restricts an object to subdomains via the &#39;blocks&#39; input parameter.
virtual const MooseVariableBase & variable() const =0
Returns the variable that this object operates on.
bool boundaryRestricted(const std::set< BoundaryID > &boundary_ids)
void validateDerivativeMaterialPropertyBase(const std::string &base)
Check if the material property base exists.
bool isNotObjectVariable(const VariableName &name)