www.mooseframework.org
GBAnisotropyBase.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 "GBAnisotropyBase.h"
11 #include "MooseMesh.h"
12 
13 #include <fstream>
14 
17 {
19  params.addCoupledVar("T", 300.0, "Temperature in Kelvin");
20  params.addParam<Real>("length_scale", 1.0e-9, "Length scale in m, where default is nm");
21  params.addParam<Real>("time_scale", 1.0e-9, "Time scale in s, where default is ns");
22  params.addParam<Real>("molar_volume_value",
23  7.11e-6,
24  "molar volume of material in m^3/mol, by default it's the value of copper");
25  params.addParam<Real>(
26  "delta_sigma", 0.1, "factor determining inclination dependence of GB energy");
27  params.addParam<Real>(
28  "delta_mob", 0.1, "factor determining inclination dependence of GB mobility");
29  params.addRequiredParam<FileName>("Anisotropic_GB_file_name",
30  "Name of the file containing: 1)GB mobility prefactor; 2) GB "
31  "migration activation energy; 3)GB energy");
32  params.addRequiredParam<bool>("inclination_anisotropy",
33  "The GB anisotropy inclination would be considered if true");
35  "v", "var_name_base", "op_num", "Array of coupled variables");
36  return params;
37 }
38 
40  : Material(parameters),
41  _mesh_dimension(_mesh.dimension()),
42  _length_scale(getParam<Real>("length_scale")),
43  _time_scale(getParam<Real>("time_scale")),
44  _M_V(getParam<Real>("molar_volume_value")),
45  _delta_sigma(getParam<Real>("delta_sigma")),
46  _delta_mob(getParam<Real>("delta_mob")),
47  _Anisotropic_GB_file_name(getParam<FileName>("Anisotropic_GB_file_name")),
48  _inclination_anisotropy(getParam<bool>("inclination_anisotropy")),
49  _T(coupledValue("T")),
50  _kappa(declareProperty<Real>("kappa_op")),
51  _gamma(declareProperty<Real>("gamma_asymm")),
52  _L(declareProperty<Real>("L")),
53  _mu(declareProperty<Real>("mu")),
54  _molar_volume(declareProperty<Real>("molar_volume")),
55  _entropy_diff(declareProperty<Real>("entropy_diff")),
56  _act_wGB(declareProperty<Real>("act_wGB")),
57  _kb(8.617343e-5), // Boltzmann constant in eV/K
58  _JtoeV(6.24150974e18), // Joule to eV conversion
59  _mu_qp(0.0),
60  _op_num(coupledComponents("v")),
61  _vals(coupledValues("v")),
62  _grad_vals(coupledGradients("v"))
63 {
64  // reshape vectors
65  _sigma.resize(_op_num);
66  _mob.resize(_op_num);
67  _Q.resize(_op_num);
68  _kappa_gamma.resize(_op_num);
69  _a_g2.resize(_op_num);
70 
71  for (unsigned int op = 0; op < _op_num; ++op)
72  {
73  _sigma[op].resize(_op_num);
74  _mob[op].resize(_op_num);
75  _Q[op].resize(_op_num);
76  _kappa_gamma[op].resize(_op_num);
77  _a_g2[op].resize(_op_num);
78  }
79 
80  // Read in data from "Anisotropic_GB_file_name"
81  std::ifstream inFile(_Anisotropic_GB_file_name.c_str());
82 
83  if (!inFile)
84  paramError("Anisotropic_GB_file_name", "Can't open GB anisotropy input file");
85 
86  for (unsigned int i = 0; i < 2; ++i)
87  inFile.ignore(255, '\n'); // ignore line
88 
89  Real data;
90  for (unsigned int i = 0; i < 3 * _op_num; ++i)
91  {
92  std::vector<Real> row; // create an empty row of double values
93  for (unsigned int j = 0; j < _op_num; ++j)
94  {
95  inFile >> data;
96  row.push_back(data);
97  }
98 
99  if (i < _op_num)
100  _sigma[i] = row; // unit: J/m^2
101 
102  else if (i < 2 * _op_num)
103  _mob[i - _op_num] = row; // unit: m^4/(J*s)
104 
105  else
106  _Q[i - 2 * _op_num] = row; // unit: eV
107  }
108 
109  inFile.close();
110 }
111 
112 void
114 {
115  Real sum_kappa = 0.0;
116  Real sum_gamma = 0.0;
117  Real sum_L = 0.0;
118  Real Val = 0.0;
119  Real sum_val = 0.0;
120  Real f_sigma = 1.0;
121  Real f_mob = 1.0;
122  Real gamma_value = 0.0;
123 
124  for (unsigned int m = 0; m < _op_num - 1; ++m)
125  {
126  for (unsigned int n = m + 1; n < _op_num; ++n) // m<n
127  {
128  gamma_value = _kappa_gamma[n][m];
129 
131  {
132  if (_mesh_dimension == 3)
133  mooseError("This material doesn't support inclination dependence for 3D for now!");
134 
135  Real phi_ave = libMesh::pi * n / (2.0 * _op_num);
136  Real sin_phi = std::sin(2.0 * phi_ave);
137  Real cos_phi = std::cos(2.0 * phi_ave);
138 
139  Real a = (*_grad_vals[m])[_qp](0) - (*_grad_vals[n])[_qp](0);
140  Real b = (*_grad_vals[m])[_qp](1) - (*_grad_vals[n])[_qp](1);
141  Real ab = a * a + b * b + 1.0e-7; // for the sake of numerical convergence, the smaller the
142  // more accurate, but more difficult to converge
143 
144  Real cos_2phi = cos_phi * (a * a - b * b) / ab + sin_phi * 2.0 * a * b / ab;
145  Real cos_4phi = 2.0 * cos_2phi * cos_2phi - 1.0;
146 
147  f_sigma = 1.0 + _delta_sigma * cos_4phi;
148  f_mob = 1.0 + _delta_mob * cos_4phi;
149 
150  Real g2 = _a_g2[n][m] * f_sigma;
151  Real y = -5.288 * g2 * g2 * g2 * g2 - 0.09364 * g2 * g2 * g2 + 9.965 * g2 * g2 -
152  8.183 * g2 + 2.007;
153  gamma_value = 1.0 / y;
154  }
155 
156  Val = (100000.0 * ((*_vals[m])[_qp]) * ((*_vals[m])[_qp]) + 0.01) *
157  (100000.0 * ((*_vals[n])[_qp]) * ((*_vals[n])[_qp]) + 0.01);
158 
159  sum_val += Val;
160  sum_kappa += _kappa_gamma[m][n] * f_sigma * Val;
161  sum_gamma += gamma_value * Val;
162  // Following comes from substituting Eq. (36c) from the paper into (36b)
163  sum_L += Val * _mob[m][n] * std::exp(-_Q[m][n] / (_kb * _T[_qp])) * f_mob * _mu_qp *
164  _a_g2[n][m] / _sigma[m][n];
165  }
166  }
167 
168  _kappa[_qp] = sum_kappa / sum_val;
169  _gamma[_qp] = sum_gamma / sum_val;
170  _L[_qp] = sum_L / sum_val;
171  _mu[_qp] = _mu_qp;
172 
173  _molar_volume[_qp] =
174  _M_V / (_length_scale * _length_scale * _length_scale); // m^3/mol converted to ls^3/mol
175  _entropy_diff[_qp] = 9.5 * _JtoeV; // J/(K mol) converted to eV(K mol)
176  _act_wGB[_qp] = 0.5e-9 / _length_scale; // 0.5 nm
177 }
MaterialProperty< Real > & _kappa
static InputParameters validParams()
const Real _delta_sigma
std::vector< std::vector< Real > > _Q
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
const unsigned int _op_num
const std::vector< const VariableValue * > _vals
const Real _delta_mob
const std::vector< const VariableGradient * > _grad_vals
std::vector< std::vector< Real > > _a_g2
const std::vector< double > y
void addRequiredParam(const std::string &name, const std::string &doc_string)
MaterialProperty< Real > & _act_wGB
const VariableValue & _T
virtual void computeQpProperties()
unsigned int _qp
std::vector< std::vector< Real > > _sigma
const FileName _Anisotropic_GB_file_name
MaterialProperty< Real > & _L
static InputParameters validParams()
MaterialProperty< Real > & _entropy_diff
const unsigned int _mesh_dimension
MaterialProperty< Real > & _molar_volume
const bool _inclination_anisotropy
void paramError(const std::string &param, Args... args) const
std::vector< std::vector< Real > > _kappa_gamma
const Real _length_scale
void addCoupledVar(const std::string &name, const std::string &doc_string)
std::vector< std::vector< Real > > _mob
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void addRequiredCoupledVarWithAutoBuild(const std::string &name, const std::string &base_name, const std::string &num_name, const std::string &doc_string)
void mooseError(Args &&... args) const
MaterialProperty< Real > & _mu
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
GBAnisotropyBase(const InputParameters &parameters)
MaterialProperty< Real > & _gamma
const Real pi