LCOV - code coverage report
Current view: top level - src/kernels - CoupledSwitchingTimeDerivative.C (source / functions) Hit Total Coverage
Test: idaholab/moose phase_field: #32971 (54bef8) with base c6cf66 Lines: 67 69 97.1 %
Date: 2026-05-29 20:38:39 Functions: 12 12 100.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             : #include "CoupledSwitchingTimeDerivative.h"
      11             : 
      12             : registerMooseObject("PhaseFieldApp", CoupledSwitchingTimeDerivative);
      13             : registerMooseObject("PhaseFieldApp", ADCoupledSwitchingTimeDerivative);
      14             : 
      15             : template <bool is_ad>
      16             : InputParameters
      17         375 : CoupledSwitchingTimeDerivativeTempl<is_ad>::validParams()
      18             : {
      19         375 :   InputParameters params = CoupledSwitchingTimeDerivativeBase<is_ad>::validParams();
      20         375 :   params.addClassDescription(
      21             :       "Coupled time derivative Kernel that multiplies the time derivative by "
      22             :       "$\\frac{dh_\\alpha}{d\\eta_i} F_\\alpha + \\frac{dh_\\beta}{d\\eta_i} F_\\beta + \\dots$");
      23         750 :   params.addRequiredParam<std::vector<MaterialPropertyName>>(
      24             :       "Fj_names", "List of functions for each phase. Place in same order as hj_names!");
      25         750 :   params.addRequiredParam<std::vector<MaterialPropertyName>>(
      26             :       "hj_names", "Switching Function Materials that provide h. Place in same order as Fj_names!");
      27         750 :   params.addCoupledVar("coupled_variables", "Vector of variable arguments of Fj and hj");
      28         375 :   return params;
      29           0 : }
      30             : template <bool is_ad>
      31         201 : CoupledSwitchingTimeDerivativeTempl<is_ad>::CoupledSwitchingTimeDerivativeTempl(
      32             :     const InputParameters & parameters)
      33             :   : DerivativeMaterialInterface<JvarMapKernelInterface<CoupledSwitchingTimeDerivativeBase<is_ad>>>(
      34             :         parameters),
      35         201 :     _v_name(this->coupledName("v", 0)),
      36         603 :     _Fj_names(this->template getParam<std::vector<MaterialPropertyName>>("Fj_names")),
      37         201 :     _num_j(_Fj_names.size()),
      38         201 :     _prop_Fj(_num_j),
      39         402 :     _hj_names(this->template getParam<std::vector<MaterialPropertyName>>("hj_names")),
      40         402 :     _prop_dhjdetai(_num_j)
      41             : {
      42             :   // check passed in parameter vectors
      43         201 :   if (_num_j != _hj_names.size())
      44           0 :     this->paramError("hj_names", "Need to pass in as many hj_names as Fj_names");
      45             : 
      46             :   // reserve space and set phase material properties
      47         645 :   for (unsigned int n = 0; n < _num_j; ++n)
      48             :   {
      49             :     // get phase free energy
      50         444 :     _prop_Fj[n] = &this->template getGenericMaterialProperty<Real, is_ad>(_Fj_names[n]);
      51             : 
      52             :     // get switching function derivatives wrt eta_i, the nonlinear variable
      53         444 :     _prop_dhjdetai[n] =
      54         888 :         &this->template getMaterialPropertyDerivative<Real, is_ad>(_hj_names[n], _v_name);
      55             :   }
      56         201 : }
      57             : 
      58         141 : CoupledSwitchingTimeDerivative::CoupledSwitchingTimeDerivative(const InputParameters & parameters)
      59             :   : CoupledSwitchingTimeDerivativeTempl<false>(parameters),
      60         282 :     _prop_dFjdv(_num_j),
      61         141 :     _prop_dFjdarg(_num_j),
      62         141 :     _prop_d2hjdetai2(_num_j),
      63         282 :     _prop_d2hjdetaidarg(_num_j)
      64             : {
      65             :   // reserve space and set phase material properties
      66         444 :   for (unsigned int n = 0; n < _num_j; ++n)
      67             :   {
      68             :     // get phase free energy and derivatives
      69         303 :     _prop_dFjdv[n] = &getMaterialPropertyDerivative<Real>(_Fj_names[n], _var.name());
      70         303 :     _prop_dFjdarg[n].resize(_n_args);
      71             : 
      72             :     // get switching function and derivatives wrt eta_i, the nonlinear variable
      73         303 :     _prop_d2hjdetai2[n] = &getMaterialPropertyDerivative<Real>(_hj_names[n], _v_name, _v_name);
      74         303 :     _prop_d2hjdetaidarg[n].resize(_n_args);
      75             : 
      76        1643 :     for (unsigned int i = 0; i < _n_args; ++i)
      77             :     {
      78             :       // Get derivatives of all Fj wrt all coupled variables
      79        1340 :       _prop_dFjdarg[n][i] = &getMaterialPropertyDerivative<Real>(_Fj_names[n], i);
      80             : 
      81             :       // Get second derivatives of all hj wrt eta_i and all coupled variables
      82        1340 :       _prop_d2hjdetaidarg[n][i] = &getMaterialPropertyDerivative<Real>(_hj_names[n], _v_name, i);
      83             :     }
      84             :   }
      85         141 : }
      86             : 
      87             : template <bool is_ad>
      88             : void
      89         159 : CoupledSwitchingTimeDerivativeTempl<is_ad>::initialSetup()
      90             : {
      91         477 :   for (unsigned int n = 0; n < _num_j; ++n)
      92         954 :     this->template validateNonlinearCoupling<GenericReal<is_ad>>(_hj_names[n]);
      93         159 : }
      94             : 
      95             : void
      96         120 : CoupledSwitchingTimeDerivative::initialSetup()
      97             : {
      98         120 :   CoupledSwitchingTimeDerivativeTempl<false>::initialSetup();
      99         360 :   for (unsigned int n = 0; n < _num_j; ++n)
     100         720 :     validateNonlinearCoupling<Real>(_Fj_names[n]);
     101         120 : }
     102             : 
     103             : Real
     104     6740800 : CoupledSwitchingTimeDerivative::computeQpResidual()
     105             : {
     106             :   Real sum = 0.0;
     107    20222400 :   for (unsigned int n = 0; n < _num_j; ++n)
     108    13481600 :     sum += (*_prop_dhjdetai[n])[_qp] * (*_prop_Fj[n])[_qp];
     109             : 
     110     6740800 :   return CoupledTimeDerivative::computeQpResidual() * sum;
     111             : }
     112             : 
     113             : ADReal
     114      436020 : ADCoupledSwitchingTimeDerivative::precomputeQpResidual()
     115             : {
     116      436020 :   ADReal sum = 0.0;
     117     1308060 :   for (unsigned int n = 0; n < _num_j; ++n)
     118     1744080 :     sum += (*_prop_dhjdetai[n])[_qp] * (*_prop_Fj[n])[_qp];
     119             : 
     120      872040 :   return _v_dot[_qp] * sum;
     121             : }
     122             : 
     123             : Real
     124     6145600 : CoupledSwitchingTimeDerivative::computeQpJacobian()
     125             : {
     126             :   Real sum = 0.0;
     127    18436800 :   for (unsigned int n = 0; n < _num_j; ++n)
     128    12291200 :     sum += (*_prop_dhjdetai[n])[_qp] * (*_prop_dFjdv[n])[_qp];
     129             : 
     130     6145600 :   return CoupledTimeDerivative::computeQpResidual() * sum * _phi[_j][_qp];
     131             : }
     132             : 
     133             : Real
     134    16131200 : CoupledSwitchingTimeDerivative::computeQpOffDiagJacobian(unsigned int jvar)
     135             : {
     136             :   // get the coupled variable jvar is referring to
     137             :   const unsigned int cvar = mapJvarToCvar(jvar);
     138             : 
     139    16131200 :   if (jvar == _v_var)
     140             :   {
     141             :     Real sum = 0.0;
     142             : 
     143    17745600 :     for (unsigned int n = 0; n < _num_j; ++n)
     144    11830400 :       sum +=
     145    11830400 :           ((*_prop_d2hjdetai2[n])[_qp] * _v_dot[_qp] + (*_prop_dhjdetai[n])[_qp] * _dv_dot[_qp]) *
     146    11830400 :           (*_prop_Fj[n])[_qp];
     147             : 
     148     5915200 :     return _phi[_j][_qp] * sum * _test[_i][_qp];
     149             :   }
     150             : 
     151             :   Real sum = 0.0;
     152    30648000 :   for (unsigned int n = 0; n < _num_j; ++n)
     153    20432000 :     sum += (*_prop_d2hjdetaidarg[n][cvar])[_qp] * (*_prop_Fj[n])[_qp] +
     154    20432000 :            (*_prop_dhjdetai[n])[_qp] * (*_prop_dFjdarg[n][cvar])[_qp];
     155             : 
     156    10216000 :   return CoupledTimeDerivative::computeQpResidual() * sum * _phi[_j][_qp];
     157             : }
     158             : 
     159             : template class CoupledSwitchingTimeDerivativeTempl<false>;
     160             : template class CoupledSwitchingTimeDerivativeTempl<true>;

Generated by: LCOV version 1.14