LCOV - code coverage report
Current view: top level - src/physics - MultiSpeciesDiffusionCG.C (source / functions) Hit Total Coverage
Test: idaholab/moose scalar_transport: #31405 (292dce) with base fef103 Lines: 125 134 93.3 %
Date: 2025-09-04 07:56:42 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 "MultiSpeciesDiffusionCG.h"
      11             : #include "MooseVariableBase.h"
      12             : 
      13             : // Register the actions for the objects actually used
      14             : registerMooseAction("ScalarTransportApp", MultiSpeciesDiffusionCG, "add_kernel");
      15             : registerMooseAction("ScalarTransportApp", MultiSpeciesDiffusionCG, "add_bc");
      16             : registerMooseAction("ScalarTransportApp", MultiSpeciesDiffusionCG, "add_variable");
      17             : registerMultiSpeciesDiffusionPhysicsBaseTasks("ScalarTransportApp", MultiSpeciesDiffusionCG);
      18             : 
      19             : InputParameters
      20         114 : MultiSpeciesDiffusionCG::validParams()
      21             : {
      22         114 :   InputParameters params = MultiSpeciesDiffusionPhysicsBase::validParams();
      23         114 :   params.addClassDescription("Discretizes diffusion equations for several species with the "
      24             :                              "continuous Galerkin finite element method");
      25         114 :   params.transferParam<MooseEnum>(MooseVariableBase::validParams(), "order", "variable_order");
      26             : 
      27         114 :   return params;
      28           0 : }
      29             : 
      30         114 : MultiSpeciesDiffusionCG::MultiSpeciesDiffusionCG(const InputParameters & parameters)
      31         114 :   : MultiSpeciesDiffusionPhysicsBase(parameters)
      32             : {
      33         114 : }
      34             : 
      35             : void
      36         114 : MultiSpeciesDiffusionCG::addFEKernels()
      37             : {
      38         456 :   for (const auto s : index_range(_species_names))
      39             :   {
      40         342 :     const auto & var_name = _species_names[s];
      41             :     // Diffusion term
      42         798 :     if (isParamValid("diffusivity_matprops") || isParamValid("diffusivity_functors"))
      43             :     {
      44             :       // Select the kernel type based on the user parameters
      45             :       std::string kernel_type;
      46         684 :       if (isParamValid("diffusivity_matprops"))
      47         285 :         kernel_type = _use_ad ? "ADMatDiffusion" : "MatDiffusion";
      48         114 :       else if (isParamValid("diffusivity_functors"))
      49             :       {
      50          57 :         const auto & d = getParam<std::vector<MooseFunctorName>>("diffusivity_functors")[s];
      51          57 :         if (getProblem().hasFunction(d))
      52             :           kernel_type = "FunctionDiffusion";
      53             :         else
      54           0 :           paramError(
      55             :               "diffusivity_functors", "No diffusion kernel implemented for the source type of", d);
      56             :       }
      57             : 
      58         342 :       InputParameters params = getFactory().getValidParams(kernel_type);
      59         684 :       params.set<NonlinearVariableName>("variable") = var_name;
      60         342 :       assignBlocks(params, _blocks);
      61             : 
      62             :       // Transfer the diffusivity parameter from the Physics to the kernel
      63         684 :       if (isParamValid("diffusivity_matprops"))
      64         570 :         params.set<MaterialPropertyName>("diffusivity") =
      65         570 :             getParam<std::vector<MaterialPropertyName>>("diffusivity_matprops")[s];
      66         114 :       else if (isParamValid("diffusivity_functors"))
      67         114 :         params.set<FunctionName>("function") =
      68         171 :             getParam<std::vector<MooseFunctorName>>("diffusivity_functors")[s];
      69             : 
      70         684 :       getProblem().addKernel(kernel_type, prefix() + var_name + "_diffusion", params);
      71         342 :     }
      72             : 
      73             :     // Source term
      74         684 :     if (isParamValid("source_functors"))
      75             :     {
      76             :       // Select the kernel type based on the user parameters
      77             :       std::string kernel_type;
      78         684 :       const auto & sources = getParam<std::vector<MooseFunctorName>>("source_functors");
      79             :       const auto & source = sources[s];
      80         342 :       if (MooseUtils::parsesToReal(source) || getProblem().hasFunction(source) ||
      81         418 :           getProblem().hasPostprocessorValueByName(source))
      82         323 :         kernel_type = _use_ad ? "ADBodyForce" : "BodyForce";
      83          19 :       else if (getProblem().hasVariable(source))
      84          19 :         kernel_type = _use_ad ? "ADCoupledForce" : "CoupledForce";
      85             :       else
      86           0 :         paramError("source_functors",
      87             :                    "No kernel defined for a source term in CG for the type of '",
      88             :                    source,
      89             :                    "'");
      90             : 
      91         342 :       InputParameters params = getFactory().getValidParams(kernel_type);
      92         684 :       params.set<NonlinearVariableName>("variable") = var_name;
      93         342 :       assignBlocks(params, _blocks);
      94             : 
      95             :       // Transfer the source and coefficient parameter from the Physics to the kernel
      96        1026 :       const auto coefs = getParam<std::vector<Real>>("source_coefs");
      97         342 :       const auto coef = coefs[s];
      98         342 :       if (MooseUtils::parsesToReal(source))
      99         285 :         params.set<Real>("value") = MooseUtils::convert<Real>(source) * coef;
     100          57 :       else if (getProblem().hasFunction(source))
     101             :       {
     102          19 :         params.set<Real>("value") = coef;
     103          38 :         params.set<FunctionName>("function") = source;
     104             :       }
     105         114 :       else if (getProblem().hasPostprocessorValueByName(source))
     106             :       {
     107          19 :         params.set<Real>("value") = coef;
     108          38 :         params.set<PostprocessorName>("postprocessor") = source;
     109             :       }
     110             :       else
     111             :       {
     112          19 :         params.set<Real>("coef") = coef;
     113          57 :         params.set<std::vector<VariableName>>("v") = {source};
     114             :       }
     115             : 
     116         684 :       getProblem().addKernel(kernel_type, prefix() + var_name + "_source", params);
     117         342 :     }
     118             : 
     119             :     // Time derivative term
     120         342 :     if (shouldCreateTimeDerivative(var_name, _blocks, false))
     121             :     {
     122         399 :       const std::string kernel_type = _use_ad ? "ADTimeDerivative" : "TimeDerivative";
     123         342 :       InputParameters params = getFactory().getValidParams(kernel_type);
     124         684 :       params.set<NonlinearVariableName>("variable") = var_name;
     125         342 :       assignBlocks(params, _blocks);
     126         684 :       getProblem().addKernel(kernel_type, prefix() + var_name + "_time", params);
     127         342 :     }
     128             :   }
     129         114 : }
     130             : 
     131             : void
     132         114 : MultiSpeciesDiffusionCG::addFEBCs()
     133             : {
     134         228 :   if (isParamSetByUser("neumann_boundaries"))
     135             :   {
     136             :     const auto & boundary_fluxes =
     137          57 :         getParam<std::vector<std::vector<MooseFunctorName>>>("boundary_fluxes");
     138             : 
     139         228 :     for (const auto s : index_range(_species_names))
     140             :     {
     141         171 :       const auto & var_name = _species_names[s];
     142             : 
     143         741 :       for (const auto i : index_range(_neumann_boundaries[s]))
     144             :       {
     145             :         const auto & bc_flux = boundary_fluxes[s][i];
     146             :         // Select the boundary type based on the user parameters and what we know to be most
     147             :         // efficient We could actually just use the very last option for everything but the
     148             :         // performance is better if one uses the specialized objects
     149         570 :         std::string bc_type = "";
     150         570 :         if (MooseUtils::parsesToReal(bc_flux))
     151         171 :           bc_type = _use_ad ? "ADNeumannBC" : "NeumannBC";
     152         399 :         else if (getProblem().hasVariable(bc_flux))
     153             :           bc_type = "CoupledVarNeumannBC"; // not AD, but still perfect Jacobian
     154         285 :         else if (getProblem().hasFunction(bc_flux))
     155         114 :           bc_type = _use_ad ? "ADFunctionNeumannBC" : "FunctionNeumannBC";
     156         513 :         else if (getProblem().hasPostprocessorValueByName(bc_flux))
     157             :           bc_type = "PostprocessorNeumannBC";
     158             :         else // this is AD, but we can mix AD and non-AD
     159             :           bc_type = "FunctorNeumannBC";
     160             : 
     161             :         // Get the parameters for the object type chosen and set the common parameters
     162         570 :         InputParameters params = getFactory().getValidParams(bc_type);
     163        1140 :         params.set<NonlinearVariableName>("variable") = var_name;
     164        1710 :         params.set<std::vector<BoundaryName>>("boundary") = {_neumann_boundaries[s][i]};
     165             : 
     166             :         // Set the flux parameter for the specific type of NeumannBC used
     167         570 :         if (MooseUtils::parsesToReal(bc_flux))
     168         171 :           params.set<Real>("value") = MooseUtils::convert<Real>(bc_flux);
     169         399 :         else if (getProblem().hasVariable(bc_flux))
     170         342 :           params.set<std::vector<VariableName>>("v") = {bc_flux};
     171         285 :         else if (getProblem().hasFunction(bc_flux))
     172         228 :           params.set<FunctionName>("function") = bc_flux;
     173         513 :         else if (getProblem().hasPostprocessorValueByName(bc_flux))
     174         342 :           params.set<PostprocessorName>("postprocessor") = bc_flux;
     175             :         else
     176           0 :           params.set<MooseFunctorName>("functor") = bc_flux;
     177             : 
     178        1140 :         getProblem().addBoundaryCondition(
     179        1140 :             bc_type, prefix() + var_name + "_neumann_bc_" + _neumann_boundaries[s][i], params);
     180         570 :       }
     181             :     }
     182             :   }
     183         228 :   if (isParamSetByUser("dirichlet_boundaries"))
     184             :   {
     185             :     const auto & boundary_values =
     186          57 :         getParam<std::vector<std::vector<MooseFunctorName>>>("boundary_values");
     187         228 :     for (const auto s : index_range(_species_names))
     188             :     {
     189         171 :       const auto & var_name = _species_names[s];
     190         627 :       for (const auto i : index_range(_dirichlet_boundaries[s]))
     191             :       {
     192             :         const auto & bc_value = boundary_values[s][i];
     193             :         // Select the boundary type based on the user parameters and what we know to be most
     194             :         // efficient
     195         456 :         std::string bc_type = "";
     196         456 :         if (MooseUtils::parsesToReal(bc_value))
     197         171 :           bc_type = _use_ad ? "ADDirichletBC" : "DirichletBC";
     198         285 :         else if (getProblem().hasVariable(bc_value))
     199          57 :           bc_type = _use_ad ? "ADMatchedValueBC" : "MatchedValueBC";
     200         228 :         else if (getProblem().hasFunction(bc_value))
     201          57 :           bc_type = _use_ad ? "ADFunctionDirichletBC" : "FunctionDirichletBC";
     202         513 :         else if (getProblem().hasPostprocessorValueByName(bc_value))
     203             :           bc_type = "PostprocessorDirichletBC";
     204             :         else // this is AD, but we can mix AD and non-AD
     205             :           bc_type = "FunctorDirichletBC";
     206             : 
     207         456 :         InputParameters params = getFactory().getValidParams(bc_type);
     208         912 :         params.set<NonlinearVariableName>("variable") = var_name;
     209        1368 :         params.set<std::vector<BoundaryName>>("boundary") = {_dirichlet_boundaries[s][i]};
     210             : 
     211             :         // Set the flux parameter for the specific type of DirichletBC used
     212         456 :         if (MooseUtils::parsesToReal(bc_value))
     213         171 :           params.set<Real>("value") = MooseUtils::convert<Real>(bc_value);
     214         285 :         else if (getProblem().hasVariable(bc_value))
     215         171 :           params.set<std::vector<VariableName>>("v") = {bc_value};
     216         228 :         else if (getProblem().hasFunction(bc_value))
     217         114 :           params.set<FunctionName>("function") = bc_value;
     218         513 :         else if (getProblem().hasPostprocessorValueByName(bc_value))
     219         342 :           params.set<PostprocessorName>("postprocessor") = bc_value;
     220             :         else
     221           0 :           params.set<MooseFunctorName>("functor") = bc_value;
     222             : 
     223         912 :         getProblem().addBoundaryCondition(
     224         912 :             bc_type, prefix() + var_name + "_dirichlet_bc_" + _dirichlet_boundaries[s][i], params);
     225         456 :       }
     226             :     }
     227             :   }
     228         114 : }
     229             : 
     230             : void
     231         114 : MultiSpeciesDiffusionCG::addSolverVariables()
     232             : {
     233         456 :   for (const auto & var_name : _species_names)
     234             :   {
     235             :     // If the variable was added outside the Physics
     236         342 :     if (variableExists(var_name, /*error_if_aux*/ true))
     237             :     {
     238           0 :       if (isParamValid("variable_order"))
     239           0 :         paramError("variable_order",
     240           0 :                    "Cannot specify the variable order if variable " + var_name +
     241             :                        " is defined outside the Physics block");
     242             :       else
     243           0 :         return;
     244             :     }
     245             : 
     246         342 :     const std::string variable_type = "MooseVariable";
     247         342 :     InputParameters params = getFactory().getValidParams(variable_type);
     248        1026 :     params.set<MooseEnum>("order") = getParam<MooseEnum>("variable_order");
     249         342 :     assignBlocks(params, _blocks);
     250         342 :     params.set<SolverSystemName>("solver_sys") = getSolverSystem(var_name);
     251             : 
     252         342 :     getProblem().addVariable(variable_type, var_name, params);
     253         342 :   }
     254             : }

Generated by: LCOV version 1.14