LCOV - code coverage report
Current view: top level - src/actions - ConservedAction.C (source / functions) Hit Total Coverage
Test: idaholab/moose phase_field: #32971 (54bef8) with base c6cf66 Lines: 150 153 98.0 %
Date: 2026-05-29 20:38:39 Functions: 3 3 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 "ConservedAction.h"
      11             : // MOOSE includes
      12             : #include "Conversion.h"
      13             : #include "FEProblem.h"
      14             : #include "Factory.h"
      15             : #include "MooseObjectAction.h"
      16             : #include "MooseMesh.h"
      17             : #include "AddVariableAction.h"
      18             : 
      19             : #include "libmesh/string_to_enum.h"
      20             : 
      21             : using namespace libMesh;
      22             : 
      23             : registerMooseAction("PhaseFieldApp", ConservedAction, "add_variable");
      24             : 
      25             : registerMooseAction("PhaseFieldApp", ConservedAction, "add_kernel");
      26             : 
      27             : InputParameters
      28          81 : ConservedAction::validParams()
      29             : {
      30          81 :   InputParameters params = Action::validParams();
      31          81 :   params.addClassDescription(
      32             :       "Set up the variable(s) and the kernels needed for a conserved phase field variable."
      33             :       " Note that for a direct solve, the element family and order are overwritten with hermite "
      34             :       "and third.");
      35         162 :   MooseEnum solves("DIRECT REVERSE_SPLIT FORWARD_SPLIT");
      36         162 :   params.addRequiredParam<MooseEnum>("solve_type", solves, "Split or direct solve?");
      37             :   // Get MooseEnums for the possible order/family options for this variable
      38          81 :   MooseEnum families(AddVariableAction::getNonlinearVariableFamilies());
      39          81 :   MooseEnum orders(AddVariableAction::getNonlinearVariableOrders());
      40         162 :   params.addParam<MooseEnum>("family",
      41             :                              families,
      42             :                              "Specifies the family of FE "
      43             :                              "shape functions to use for this variable");
      44         162 :   params.addParam<MooseEnum>("order",
      45             :                              orders,
      46             :                              "Specifies the order of the FE "
      47             :                              "shape function to use for this variable");
      48         162 :   params.addParam<Real>("scaling", 1.0, "Specifies a scaling factor to apply to this variable");
      49         162 :   params.addParam<bool>("implicit", true, "Whether kernels are implicit or not");
      50         162 :   params.addParam<bool>(
      51         162 :       "use_displaced_mesh", false, "Whether to use displaced mesh in the kernels");
      52         162 :   params.addParamNamesToGroup("scaling implicit use_displaced_mesh", "Advanced");
      53         162 :   params.addRequiredParam<MaterialPropertyName>("mobility", "The mobility used with the kernel");
      54         162 :   params.addCoupledVar("coupled_variables",
      55             :                        "Vector of nonlinear variable arguments this kernel depends on");
      56             : 
      57         162 :   params.addRequiredParam<MaterialPropertyName>(
      58             :       "free_energy", "Base name of the free energy function F defined in a free energy material");
      59         162 :   params.addRequiredParam<MaterialPropertyName>("kappa", "The kappa used with the kernel");
      60         162 :   params.addParam<std::vector<SubdomainName>>(
      61             :       "block", {}, "Block restriction for the variables and kernels");
      62          81 :   return params;
      63          81 : }
      64             : 
      65          81 : ConservedAction::ConservedAction(const InputParameters & params)
      66             :   : Action(params),
      67         162 :     _solve_type(getParam<MooseEnum>("solve_type").getEnum<SolveType>()),
      68             :     _var_name(name()),
      69         243 :     _scaling(getParam<Real>("scaling"))
      70             : {
      71          81 :   switch (_solve_type)
      72             :   {
      73          28 :     case SolveType::DIRECT:
      74          28 :       _fe_type = FEType(Utility::string_to_enum<Order>("THIRD"),
      75             :                         Utility::string_to_enum<FEFamily>("HERMITE"));
      76          56 :       if (!parameters().isParamSetByAddParam("order") &&
      77          28 :           !parameters().isParamSetByAddParam("family"))
      78           0 :         mooseWarning("Order and family autoset to third and hermite in ConservedAction");
      79             :       break;
      80          53 :     case SolveType::REVERSE_SPLIT:
      81             :     case SolveType::FORWARD_SPLIT:
      82         159 :       _fe_type = FEType(Utility::string_to_enum<Order>(getParam<MooseEnum>("order")),
      83          53 :                         Utility::string_to_enum<FEFamily>(getParam<MooseEnum>("family")));
      84             :       // Set name of chemical potential variable
      85          53 :       _chempot_name = "chem_pot_" + _var_name;
      86          53 :       break;
      87           0 :     default:
      88           0 :       paramError("solve_type", "Incorrect solve_type in ConservedAction");
      89             :   }
      90          81 : }
      91             : 
      92             : void
      93         162 : ConservedAction::act()
      94             : {
      95             :   //
      96             :   // Add variable(s)
      97             :   //
      98         162 :   if (_current_task == "add_variable")
      99             :   {
     100          81 :     auto type = AddVariableAction::variableType(_fe_type);
     101          81 :     auto var_params = _factory.getValidParams(type);
     102         162 :     var_params.set<MooseEnum>("family") = Moose::stringify(_fe_type.family);
     103          81 :     var_params.set<MooseEnum>("order") = _fe_type.order.get_order();
     104          81 :     var_params.set<std::vector<Real>>("scaling") = {_scaling};
     105          81 :     var_params.applySpecificParameters(parameters(), {"block"});
     106             : 
     107             :     // Create conserved variable _var_name
     108          81 :     _problem->addVariable(type, _var_name, var_params);
     109             : 
     110             :     // Create chemical potential variable for split form
     111          81 :     switch (_solve_type)
     112             :     {
     113             :       case SolveType::DIRECT:
     114             :         break;
     115          53 :       case SolveType::REVERSE_SPLIT:
     116             :       case SolveType::FORWARD_SPLIT:
     117          53 :         _problem->addVariable(type, _chempot_name, var_params);
     118             :     }
     119          81 :   }
     120             : 
     121             :   //
     122             :   // Add Kernels
     123             :   //
     124          81 :   else if (_current_task == "add_kernel")
     125             :   {
     126          81 :     switch (_solve_type)
     127             :     {
     128             :       case SolveType::DIRECT:
     129             :         // Add time derivative kernel
     130             :         {
     131          28 :           std::string kernel_type = "TimeDerivative";
     132             : 
     133          28 :           std::string kernel_name = _var_name + "_" + kernel_type;
     134          28 :           InputParameters params = _factory.getValidParams(kernel_type);
     135          56 :           params.set<NonlinearVariableName>("variable") = _var_name;
     136          28 :           params.applyParameters(parameters());
     137             : 
     138          28 :           _problem->addKernel(kernel_type, kernel_name, params);
     139          28 :         }
     140             : 
     141             :         // Add CahnHilliard kernel
     142             :         {
     143          28 :           std::string kernel_type = "CahnHilliard";
     144             : 
     145          28 :           std::string kernel_name = _var_name + "_" + kernel_type;
     146          28 :           InputParameters params = _factory.getValidParams(kernel_type);
     147          28 :           params.set<NonlinearVariableName>("variable") = _var_name;
     148          84 :           params.set<MaterialPropertyName>("mob_name") = getParam<MaterialPropertyName>("mobility");
     149          56 :           params.set<MaterialPropertyName>("f_name") =
     150          56 :               getParam<MaterialPropertyName>("free_energy");
     151          28 :           params.applyParameters(parameters());
     152             : 
     153          28 :           _problem->addKernel(kernel_type, kernel_name, params);
     154          28 :         }
     155             : 
     156             :         // Add ACInterface kernel
     157             :         {
     158          28 :           std::string kernel_type = "CHInterface";
     159             : 
     160          28 :           std::string kernel_name = _var_name + "_" + kernel_type;
     161          28 :           InputParameters params = _factory.getValidParams(kernel_type);
     162          28 :           params.set<NonlinearVariableName>("variable") = _var_name;
     163          84 :           params.set<MaterialPropertyName>("mob_name") = getParam<MaterialPropertyName>("mobility");
     164          84 :           params.set<MaterialPropertyName>("kappa_name") = getParam<MaterialPropertyName>("kappa");
     165          28 :           params.applyParameters(parameters());
     166             : 
     167          28 :           _problem->addKernel(kernel_type, kernel_name, params);
     168          28 :         }
     169          28 :         break;
     170             : 
     171             :       case SolveType::REVERSE_SPLIT:
     172             :         // Add time derivative kernel
     173             :         {
     174          46 :           std::string kernel_type = "CoupledTimeDerivative";
     175             : 
     176          46 :           std::string kernel_name = _var_name + "_" + kernel_type;
     177          46 :           InputParameters params = _factory.getValidParams(kernel_type);
     178          92 :           params.set<NonlinearVariableName>("variable") = _chempot_name;
     179         138 :           params.set<std::vector<VariableName>>("v") = {_var_name};
     180          46 :           params.applyParameters(parameters());
     181             : 
     182          46 :           _problem->addKernel(kernel_type, kernel_name, params);
     183          46 :         }
     184             : 
     185             :         // Add SplitCHWRes kernel
     186             :         {
     187          46 :           std::string kernel_type = "SplitCHWRes";
     188             : 
     189          46 :           std::string kernel_name = _var_name + "_" + kernel_type;
     190          46 :           InputParameters params = _factory.getValidParams(kernel_type);
     191          92 :           params.set<NonlinearVariableName>("variable") = _chempot_name;
     192         138 :           params.set<MaterialPropertyName>("mob_name") = getParam<MaterialPropertyName>("mobility");
     193          46 :           params.applyParameters(parameters());
     194             : 
     195          46 :           _problem->addKernel(kernel_type, kernel_name, params);
     196          46 :         }
     197             : 
     198             :         // Add SplitCHParsed kernel
     199             :         {
     200          46 :           std::string kernel_type = "SplitCHParsed";
     201             : 
     202          46 :           std::string kernel_name = _var_name + "_" + kernel_type;
     203          46 :           InputParameters params = _factory.getValidParams(kernel_type);
     204          92 :           params.set<NonlinearVariableName>("variable") = _var_name;
     205         138 :           params.set<std::vector<VariableName>>("w") = {_chempot_name};
     206          92 :           params.set<MaterialPropertyName>("f_name") =
     207          46 :               getParam<MaterialPropertyName>("free_energy");
     208         138 :           params.set<MaterialPropertyName>("kappa_name") = getParam<MaterialPropertyName>("kappa");
     209          46 :           params.applyParameters(parameters());
     210             : 
     211          46 :           _problem->addKernel(kernel_type, kernel_name, params);
     212          46 :         }
     213          46 :         break;
     214             : 
     215             :       case SolveType::FORWARD_SPLIT:
     216             :         // Add time derivative kernel
     217             :         {
     218           7 :           std::string kernel_type = "TimeDerivative";
     219             : 
     220           7 :           std::string kernel_name = _var_name + "_" + kernel_type;
     221           7 :           InputParameters params = _factory.getValidParams(kernel_type);
     222          14 :           params.set<NonlinearVariableName>("variable") = _var_name;
     223           7 :           params.applyParameters(parameters());
     224             : 
     225           7 :           _problem->addKernel(kernel_type, kernel_name, params);
     226           7 :         }
     227             : 
     228             :         // Add MatDiffusion kernel for c residual
     229             :         {
     230           7 :           std::string kernel_type = "MatDiffusion";
     231             : 
     232           7 :           std::string kernel_name = _var_name + "_" + kernel_type;
     233           7 :           InputParameters params = _factory.getValidParams(kernel_type);
     234           7 :           params.set<NonlinearVariableName>("variable") = _var_name;
     235          21 :           params.set<std::vector<VariableName>>("v") = {_chempot_name};
     236          14 :           params.set<MaterialPropertyName>("diffusivity") =
     237          14 :               getParam<MaterialPropertyName>("mobility");
     238           7 :           params.applyParameters(parameters());
     239             : 
     240           7 :           _problem->addKernel(kernel_type, kernel_name, params);
     241           7 :         }
     242             :         // Add MatDiffusion kernel for chemical potential residual
     243             :         {
     244           7 :           std::string kernel_type = "MatDiffusion";
     245             : 
     246           7 :           std::string kernel_name = _chempot_name + "_" + kernel_type;
     247           7 :           InputParameters params = _factory.getValidParams(kernel_type);
     248          14 :           params.set<NonlinearVariableName>("variable") = _chempot_name;
     249          21 :           params.set<std::vector<VariableName>>("v") = {_var_name};
     250          21 :           params.set<MaterialPropertyName>("diffusivity") = getParam<MaterialPropertyName>("kappa");
     251           7 :           params.applyParameters(parameters());
     252             : 
     253           7 :           _problem->addKernel(kernel_type, kernel_name, params);
     254           7 :         }
     255             : 
     256             :         // Add CoupledMaterialDerivative kernel
     257             :         {
     258           7 :           std::string kernel_type = "CoupledMaterialDerivative";
     259             : 
     260           7 :           std::string kernel_name = _chempot_name + "_" + kernel_type;
     261           7 :           InputParameters params = _factory.getValidParams(kernel_type);
     262          14 :           params.set<NonlinearVariableName>("variable") = _chempot_name;
     263          21 :           params.set<std::vector<VariableName>>("v") = {_var_name};
     264          14 :           params.set<MaterialPropertyName>("f_name") =
     265          14 :               getParam<MaterialPropertyName>("free_energy");
     266           7 :           params.applyParameters(parameters());
     267             : 
     268           7 :           _problem->addKernel(kernel_type, kernel_name, params);
     269           7 :         }
     270             : 
     271             :         // Add CoefReaction kernel
     272             :         {
     273           7 :           std::string kernel_type = "CoefReaction";
     274             : 
     275           7 :           std::string kernel_name = _chempot_name + "_" + kernel_type;
     276           7 :           InputParameters params = _factory.getValidParams(kernel_type);
     277          14 :           params.set<NonlinearVariableName>("variable") = _chempot_name;
     278           7 :           params.set<Real>("coefficient") = -1.0;
     279           7 :           params.applyParameters(parameters());
     280             : 
     281           7 :           _problem->addKernel(kernel_type, kernel_name, params);
     282           7 :         }
     283             :     }
     284             :   }
     285         162 : }

Generated by: LCOV version 1.14