https://mooseframework.inl.gov
Loading...
Searching...
No Matches
DerivativeMaterialInterface.h
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
10#pragma once
11
12#include "AuxiliarySystem.h"
13#include "BlockRestrictable.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
23class FEProblemBase;
24template <typename>
26
31template <class T>
33{
34public:
36
38
43 template <typename U, bool is_ad = false>
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
173private:
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
197template <class T>
199 : T(parameters),
200 _dmi_fe_problem(*parameters.getCheckedPointerParam<FEProblemBase *>("_fe_problem_base"))
201{
202}
203
204template <>
205template <typename U, bool is_ad>
206bool
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
214template <class T>
215template <typename U, bool is_ad>
216bool
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
228template <class T>
229template <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
246template <class T>
247template <typename U, bool is_ad>
250{
251 // TODO: deprecate this
252 return this->template getGenericZeroMaterialPropertyByName<U, is_ad>(prop_name);
253}
254
255template <class T>
256template <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
265template <class T>
266template <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
274template <class T>
275template <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
291template <class T>
292template <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
301template <class T>
302template <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
321template <class T>
322template <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<Real, 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
349template <class T>
350template <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
364template <class T>
365template <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
379template <class T>
380template <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
389template <class T>
390template <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
399template <class T>
400template <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
418template <class T>
419template <typename U, bool is_ad>
420void
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 libMesh::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
458template <class T>
459template <typename U, bool is_ad>
460void
461DerivativeMaterialInterface<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
492template <class T>
493std::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
512template <class T>
513template <typename U, bool is_ad>
514void
515DerivativeMaterialInterface<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
523template <class T>
524template <typename U, bool is_ad>
525void
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
534template <class T>
535template <typename U, bool is_ad>
536void
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
553template <class T>
554inline 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}
typename GenericMaterialPropertyStruct< T, is_ad >::type GenericMaterialProperty
void mooseWarning(Args &&... args)
Emit a warning message with the given stringified, concatenated args.
Definition MooseError.h:345
An interface that restricts an object to subdomains via the 'blocks' input parameter.
Base class for creating new types of boundary conditions.
/class BoundaryRestrictable /brief Provides functionality for limiting the object to certain boundary...
virtual bool boundaryRestricted() const
Returns true if this object has been restricted to a boundary.
Interface class ("Veneer") to provide generator methods for derivative material property names.
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivative(const std::string &base, const SymbolName &c1, const SymbolName &c2="", const SymbolName &c3="")
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 != "")
DerivativeMaterialPropertyNameInterface::SymbolName SymbolName
void validateCoupling(const MaterialPropertyName &base, const VariableName &c1="", const VariableName &c2="", const VariableName &c3="")
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivative(const std::string &base, const std::vector< SymbolName > &c)
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
FEProblemBase & _dmi_fe_problem
Reference to FEProblemBase.
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivativeByName(const MaterialPropertyName &base, const std::vector< SymbolName > &c)
const GenericMaterialProperty< U, is_ad > & getDefaultMaterialPropertyByName(const std::string &name)
Fetch a material property by name if it exists, otherwise return getZeroMaterialProperty.
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivative(const std::string &base, const SymbolName &c1, unsigned int v2, unsigned int v3=libMesh::invalid_uint)
Convenience methods for retrieving derivative material properties based on a mix of variable names c ...
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivative(const std::string &base, unsigned int v1, unsigned int v2=libMesh::invalid_uint, unsigned int v3=libMesh::invalid_uint)
GenericMaterialProperty< U, is_ad > & declarePropertyDerivative(const std::string &base, const SymbolName &c1, const SymbolName &c2="", const SymbolName &c3="")
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivativeByName(const MaterialPropertyName &base, const std::vector< VariableName > &c)
Methods for retrieving derivative material properties.
DerivativeMaterialInterface(const InputParameters &parameters)
void validateNonlinearCoupling(const MaterialPropertyName &base, const VariableName &c1="", const VariableName &c2="", const VariableName &c3="")
bool haveMaterialProperty(const std::string &prop_name)
Check if a material property is present with the applicable restrictions.
bool isNotObjectVariable(const VariableName &name)
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivative(const std::string &base, const std::vector< VariableName > &c)
Methods for retrieving derivative material properties.
GenericMaterialProperty< U, is_ad > & declarePropertyDerivative(const std::string &base, const std::vector< SymbolName > &c)
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivativeByName(const MaterialPropertyName &base, const SymbolName &c1, const SymbolName &c2="", const SymbolName &c3="")
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...
const GenericMaterialProperty< U, is_ad > & getDefaultMaterialProperty(const std::string &name)
Fetch a material property if it exists, otherwise return getZeroMaterialProperty.
void validateDerivativeMaterialPropertyBase(const std::string &base)
Check if the material property base exists.
GenericMaterialProperty< U, is_ad > & declarePropertyDerivative(const std::string &base, const std::vector< VariableName > &c)
Methods for declaring derivative material properties.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
This is the common base class for the three main kernel types implemented in MOOSE,...
Definition KernelBase.h:29
const std::string & name() const
Get the name of the class.
Definition MooseBase.h:103
virtual const MooseVariableBase & variable() const =0
Returns the variable that this object operates on.
unsigned int n_variables() const
const std::string & name(unsigned int v) const
const unsigned int invalid_uint