LCOV - code coverage report
Current view: top level - src/physics - DiffusionPhysicsBase.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 86 95 90.5 %
Date: 2025-07-17 01:28:37 Functions: 6 7 85.7 %
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 "DiffusionPhysicsBase.h"
      11             : #include "PetscSupport.h"
      12             : #include "MooseEnumItem.h"
      13             : 
      14             : InputParameters
      15         676 : DiffusionPhysicsBase::validParams()
      16             : {
      17         676 :   InputParameters params = PhysicsBase::validParams();
      18         676 :   params += PhysicsComponentInterface::validParams();
      19         676 :   params.addClassDescription("Base class for creating a diffusion equation");
      20             : 
      21             :   // Variable parameters
      22         676 :   params.addParam<VariableName>("variable_name", "u", "Variable name for the equation");
      23         676 :   params.addParam<FunctionName>("initial_condition", "Initial condition for the diffused variable");
      24             : 
      25             :   // Diffusivity
      26         676 :   params.addParam<MaterialPropertyName>("diffusivity_matprop",
      27             :                                         "Material property defining the diffusion coefficient");
      28         676 :   params.addParam<MooseFunctorName>("diffusivity_functor", "Functor specifying the diffusivity");
      29             : 
      30             :   // Source term
      31         676 :   params.addParam<MooseFunctorName>("source_functor", "Source term in the diffusion problem");
      32         676 :   params.addParam<Real>("source_coef", 1, "Coefficient multiplying the source");
      33             : 
      34             :   // Boundary conditions
      35         676 :   params.addParam<std::vector<BoundaryName>>(
      36             :       "neumann_boundaries", {}, "Boundaries on which to apply a diffusive flux");
      37         676 :   params.addParam<std::vector<BoundaryName>>(
      38             :       "dirichlet_boundaries", {}, "Boundaries on which to apply a fixed value");
      39         676 :   params.addParam<std::vector<MooseFunctorName>>(
      40             :       "boundary_fluxes", {}, "Functors to compute the diffusive flux on each Neumann boundary'");
      41         676 :   params.addParam<std::vector<MooseFunctorName>>(
      42             :       "boundary_values", {}, "Functors to compute the diffusive flux on each Dirichlet boundary'");
      43         676 :   params.addParamNamesToGroup("neumann_boundaries dirichlet_boundaries boundary_fluxes "
      44             :                               "boundary_values",
      45             :                               "Boundary conditions");
      46             : 
      47             :   // Postprocessing
      48         676 :   params.addParam<std::vector<BoundaryName>>(
      49             :       "compute_diffusive_fluxes_on", {}, "Surfaces to compute the diffusive flux on");
      50             : 
      51             :   // Preconditioning is implemented so let's use it by default
      52         676 :   MooseEnum pc_options("default none", "default");
      53         676 :   params.addParam<MooseEnum>(
      54             :       "preconditioning", pc_options, "Which preconditioning to use for this Physics");
      55             : 
      56        1352 :   return params;
      57         676 : }
      58             : 
      59         270 : DiffusionPhysicsBase::DiffusionPhysicsBase(const InputParameters & parameters)
      60             :   : PhysicsBase(parameters),
      61             :     PhysicsComponentInterface(parameters),
      62         270 :     _var_name(getParam<VariableName>("variable_name")),
      63         270 :     _neumann_boundaries(getParam<std::vector<BoundaryName>>("neumann_boundaries")),
      64         540 :     _dirichlet_boundaries(getParam<std::vector<BoundaryName>>("dirichlet_boundaries"))
      65             : {
      66             :   // Keep track of variables
      67         270 :   saveSolverVariableName(_var_name);
      68             : 
      69             :   // Parameter checking
      70         270 :   checkVectorParamsSameLength<BoundaryName, MooseFunctorName>("neumann_boundaries",
      71             :                                                               "boundary_fluxes");
      72         270 :   checkVectorParamsSameLength<BoundaryName, MooseFunctorName>("dirichlet_boundaries",
      73             :                                                               "boundary_values");
      74         810 :   checkVectorParamsNoOverlap<BoundaryName>({"neumann_boundaries", "dirichlet_boundaries"});
      75         270 :   if (isParamSetByUser("source_coef"))
      76         128 :     checkParamsBothSetOrNotSet("source_functor", "source_coef");
      77             : 
      78         270 :   addRequiredPhysicsTask("add_preconditioning");
      79         270 :   addRequiredPhysicsTask("add_postprocessor");
      80         810 : }
      81             : 
      82             : void
      83         222 : DiffusionPhysicsBase::addPreconditioning()
      84             : {
      85             :   // Use a multigrid method, known to work for elliptic problems such as diffusion
      86         222 :   if (_preconditioning == "default")
      87             :   {
      88             :     // We only pass petsc options as that's all that's needed to set up the preconditioner
      89             :     const auto option_pair1 =
      90         222 :         std::make_pair<MooseEnumItem, std::string>(MooseEnumItem("-pc_type"), "hypre");
      91             :     const auto option_pair2 =
      92         222 :         std::make_pair<MooseEnumItem, std::string>(MooseEnumItem("-pc_hypre_type"), "boomeramg");
      93         666 :     addPetscPairsToPetscOptions({option_pair1, option_pair2});
      94         222 :   }
      95         444 : }
      96             : 
      97             : void
      98         222 : DiffusionPhysicsBase::addPostprocessors()
      99             : {
     100         222 :   for (const auto & boundary_name :
     101         456 :        getParam<std::vector<BoundaryName>>("compute_diffusive_fluxes_on"))
     102             :   {
     103             :     // Create the boundary integration of the flux
     104          24 :     const bool use_ad = isParamValid("use_automatic_differentiation")
     105          24 :                             ? getParam<bool>("use_automatic_differentiation")
     106          12 :                             : false;
     107             :     const std::string pp_type =
     108          12 :         use_ad ? "ADSideDiffusiveFluxIntegral" : "SideDiffusiveFluxIntegral";
     109          12 :     auto params = _factory.getValidParams(pp_type);
     110          24 :     params.set<std::vector<VariableName>>("variable") = {_var_name};
     111          12 :     if (isParamValid("diffusivity_matprop"))
     112          24 :       params.set<MaterialPropertyName>("diffusivity") =
     113          36 :           getParam<MaterialPropertyName>("diffusivity_matprop");
     114           0 :     else if (isParamValid("diffusivity_functor"))
     115           0 :       params.set<MooseFunctorName>("functor_diffusivity") =
     116           0 :           getParam<MooseFunctorName>("diffusivity_functor");
     117             :     else
     118           0 :       params.set<MooseFunctorName>("functor_diffusivity") = "1";
     119          24 :     params.set<std::vector<BoundaryName>>("boundary") = {boundary_name};
     120             :     // Default to maximum computation
     121          24 :     params.set<ExecFlagEnum>("execute_on") = {
     122          72 :         EXEC_INITIAL, EXEC_TIMESTEP_END, EXEC_NONLINEAR, EXEC_LINEAR};
     123          12 :     getProblem().addPostprocessor(pp_type, prefix() + "diffusive_flux_" + boundary_name, params);
     124          12 :   }
     125         258 : }
     126             : 
     127             : void
     128         226 : DiffusionPhysicsBase::addInitialConditions()
     129             : {
     130         226 :   InputParameters params = getFactory().getValidParams("FunctionIC");
     131             : 
     132             :   // Get the list of blocks that have ics from components
     133         226 :   std::vector<SubdomainName> component_ic_blocks;
     134         318 :   for (const auto & [component_name, component_bc_map] : _components_initial_conditions)
     135             :   {
     136          92 :     if (!component_bc_map.count(_var_name))
     137           0 :       continue;
     138          92 :     const auto & comp_blocks = getActionComponent(component_name).blocks();
     139          92 :     component_ic_blocks.insert(component_ic_blocks.end(), comp_blocks.begin(), comp_blocks.end());
     140             :   }
     141             : 
     142             :   // Keep only blocks that have no component IC
     143         226 :   std::vector<SubdomainName> remaining_blocks;
     144         584 :   for (const auto & block : _blocks)
     145         358 :     if (std::find(component_ic_blocks.begin(), component_ic_blocks.end(), block) ==
     146         716 :         component_ic_blocks.end())
     147         234 :       remaining_blocks.push_back(block);
     148             : 
     149             :   // No need to add BCs on the Physics block restriction if Components are covering all of it
     150         226 :   if (remaining_blocks.empty())
     151          32 :     return;
     152         194 :   assignBlocks(params, remaining_blocks);
     153             : 
     154             :   // first obey any component-specific initial condition
     155             :   // then obey the user specification of initial conditions
     156             :   // NOTE: we may conflict with ICs in the input
     157             :   // there are no default initial conditions
     158             :   mooseAssert(parameters().isParamSetByUser("initial_condition") ||
     159             :                   !parameters().hasDefault("initial_condition"),
     160             :               "Should not have a default");
     161         194 :   if (isParamValid("initial_condition") &&
     162           4 :       shouldCreateIC(
     163             :           _var_name, remaining_blocks, /*ic is a default*/ false, /*error if defined*/ true))
     164             :   {
     165           0 :     params.set<VariableName>("variable") = _var_name;
     166           0 :     params.set<FunctionName>("function") = getParam<FunctionName>("initial_condition");
     167             : 
     168           0 :     getProblem().addInitialCondition("FunctionIC", prefix() + _var_name + "_ic", params);
     169             :   }
     170         286 : }
     171             : 
     172             : void
     173         226 : DiffusionPhysicsBase::addInitialConditionsFromComponents()
     174             : {
     175         226 :   InputParameters params = getFactory().getValidParams("FunctorIC");
     176             : 
     177             :   // ICs from components are considered always set by the user, so we do not skip them when
     178             :   // restarting
     179         318 :   for (const auto & [component_name, component_bc_map] : _components_initial_conditions)
     180             :   {
     181          92 :     if (!component_bc_map.count(_var_name))
     182           0 :       continue;
     183          92 :     assignBlocks(params, getActionComponent(component_name).blocks());
     184          92 :     params.set<VariableName>("variable") = _var_name;
     185          92 :     params.set<MooseFunctorName>("functor") = libmesh_map_find(component_bc_map, _var_name);
     186             : 
     187         184 :     getProblem().addInitialCondition(
     188         184 :         "FunctorIC", prefix() + _var_name + "_ic_" + component_name, params);
     189             :   }
     190         226 : }

Generated by: LCOV version 1.14