https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
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 {
94
95 for (const auto n : make_range(_num_j))
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
122Real
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
175Real
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}
void mooseError(Args &&... args)
registerMooseObject("PhaseFieldApp", NestedKKSMultiACBulkC)
const MaterialProperty< Real > & _L
Mobility.
Definition ACBulk.h:46
virtual Real computeQpOffDiagJacobian(unsigned int jvar)
Definition ACBulk.h:110
void addRequiredCoupledVar(const std::string &name, const std::string &doc_string)
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
ACBulk child class that sets up necessary variables and materials for calculation of residual contrib...
std::vector< MaterialPropertyName > _Fj_names
Names of free energy functions for each phase .
unsigned int _etai_var
index of order parameter that derivatives are taken wrt
std::vector< const MaterialProperty< Real > * > _prop_dhjdetai
Derivatives of the switching functions wrt the order parameter for this kernel.
static InputParameters validParams()
std::vector< MaterialPropertyName > _hj_names
switching function names
KKSACBulkBase child class for the phase concentration term in the the Allen-Cahn bulk residual.
unsigned int _num_c
Number of global concentrations.
std::vector< MaterialPropertyName > _ci_names
Phase concentrations.
std::vector< std::vector< MaterialPropertyName > > _ci_name_matrix
std::vector< std::vector< std::vector< const MaterialProperty< Real > * > > > _dcidetaj
Derivative of phase concentrations wrt etaj .
int _k
Position of the nonlinear variable in the list of cj's.
std::vector< const MaterialProperty< Real > * > _dF1dc1
Derivative of the free energy function .
std::vector< std::vector< const MaterialProperty< Real > * > > _d2F1dc1db1
Second derivative of the free energy function .
std::vector< std::vector< const MaterialProperty< Real > * > > _prop_ci
std::vector< std::vector< const MaterialProperty< Real > * > > _prop_d2hjdetaidetap
Second derivative of switching function .
std::vector< std::vector< std::vector< const MaterialProperty< Real > * > > > _dcidb
Derivative of phase concentrations wrt global concentrations .
virtual Real computeDFDOP(PFFunctionType type)
NestedKKSMultiACBulkC(const InputParameters &parameters)
virtual Real computeQpOffDiagJacobian(unsigned int jvar)
std::vector< VariableName > _c_names
Global concentrations.
static InputParameters validParams()
std::vector< VariableName > _eta_names
Phase parameters.
std::vector< std::vector< const MaterialProperty< Real > * > > _d2F1dc1darg
Mixed partial derivatives of the free energy function wrt c and any other coupled variables .