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

Generated by: LCOV version 1.14