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:
35  DerivativeMaterialInterface(const InputParameters & parameters);
36 
41  template <typename U>
42  const MaterialProperty<U> & getDefaultMaterialProperty(const std::string & name);
43 
45  template <typename U>
46  const MaterialProperty<U> & getDefaultMaterialPropertyByName(const std::string & name);
47 
49 
55  template <typename U>
56  MaterialProperty<U> & declarePropertyDerivative(const std::string & base,
57  const std::vector<VariableName> & c);
58  template <typename U>
59  MaterialProperty<U> & declarePropertyDerivative(const std::string & base,
60  const VariableName & c1,
61  const VariableName & c2 = "",
62  const VariableName & c3 = "");
64 
66 
72  template <typename U>
73  const MaterialProperty<U> & getMaterialPropertyDerivative(const std::string & base,
74  const std::vector<VariableName> & c);
75  template <typename U>
76  const MaterialProperty<U> & getMaterialPropertyDerivative(const std::string & base,
77  const VariableName & c1,
78  const VariableName & c2 = "",
79  const VariableName & c3 = "");
81 
83 
89  template <typename U>
90  const MaterialProperty<U> &
91  getMaterialPropertyDerivativeByName(const MaterialPropertyName & base,
92  const std::vector<VariableName> & c);
93  template <typename U>
94  const MaterialProperty<U> & getMaterialPropertyDerivativeByName(const MaterialPropertyName & base,
95  const VariableName & c1,
96  const VariableName & c2 = "",
97  const VariableName & c3 = "");
99 
101 
105  template <typename U>
106  void validateCoupling(const MaterialPropertyName & base,
107  const std::vector<VariableName> & c,
108  bool validate_aux = true);
109  template <typename U>
110  void validateCoupling(const MaterialPropertyName & base,
111  const VariableName & c1 = "",
112  const VariableName & c2 = "",
113  const VariableName & c3 = "");
114  template <typename U>
115  void validateNonlinearCoupling(const MaterialPropertyName & base,
116  const VariableName & c1 = "",
117  const VariableName & c2 = "",
118  const VariableName & c3 = "");
120 
127  template <typename U>
128  void validateDerivativeMaterialPropertyBase(const std::string & base);
129 
130 private:
132  template <typename U>
133  bool haveMaterialProperty(const std::string & prop_name);
134 
136  std::vector<VariableName>
137  buildVariableVector(const VariableName & c1, const VariableName & c2, const VariableName & c3);
138 
140  template <typename U>
141  void validateCouplingHelper(const MaterialPropertyName & base,
142  const std::vector<VariableName> & c,
143  const System & system,
144  std::vector<VariableName> & missing);
145 
146  // check if the speciified variable name is not the variable this kernel is acting on (always true
147  // for any other type of object)
148  bool isNotObjectVariable(const VariableName & name);
149 
152 };
153 
154 template <class T>
156  : T(parameters),
157  _dmi_fe_problem(*parameters.getCheckedPointerParam<FEProblemBase *>("_fe_problem_base"))
158 {
159 }
160 
161 template <>
162 template <typename U>
163 bool
165 {
166  return (
167  (this->boundaryRestricted() && this->template hasBoundaryMaterialProperty<U>(prop_name)) ||
168  (this->template hasBlockMaterialProperty<U>(prop_name)));
169 }
170 
171 template <class T>
172 template <typename U>
173 bool
175 {
176  // Call the correct method to test for material property declarations
177  BlockRestrictable * blk = dynamic_cast<BlockRestrictable *>(this);
178  BoundaryRestrictable * bnd = dynamic_cast<BoundaryRestrictable *>(this);
179  return ((bnd && bnd->boundaryRestricted() &&
180  bnd->template hasBoundaryMaterialProperty<U>(prop_name)) ||
181  (blk && blk->template hasBlockMaterialProperty<U>(prop_name)) ||
182  (this->template hasMaterialProperty<U>(prop_name)));
183 }
184 
185 template <class T>
186 template <typename U>
187 const MaterialProperty<U> &
189 {
190  // get the base property name
191  std::string prop_name = this->deducePropertyName(name);
192 
193  // Check if it's just a constant
194  const MaterialProperty<U> * default_property =
195  this->template defaultMaterialProperty<U>(prop_name);
196  if (default_property)
197  return *default_property;
198 
199  // if found return the requested property
200  return getDefaultMaterialPropertyByName<U>(prop_name);
201 }
202 
203 template <class T>
204 template <typename U>
205 const MaterialProperty<U> &
207 {
208  // if found return the requested property
209  if (haveMaterialProperty<U>(prop_name))
210  return this->template getMaterialPropertyByName<U>(prop_name);
211 
212  return this->template getZeroMaterialProperty<U>(prop_name);
213 }
214 
215 template <class T>
216 template <typename U>
219  const std::vector<VariableName> & c)
220 {
221  return this->template declareProperty<U>(derivativePropertyName(base, c));
222 }
223 
224 template <class T>
225 template <typename U>
228  const VariableName & c1,
229  const VariableName & c2,
230  const VariableName & c3)
231 {
232  if (c3 != "")
233  return this->template declareProperty<U>(derivativePropertyNameThird(base, c1, c2, c3));
234  if (c2 != "")
235  return this->template declareProperty<U>(derivativePropertyNameSecond(base, c1, c2));
236  return this->template declareProperty<U>(derivativePropertyNameFirst(base, c1));
237 }
238 
239 template <class T>
240 template <typename U>
241 const MaterialProperty<U> &
243  const std::vector<VariableName> & c)
244 {
245  // get the base property name
246  std::string prop_name = this->deducePropertyName(base);
247 
252  if (this->template defaultMaterialProperty<U>(prop_name))
253  return this->template getZeroMaterialProperty<U>(prop_name + "_zeroderivative");
254 
255  return getDefaultMaterialPropertyByName<U>(derivativePropertyName(prop_name, c));
256 }
257 
258 template <class T>
259 template <typename U>
260 const MaterialProperty<U> &
262  const VariableName & c1,
263  const VariableName & c2,
264  const VariableName & c3)
265 {
266  // get the base property name
267  std::string prop_name = this->deducePropertyName(base);
268 
273  if (this->template defaultMaterialProperty<U>(prop_name))
274  return this->template getZeroMaterialProperty<U>(prop_name + "_zeroderivative");
275 
276  if (c3 != "")
277  return getDefaultMaterialPropertyByName<U>(derivativePropertyNameThird(prop_name, c1, c2, c3));
278  if (c2 != "")
279  return getDefaultMaterialPropertyByName<U>(derivativePropertyNameSecond(prop_name, c1, c2));
280  return getDefaultMaterialPropertyByName<U>(derivativePropertyNameFirst(prop_name, c1));
281 }
282 
283 template <class T>
284 template <typename U>
285 const MaterialProperty<U> &
287  const MaterialPropertyName & base, const std::vector<VariableName> & c)
288 {
289  return getDefaultMaterialPropertyByName<U>(derivativePropertyName(base, c));
290 }
291 
292 template <class T>
293 template <typename U>
294 const MaterialProperty<U> &
296  const MaterialPropertyName & base,
297  const VariableName & c1,
298  const VariableName & c2,
299  const VariableName & c3)
300 {
301  if (c3 != "")
302  return getDefaultMaterialPropertyByName<U>(derivativePropertyNameThird(base, c1, c2, c3));
303  if (c2 != "")
304  return getDefaultMaterialPropertyByName<U>(derivativePropertyNameSecond(base, c1, c2));
305  return getDefaultMaterialPropertyByName<U>(derivativePropertyNameFirst(base, c1));
306 }
307 
308 template <class T>
309 template <typename U>
310 void
312  const std::vector<VariableName> & c,
313  const System & system,
314  std::vector<VariableName> & missing)
315 {
316  unsigned int ncoupled = this->_coupled_moose_vars.size();
317 
318  // iterate over all variables in the current system (in groups)
319  for (unsigned int i = 0; i < system.n_variable_groups(); ++i)
320  {
321  const VariableGroup & vg = system.variable_group(i);
322  for (unsigned int j = 0; j < vg.n_variables(); ++j)
323  {
324  std::vector<VariableName> cj(c);
325  VariableName jname = vg.name(j);
326  cj.push_back(jname);
327 
328  // if the derivative exists make sure the variable is coupled
329  if (haveMaterialProperty<U>(derivativePropertyName(base, cj)))
330  {
331  // kernels and BCs to not have the variable they are acting on in coupled_moose_vars
332  bool is_missing = isNotObjectVariable(jname);
333 
334  for (unsigned int k = 0; k < ncoupled; ++k)
335  if (this->_coupled_moose_vars[k]->name() == jname)
336  {
337  is_missing = false;
338  break;
339  }
340 
341  if (is_missing)
342  missing.push_back(jname);
343  }
344  }
345  }
346 }
347 
348 template <class T>
349 template <typename U>
350 void
351 DerivativeMaterialInterface<T>::validateCoupling(const MaterialPropertyName & base,
352  const std::vector<VariableName> & c,
353  bool validate_aux)
354 {
355  // get the base property name
356  std::string prop_name = this->deducePropertyName(base);
357  // list of potentially missing coupled variables
358  std::vector<VariableName> missing;
359 
360  // iterate over all variables in the both the non-linear and auxiliary system (optional)
361  validateCouplingHelper<U>(
362  prop_name, c, _dmi_fe_problem.getNonlinearSystemBase().system(), missing);
363  if (validate_aux)
364  validateCouplingHelper<U>(prop_name, c, _dmi_fe_problem.getAuxiliarySystem().system(), missing);
365 
366  if (missing.size() > 0)
367  {
368  // join list of missing variable names
369  std::string list = missing[0];
370  for (unsigned int i = 1; i < missing.size(); ++i)
371  list += ", " + missing[i];
372 
373  mooseWarning("Missing coupled variables {",
374  list,
375  "} (add them to args parameter of ",
376  this->name(),
377  ")");
378  }
379 }
380 
381 template <class T>
382 std::vector<VariableName>
384  const VariableName & c2,
385  const VariableName & c3)
386 {
387  std::vector<VariableName> c;
388  if (c1 != "")
389  {
390  c.push_back(c1);
391  if (c2 != "")
392  {
393  c.push_back(c2);
394  if (c3 != "")
395  c.push_back(c3);
396  }
397  }
398  return c;
399 }
400 
401 template <class T>
402 template <typename U>
403 void
404 DerivativeMaterialInterface<T>::validateCoupling(const MaterialPropertyName & base,
405  const VariableName & c1,
406  const VariableName & c2,
407  const VariableName & c3)
408 {
409  validateCoupling<U>(base, buildVariableVector(c1, c2, c3), true);
410 }
411 
412 template <class T>
413 template <typename U>
414 void
416  const VariableName & c1,
417  const VariableName & c2,
418  const VariableName & c3)
419 {
420  validateCoupling<U>(base, buildVariableVector(c1, c2, c3), false);
421 }
422 
423 template <class T>
424 template <typename U>
425 void
427 {
428  // resolve the input parameter name base to the actual material property name
429  const MaterialPropertyName prop_name = this->template getParam<MaterialPropertyName>(base);
430 
431  // check if the material property does not exist on the blocks of the current object,
432  // and check if it is not a plain number in the input file
433  if (!haveMaterialProperty<U>(prop_name) &&
434  this->template defaultMaterialProperty<U>(prop_name) == 0)
435  mooseWarning("The material property '",
436  prop_name,
437  "' does not exist. The kernel '",
438  this->name(),
439  "' only needs its derivatives, but this may indicate a typo in the input file.");
440 }
441 
442 template <class T>
443 inline bool
445 {
446  // try to cast this to a Kernel pointer
447  KernelBase * kernel_ptr = dynamic_cast<KernelBase *>(this);
448  if (kernel_ptr != nullptr)
449  return kernel_ptr->variable().name() != name;
450 
451  // try to cast this to a BoundaryCondition pointer
452  BoundaryCondition * bc_ptr = dynamic_cast<BoundaryCondition *>(this);
453  if (bc_ptr != nullptr)
454  return bc_ptr->variable().name() != name;
455 
456  // This interface is not templated on a class derived from either Kernel or BC
457  return true;
458 }
459 
virtual MooseVariableFEBase & variable()=0
Returns the variable number that this Kernel operates on.
DerivativeMaterialInterface(const InputParameters &parameters)
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.
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 MaterialProperty< U > & getMaterialPropertyDerivative(const std::string &base, const std::vector< VariableName > &c)
Methods for retreiving derivative material properties.
void mooseWarning(Args &&... args)
Emit a warning message with the given stringified, concatenated args.
Definition: MooseError.h:219
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
/class BoundaryRestrictable /brief Provides functionality for limiting the object to certain boundary...
const MaterialProperty< U > & getDefaultMaterialPropertyByName(const std::string &name)
Fetch a material property by name if it exists, otherwise return getZeroMaterialProperty.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
virtual MooseVariableFEBase & variable()=0
Get a reference to the MooseVariableFE.
nl system()
This is the common base class for the two main kernel types implemented in MOOSE, EigenKernel and Ker...
Definition: KernelBase.h:44
void validateNonlinearCoupling(const MaterialPropertyName &base, const VariableName &c1="", const VariableName &c2="", const VariableName &c3="")
FEProblemBase & _dmi_fe_problem
Reference to FEProblemBase.
Base class for creating new types of boundary conditions.
void validateDerivativeMaterialPropertyBase(const std::string &base)
Check if the material property base exists.
bool haveMaterialProperty(const std::string &prop_name)
Check if a material property is present with the applicable restrictions.
Interface class ("Veneer") to provide generator methods for derivative material property names...
const std::string & name() const
Get the variable name.
Concrete definition of a parameter value for a specified type.
An interface that restricts an object to subdomains via the &#39;blocks&#39; input parameter.
const MaterialProperty< U > & getMaterialPropertyDerivativeByName(const MaterialPropertyName &base, const std::vector< VariableName > &c)
Methods for retreiving derivative material properties.
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
const MaterialProperty< U > & getDefaultMaterialProperty(const std::string &name)
Fetch a material property if it exists, otherwise return getZeroMaterialProperty. ...
MaterialProperty< U > & declarePropertyDerivative(const std::string &base, const std::vector< VariableName > &c)
Methods for declaring derivative material properties.
bool isNotObjectVariable(const VariableName &name)