Skip to content

Commit

Permalink
Add (an)isotropic CHInterface kernels (idaholab#5596)
Browse files Browse the repository at this point in the history
  • Loading branch information
dschwen committed Aug 25, 2015
1 parent b75d205 commit 790236a
Show file tree
Hide file tree
Showing 6 changed files with 234 additions and 148 deletions.
54 changes: 7 additions & 47 deletions modules/phase_field/include/kernels/CHInterface.h
Expand Up @@ -7,59 +7,19 @@
#ifndef CHINTERFACE_H
#define CHINTERFACE_H

#include "Kernel.h"
#include "Material.h"
#include "JvarMapInterface.h"
#include "DerivativeKernelInterface.h"

//Forward Declarations
class CHInterface;

template<>
InputParameters validParams<CHInterface>();
#include "CHInterfaceBase.h"

/**
* This is the Cahn-Hilliard equation base class that implements the interfacial or gradient energy term of the equation.
* See M.R. Tonks et al. / Computational Materials Science 51 (2012) 20–29 for more information.
* This is the Cahn-Hilliard equation base class that implements the interfacial
* or gradient energy term of the equation. With a scalar (isotropic) mobility.
*/
class CHInterface : public DerivativeMaterialInterface<JvarMapInterface<Kernel> >
class CHInterface : public CHInterfaceBase<Real>
{
public:
CHInterface(const InputParameters & parameters);

protected:
virtual Real computeQpResidual();
virtual Real computeQpJacobian();
virtual Real computeQpOffDiagJacobian(unsigned int jvar);

const MaterialProperty<Real> & _kappa;

///@{
/// Mobility material property value and concentration derivatives
const MaterialProperty<Real> & _M;
const MaterialProperty<Real> & _dMdc;
const MaterialProperty<Real> & _d2Mdc2;
///@}

///@{
/// Variables for second order derivatives
VariableSecond & _second_u;
VariableTestSecond & _second_test;
VariablePhiSecond & _second_phi;
///@}

///Number of variables
unsigned int _nvar;

///@{
/// Mobility derivatives w.r.t. its dependent variables
std::vector<const MaterialProperty<Real> *> _dMdarg;
std::vector<const MaterialProperty<Real> *> _d2Mdcdarg;
std::vector<std::vector<const MaterialProperty<Real>* > > _d2Mdargdarg;
///@}

/// Coupled variables used in mobility
std::vector<VariableGradient *> _coupled_grad_vars;
};

template<>
InputParameters validParams<CHInterface>();

#endif //CHINTERFACE_H
25 changes: 25 additions & 0 deletions modules/phase_field/include/kernels/CHInterfaceAniso.h
@@ -0,0 +1,25 @@
/****************************************************************/
/* MOOSE - Multiphysics Object Oriented Simulation Environment */
/* */
/* All contents are licensed under LGPL V2.1 */
/* See LICENSE for full restrictions */
/****************************************************************/
#ifndef CHINTERFACEANISO_H
#define CHINTERFACEANISO_H

#include "CHInterfaceBase.h"

/**
* This is the Cahn-Hilliard equation base class that implements the interfacial
* or gradient energy term of the equation. With a scalar (isotropic) mobility.
*/
class CHInterfaceAniso : public CHInterfaceBase<RealTensorValue>
{
public:
CHInterfaceAniso(const InputParameters & parameters);
};

template<>
InputParameters validParams<CHInterfaceAniso>();

#endif //CHINTERFACEANISO_H
177 changes: 177 additions & 0 deletions modules/phase_field/include/kernels/CHInterfaceBase.h
@@ -0,0 +1,177 @@
/****************************************************************/
/* MOOSE - Multiphysics Object Oriented Simulation Environment */
/* */
/* All contents are licensed under LGPL V2.1 */
/* See LICENSE for full restrictions */
/****************************************************************/
#ifndef CHINTERFACEBASE_H
#define CHINTERFACEBASE_H

#include "Kernel.h"
#include "Material.h"
#include "JvarMapInterface.h"
#include "DerivativeKernelInterface.h"

/**
* This is the Cahn-Hilliard equation base class that implements the interfacial or gradient energy term of the equation.
* See M.R. Tonks et al. / Computational Materials Science 51 (2012) 20–29 for more information.
*/
template<typename T>
class CHInterfaceBase : public DerivativeMaterialInterface<JvarMapInterface<Kernel> >
{
public:
CHInterfaceBase(const InputParameters & parameters);

static InputParameters validParams();

protected:
virtual Real computeQpResidual();
virtual Real computeQpJacobian();
virtual Real computeQpOffDiagJacobian(unsigned int jvar);

const MaterialProperty<Real> & _kappa;

///@{
/// Mobility material property value and concentration derivatives
const MaterialProperty<T> & _M;
const MaterialProperty<T> & _dMdc;
const MaterialProperty<T> & _d2Mdc2;
///@}

///@{
/// Variables for second order derivatives
VariableSecond & _second_u;
VariableTestSecond & _second_test;
VariablePhiSecond & _second_phi;
///@}

///Number of variables
unsigned int _nvar;

///@{
/// Mobility derivatives w.r.t. its dependent variables
std::vector<const MaterialProperty<T> *> _dMdarg;
std::vector<const MaterialProperty<T> *> _d2Mdcdarg;
std::vector<std::vector<const MaterialProperty<T>* > > _d2Mdargdarg;
///@}

/// Coupled variables used in mobility
std::vector<VariableGradient *> _coupled_grad_vars;
};

template<typename T>
CHInterfaceBase<T>::CHInterfaceBase(const InputParameters & parameters) :
DerivativeMaterialInterface<JvarMapInterface<Kernel> >(parameters),
_kappa(getMaterialProperty<Real>("kappa_name")),
_M(getMaterialProperty<T>("mob_name")),
_dMdc(getMaterialPropertyDerivative<T>("mob_name", _var.name())),
_d2Mdc2(getMaterialPropertyDerivative<T>("mob_name", _var.name(), _var.name())),
_second_u(second()),
_second_test(secondTest()),
_second_phi(secondPhi()),
_nvar(_coupled_moose_vars.size()),
_dMdarg(_nvar),
_d2Mdcdarg(_nvar),
_d2Mdargdarg(_nvar),
_coupled_grad_vars(_nvar)
{
// Iterate over all coupled variables
for (unsigned int i = 0; i < _nvar; ++i)
{
//Set material property values
_dMdarg[i] = &getMaterialPropertyDerivative<T>("mob_name", _coupled_moose_vars[i]->name());
_d2Mdcdarg[i] = &getMaterialPropertyDerivative<T>("mob_name", _var.name(), _coupled_moose_vars[i]->name());
_d2Mdargdarg[i].resize(_nvar);
for (unsigned int j = 0; j < _nvar; ++j)
_d2Mdargdarg[i][j] = &getMaterialPropertyDerivative<T>("mob_name", _coupled_moose_vars[i]->name(), _coupled_moose_vars[j]->name());

//Set coupled variable gradients
_coupled_grad_vars[i] = &coupledGradient("args", i);
}
}

template<typename T>
InputParameters
CHInterfaceBase<T>::validParams()
{
InputParameters params = ::validParams<Kernel>();
params.addClassDescription("Gradient energy Cahn-Hilliard base Kernel");
params.addRequiredParam<MaterialPropertyName>("kappa_name", "The kappa used with the kernel");
params.addRequiredParam<MaterialPropertyName>("mob_name", "The mobility used with the kernel");
params.addCoupledVar("args", "Vector of arguments to mobility");
return params;
}

template<typename T>
Real
CHInterfaceBase<T>::computeQpResidual()
{
RealGradient grad_M = _dMdc[_qp] * _grad_u[_qp];
for (unsigned int i = 0; i < _nvar; ++i)
grad_M += (*_dMdarg[i])[_qp] * (*_coupled_grad_vars[i])[_qp];

return _kappa[_qp] * _second_u[_qp].tr()
* (
(_M[_qp] * _second_test[_i][_qp]).tr()
+ grad_M * _grad_test[_i][_qp]
);
}

template<typename T>
Real
CHInterfaceBase<T>::computeQpJacobian()
{
// Set the gradient and gradient derivative values
RealGradient grad_M = _dMdc[_qp] * _grad_u[_qp];

RealGradient dgrad_Mdc = _d2Mdc2[_qp] * _phi[_j][_qp] * _grad_u[_qp]
+ _dMdc[_qp] * _grad_phi[_j][_qp];

for (unsigned int i = 0; i < _nvar; ++i)
{
grad_M += (*_dMdarg[i])[_qp] * (*_coupled_grad_vars[i])[_qp];
dgrad_Mdc += (*_d2Mdcdarg[i])[_qp] * _phi[_j][_qp] * (*_coupled_grad_vars[i])[_qp];
}

//Jacobian value using product rule
Real value = _kappa[_qp] * _second_phi[_j][_qp].tr()
* (
(_M[_qp] * _second_test[_i][_qp]).tr()
+ grad_M * _grad_test[_i][_qp]
)
+ _kappa[_qp] * _second_u[_qp].tr()
* (
(_dMdc[_qp] * _second_test[_i][_qp]).tr() * _phi[_j][_qp]
+ dgrad_Mdc * _grad_test[_i][_qp]
);

return value;
}

template<typename T>
Real
CHInterfaceBase<T>::computeQpOffDiagJacobian(unsigned int jvar)
{
// get the coupled variable jvar is referring to
unsigned int cvar;
if (!mapJvarToCvar(jvar, cvar))
return 0.0;

// Set the gradient derivative
RealGradient dgrad_Mdarg = (*_d2Mdcdarg[cvar])[_qp] * _phi[_j][_qp] * _grad_u[_qp]
+ (*_dMdarg[cvar])[_qp] * _grad_phi[_j][_qp];

for (unsigned int i = 0; i < _nvar; ++i)
dgrad_Mdarg += (*_d2Mdargdarg[cvar][i])[_qp] * _phi[_j][_qp] * (*_coupled_grad_vars[cvar])[_qp];

//Jacobian value using product rule
Real value = _kappa[_qp] * _second_u[_qp].tr()
* (
((*_dMdarg[cvar])[_qp] * _second_test[_i][_qp]).tr() * _phi[_j][_qp]
+ dgrad_Mdarg * _grad_test[_i][_qp]
);

return value;
}

#endif //CHINTERFACE_H
2 changes: 2 additions & 0 deletions modules/phase_field/src/base/PhaseFieldApp.C
Expand Up @@ -22,6 +22,7 @@
#include "CHBulkPFCTrad.h"
#include "CHCpldPFCTrad.h"
#include "CHInterface.h"
#include "CHInterfaceAniso.h"
#include "CHMath.h"
#include "CHPFCRFF.h"
#include "CHSplitVar.h"
Expand Down Expand Up @@ -227,6 +228,7 @@ PhaseFieldApp::registerObjects(Factory & factory)
registerKernel(CHBulkPFCTrad);
registerKernel(CHCpldPFCTrad);
registerKernel(CHInterface);
registerKernel(CHInterfaceAniso);
registerKernel(CHMath);
registerKernel(CHPFCRFF);
registerKernel(CHSplitVar);
Expand Down

0 comments on commit 790236a

Please sign in to comment.