https://mooseframework.inl.gov
ACSwitching.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 
10 #include "ACSwitching.h"
11 
12 registerMooseObject("PhaseFieldApp", ACSwitching);
13 registerMooseObject("PhaseFieldApp", ADACSwitching);
14 
15 template <bool is_ad>
18 {
20  params.addClassDescription(
21  "Kernel for Allen-Cahn equation that adds derivatives of switching functions and energies");
22  params.addRequiredParam<std::vector<MaterialPropertyName>>(
23  "Fj_names", "List of free energies for each phase. Place in same order as hj_names!");
24  params.addRequiredParam<std::vector<MaterialPropertyName>>(
25  "hj_names", "Switching Function Materials that provide h. Place in same order as Fj_names!");
26  return params;
27 }
28 
29 template <bool is_ad>
30 ACSwitchingTempl<is_ad>::ACSwitchingTempl(const InputParameters & parameters)
31  : ACSwitchingBase<is_ad>(parameters),
32  _etai_name(_var.name()),
33  _Fj_names(this->template getParam<std::vector<MaterialPropertyName>>("Fj_names")),
34  _num_j(_Fj_names.size()),
35  _prop_Fj(_num_j),
36  _hj_names(this->template getParam<std::vector<MaterialPropertyName>>("hj_names")),
37  _prop_dhjdetai(_num_j)
38 {
39  // check passed in parameter vectors
40  if (_num_j != _hj_names.size())
41  this->paramError("hj_names", "Need to pass in as many hj_names as Fj_names");
42 
43  // reserve space and set phase material properties
44  for (unsigned int n = 0; n < _num_j; ++n)
45  {
46  // get phase free energy
47  _prop_Fj[n] = &this->template getGenericMaterialProperty<Real, is_ad>(_Fj_names[n]);
48 
49  // get first derivative of the switching functions
50  _prop_dhjdetai[n] =
51  &this->template getMaterialPropertyDerivative<Real, is_ad>(_hj_names[n], _etai_name);
52  }
53 }
54 
55 ACSwitching::ACSwitching(const InputParameters & parameters)
56  : ACSwitchingTempl<false>(parameters),
57  _prop_dFjdarg(_num_j),
58  _prop_d2hjdetai2(_num_j),
59  _prop_d2hjdetaidarg(_num_j)
60 {
61  // reserve space and set phase material properties
62  for (unsigned int n = 0; n < _num_j; ++n)
63  {
64  // get derivatives of the phase free energy and the switching functions
65  _prop_dFjdarg[n].resize(_n_args);
66  _prop_d2hjdetai2[n] =
67  &getMaterialPropertyDerivative<Real>(_hj_names[n], _etai_name, _etai_name);
68  _prop_d2hjdetaidarg[n].resize(_n_args);
69 
70  for (unsigned int i = 0; i < _n_args; ++i)
71  {
72  // Get derivatives of all Fj wrt all coupled variables
73  _prop_dFjdarg[n][i] = &getMaterialPropertyDerivative<Real>(_Fj_names[n], i);
74 
75  // Get second derivatives of all hj wrt eta_i and all coupled variables
76  _prop_d2hjdetaidarg[n][i] = &getMaterialPropertyDerivative<Real>(_hj_names[n], _etai_name, i);
77  }
78  }
79 }
80 
81 template <bool is_ad>
82 void
83 ACSwitchingTempl<is_ad>::initialSetup()
84 {
85  ACSwitchingBase<is_ad>::initialSetup();
86  for (unsigned int n = 0; n < _num_j; ++n)
87  this->template validateNonlinearCoupling<GenericReal<is_ad>>(_hj_names[n]);
88 }
89 
90 void
91 ACSwitching::initialSetup()
92 {
93  ACSwitchingTempl<false>::initialSetup();
94  for (unsigned int n = 0; n < _num_j; ++n)
95  validateNonlinearCoupling<Real>(_Fj_names[n]);
96 }
97 
98 Real
99 ACSwitching::computeDFDOP(PFFunctionType type)
100 {
101  Real sum = 0.0;
102 
103  switch (type)
104  {
105  case Residual:
106  for (unsigned int n = 0; n < _num_j; ++n)
107  sum += (*_prop_dhjdetai[n])[_qp] * (*_prop_Fj[n])[_qp];
108 
109  return sum;
110 
111  case Jacobian:
112  for (unsigned int n = 0; n < _num_j; ++n)
113  sum += (*_prop_d2hjdetai2[n])[_qp] * (*_prop_Fj[n])[_qp];
114 
115  return _phi[_j][_qp] * sum;
116  }
117 
118  mooseError("Invalid type passed in to ACSwitching::computeDFDOP");
119 }
120 
121 ADReal
122 ADACSwitching::computeDFDOP()
123 {
124  ADReal sum = 0.0;
125  for (unsigned int n = 0; n < _num_j; ++n)
126  sum += (*_prop_dhjdetai[n])[_qp] * (*_prop_Fj[n])[_qp];
127  return sum;
128 }
129 
130 Real
131 ACSwitching::computeQpOffDiagJacobian(unsigned int jvar)
132 {
133  // get the coupled variable jvar is referring to
134  const unsigned int cvar = mapJvarToCvar(jvar);
135 
136  // first get dependence of mobility _L on other variables using parent class
137  // member function
139 
140  // Then add dependence of ACSwitching on other variables
141  Real sum = 0.0;
142  for (unsigned int n = 0; n < _num_j; ++n)
143  sum += (*_prop_d2hjdetaidarg[n][cvar])[_qp] * (*_prop_Fj[n])[_qp] +
144  (*_prop_dhjdetai[n])[_qp] * (*_prop_dFjdarg[n][cvar])[_qp];
145 
146  res += _L[_qp] * sum * _phi[_j][_qp] * _test[_i][_qp];
147 
148  return res;
149 }
150 
151 template class ACSwitchingTempl<false>;
152 template class ACSwitchingTempl<true>;
Moose::GenericType< Real, is_ad > GenericReal
void mooseError(Args &&... args)
DualNumber< Real, DNDerivativeType, true > ADReal
registerMooseObject("PhaseFieldApp", ACSwitching)
void addRequiredParam(const std::string &name, const std::string &doc_string)
InputParameters validParams()
const std::string name
Definition: Setup.h:20
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual Real computeQpOffDiagJacobian(unsigned int jvar)
Definition: ACBulk.h:110
void addClassDescription(const std::string &doc_string)