Real DerivativeTwoPhaseMaterial::computeD3F(unsigned int i_var, unsigned int j_var, unsigned int k_var) { if (i_var == _eta_var && j_var == _eta_var && k_var == _eta_var) return _d3h[_qp] * (_prop_Fb[_qp] - _prop_Fa[_qp]) + _W * _d3g[_qp]; unsigned int i = argIndex(i_var); unsigned int j = argIndex(j_var); unsigned int k = argIndex(k_var); if (j_var == _eta_var && k_var == _eta_var) return _d2h[_qp] * ((*_prop_dFb[i])[_qp] - (*_prop_dFa[i])[_qp]); if (i_var == _eta_var && k_var == _eta_var) return _d2h[_qp] * ((*_prop_dFb[j])[_qp] - (*_prop_dFa[j])[_qp]); if (i_var == _eta_var && j_var == _eta_var) return _d2h[_qp] * ((*_prop_dFb[k])[_qp] - (*_prop_dFa[k])[_qp]); if (i_var == _eta_var) return _dh[_qp] * (*_prop_d2Fb[j][k])[_qp] + (1.0 - _dh[_qp]) * (*_prop_d2Fa[j][k])[_qp]; if (j_var == _eta_var) return _dh[_qp] * (*_prop_d2Fb[i][k])[_qp] + (1.0 - _dh[_qp]) * (*_prop_d2Fa[i][k])[_qp]; if (k_var == _eta_var) return _dh[_qp] * (*_prop_d2Fb[i][j])[_qp] + (1.0 - _dh[_qp]) * (*_prop_d2Fa[i][j])[_qp]; return _h[_qp] * (*_prop_d3Fb[i][j][k])[_qp] + (1.0 - _h[_qp]) * (*_prop_d3Fa[i][j][k])[_qp]; }
Real DerivativeMultiPhaseMaterial::computeD2F(unsigned int i_var, unsigned int j_var) { const unsigned int i = argIndex(i_var); const int i_eta = _eta_index[i]; const unsigned int j = argIndex(j_var); const int j_eta = _eta_index[j]; if (i_eta >= 0 && j_eta >= 0) { // if the derivatives are taken w.r.t. a single eta the d2hi term for eta_i appears, otherwise it drops out // because we assume that hi _only_ depends on eta_i Real d2F = (i_eta == j_eta) ? (*_d2hi[i_eta])[_qp] * (*_prop_Fi[i_eta])[_qp] : 0.0; return d2F + _W * (*_d2g[i_eta][j_eta])[_qp]; } if (i_eta >= 0) return (*_dhi[i_eta])[_qp] * (*_prop_dFi[i_eta][j])[_qp]; if (j_eta >= 0) return (*_dhi[j_eta])[_qp] * (*_prop_dFi[j_eta][i])[_qp]; Real d2F = 0.0; for (unsigned n = 0; n < _num_fi; ++n) d2F += (*_hi[n])[_qp] * (*_prop_d2Fi[n][i][j])[_qp]; return d2F; }
Real DerivativeMultiPhaseMaterial::computeD3F(unsigned int i_var, unsigned int j_var, unsigned int k_var) { const unsigned int i = argIndex(i_var); const int i_eta = _eta_index[i]; const unsigned int j = argIndex(j_var); const int j_eta = _eta_index[j]; const unsigned int k = argIndex(k_var); const int k_eta = _eta_index[k]; // all arguments are eta-variables if (i_eta >= 0 && j_eta >= 0 && k_eta >= 0) { // if the derivatives are taken w.r.t. a single eta the d3hi term for eta_i appears, otherwise it drops out // because we assume that hi _only_ depends on eta_i Real d3F = (i_eta == j_eta && j_eta == k_eta) ? (*_d3hi[i_eta])[_qp] * (*_prop_Fi[i_eta])[_qp] : 0.0; return d3F + _W * (*_d3g[i_eta][j_eta][k_eta])[_qp]; } // two arguments are eta-variables if (i_eta >= 0 && j_eta >= 0) return (i_eta == j_eta) ? (*_d2hi[i_eta])[_qp] * (*_prop_dFi[i_eta][k])[_qp] : 0.0; if (j_eta >= 0 && k_eta >= 0) return (j_eta == k_eta) ? (*_d2hi[j_eta])[_qp] * (*_prop_dFi[j_eta][i])[_qp] : 0.0; if (k_eta >= 0 && i_eta >= 0) return (k_eta == i_eta) ? (*_d2hi[k_eta])[_qp] * (*_prop_dFi[k_eta][j])[_qp] : 0.0; // one argument is an eta-variable if (i_eta >= 0) return (*_dhi[i_eta])[_qp] * (*_prop_d2Fi[i_eta][j][k])[_qp]; if (j_eta >= 0) return (*_dhi[j_eta])[_qp] * (*_prop_d2Fi[j_eta][i][k])[_qp]; if (k_eta >= 0) return (*_dhi[k_eta])[_qp] * (*_prop_d2Fi[k_eta][i][j])[_qp]; // no arguments are eta-variables Real d3F = 0.0; for (unsigned n = 0; n < _num_fi; ++n) d3F += (*_hi[n])[_qp] * (*_prop_d3Fi[n][i][j][k])[_qp]; return d3F; }
Real ElasticEnergyMaterial::computeDF(unsigned int i_var) { unsigned int i = argIndex(i_var); // product rule d/di computeF (doubleContraction commutes) return 0.5 * ((*_delasticity_tensor[i])[_qp] * _strain[_qp]).doubleContraction(_strain[_qp]) + (_elasticity_tensor[_qp] * (*_dstrain[i])[_qp]).doubleContraction(_strain[_qp]); }
Real DerivativeTwoPhaseMaterial::computeDF(unsigned int i_var) { if (i_var == _eta_var) return _dh[_qp] * (_prop_Fb[_qp] - _prop_Fa[_qp]) + _W * _dg[_qp]; else { unsigned int i = argIndex(i_var); return _h[_qp] * (*_prop_dFb[i])[_qp] + (1.0 - _h[_qp]) * (*_prop_dFa[i])[_qp]; } }
Real ElasticEnergyMaterial::computeD2F(unsigned int i_var, unsigned int j_var) { unsigned int i = argIndex(i_var); unsigned int j = argIndex(j_var); // product rule d/dj computeDF // TODO: simplify because doubleContraction commutes return 0.5 * (((*_d2elasticity_tensor[i][j])[_qp] * _strain[_qp] + (*_delasticity_tensor[i])[_qp] * (*_dstrain[j])[_qp] + (*_delasticity_tensor[j])[_qp] * (*_dstrain[i])[_qp] + _elasticity_tensor[_qp] * (*_d2strain[i][j])[_qp]) .doubleContraction(_strain[_qp]) + ((*_delasticity_tensor[i])[_qp] * _strain[_qp] + _elasticity_tensor[_qp] * (*_dstrain[i])[_qp]) .doubleContraction((*_dstrain[j])[_qp]) + ( // dstress/dj (*_delasticity_tensor[j])[_qp] * _strain[_qp] + _elasticity_tensor[_qp] * (*_dstrain[j])[_qp]) .doubleContraction((*_dstrain[i])[_qp]) + _stress[_qp].doubleContraction((*_d2strain[i][j])[_qp])); }
Real DerivativeMultiPhaseMaterial::computeDF(unsigned int i_var) { const unsigned int i = argIndex(i_var); const int i_eta = _eta_index[i]; if (i_eta >= 0) return (*_dhi[i_eta])[_qp] * (*_prop_Fi[i_eta])[_qp] + _W * (*_dg[i_eta])[_qp]; else { Real dF = 0.0; for (unsigned n = 0; n < _num_fi; ++n) dF += (*_hi[n])[_qp] * (*_prop_dFi[n][i])[_qp]; return dF; } }
DiscreteNucleation::DiscreteNucleation(const InputParameters & params) : DerivativeFunctionMaterialBase(params), _nvar(coupledComponents("op_names")), _op_index(_nvar), _op_values(getParam<std::vector<Real>>("op_values")), _penalty(getParam<Real>("penalty")), _penalty_mode(getParam<MooseEnum>("penalty_mode")), _map(getUserObject<DiscreteNucleationMap>("map")) { // check inputs if (_nvar != _op_values.size()) mooseError("The op_names and op_values parameter vectors must have the same number of entries"); if (_nvar != _args.size()) mooseError("Internal error."); // get libMesh variable numbers for (unsigned int i = 0; i < _nvar; ++i) _op_index[i] = argIndex(coupled("op_names", i)); }
DiscreteNucleation::DiscreteNucleation(const InputParameters & params) : DerivativeFunctionMaterialBase(params), _nvar(coupledComponents("op_names")), _op_index(_nvar), _op_values(getParam<std::vector<Real> >("op_values")), _penalty(getParam<Real>("penalty")), _penalty_mode(getParam<MooseEnum>("penalty_mode")), _map(getUserObject<DiscreteNucleationMap>("map")) { // check inputs if (_nvar != _op_values.size()) mooseError("The op_names and op_values parameter vectors must have the same number of entries"); if (_nvar != _args.size()) mooseError("Internal error."); // this does not work with legacy UO initialization if (_fe_problem.legacyUoInitialization()) mooseError("DiscreteNucleation needs to be run with legacy UO initialization disabled. Set Problem/use_legacy_uo_initialization=false"); // get libMesh variable numbers for (unsigned int i = 0; i < _nvar; ++i) _op_index[i] = argIndex(coupled("op_names", i)); }
DerivativeMultiPhaseBase::DerivativeMultiPhaseBase(const InputParameters & parameters) : DerivativeFunctionMaterialBase(parameters), _eta_index(_nargs, -1), _num_etas(coupledComponents("etas")), _eta_names(_num_etas), _eta_vars(_num_etas), _fi_names(getParam<std::vector<MaterialPropertyName> >("fi_names")), _num_fi(_fi_names.size()), _prop_Fi(_num_fi), _prop_dFi(_num_fi), _prop_d2Fi(_num_fi), _prop_d3Fi(_num_fi), _hi_names(getParam<std::vector<MaterialPropertyName> >("hi_names")), _num_hi(_hi_names.size()), _hi(_num_hi), _g(getMaterialProperty<Real>("g")), _dg(_num_etas), _d2g(_num_etas), _d3g(_num_etas), _W(getParam<Real>("W")) { // check passed in parameter vectors if (_num_fi != _num_hi) mooseError("Need to pass in as many hi_names as fi_names in DerivativeMultiPhaseBase " << name()); // get order parameter names and libmesh variable names, set barrier function derivatives for (unsigned int i = 0; i < _num_etas; ++i) { _eta_names[i] = getVar("etas", i)->name(); _eta_vars[i] = coupled("etas", i); // for each coupled variable we need to know if it was coupled through "etas" // and - if so - which coupled component of "etas" it comes from _eta_index[argIndex(_eta_vars[i])] = i; // barrier function derivatives _dg[i] = &getMaterialPropertyDerivative<Real>("g", _eta_names[i]); _d2g[i].resize(_num_etas); if (_third_derivatives) _d3g[i].resize(_num_etas); for (unsigned int j = 0; j < _num_etas; ++j) { _d2g[i][j] = &getMaterialPropertyDerivative<Real>("g", _eta_names[i], _eta_names[j]); if (_third_derivatives) { _d3g[i][j].resize(_num_etas); for (unsigned int k = 0; k < _num_etas; ++k) _d3g[i][j][k] = &getMaterialPropertyDerivative<Real>("g", _eta_names[i], _eta_names[j], _eta_names[k]); } } } // reserve space and set phase material properties for (unsigned int n = 0; n < _num_fi; ++n) { // get phase free energy _prop_Fi[n] = &getMaterialPropertyByName<Real>(_fi_names[n]); _prop_dFi[n].resize(_nargs); _prop_d2Fi[n].resize(_nargs); _prop_d3Fi[n].resize(_nargs); // get switching function _hi[n] = &getMaterialPropertyByName<Real>(_hi_names[n]); for (unsigned int i = 0; i < _nargs; ++i) { _prop_dFi[n][i] = &getMaterialPropertyDerivative<Real>(_fi_names[n], _arg_names[i]); _prop_d2Fi[n][i].resize(_nargs); if (_third_derivatives) _prop_d3Fi[n][i].resize(_nargs); for (unsigned int j = 0; j < _nargs; ++j) { _prop_d2Fi[n][i][j] = &getMaterialPropertyDerivative<Real>(_fi_names[n], _arg_names[i], _arg_names[j]); if (_third_derivatives) { _prop_d3Fi[n][i][j].resize(_nargs); for (unsigned int k = 0; k < _nargs; ++k) _prop_d3Fi[n][i][j][k] = &getMaterialPropertyDerivative<Real>(_fi_names[n], _arg_names[i], _arg_names[j], _arg_names[k]); } } } } }