LCOV - code coverage report
Current view: top level - src/kernels - SLKKSMultiACBulkC.C (source / functions) Hit Total Coverage
Test: idaholab/moose phase_field: #31405 (292dce) with base fef103 Lines: 78 81 96.3 %
Date: 2025-09-04 07:55:36 Functions: 5 5 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 "SLKKSMultiACBulkC.h"
      11             : 
      12             : registerMooseObject("PhaseFieldApp", SLKKSMultiACBulkC);
      13             : 
      14             : InputParameters
      15          80 : SLKKSMultiACBulkC::validParams()
      16             : {
      17          80 :   auto params = SLKKSMultiPhaseBase::validParams();
      18          80 :   params.addClassDescription("Multi-phase SLKKS model kernel for the bulk Allen-Cahn. "
      19             :                              "This includes all terms dependent on chemical potential.");
      20         160 :   params.addRequiredParam<MaterialPropertyName>(
      21             :       "F", "Phase free energy function that is a function of 'c'");
      22         160 :   params.addRequiredCoupledVar("c", "Concentration variable F depends on");
      23         160 :   params.addCoupledVar("eta_i",
      24             :                        "Order parameter that derivatives are taken with respect to (kernel "
      25             :                        "variable is used if this is not specified)");
      26         160 :   params.addParam<MaterialPropertyName>("mob_name", "L", "The mobility used with the kernel");
      27          80 :   return params;
      28           0 : }
      29             : 
      30          42 : SLKKSMultiACBulkC::SLKKSMultiACBulkC(const InputParameters & parameters)
      31             :   : SLKKSMultiPhaseBase(parameters),
      32          42 :     _c_name(coupledName("c", 0)),
      33          42 :     _lagrange(isCoupled("eta_i")),
      34          84 :     _etai_name(_lagrange ? coupledName("eta_i", 0) : _var.name()),
      35          42 :     _etai_var(_lagrange ? coupled("eta_i") : _var.number()),
      36          42 :     _cs_names(_ncs),
      37          42 :     _prop_dFdc(getMaterialPropertyDerivative<Real>("F", _c_name)),
      38          42 :     _prop_d2Fdcdcs(_ncs),
      39          42 :     _prop_dhdni(_nh),
      40          42 :     _prop_d2hdnidn(_nh),
      41          42 :     _l_cs(-1),
      42          42 :     _l_etai(-1),
      43         126 :     _mob(getMaterialProperty<Real>("mob_name"))
      44             : {
      45             :   // Determine position of the selected concentration variable
      46         210 :   for (std::size_t i = 0; i < _ncs; ++i)
      47             :   {
      48         168 :     _cs_names[i] = coupledName("cs", i);
      49         168 :     if (coupled("cs", i) == _c_var)
      50          42 :       _l_cs = i;
      51             :   }
      52             : 
      53             :   // Check to make sure the nonlinear variable is in the cs list
      54          42 :   if (_l_cs < 0)
      55           0 :     paramError("cs", "One of the listed variables must be the 'c' variable");
      56             : 
      57             :   // Determine position of the selected concentration variable
      58         126 :   for (std::size_t i = 0; i < _neta; ++i)
      59          84 :     if (coupled("eta", i) == _etai_var)
      60          42 :       _l_etai = i;
      61             : 
      62             :   // Check to make sure the nonlinear variable or eta_i (if supplied) is in the eta list
      63          42 :   if (_l_etai < 0)
      64           0 :     paramError("eta_i",
      65             :                "Either eta_i or the kernel variable must be one of the listed 'eta' variables");
      66             : 
      67             :   // Iterate over all sublattice concentrations
      68         210 :   for (std::size_t i = 0; i < _ncs; ++i)
      69             :     // get second partial derivatives w.r.t. c and cs (only if c and cs are in the same phase)
      70         336 :     _prop_d2Fdcdcs[i] = (_phase[i] == _phase[_l_cs])
      71         252 :                             ? &getMaterialPropertyDerivative<Real>("F", _c_name, _cs_names[i])
      72             :                             : nullptr;
      73             : 
      74             :   // fetch all switching function derivatives
      75         126 :   for (std::size_t i = 0; i < _nh; ++i)
      76             :   {
      77          84 :     _prop_dhdni[i] = &getMaterialPropertyDerivativeByName<Real>(_h_names[i], _etai_name);
      78             : 
      79          84 :     _prop_d2hdnidn[i].resize(_neta);
      80         252 :     for (std::size_t j = 0; j < _neta; ++j)
      81         168 :       _prop_d2hdnidn[i][j] =
      82         336 :           &getMaterialPropertyDerivativeByName<Real>(_h_names[i], _etai_name, _eta_names[j]);
      83             :   }
      84          42 : }
      85             : 
      86             : Real
      87       84360 : SLKKSMultiACBulkC::precomputeQpResidual()
      88             : { // sum over phases
      89             :   std::size_t k = 0;
      90             :   Real sum = 0.0;
      91      253080 :   for (std::size_t i = 0; i < _nh; ++i)
      92             :   {
      93             :     // sum sublattice concentrations
      94             :     Real csum = 0.0;
      95      506160 :     for (unsigned int j = 0; j < _ns[i]; ++j)
      96             :     {
      97      337440 :       csum += (*_cs[k])[_qp] * _a_cs[k];
      98      337440 :       k++;
      99             :     }
     100      168720 :     sum += (*_prop_dhdni[i])[_qp] * csum;
     101             :   }
     102             : 
     103       84360 :   return -_mob[_qp] * _prop_dFdc[_qp] / _a_cs[_l_cs] * sum;
     104             : }
     105             : 
     106             : Real
     107      139680 : SLKKSMultiACBulkC::precomputeQpJacobian()
     108             : {
     109             :   // For when this kernel is used in the Lagrange multiplier equation
     110      139680 :   if (_lagrange)
     111             :     return 0.0;
     112             : 
     113             :   // For when eta_i is the nonlinear variable
     114             :   std::size_t k = 0;
     115             :   Real sum = 0.0;
     116      419040 :   for (std::size_t i = 0; i < _nh; ++i)
     117             :   {
     118             :     // sum sublattice concentrations
     119             :     Real csum = 0.0;
     120      838080 :     for (unsigned int j = 0; j < _ns[i]; ++j)
     121             :     {
     122      558720 :       csum += (*_cs[k])[_qp] * _a_cs[k];
     123      558720 :       k++;
     124             :     }
     125      279360 :     sum += (*_prop_d2hdnidn[i][_l_etai])[_qp] * csum;
     126             :   }
     127             : 
     128      139680 :   return -_mob[_qp] * _phi[_j][_qp] * _prop_dFdc[_qp] / _a_cs[_l_cs] * sum;
     129             : }
     130             : 
     131             : Real
     132     1396800 : SLKKSMultiACBulkC::computeQpOffDiagJacobian(unsigned int jvar)
     133             : {
     134             :   // concentration variables
     135     1396800 :   auto csvar = mapJvarToCvar(jvar, _cs_map);
     136     1396800 :   if (csvar >= 0)
     137             :   {
     138             :     // does F depend on the csvar? if so we need to apply the product rule
     139     1117440 :     if (_phase[csvar] == _phase[_l_cs])
     140             :     {
     141             :       // sum over phases
     142             :       std::size_t k = 0;
     143             :       Real sum = 0.0;
     144      838080 :       for (std::size_t i = 0; i < _nh; ++i)
     145             :       {
     146             :         // sum sublattice concentrations
     147             :         Real csum = 0.0;
     148     1676160 :         for (unsigned int j = 0; j < _ns[i]; ++j)
     149             :         {
     150     1117440 :           csum += (*_cs[k])[_qp] * _a_cs[k];
     151     1117440 :           k++;
     152             :         }
     153      558720 :         sum += (*_prop_dhdni[i])[_qp] * csum;
     154             :       }
     155             : 
     156      279360 :       return -_mob[_qp] *
     157      279360 :              ((*_prop_d2Fdcdcs[csvar])[_qp] * sum +
     158      279360 :               _prop_dFdc[_qp] * (*_prop_dhdni[_phase[csvar]])[_qp] * _a_cs[csvar]) /
     159      279360 :              _a_cs[_l_cs] * _phi[_j][_qp] * _test[_i][_qp];
     160             :     }
     161             : 
     162      838080 :     return -_mob[_qp] * _prop_dFdc[_qp] / _a_cs[_l_cs] * (*_prop_dhdni[_phase[csvar]])[_qp] *
     163      838080 :            _a_cs[csvar] * _phi[_j][_qp] * _test[_i][_qp];
     164             :   }
     165             : 
     166             :   // order parameters
     167      279360 :   auto etavar = mapJvarToCvar(jvar, _eta_map);
     168      279360 :   if (etavar >= 0)
     169             :   {
     170             :     // sum over phases
     171             :     std::size_t k = 0;
     172             :     Real sum = 0.0;
     173      838080 :     for (std::size_t i = 0; i < _nh; ++i)
     174             :     {
     175             :       // sum sublattice concentrations
     176             :       Real csum = 0.0;
     177     1676160 :       for (unsigned int j = 0; j < _ns[i]; ++j)
     178             :       {
     179     1117440 :         csum += (*_cs[k])[_qp] * _a_cs[k];
     180     1117440 :         k++;
     181             :       }
     182      558720 :       sum += (*_prop_d2hdnidn[i][etavar])[_qp] * csum;
     183             :     }
     184             : 
     185      279360 :     return -_mob[_qp] * _prop_dFdc[_qp] / _a_cs[_l_cs] * sum * _phi[_j][_qp] * _test[_i][_qp];
     186             :   }
     187             : 
     188             :   return 0.0;
     189             : }

Generated by: LCOV version 1.14