LCOV - code coverage report
Current view: top level - include/kernels - CahnHilliardBase.h (source / functions) Hit Total Coverage
Test: idaholab/moose phase_field: #31405 (292dce) with base fef103 Lines: 49 54 90.7 %
Date: 2025-09-04 07:55:36 Functions: 9 10 90.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       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             : #pragma once
      11             : 
      12             : #include "CHBulk.h"
      13             : 
      14             : /**
      15             :  * CahnHilliardBase implements the residual of the Cahn-Hilliard
      16             :  * equation in a general way that can be templated to a scalar or
      17             :  * tensor mobility.
      18             :  */
      19             : template <typename T>
      20             : class CahnHilliardBase : public CHBulk<T>
      21             : {
      22             : public:
      23             :   CahnHilliardBase(const InputParameters & parameters);
      24             : 
      25             :   static InputParameters validParams();
      26             :   virtual void initialSetup();
      27             : 
      28             : protected:
      29             :   typedef typename CHBulk<T>::PFFunctionType PFFunctionType;
      30             :   virtual RealGradient computeGradDFDCons(PFFunctionType type);
      31             :   virtual Real computeQpOffDiagJacobian(unsigned int jvar);
      32             : 
      33             :   // Explicitly declare the use of the following members of the parent class
      34             :   // https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-members
      35             :   using CHBulk<T>::_M;
      36             :   using CHBulk<T>::_i;
      37             :   using CHBulk<T>::_j;
      38             :   using CHBulk<T>::_qp;
      39             :   using CHBulk<T>::_var;
      40             :   using CHBulk<T>::_phi;
      41             :   using CHBulk<T>::_grad_u;
      42             :   using CHBulk<T>::_grad_phi;
      43             :   using CHBulk<T>::_grad_test;
      44             :   using CHBulk<T>::_coupled_moose_vars;
      45             :   using CHBulk<T>::_subproblem;
      46             :   using CHBulk<T>::_tid;
      47             : 
      48             : private:
      49             :   const unsigned int _nvar;
      50             :   std::vector<const MaterialProperty<Real> *> _second_derivatives;
      51             :   std::vector<const MaterialProperty<Real> *> _third_derivatives;
      52             :   std::vector<std::vector<const MaterialProperty<Real> *>> _third_cross_derivatives;
      53             :   std::vector<const VariableGradient *> _grad_vars;
      54             : };
      55             : 
      56             : template <typename T>
      57             : InputParameters
      58         260 : CahnHilliardBase<T>::validParams()
      59             : {
      60         260 :   InputParameters params = CHBulk<Real>::validParams();
      61         260 :   params.addClassDescription("Cahn-Hilliard Kernel that uses a DerivativeMaterial Free Energy");
      62         520 :   params.addRequiredParam<MaterialPropertyName>(
      63             :       "f_name", "Base name of the free energy function F defined in a DerivativeParsedMaterial");
      64         520 :   params.addCoupledVar("displacement_gradients",
      65             :                        "Vector of displacement gradient variables (see "
      66             :                        "Modules/PhaseField/DisplacementGradients "
      67             :                        "action)");
      68         260 :   return params;
      69           0 : }
      70             : 
      71             : template <typename T>
      72         138 : CahnHilliardBase<T>::CahnHilliardBase(const InputParameters & parameters)
      73             :   : CHBulk<T>(parameters),
      74         138 :     _nvar(_coupled_moose_vars.size()),
      75         138 :     _second_derivatives(_nvar + 1),
      76         138 :     _third_derivatives(_nvar + 1),
      77         138 :     _third_cross_derivatives(_nvar),
      78         276 :     _grad_vars(_nvar + 1)
      79             : {
      80             :   // derivatives w.r.t. and gradients of the kernel variable
      81         138 :   _second_derivatives[0] =
      82         276 :       &this->template getMaterialPropertyDerivative<Real>("f_name", _var.name(), _var.name());
      83         138 :   _third_derivatives[0] = &this->template getMaterialPropertyDerivative<Real>(
      84         138 :       "f_name", _var.name(), _var.name(), _var.name());
      85         138 :   _grad_vars[0] = &(_grad_u);
      86             : 
      87             :   // Iterate over all coupled variables
      88         177 :   for (unsigned int i = 0; i < _nvar; ++i)
      89             :   {
      90          39 :     const VariableName iname = _coupled_moose_vars[i]->name();
      91          39 :     if (iname == _var.name())
      92             :     {
      93           0 :       if (this->isCoupled("args"))
      94           0 :         this->paramError(
      95             :             "args", "The kernel variable should not be specified in the coupled `args` parameter.");
      96             :       else
      97           0 :         this->paramError("coupled_variables",
      98             :                          "The kernel variable should not be specified in the coupled "
      99             :                          "`coupled_variables` parameter.");
     100             :     }
     101          39 :     _second_derivatives[i + 1] =
     102          78 :         &this->template getMaterialPropertyDerivative<Real>("f_name", _var.name(), iname);
     103          39 :     _third_derivatives[i + 1] = &this->template getMaterialPropertyDerivative<Real>(
     104          39 :         "f_name", _var.name(), _var.name(), iname);
     105             : 
     106          39 :     _third_cross_derivatives[i].resize(_nvar);
     107         132 :     for (unsigned int j = 0; j < _nvar; ++j)
     108             :     {
     109          93 :       VariableName jname = _coupled_moose_vars[j]->name();
     110          93 :       _third_cross_derivatives[i][j] =
     111         186 :           &this->template getMaterialPropertyDerivative<Real>("f_name", _var.name(), iname, jname);
     112             :     }
     113             : 
     114          39 :     _grad_vars[i + 1] = &_subproblem.getStandardVariable(_tid, iname).gradSln();
     115             :   }
     116         138 : }
     117             : 
     118             : template <typename T>
     119             : void
     120         120 : CahnHilliardBase<T>::initialSetup()
     121             : {
     122             :   /**
     123             :    * Check if both the non-linear as well as the auxiliary variables variables
     124             :    * are coupled. Derivatives with respect to both types of variables contribute
     125             :    * the residual.
     126             :    */
     127         480 :   this->template validateCoupling<Real>("f_name", _var.name());
     128         120 :   this->template validateDerivativeMaterialPropertyBase<Real>("f_name");
     129         120 : }
     130             : 
     131             : template <typename T>
     132             : RealGradient
     133    97486424 : CahnHilliardBase<T>::computeGradDFDCons(PFFunctionType type)
     134             : {
     135             :   RealGradient res = 0.0;
     136             : 
     137    97486424 :   switch (type)
     138             :   {
     139             :     case CHBulk<T>::Residual:
     140   149901264 :       for (unsigned int i = 0; i <= _nvar; ++i)
     141    87538536 :         res += (*_grad_vars[i])[_qp] * (*_second_derivatives[i])[_qp];
     142             :       return res;
     143             : 
     144    35123696 :     case CHBulk<T>::Jacobian:
     145    35123696 :       res = _grad_phi[_j][_qp] * (*_second_derivatives[0])[_qp];
     146    72296928 :       for (unsigned int i = 0; i <= _nvar; ++i)
     147    37173232 :         res += _phi[_j][_qp] * (*_grad_vars[i])[_qp] * (*_third_derivatives[i])[_qp];
     148             :       return res;
     149             :   }
     150             : 
     151           0 :   mooseError("Internal error");
     152             : }
     153             : 
     154             : template <typename T>
     155             : Real
     156    22962176 : CahnHilliardBase<T>::computeQpOffDiagJacobian(unsigned int jvar)
     157             : {
     158             :   // get the coupled variable jvar is referring to
     159             :   const unsigned int cvar = this->mapJvarToCvar(jvar);
     160             : 
     161    22962176 :   RealGradient J = _grad_u[_qp] * _phi[_j][_qp] * (*_third_derivatives[cvar + 1])[_qp] +
     162    22962176 :                    _grad_phi[_j][_qp] * (*_second_derivatives[cvar + 1])[_qp];
     163             : 
     164    45924352 :   for (unsigned int i = 0; i < _nvar; ++i)
     165    22962176 :     J += _phi[_j][_qp] * (*_grad_vars[i + 1])[_qp] * (*_third_cross_derivatives[i][cvar])[_qp];
     166             : 
     167    22962176 :   return CHBulk<T>::computeQpOffDiagJacobian(jvar) + _M[_qp] * _grad_test[_i][_qp] * J;
     168             : }

Generated by: LCOV version 1.14