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));
}
Beispiel #9
0
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]);
        }
      }
    }
  }
}