https://mooseframework.inl.gov
Loading...
Searching...
No Matches
SLKKSMultiACBulkC.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 "SLKKSMultiACBulkC.h"
11
13
16{
18 params.addClassDescription("Multi-phase SLKKS model kernel for the bulk Allen-Cahn. "
19 "This includes all terms dependent on chemical potential.");
20 params.addRequiredParam<MaterialPropertyName>(
21 "F", "Phase free energy function that is a function of 'c'");
22 params.addRequiredCoupledVar("c", "Concentration variable F depends on");
23 params.addCoupledVar("eta_i",
24 "Order parameter that derivatives are taken with respect to (kernel "
25 "variable is used if this is not specified)");
26 params.addParam<MaterialPropertyName>("mob_name", "L", "The mobility used with the kernel");
27 return params;
28}
29
31 : SLKKSMultiPhaseBase(parameters),
32 _c_name(coupledName("c", 0)),
33 _lagrange(isCoupled("eta_i")),
34 _etai_name(_lagrange ? coupledName("eta_i", 0) : _var.name()),
35 _etai_var(_lagrange ? coupled("eta_i") : _var.number()),
36 _cs_names(_ncs),
37 _prop_dFdc(getMaterialPropertyDerivative<Real>("F", _c_name)),
38 _prop_d2Fdcdcs(_ncs),
39 _prop_dhdni(_nh),
40 _prop_d2hdnidn(_nh),
41 _l_cs(-1),
42 _l_etai(-1),
43 _mob(getMaterialProperty<Real>("mob_name"))
44{
45 // Determine position of the selected concentration variable
46 for (std::size_t i = 0; i < _ncs; ++i)
47 {
48 _cs_names[i] = coupledName("cs", i);
49 if (coupled("cs", i) == _c_var)
50 _l_cs = i;
51 }
52
53 // Check to make sure the nonlinear variable is in the cs list
54 if (_l_cs < 0)
55 paramError("cs", "One of the listed variables must be the 'c' variable");
56
57 // Determine position of the selected concentration variable
58 for (std::size_t i = 0; i < _neta; ++i)
59 if (coupled("eta", i) == _etai_var)
60 _l_etai = i;
61
62 // Check to make sure the nonlinear variable or eta_i (if supplied) is in the eta list
63 if (_l_etai < 0)
64 paramError("eta_i",
65 "Either eta_i or the kernel variable must be one of the listed 'eta' variables");
66
67 // Iterate over all sublattice concentrations
68 for (std::size_t i = 0; i < _ncs; ++i)
69 // get second partial derivatives w.r.t. c and cs (only if c and cs are in the same phase)
70 _prop_d2Fdcdcs[i] = (_phase[i] == _phase[_l_cs])
71 ? &getMaterialPropertyDerivative<Real>("F", _c_name, _cs_names[i])
72 : nullptr;
73
74 // fetch all switching function derivatives
75 for (std::size_t i = 0; i < _nh; ++i)
76 {
77 _prop_dhdni[i] = &getMaterialPropertyDerivativeByName<Real>(_h_names[i], _etai_name);
78
79 _prop_d2hdnidn[i].resize(_neta);
80 for (std::size_t j = 0; j < _neta; ++j)
81 _prop_d2hdnidn[i][j] =
82 &getMaterialPropertyDerivativeByName<Real>(_h_names[i], _etai_name, _eta_names[j]);
83 }
84}
85
86Real
88{ // sum over phases
89 std::size_t k = 0;
90 Real sum = 0.0;
91 for (std::size_t i = 0; i < _nh; ++i)
92 {
93 // sum sublattice concentrations
94 Real csum = 0.0;
95 for (unsigned int j = 0; j < _ns[i]; ++j)
96 {
97 csum += (*_cs[k])[_qp] * _a_cs[k];
98 k++;
99 }
100 sum += (*_prop_dhdni[i])[_qp] * csum;
101 }
102
103 return -_mob[_qp] * _prop_dFdc[_qp] / _a_cs[_l_cs] * sum;
104}
105
106Real
108{
109 // For when this kernel is used in the Lagrange multiplier equation
110 if (_lagrange)
111 return 0.0;
112
113 // For when eta_i is the nonlinear variable
114 std::size_t k = 0;
115 Real sum = 0.0;
116 for (std::size_t i = 0; i < _nh; ++i)
117 {
118 // sum sublattice concentrations
119 Real csum = 0.0;
120 for (unsigned int j = 0; j < _ns[i]; ++j)
121 {
122 csum += (*_cs[k])[_qp] * _a_cs[k];
123 k++;
124 }
125 sum += (*_prop_d2hdnidn[i][_l_etai])[_qp] * csum;
126 }
127
128 return -_mob[_qp] * _phi[_j][_qp] * _prop_dFdc[_qp] / _a_cs[_l_cs] * sum;
129}
130
131Real
133{
134 // concentration variables
135 auto csvar = mapJvarToCvar(jvar, _cs_map);
136 if (csvar >= 0)
137 {
138 // does F depend on the csvar? if so we need to apply the product rule
139 if (_phase[csvar] == _phase[_l_cs])
140 {
141 // sum over phases
142 std::size_t k = 0;
143 Real sum = 0.0;
144 for (std::size_t i = 0; i < _nh; ++i)
145 {
146 // sum sublattice concentrations
147 Real csum = 0.0;
148 for (unsigned int j = 0; j < _ns[i]; ++j)
149 {
150 csum += (*_cs[k])[_qp] * _a_cs[k];
151 k++;
152 }
153 sum += (*_prop_dhdni[i])[_qp] * csum;
154 }
155
156 return -_mob[_qp] *
157 ((*_prop_d2Fdcdcs[csvar])[_qp] * sum +
158 _prop_dFdc[_qp] * (*_prop_dhdni[_phase[csvar]])[_qp] * _a_cs[csvar]) /
159 _a_cs[_l_cs] * _phi[_j][_qp] * _test[_i][_qp];
160 }
161
162 return -_mob[_qp] * _prop_dFdc[_qp] / _a_cs[_l_cs] * (*_prop_dhdni[_phase[csvar]])[_qp] *
163 _a_cs[csvar] * _phi[_j][_qp] * _test[_i][_qp];
164 }
165
166 // order parameters
167 auto etavar = mapJvarToCvar(jvar, _eta_map);
168 if (etavar >= 0)
169 {
170 // sum over phases
171 std::size_t k = 0;
172 Real sum = 0.0;
173 for (std::size_t i = 0; i < _nh; ++i)
174 {
175 // sum sublattice concentrations
176 Real csum = 0.0;
177 for (unsigned int j = 0; j < _ns[i]; ++j)
178 {
179 csum += (*_cs[k])[_qp] * _a_cs[k];
180 k++;
181 }
182 sum += (*_prop_d2hdnidn[i][etavar])[_qp] * csum;
183 }
184
185 return -_mob[_qp] * _prop_dFdc[_qp] / _a_cs[_l_cs] * sum * _phi[_j][_qp] * _test[_i][_qp];
186 }
187
188 return 0.0;
189}
registerMooseObject("PhaseFieldApp", SLKKSMultiACBulkC)
const std::string name
Definition Setup.h:21
SLKKSMultiPhaseBase child class for the phase concentration term in the the Allen-Cahn bulk residual...
std::vector< const MaterialProperty< Real > * > _prop_d2Fdcdcs
Second derivatives of F w.r.t. c and all cs.
static InputParameters validParams()
virtual Real computeQpOffDiagJacobian(unsigned int jvar)
virtual Real precomputeQpResidual()
const MaterialProperty< Real > & _prop_dFdc
Derivative of the free energy function w.r.t. c.
const MaterialProperty< Real > & _mob
Mobility.
std::vector< VariableName > _cs_names
names of all sublattice concentrations
SLKKSMultiACBulkC(const InputParameters &parameters)
std::vector< const MaterialProperty< Real > * > _prop_dhdni
first derivatives of all h w.r.t. to etai
int _l_etai
Position of the eta_i variable in the eta list.
const bool _lagrange
is eta_i supplied (then we assume the kernel operates on the Lagrange var)
virtual Real precomputeQpJacobian()
int _l_cs
Position of the c variable in the cs list.
const VariableName _c_name
name of the coupled concentration variable c
std::vector< std::vector< const MaterialProperty< Real > * > > _prop_d2hdnidn
first derivatives of all h w.r.t. to the kernel variable and other etas
VariableName _etai_name
name of order parameter that derivatives are taken w.r.t.
unsigned int _etai_var
index of order parameter that derivatives are taken w.r.t.
Enforce sum of phase sublattice concentrations to be the real concentration.
std::vector< const VariableValue * > _cs
const std::size_t _neta
Order parameters for each phase .
const unsigned int _c_var
std::vector< MaterialPropertyName > _h_names
Switching function names.
const std::size_t _nh
std::vector< unsigned int > _phase
phase index of each cs entry
static InputParameters validParams()
std::vector< Real > _a_cs
Sublattice site numbers.
const std::size_t _ncs
Sublattice concentrations.
std::vector< VariableName > _eta_names
std::vector< unsigned int > _ns
Number of sublattices per phase.