Skip to content
Permalink
Browse files

Merge pull request #13199 from dschwen/adallencahn_13197

AD enabled Allen-Cahn phase field model
  • Loading branch information...
permcody committed Apr 11, 2019
2 parents 0ea7a33 + b08c5a6 commit 504b617cbed0a5a147b0e9d7a64b8765276ec22f
Showing with 820 additions and 68 deletions.
  1. +1 −0 framework/include/interfaces/Coupleable.h
  2. +9 −7 modules/phase_field/doc/content/source/kernels/ACInterface.md
  3. +21 −0 modules/phase_field/doc/content/source/kernels/ADACInterface.md
  4. +25 −0 modules/phase_field/doc/content/source/kernels/ADAllenCahn.md
  5. +9 −10 modules/phase_field/doc/content/source/kernels/AllenCahn.md
  6. +60 −0 modules/phase_field/include/kernels/ADACInterface.h
  7. +41 −0 modules/phase_field/include/kernels/ADAllenCahn.h
  8. +70 −0 modules/phase_field/include/kernels/ADAllenCahnBase.h
  9. +3 −3 modules/phase_field/include/kernels/ADSplitCHWResBase.h
  10. +73 −0 modules/phase_field/src/kernels/ADACInterface.C
  11. +35 −0 modules/phase_field/src/kernels/ADAllenCahn.C
  12. +17 −0 modules/phase_field/src/kernels/ADAllenCahnBase.C
  13. +57 −0 modules/phase_field/test/include/materials/ADTestDerivativeFunction.h
  14. +74 −0 modules/phase_field/test/src/materials/ADTestDerivativeFunction.C
  15. +76 −0 modules/phase_field/test/tests/phase_field_kernels/ADAllenCahn.i
  16. +88 −0 modules/phase_field/test/tests/phase_field_kernels/ADAllenCahnVariableL.i
  17. +1 −10 modules/phase_field/test/tests/phase_field_kernels/ADSplitCahnHilliard.i
  18. +8 −23 modules/phase_field/test/tests/phase_field_kernels/AllenCahn.i
  19. +89 −0 modules/phase_field/test/tests/phase_field_kernels/AllenCahnVariableL.i
  20. +6 −13 modules/phase_field/test/tests/phase_field_kernels/CoupledAllenCahn.i
  21. +1 −0 modules/phase_field/test/tests/phase_field_kernels/gold/ADAllenCahnVariableL_out.e
  22. +1 −0 modules/phase_field/test/tests/phase_field_kernels/gold/ADAllenCahn_out.e
  23. BIN modules/phase_field/test/tests/phase_field_kernels/gold/AllenCahnVariableL_out.e
  24. BIN modules/phase_field/test/tests/phase_field_kernels/gold/AllenCahn_out.e
  25. +55 −2 modules/phase_field/test/tests/phase_field_kernels/tests
@@ -19,6 +19,7 @@
#define usingCoupleableMembers \
using Coupleable::_zero; \
using Coupleable::_grad_zero; \
using Coupleable::_coupled_standard_moose_vars; \
using Coupleable::isCoupled; \
using Coupleable::coupledComponents; \
using Coupleable::coupled; \
@@ -2,15 +2,17 @@

!syntax description /Kernels/ACInterface

Implements the Allen-Cahn term for the $\frac{\kappa_i}2|\nabla \eta_i|^2$ gradient
energy contribution for the isotropic mobility case. Its weak form is
Implements the Allen-Cahn term for the $\frac{\kappa_i}2|\nabla \eta_i|^2$
gradient energy contribution for the isotropic mobility case. Its weak form is

\begin{equation}
\left( \kappa_i \nabla \eta_i, \nabla \cdot (L_i \psi_m ) \right),
\left( \kappa_i \nabla \eta_i, \nabla (L_i \psi_m ) \right),
\end{equation}
where $\kappa_i$ (`kappa_name`) is the gradient energy coefficent, $\eta_i$ the non-conserved
non-linear order parameter variable the kernel is acting on, $L_i$ (`mob_name`) is
the scalar (isotropic) mobility associated with the order parameter, and $\psi_m$
is the test function.

where $\kappa_i$ (`kappa_name`) is the gradient energy coefficent, $\eta_i$ the
non-conserved non-linear order parameter variable the kernel is acting on, $L_i$
(`mob_name`) is the scalar (isotropic) mobility associated with the order
parameter, and $\psi_m$ is the test function.

!syntax parameters /Kernels/ACInterface

@@ -0,0 +1,21 @@
# ADACInterface

!syntax description /Kernels/ADACInterface<RESIDUAL>

Implements the Allen-Cahn term for the $\frac{\kappa_i}2|\nabla \eta_i|^2$
gradient energy contribution for the isotropic mobility case. Its weak form is

\begin{equation}
\left( \kappa_i \nabla \eta_i, \nabla (L_i \psi_m ) \right),
\end{equation}

where $\kappa_i$ (`kappa_name`) is the gradient energy coefficent, $\eta_i$ the
non-conserved non-linear order parameter variable the kernel is acting on, $L_i$
(`mob_name`) is the scalar (isotropic) mobility associated with the order
parameter, and $\psi_m$ is the test function.

!syntax parameters /Kernels/ADACInterface<RESIDUAL>

!syntax inputs /Kernels/ADACInterface<RESIDUAL>

!syntax children /Kernels/ADACInterface<RESIDUAL>
@@ -0,0 +1,25 @@
# ADAllenCahn

!syntax description /Kernels/ADAllenCahn<RESIDUAL>

Implements the term

\begin{equation}
L\frac{\partial f_{bulk}}(\eta)}{\partial\eta},
\end{equation}

where $\eta$ is the variable the kernel is acting on, $L$ (`mob_name`) its
associated mobility, and $f_{bulk}$ (`f_name`) is the bulk free energy density
of the system which is provided by a [function material](../../introduction/FunctionMaterials).

The $\nabla \eta$ dependent terms in the free energy functional of the system
that arise from the gradient interface energy are handled separately in the
[`ADACInterface`](/ADACInterface.md) kernel.

!syntax parameters /Kernels/ADAllenCahn<RESIDUAL>

!syntax inputs /Kernels/ADAllenCahn<RESIDUAL>

!syntax children /Kernels/ADAllenCahn<RESIDUAL>

!bibtex bibliography
@@ -2,20 +2,19 @@

!syntax description /Kernels/AllenCahn

Implements the term

\begin{equation}
L(\eta,a,b,\dots)\frac{\delta F}{\delta\eta} = L(\eta,a,b,\dots)\frac{\partial f(\eta,a,b,\dots)}{\partial\eta}
L(\eta,a,b,\dots)\frac{\partial f_{bulk}}(\eta,a,b,\dots)}{\partial\eta},
\end{equation}

$F$ is the free energy functional of the system that is defined as $F=\int f(\eta) d\Omega$.

$\eta$ is the variable the kernel is acting on, $L$ (`mob_name`) its associated mobility,
$f$ (`f_name`) is a free energy density provided by a [function material](../../introduction/FunctionMaterials), and
$a,b,\dots$ (`args`) are additional variable dependencies of the mobility and free energy density.
where $\eta$ is the variable the kernel is acting on, $L$ (`mob_name`) its
associated mobility, and $f_{bulk}$ (`f_name`) is the bulk free energy density
of the system which is provided by a [function material](../../introduction/FunctionMaterials).
$a,b,\dots$ (`args`) are additional variable dependencies of the mobility and
free energy density.

Note that this makes the assumption that $F$ is *not* depending on $\nabla\eta$. The $\nabla \eta$ dependent terms
that arise from the gradient interface energy are handled separately in the [`ACInterface`](/ACInterface.md) kernel.
The $\nabla \eta$ dependent terms in the free energy functional of the system
that arise from the gradient interface energy are handled separately in the
[`ACInterface`](/ACInterface.md) kernel.

!syntax parameters /Kernels/AllenCahn

@@ -0,0 +1,60 @@
//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#ifndef ADACINTERFACE_H
#define ADACINTERFACE_H

#include "ADKernel.h"
#include "DerivativeMaterialPropertyNameInterface.h"

template <ComputeStage>
class ADACInterface;

declareADValidParams(ADACInterface);

/**
* Compute the Allen-Cahn interface term with the weak form residual
* \f$ \left( \kappa_i \nabla\eta_i, \nabla (L_i \psi) \right) \f$
*/
template <ComputeStage compute_stage>
class ADACInterface : public ADKernel<compute_stage>, public DerivativeMaterialPropertyNameInterface
{
public:
ADACInterface(const InputParameters & parameters);

protected:
virtual ADReal computeQpResidual();

/// Mobility
const ADMaterialProperty(Real) & _prop_L;
/// Mobility property name
const MaterialPropertyName & _name_L;

/// Interfacial parameter
const ADMaterialProperty(Real) & _kappa;

/// flag set if L is a function of non-linear variables in args
const bool _variable_L;

/// Mobility derivative w.r.t. order parameter
const ADMaterialProperty(Real) * _dLdop;

/// number of coupled variables
const unsigned int _nvar;

/// Mobility derivative w.r.t. other coupled variables
std::vector<const ADMaterialProperty(Real) *> _dLdarg;

/// Gradients for all coupled variables
std::vector<const ADVariableGradient *> _gradarg;

usingKernelMembers;
};

#endif // ADACINTERFACE_H
@@ -0,0 +1,41 @@
//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#ifndef ADALLENCAHN_H
#define ADALLENCAHN_H

#include "ADAllenCahnBase.h"

// Forward Declarations
template <ComputeStage>
class ADAllenCahn;

declareADValidParams(ADAllenCahn);

/**
* ADAllenCahn uses the Free Energy function and derivatives
* provided by a DerivativeParsedMaterial to computer the
* residual for the bulk part of the Allen-Cahn equation.
*/
template <ComputeStage compute_stage>
class ADAllenCahn : public ADAllenCahnBase<compute_stage, Real>
{
public:
ADAllenCahn(const InputParameters & parameters);

protected:
virtual ADReal computeDFDOP();

const MaterialPropertyName _f_name;
const ADMaterialProperty(Real) & _dFdEta;

usingAllenCahnBaseMembers(Real);
};

#endif // ADALLENCAHN_H
@@ -0,0 +1,70 @@
//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#ifndef ADALLENCAHNBASE_H
#define ADALLENCAHNBASE_H

#include "ADKernelValue.h"
#include "DerivativeMaterialPropertyNameInterface.h"

#define usingAllenCahnBaseMembers(T) \
usingKernelValueMembers; \
using ADAllenCahnBase<compute_stage, T>::_prop_L; \
using ADAllenCahnBase<compute_stage, T>::computeDFDOP

// Forward declarations
template <ComputeStage compute_stage, typename T = void>
class ADAllenCahnBase;

declareADValidParams(ADAllenCahnBase);

/**
* This is the Allen-Cahn equation base class that implements the bulk or
* local energy term of the equation. It is templated on the type of the mobility,
* which can be either a number (Real) or a tensor (RealValueTensor).
* Note that the function computeDFDOP MUST be overridden in any kernel that inherits from
* ADAllenCahnBase. This is the AD equivalent of ACBulk<>.
*/
template <ComputeStage compute_stage, typename T>
class ADAllenCahnBase : public ADKernelValue<compute_stage>,
public DerivativeMaterialPropertyNameInterface
{
public:
ADAllenCahnBase(const InputParameters & parameters);

static InputParameters validParams();

protected:
virtual ADReal precomputeQpResidual();

/// Compute the derivative of the bulk free energy w.r.t the order parameter
virtual ADReal computeDFDOP() = 0;

/// Mobility
const ADMaterialProperty(T) & _prop_L;

usingKernelValueMembers;
};

template <ComputeStage compute_stage, typename T>
ADAllenCahnBase<compute_stage, T>::ADAllenCahnBase(const InputParameters & parameters)
: ADKernelValue<compute_stage>(parameters),
DerivativeMaterialPropertyNameInterface(),
_prop_L(adGetADMaterialProperty<T>("mob_name"))
{
}

template <ComputeStage compute_stage, typename T>
ADReal
ADAllenCahnBase<compute_stage, T>::precomputeQpResidual()
{
return _prop_L[_qp] * computeDFDOP();
}

#endif // ADALLENCAHNBASE_H
@@ -13,10 +13,10 @@
#include "ADKernelGrad.h"
#include "DerivativeMaterialInterface.h"

#define usingSplitCHWResBase \
#define usingSplitCHWResBase(T) \
usingKernelMembers; \
using ADSplitCHCRes<compute_stage>::_mob_name; \
using ADSplitCHCRes<compute_stage>::_mob
using ADSplitCHWResBase<compute_stage, T>::_mob_name; \
using ADSplitCHWResBase<compute_stage, T>::_mob

// Forward declarations
template <ComputeStage compute_stage, typename T = void>
@@ -0,0 +1,73 @@
//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#include "ADACInterface.h"

registerADMooseObject("PhaseFieldApp", ADACInterface);

defineADValidParams(
ADACInterface, ADKernel, params.addClassDescription("Gradient energy Allen-Cahn Kernel");
params.addParam<MaterialPropertyName>("mob_name", "L", "The mobility used with the kernel");
params.addParam<MaterialPropertyName>("kappa_name",
"kappa_op",
"The kappa used with the kernel");
params.addCoupledVar("args", "Vector of nonlinear variable arguments this object depends on");
params.addParam<bool>("variable_L",
true,
"The mobility is a function of any MOOSE variable (if "
"this is set to false L must be constant over the "
"entire domain!)"););

template <ComputeStage compute_stage>
ADACInterface<compute_stage>::ADACInterface(const InputParameters & parameters)
: ADKernel<compute_stage>(parameters),
_prop_L(adGetADMaterialProperty<Real>("mob_name")),
_name_L(adGetParam<MaterialPropertyName>("mob_name")),
_kappa(adGetADMaterialProperty<Real>("kappa_name")),
_variable_L(adGetParam<bool>("variable_L")),
_dLdop(_variable_L
? &adGetADMaterialProperty<Real>(derivativePropertyNameFirst(_name_L, _var.name()))
: nullptr),
_nvar(_coupled_standard_moose_vars.size()),
_dLdarg(_nvar),
_gradarg(_nvar)
{
// Get mobility and kappa derivatives and coupled variable gradients
if (_variable_L)
for (unsigned int i = 0; i < _nvar; ++i)
{
MooseVariable * ivar = _coupled_standard_moose_vars[i];
const VariableName iname = ivar->name();
if (iname == _var.name())
paramError("args",
"The kernel variable should not be specified in the coupled `args` parameter.");

_dLdarg[i] = &adGetADMaterialProperty<Real>(derivativePropertyNameFirst(_name_L, iname));
_gradarg[i] = &(ivar->adGradSln<compute_stage>());
}
}

template <ComputeStage compute_stage>
ADReal
ADACInterface<compute_stage>::computeQpResidual()
{
// nabla_Lpsi is the product rule gradient \f$ \nabla (L\psi) \f$
ADRealVectorValue nabla_Lpsi = _prop_L[_qp] * _grad_test[_i][_qp];

if (_variable_L)
{
ADRealVectorValue grad_L = _grad_u[_qp] * (*_dLdop)[_qp];
for (unsigned int i = 0; i < _nvar; ++i)
grad_L += (*_gradarg[i])[_qp] * (*_dLdarg[i])[_qp];

nabla_Lpsi += grad_L * _test[_i][_qp];
}

return _grad_u[_qp] * _kappa[_qp] * nabla_Lpsi;
}
Oops, something went wrong.

0 comments on commit 504b617

Please sign in to comment.
You can’t perform that action at this time.