LCOV - code coverage report
Current view: top level - src/physics - DiffusionPhysicsBase.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 419b9d Lines: 86 95 90.5 %
Date: 2025-08-08 20:01:16 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         692 : DiffusionPhysicsBase::validParams()
      16             : {
      17         692 :   InputParameters params = PhysicsBase::validParams();
      18         692 :   params += PhysicsComponentInterface::validParams();
      19         692 :   params.addClassDescription("Base class for creating a diffusion equation");
      20             : 
      21             :   // Variable parameters
      22         692 :   params.addParam<VariableName>("variable_name", "u", "Variable name for the equation");
      23         692 :   params.addParam<FunctionName>("initial_condition", "Initial condition for the diffused variable");
      24             : 
      25             :   // Diffusivity
      26         692 :   params.addParam<MaterialPropertyName>("diffusivity_matprop",
      27             :                                         "Material property defining the diffusion coefficient");
      28         692 :   params.addParam<MooseFunctorName>("diffusivity_functor", "Functor specifying the diffusivity");
      29             : 
      30             :   // Source term
      31         692 :   params.addParam<MooseFunctorName>("source_functor", "Source term in the diffusion problem");
      32         692 :   params.addParam<Real>("source_coef", 1, "Coefficient multiplying the source");
      33             : 
      34             :   // Boundary conditions
      35         692 :   params.addParam<std::vector<BoundaryName>>(
      36             :       "neumann_boundaries", {}, "Boundaries on which to apply a diffusive flux");
      37         692 :   params.addParam<std::vector<BoundaryName>>(
      38             :       "dirichlet_boundaries", {}, "Boundaries on which to apply a fixed value");
      39         692 :   params.addParam<std::vector<MooseFunctorName>>(
      40             :       "boundary_fluxes", {}, "Functors to compute the diffusive flux on each Neumann boundary'");
      41         692 :   params.addParam<std::vector<MooseFunctorName>>(
      42             :       "boundary_values", {}, "Functors to compute the diffusive flux on each Dirichlet boundary'");
      43         692 :   params.addParamNamesToGroup("neumann_boundaries dirichlet_boundaries boundary_fluxes "
      44             :                               "boundary_values",
      45             :                               "Boundary conditions");
      46             : 
      47             :   // Postprocessing
      48         692 :   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         692 :   MooseEnum pc_options("default defer", "default");
      53         692 :   params.addParam<MooseEnum>(
      54             :       "preconditioning", pc_options, "Which preconditioning to use for this Physics");
      55             : 
      56        1384 :   return params;
      57         692 : }
      58             : 
      59         286 : DiffusionPhysicsBase::DiffusionPhysicsBase(const InputParameters & parameters)
      60             :   : PhysicsBase(parameters),
      61             :     PhysicsComponentInterface(parameters),
      62         286 :     _var_name(getParam<VariableName>("variable_name")),
      63         286 :     _neumann_boundaries(getParam<std::vector<BoundaryName>>("neumann_boundaries")),
      64         572 :     _dirichlet_boundaries(getParam<std::vector<BoundaryName>>("dirichlet_boundaries"))
      65             : {
      66             :   // Keep track of variables
      67         286 :   saveSolverVariableName(_var_name);
      68             : 
      69             :   // Parameter checking
      70         286 :   checkVectorParamsSameLength<BoundaryName, MooseFunctorName>("neumann_boundaries",
      71             :                                                               "boundary_fluxes");
      72         286 :   checkVectorParamsSameLength<BoundaryName, MooseFunctorName>("dirichlet_boundaries",
      73             :                                                               "boundary_values");
      74         858 :   checkVectorParamsNoOverlap<BoundaryName>({"neumann_boundaries", "dirichlet_boundaries"});
      75         286 :   if (isParamSetByUser("source_coef"))
      76         136 :     checkParamsBothSetOrNotSet("source_functor", "source_coef");
      77             : 
      78         286 :   addRequiredPhysicsTask("add_preconditioning");
      79         286 :   addRequiredPhysicsTask("add_postprocessor");
      80         858 : }
      81             : 
      82             : void
      83         238 : DiffusionPhysicsBase::addPreconditioning()
      84             : {
      85             :   // Use a multigrid method, known to work for elliptic problems such as diffusion
      86         238 :   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         238 :         std::make_pair<MooseEnumItem, std::string>(MooseEnumItem("-pc_type"), "hypre");
      91             :     const auto option_pair2 =
      92         238 :         std::make_pair<MooseEnumItem, std::string>(MooseEnumItem("-pc_hypre_type"), "boomeramg");
      93         714 :     addPetscPairsToPetscOptions({option_pair1, option_pair2});
      94         238 :   }
      95         476 : }
      96             : 
      97             : void
      98         238 : DiffusionPhysicsBase::addPostprocessors()
      99             : {
     100         238 :   for (const auto & boundary_name :
     101         489 :        getParam<std::vector<BoundaryName>>("compute_diffusive_fluxes_on"))
     102             :   {
     103             :     // Create the boundary integration of the flux
     104          26 :     const bool use_ad = isParamValid("use_automatic_differentiation")
     105          26 :                             ? getParam<bool>("use_automatic_differentiation")
     106          13 :                             : false;
     107             :     const std::string pp_type =
     108          13 :         use_ad ? "ADSideDiffusiveFluxIntegral" : "SideDiffusiveFluxIntegral";
     109          13 :     auto params = _factory.getValidParams(pp_type);
     110          26 :     params.set<std::vector<VariableName>>("variable") = {_var_name};
     111          13 :     if (isParamValid("diffusivity_matprop"))
     112          26 :       params.set<MaterialPropertyName>("diffusivity") =
     113          39 :           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          26 :     params.set<std::vector<BoundaryName>>("boundary") = {boundary_name};
     120             :     // Default to maximum computation
     121          26 :     params.set<ExecFlagEnum>("execute_on") = {
     122          78 :         EXEC_INITIAL, EXEC_TIMESTEP_END, EXEC_NONLINEAR, EXEC_LINEAR};
     123          13 :     getProblem().addPostprocessor(pp_type, prefix() + "diffusive_flux_" + boundary_name, params);
     124          13 :   }
     125         277 : }
     126             : 
     127             : void
     128         242 : DiffusionPhysicsBase::addInitialConditions()
     129             : {
     130         242 :   InputParameters params = getFactory().getValidParams("FunctionIC");
     131             : 
     132             :   // Get the list of blocks that have ics from components
     133         242 :   std::vector<SubdomainName> component_ic_blocks;
     134         340 :   for (const auto & [component_name, component_bc_map] : _components_initial_conditions)
     135             :   {
     136          98 :     if (!component_bc_map.count(_var_name))
     137           0 :       continue;
     138          98 :     const auto & comp_blocks = getActionComponent(component_name).blocks();
     139          98 :     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         242 :   std::vector<SubdomainName> remaining_blocks;
     144         625 :   for (const auto & block : _blocks)
     145         383 :     if (std::find(component_ic_blocks.begin(), component_ic_blocks.end(), block) ==
     146         766 :         component_ic_blocks.end())
     147         251 :       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         242 :   if (remaining_blocks.empty())
     151          34 :     return;
     152         208 :   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         208 :   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         306 : }
     171             : 
     172             : void
     173         242 : DiffusionPhysicsBase::addInitialConditionsFromComponents()
     174             : {
     175         242 :   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         340 :   for (const auto & [component_name, component_bc_map] : _components_initial_conditions)
     180             :   {
     181          98 :     if (!component_bc_map.count(_var_name))
     182           0 :       continue;
     183          98 :     assignBlocks(params, getActionComponent(component_name).blocks());
     184          98 :     params.set<VariableName>("variable") = _var_name;
     185          98 :     params.set<MooseFunctorName>("functor") = libmesh_map_find(component_bc_map, _var_name);
     186             : 
     187         196 :     getProblem().addInitialCondition(
     188         196 :         "FunctorIC", prefix() + _var_name + "_ic_" + component_name, params);
     189             :   }
     190         242 : }

Generated by: LCOV version 1.14