https://mooseframework.inl.gov
NestedKKSMultiACBulkC.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 "NestedKKSMultiACBulkC.h"
11 
13 
16 {
18  params.addClassDescription("Multi-phase KKS model kernel (part 2 of 2) for the Bulk Allen-Cahn. "
19  "This includes all terms dependent on chemical potential.");
20  params.addRequiredCoupledVar("global_cs", "Global concentrations, for example, c, b.");
21  params.addRequiredCoupledVar("all_etas", "Order parameters.");
22  params.addRequiredParam<std::vector<MaterialPropertyName>>(
23  "ci_names",
24  "Phase concentrations. They must have the same order as Fj_names and global_cs, for "
25  "example, c1, c2, b1, b2.");
26  return params;
27 }
28 
30  : KKSMultiACBulkBase(parameters),
31  _c_names(coupledNames("global_cs")),
32  _c_map(getParameterJvarMap("global_cs")),
33  _num_c(coupledComponents("global_cs")),
34  _eta_names(coupledNames("all_etas")),
35  _eta_map(getParameterJvarMap("all_etas")),
36  _k(-1),
37  _ci_names(getParam<std::vector<MaterialPropertyName>>("ci_names")),
38  _ci_name_matrix(_num_c),
39  _prop_ci(_num_c),
40  _dcidetaj(_num_c),
41  _dcidb(_num_c),
42  _prop_d2hjdetaidetap(_num_j),
43  _dF1dc1(_num_c),
44  _d2F1dc1db1(_num_c),
45  _d2F1dc1darg(_n_args)
46 {
47  for (unsigned int i = 0; i < _num_j; ++i)
48  {
49  // get order parameter names and variable indices
50  _eta_names[i] = getVar("all_etas", i)->name();
51 
52  // Set _k to the position of the nonlinear variable in the list of etaj's
53  if (coupled("all_etas", i) == _var.number())
54  _k = i;
55  }
56 
57  // initialize _ci_name_matrix and _prop_ci for easy reference
58  for (unsigned int m = 0; m < _num_c; ++m)
59  {
60  _ci_name_matrix[m].resize(_num_j);
61  _prop_ci[m].resize(_num_j);
62 
63  for (const auto n : make_range(_num_j))
64  {
65  _ci_name_matrix[m][n] = _ci_names[m * _num_j + n];
66  _prop_ci[m][n] = &getMaterialPropertyByName<Real>(_ci_name_matrix[m][n]);
67  }
68  }
69 
70  // _dcidetaj and _dcidb are computed in KKSPhaseConcentrationMultiPhaseDerivatives
71  for (const auto m : make_range(_num_c))
72  {
73  _dcidetaj[m].resize(_num_j);
74  _dcidb[m].resize(_num_j);
75 
76  for (const auto n : make_range(_num_j))
77  {
78  _dcidetaj[m][n].resize(_num_j);
79  _dcidb[m][n].resize(_num_c);
80 
81  for (const auto l : make_range(_num_j))
82  _dcidetaj[m][n][l] =
83  &getMaterialPropertyDerivative<Real>(_ci_names[n + m * _num_j], _eta_names[l]);
84 
85  for (const auto l : make_range(_num_c))
86  _dcidb[m][n][l] =
87  &getMaterialPropertyDerivative<Real>(_ci_names[n + m * _num_j], _c_names[l]);
88  }
89  }
90 
91  for (const auto m : make_range(_num_j))
92  {
93  _prop_d2hjdetaidetap[m].resize(_num_j);
94 
95  for (const auto n : make_range(_num_j))
96  _prop_d2hjdetaidetap[m][n] =
97  &getMaterialPropertyDerivative<Real>(_hj_names[m], _eta_names[_k], _eta_names[n]);
98  }
99 
100  // _dF1dc1 and _d2F1dc1db1 are computed in KKSPhaseConcentrationMultiPhaseMaterial
101  for (const auto m : make_range(_num_c))
102  {
103  _dF1dc1[m] = &getMaterialPropertyDerivative<Real>(_Fj_names[0], _ci_names[m * _num_j]);
104  _d2F1dc1db1[m].resize(_num_c);
105 
106  for (const auto n : make_range(_num_c))
107  _d2F1dc1db1[m][n] = &getMaterialPropertyDerivative<Real>(
108  _Fj_names[0], _ci_name_matrix[m][0], _ci_name_matrix[n][0]);
109  }
110 
111  // _d2F1dc1darg are computed in KKSPhaseConcentrationMultiPhaseMaterial
112  for (const auto m : make_range(_num_c))
113  {
114  _d2F1dc1darg[m].resize(_n_args);
115 
116  for (const auto n : make_range(_n_args))
117  _d2F1dc1darg[m][n] =
118  &getMaterialPropertyDerivative<Real>(_Fj_names[0], _ci_name_matrix[m][0], n);
119  }
120 }
121 
122 Real
124 {
125  Real sum = 0.0;
126 
127  switch (type)
128  {
129  case Residual:
130 
131  for (const auto m : make_range(_num_c))
132  {
133  Real sum1 = 0.0;
134 
135  for (const auto n : make_range(_num_j))
136  sum1 += (*_prop_dhjdetai[n])[_qp] * (*_prop_ci[m][n])[_qp];
137 
138  sum += (*_dF1dc1[m])[_qp] * sum1;
139  }
140 
141  return -sum;
142 
143  case Jacobian:
146  if (_etai_var != _var.number())
147  return 0.0;
148 
149  for (const auto m : make_range(_num_c))
150  {
151  Real sum1 = 0.0;
152  Real sum2 = 0.0;
153  Real sum3 = 0.0;
154 
155  for (const auto n : make_range(_num_c))
156  sum1 += (*_d2F1dc1db1[m][n])[_qp] * (*_dcidetaj[n][0][_k])[_qp];
157 
158  for (const auto l : make_range(_num_j))
159  {
160  sum2 += (*_prop_dhjdetai[l])[_qp] * (*_prop_ci[m][l])[_qp];
161 
162  sum3 += (*_prop_d2hjdetaidetap[l][_k])[_qp] * (*_prop_ci[m][l])[_qp] +
163  (*_prop_dhjdetai[l])[_qp] * (*_dcidetaj[m][l][_k])[_qp];
164  }
165 
166  sum += sum1 * sum2 + (*_dF1dc1[m])[_qp] * sum3;
167  }
168 
169  return -sum * _phi[_j][_qp];
170  }
171 
172  mooseError("Invalid type passed in");
173 }
174 
175 Real
177 {
178  // first get dependence of mobility _L on other variables using parent class member function Real
180 
181  Real sum = 0.0;
182 
183  // Then add dependence of KKSACBulkF on other variables if other cs are the coupled variables
184  auto compvar = mapJvarToCvar(jvar, _c_map);
185  if (compvar >= 0)
186  {
187  for (const auto m : make_range(_num_c))
188  {
189  Real sum1 = 0.0;
190  Real sum2 = 0.0;
191  Real sum3 = 0.0;
192 
193  for (const auto n : make_range(_num_c))
194  sum1 += (*_d2F1dc1db1[m][n])[_qp] * (*_dcidb[n][0][compvar])[_qp];
195 
196  for (const auto l : make_range(_num_j))
197  {
198  sum2 += (*_prop_dhjdetai[l])[_qp] * (*_prop_ci[m][l])[_qp];
199  sum3 += (*_prop_dhjdetai[l])[_qp] * (*_dcidb[m][l][compvar])[_qp];
200  }
201 
202  sum += sum1 * sum2 + (*_dF1dc1[m])[_qp] * sum3;
203  }
204 
205  res += -_L[_qp] * sum * _phi[_j][_qp] * _test[_i][_qp];
206 
207  return res;
208  }
209 
210  // if order parameters are the coupled variables
211  auto etavar = mapJvarToCvar(jvar, _eta_map);
212  if (etavar >= 0)
213  {
214  for (const auto m : make_range(_num_c))
215  {
216  Real sum1 = 0.0;
217  Real sum2 = 0.0;
218  Real sum3 = 0.0;
219 
220  for (const auto n : make_range(_num_c))
221  sum1 += (*_d2F1dc1db1[m][n])[_qp] * (*_dcidetaj[n][0][etavar])[_qp];
222 
223  for (const auto l : make_range(_num_j))
224  {
225  sum2 += (*_prop_dhjdetai[l])[_qp] * (*_prop_ci[m][l])[_qp];
226 
227  sum3 += (*_prop_d2hjdetaidetap[l][etavar])[_qp] * (*_prop_ci[m][l])[_qp] +
228  (*_prop_dhjdetai[l])[_qp] * (*_dcidetaj[m][l][etavar])[_qp];
229  }
230 
231  sum += sum1 * sum2 + (*_dF1dc1[m])[_qp] * sum3;
232  }
233 
234  res += -_L[_qp] * sum * _phi[_j][_qp] * _test[_i][_qp];
235  }
236 
237  // for all other vars get the coupled variable jvar is referring to
238  const unsigned int cvar = mapJvarToCvar(jvar);
239  for (unsigned int m = 0; m < _num_c; ++m)
240  {
241  Real sum1 = 0.0;
242 
243  for (const auto n : make_range(_num_j))
244  sum1 += (*_d2F1dc1darg[m][cvar])[_qp] * (*_prop_dhjdetai[n])[_qp] * (*_prop_ci[m][n])[_qp];
245 
246  res += -_L[_qp] * sum1 * _phi[_j][_qp] * _test[_i][_qp];
247  }
248 
249  return res;
250 }
std::vector< MaterialPropertyName > _ci_names
Phase concentrations.
std::vector< std::vector< const MaterialProperty< Real > * > > _d2F1dc1darg
Mixed partial derivatives of the free energy function wrt c and any other coupled variables ...
std::vector< std::vector< const MaterialProperty< Real > * > > _prop_ci
const MaterialProperty< Real > & _L
Mobility.
Definition: ACBulk.h:46
virtual Real computeQpOffDiagJacobian(unsigned int jvar)
std::vector< std::vector< std::vector< const MaterialProperty< Real > * > > > _dcidb
Derivative of phase concentrations wrt global concentrations .
ACBulk child class that sets up necessary variables and materials for calculation of residual contrib...
void mooseError(Args &&... args)
static InputParameters validParams()
std::vector< MaterialPropertyName > _Fj_names
Names of free energy functions for each phase .
KKSACBulkBase child class for the phase concentration term in the the Allen-Cahn bulk residual...
void addRequiredParam(const std::string &name, const std::string &doc_string)
std::vector< const MaterialProperty< Real > * > _dF1dc1
Derivative of the free energy function .
std::vector< const MaterialProperty< Real > * > _prop_dhjdetai
Derivatives of the switching functions wrt the order parameter for this kernel.
std::vector< std::vector< std::vector< const MaterialProperty< Real > * > > > _dcidetaj
Derivative of phase concentrations wrt etaj .
std::vector< MaterialPropertyName > _hj_names
switching function names
virtual Real computeDFDOP(PFFunctionType type)
void addRequiredCoupledVar(const std::string &name, const std::string &doc_string)
static InputParameters validParams()
std::vector< VariableName > _c_names
Global concentrations.
std::vector< std::vector< const MaterialProperty< Real > * > > _prop_d2hjdetaidetap
Second derivative of switching function .
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
int _k
Position of the nonlinear variable in the list of cj&#39;s.
virtual Real computeQpOffDiagJacobian(unsigned int jvar)
Definition: ACBulk.h:110
IntRange< T > make_range(T beg, T end)
unsigned int _num_c
Number of global concentrations.
void addClassDescription(const std::string &doc_string)
std::vector< VariableName > _eta_names
Phase parameters.
std::vector< std::vector< MaterialPropertyName > > _ci_name_matrix
unsigned int _etai_var
index of order parameter that derivatives are taken wrt
registerMooseObject("PhaseFieldApp", NestedKKSMultiACBulkC)
std::vector< std::vector< const MaterialProperty< Real > * > > _d2F1dc1db1
Second derivative of the free energy function .
NestedKKSMultiACBulkC(const InputParameters &parameters)