https://mooseframework.inl.gov
InterfaceOrientationMultiphaseMaterial.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 #include "MooseMesh.h"
12 #include "MathUtils.h"
13 
15 
18 {
20  params.addClassDescription(
21  "This Material accounts for the the orientation dependence "
22  "of interfacial energy for multi-phase multi-order parameter phase-field model.");
23  params.addRequiredParam<MaterialPropertyName>("kappa_name",
24  "Name of the kappa for the given phase");
25  params.addRequiredParam<MaterialPropertyName>(
26  "dkappadgrad_etaa_name", "Name of the derivative of kappa w.r.t. the gradient of eta");
27  params.addRequiredParam<MaterialPropertyName>(
28  "d2kappadgrad_etaa_name",
29  "Name of the second derivative of kappa w.r.t. the gradient of eta");
30  params.addParam<Real>(
31  "anisotropy_strength", 0.04, "Strength of the anisotropy (typically < 0.05)");
32  params.addParam<unsigned int>("mode_number", 4, "Mode number for anisotropy");
33  params.addParam<Real>(
34  "reference_angle", 90, "Reference angle for defining anisotropy in degrees");
35  params.addParam<Real>("kappa_bar", 0.1125, "Average value of the interface parameter kappa");
36  params.addRequiredCoupledVar("etaa", "Order parameter for the current phase alpha");
37  params.addRequiredCoupledVar("etab", "Order parameter for the neighboring phase beta");
38  return params;
39 }
40 
42  const InputParameters & parameters)
43  : Material(parameters),
44  _kappa_name(getParam<MaterialPropertyName>("kappa_name")),
45  _dkappadgrad_etaa_name(getParam<MaterialPropertyName>("dkappadgrad_etaa_name")),
46  _d2kappadgrad_etaa_name(getParam<MaterialPropertyName>("d2kappadgrad_etaa_name")),
47  _delta(getParam<Real>("anisotropy_strength")),
48  _j(getParam<unsigned int>("mode_number")),
49  _theta0(getParam<Real>("reference_angle")),
50  _kappa_bar(getParam<Real>("kappa_bar")),
51  _kappa(declareProperty<Real>(_kappa_name)),
52  _dkappadgrad_etaa(declareProperty<RealGradient>(_dkappadgrad_etaa_name)),
53  _d2kappadgrad_etaa(declareProperty<RealTensorValue>(_d2kappadgrad_etaa_name)),
54  _etaa(coupledValue("etaa")),
55  _grad_etaa(coupledGradient("etaa")),
56  _etab(coupledValue("etab")),
57  _grad_etab(coupledGradient("etab"))
58 {
59  // this currently only works in 2D simulations
60  if (_mesh.dimension() != 2)
61  mooseError("InterfaceOrientationMultiphaseMaterial requires a two-dimensional mesh.");
62 }
63 
64 void
66 {
67  const Real tol = 1e-9;
68  const Real cutoff = 1.0 - tol;
69 
70  // Normal direction of the interface
71  Real n = 0.0;
72  const RealGradient nd = _grad_etaa[_qp] - _grad_etab[_qp];
73  const Real nx = nd(0);
74  const Real ny = nd(1);
75  const Real n2x = nd(0) * nd(0);
76  const Real n2y = nd(1) * nd(1);
77  const Real nsq = nd.norm_sq();
78  const Real n2sq = nsq * nsq;
79  if (nsq > tol)
80  n = nx / std::sqrt(nsq);
81 
82  if (n > cutoff)
83  n = cutoff;
84 
85  if (n < -cutoff)
86  n = -cutoff;
87 
88  // Calculate the orientation angle
89  const Real angle = std::acos(n) * MathUtils::sign(ny);
90 
91  // Compute derivatives of the angle wrt n
92  const Real dangledn = -MathUtils::sign(ny) / std::sqrt(1.0 - n * n);
93  const Real d2angledn2 = -MathUtils::sign(ny) * n / (1.0 - n * n) / std::sqrt(1.0 - n * n);
94 
95  // Compute derivative of n wrt grad_eta
96  RealGradient dndgrad_etaa;
97  if (nsq > tol)
98  {
99  dndgrad_etaa(0) = ny * ny;
100  dndgrad_etaa(1) = -nx * ny;
101  dndgrad_etaa /= nsq * std::sqrt(nsq);
102  }
103 
104  // Compute the square of dndgrad_etaa
105  RealTensorValue dndgrad_etaa_sq;
106  if (nsq > tol)
107  {
108  dndgrad_etaa_sq(0, 0) = n2y * n2y;
109  dndgrad_etaa_sq(0, 1) = -nx * ny * n2y;
110  dndgrad_etaa_sq(1, 0) = -nx * ny * n2y;
111  dndgrad_etaa_sq(1, 1) = n2x * n2y;
112  dndgrad_etaa_sq /= n2sq * nsq;
113  }
114 
115  // Compute the second derivative of n wrt grad_eta
116  RealTensorValue d2ndgrad_etaa2;
117  if (nsq > tol)
118  {
119  d2ndgrad_etaa2(0, 0) = -3.0 * nx * n2y;
120  d2ndgrad_etaa2(0, 1) = -ny * n2y + 2.0 * ny * n2x;
121  d2ndgrad_etaa2(1, 0) = -ny * n2y + 2.0 * ny * n2x;
122  d2ndgrad_etaa2(1, 1) = -nx * n2x + 2.0 * nx * n2y;
123  d2ndgrad_etaa2 /= n2sq * std::sqrt(nsq);
124  }
125 
126  // Calculate interfacial coefficient kappa and its derivatives wrt the angle
127  Real anglediff = _j * (angle - _theta0 * libMesh::pi / 180.0);
128  _kappa[_qp] =
129  _kappa_bar * (1.0 + _delta * std::cos(anglediff)) * (1.0 + _delta * std::cos(anglediff));
130  Real dkappadangle =
131  -2.0 * _kappa_bar * _delta * _j * (1.0 + _delta * std::cos(anglediff)) * std::sin(anglediff);
132  Real d2kappadangle =
133  2.0 * _kappa_bar * _delta * _delta * _j * _j * std::sin(anglediff) * std::sin(anglediff) -
134  2.0 * _kappa_bar * _delta * _j * _j * (1.0 + _delta * std::cos(anglediff)) *
135  std::cos(anglediff);
136 
137  // Compute derivatives of kappa wrt grad_eta
138  _dkappadgrad_etaa[_qp] = dkappadangle * dangledn * dndgrad_etaa;
139  _d2kappadgrad_etaa[_qp] = d2kappadangle * dangledn * dangledn * dndgrad_etaa_sq +
140  dkappadangle * d2angledn2 * dndgrad_etaa_sq +
141  dkappadangle * dangledn * d2ndgrad_etaa2;
142 }
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
const double tol
void addRequiredParam(const std::string &name, const std::string &doc_string)
unsigned int _qp
Material to compute the angular orientation of order parameter interfaces.
TensorValue< Real > RealTensorValue
auto norm_sq() const -> decltype(std::norm(Real()))
MooseMesh & _mesh
static InputParameters validParams()
virtual unsigned int dimension() const
registerMooseObject("PhaseFieldApp", InterfaceOrientationMultiphaseMaterial)
T sign(T x)
MaterialProperty< RealTensorValue > & _d2kappadgrad_etaa
InterfaceOrientationMultiphaseMaterial(const InputParameters &parameters)
void addRequiredCoupledVar(const std::string &name, const std::string &doc_string)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void mooseError(Args &&... args) const
void addClassDescription(const std::string &doc_string)
void ErrorVector unsigned int
const Real pi