LCOV - code coverage report
Current view: top level - src/actions - PorousFlowFullySaturated.C (source / functions) Hit Total Coverage
Test: idaholab/moose porous_flow: #32971 (54bef8) with base c6cf66 Lines: 200 207 96.6 %
Date: 2026-05-29 20:38:56 Functions: 6 6 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 "PorousFlowFullySaturated.h"
      11             : 
      12             : #include "FEProblem.h"
      13             : #include "Conversion.h"
      14             : #include "libmesh/string_to_enum.h"
      15             : 
      16             : registerMooseAction("PorousFlowApp", PorousFlowFullySaturated, "add_user_object");
      17             : 
      18             : registerMooseAction("PorousFlowApp", PorousFlowFullySaturated, "add_kernel");
      19             : 
      20             : registerMooseAction("PorousFlowApp", PorousFlowFullySaturated, "add_material");
      21             : 
      22             : registerMooseAction("PorousFlowApp", PorousFlowFullySaturated, "add_aux_variable");
      23             : 
      24             : registerMooseAction("PorousFlowApp", PorousFlowFullySaturated, "add_aux_kernel");
      25             : 
      26             : InputParameters
      27        1482 : PorousFlowFullySaturated::validParams()
      28             : {
      29        1482 :   InputParameters params = PorousFlowSinglePhaseBase::validParams();
      30        2964 :   params.addParam<bool>(
      31             :       "multiply_by_density",
      32        2964 :       true,
      33             :       "If true, then the Kernels for fluid flow are multiplied by "
      34             :       "the fluid density.  If false, this multiplication is not "
      35             :       "performed, which means the problem becomes more linear, but care must be taken when using "
      36             :       "other PorousFlow objects, since MOOSE will be computing volume fluxes, not mass fluxes.");
      37        1482 :   params.addClassDescription(
      38             :       "Adds Kernels and fluid-property Materials necessary to simulate a "
      39             :       "single-phase fully-saturated flow problem.  Numerical stabilization options for the fluid "
      40             :       "and heat flow are: no upwinding, full-upwinding or KT stabilization.  No Kernels for "
      41             :       "diffusion and dispersion of "
      42             :       "fluid components are added.  To run a simulation you will also "
      43             :       "need to provide various other Materials for each mesh "
      44             :       "block, depending on your simulation type, viz: permeability, "
      45             :       "porosity, elasticity tensor, strain calculator, stress calculator, "
      46             :       "matrix internal energy, thermal conductivity, diffusivity");
      47        1482 :   return params;
      48           0 : }
      49             : 
      50        1482 : PorousFlowFullySaturated::PorousFlowFullySaturated(const InputParameters & params)
      51        2952 :   : PorousFlowSinglePhaseBase(params), _multiply_by_density(getParam<bool>("multiply_by_density"))
      52             : {
      53        1470 : }
      54             : 
      55             : void
      56        1470 : PorousFlowFullySaturated::addMaterialDependencies()
      57             : {
      58        1470 :   PorousFlowSinglePhaseBase::addMaterialDependencies();
      59             : 
      60             :   // Add necessary objects to list of PorousFlow objects added by this action
      61        1470 :   if (_stabilization == StabilizationEnum::None)
      62         790 :     _included_objects.push_back("PorousFlowFullySaturatedDarcyFlow");
      63        1075 :   else if (_stabilization == StabilizationEnum::Full)
      64        1900 :     _included_objects.push_back("PorousFlowFullySaturatedAdvectiveFlux");
      65         125 :   else if (_stabilization == StabilizationEnum::KT)
      66         250 :     _included_objects.push_back("PorousFlowFluxLimitedTVDAdvection");
      67             : 
      68        1470 :   if (_transient)
      69        2730 :     _included_objects.push_back("PorousFlowMassTimeDerivative");
      70             : 
      71        1470 :   if (_mechanical && _transient)
      72         870 :     _included_objects.push_back("PorousFlowMassVolumetricExpansion");
      73             : 
      74        1470 :   if (_thermal)
      75             :   {
      76         645 :     if (_stabilization == StabilizationEnum::None)
      77         360 :       _included_objects.push_back("PorousFlowFullySaturatedHeatAdvection");
      78         465 :     else if (_stabilization == StabilizationEnum::Full)
      79         770 :       _included_objects.push_back("PorousFlowFullySaturatedUpwindHeatAdvection");
      80          80 :     else if (_stabilization == StabilizationEnum::KT)
      81         160 :       _included_objects.push_back("PorousFlowFluxLimitedTVDAdvection");
      82             :   }
      83             : 
      84        1470 :   if (_stabilization == StabilizationEnum::KT && _thermal)
      85         160 :     _included_objects.push_back("PorousFlowAdvectiveFluxCalculatorSaturatedHeat");
      86             : 
      87        1470 :   if (_stabilization == StabilizationEnum::KT)
      88         250 :     _included_objects.push_back("PorousFlowAdvectiveFluxCalculatorSaturatedMultiComponent");
      89             : 
      90        1470 :   if (_stabilization == StabilizationEnum::KT && _thermal)
      91         160 :     _included_objects.push_back("PorousFlowAdvectiveFluxCalculatorSaturatedHeat");
      92        1470 : }
      93             : 
      94             : void
      95         294 : PorousFlowFullySaturated::addKernels()
      96             : {
      97         294 :   PorousFlowSinglePhaseBase::addKernels();
      98             : 
      99         294 :   if (_stabilization == StabilizationEnum::None)
     100             :   {
     101          79 :     const std::string kernel_type = "PorousFlowFullySaturatedDarcyFlow";
     102          79 :     InputParameters params = _factory.getValidParams(kernel_type);
     103         158 :     params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
     104          79 :     params.set<RealVectorValue>("gravity") = _gravity;
     105          79 :     params.set<bool>("multiply_by_density") = _multiply_by_density;
     106             : 
     107         113 :     for (unsigned i = 0; i < _num_mass_fraction_vars; ++i)
     108             :     {
     109          34 :       const std::string kernel_name = "PorousFlowFullySaturated_DarcyFlow" + Moose::stringify(i);
     110          34 :       params.set<unsigned int>("fluid_component") = i;
     111          68 :       params.set<NonlinearVariableName>("variable") = _mass_fraction_vars[i];
     112          34 :       _problem->addKernel(kernel_type, kernel_name, params);
     113             :     }
     114             : 
     115             :     const std::string kernel_name =
     116          79 :         "PorousFlowFullySaturated_DarcyFlow" + Moose::stringify(_num_mass_fraction_vars);
     117          79 :     params.set<unsigned int>("fluid_component") = _num_mass_fraction_vars;
     118         158 :     params.set<NonlinearVariableName>("variable") = _pp_var;
     119          79 :     _problem->addKernel(kernel_type, kernel_name, params);
     120          79 :   }
     121         215 :   else if (_stabilization == StabilizationEnum::Full)
     122             :   {
     123         190 :     const std::string kernel_type = "PorousFlowFullySaturatedAdvectiveFlux";
     124         190 :     InputParameters params = _factory.getValidParams(kernel_type);
     125         380 :     params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
     126         190 :     params.set<RealVectorValue>("gravity") = _gravity;
     127         190 :     params.set<bool>("multiply_by_density") = _multiply_by_density;
     128             : 
     129         247 :     for (unsigned i = 0; i < _num_mass_fraction_vars; ++i)
     130             :     {
     131             :       const std::string kernel_name =
     132          57 :           "PorousFlowFullySaturated_AdvectiveFlux" + Moose::stringify(i);
     133          57 :       params.set<unsigned int>("fluid_component") = i;
     134         114 :       params.set<NonlinearVariableName>("variable") = _mass_fraction_vars[i];
     135          57 :       _problem->addKernel(kernel_type, kernel_name, params);
     136             :     }
     137             : 
     138             :     const std::string kernel_name =
     139         190 :         "PorousFlowFullySaturated_AdvectiveFlux" + Moose::stringify(_num_mass_fraction_vars);
     140         190 :     params.set<unsigned int>("fluid_component") = _num_mass_fraction_vars;
     141         380 :     params.set<NonlinearVariableName>("variable") = _pp_var;
     142         190 :     _problem->addKernel(kernel_type, kernel_name, params);
     143         190 :   }
     144          25 :   else if (_stabilization == StabilizationEnum::KT)
     145             :   {
     146          25 :     const std::string kernel_type = "PorousFlowFluxLimitedTVDAdvection";
     147          25 :     InputParameters params = _factory.getValidParams(kernel_type);
     148          50 :     params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
     149             : 
     150          34 :     for (unsigned i = 0; i < _num_mass_fraction_vars; ++i)
     151             :     {
     152          18 :       const std::string kernel_name = "PorousFlowFluxLimited_DarcyFlow" + Moose::stringify(i);
     153          18 :       params.set<UserObjectName>("advective_flux_calculator") =
     154           9 :           "PorousFlowFullySaturated_AC_" + Moose::stringify(i);
     155          18 :       params.set<NonlinearVariableName>("variable") = _mass_fraction_vars[i];
     156           9 :       _problem->addKernel(kernel_type, kernel_name, params);
     157             :     }
     158             : 
     159             :     const std::string kernel_name =
     160          25 :         "PorousFlowFluxLimited_DarcyFlow" + Moose::stringify(_num_mass_fraction_vars);
     161          50 :     params.set<NonlinearVariableName>("variable") = _pp_var;
     162          50 :     params.set<UserObjectName>("advective_flux_calculator") =
     163          25 :         "PorousFlowFullySaturated_AC_" + Moose::stringify(_num_mass_fraction_vars);
     164          25 :     _problem->addKernel(kernel_type, kernel_name, params);
     165          25 :   }
     166             : 
     167         294 :   if (_transient)
     168             :   {
     169         273 :     std::string kernel_name = "PorousFlowFullySaturated_MassTimeDerivative";
     170         273 :     std::string kernel_type = "PorousFlowMassTimeDerivative";
     171         273 :     InputParameters params = _factory.getValidParams(kernel_type);
     172         546 :     params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
     173         273 :     params.set<bool>("multiply_by_density") = _multiply_by_density;
     174         273 :     params.set<bool>("strain_at_nearest_qp") = _strain_at_nearest_qp;
     175         273 :     if (!_base_name.empty())
     176           0 :       params.set<std::string>("base_name") = _base_name;
     177             : 
     178         361 :     for (unsigned i = 0; i < _num_mass_fraction_vars; ++i)
     179             :     {
     180          88 :       kernel_name = "PorousFlowFullySaturated_MassTimeDerivative" + Moose::stringify(i);
     181          88 :       params.set<unsigned int>("fluid_component") = i;
     182         176 :       params.set<NonlinearVariableName>("variable") = _mass_fraction_vars[i];
     183          88 :       if (_save_component_rate_in.size() != 0)
     184           0 :         params.set<std::vector<AuxVariableName>>("save_in") = {_save_component_rate_in[i]};
     185          88 :       _problem->addKernel(kernel_type, kernel_name, params);
     186             :     }
     187             : 
     188             :     kernel_name =
     189         273 :         "PorousFlowFullySaturated_MassTimeDerivative" + Moose::stringify(_num_mass_fraction_vars);
     190         273 :     params.set<unsigned int>("fluid_component") = _num_mass_fraction_vars;
     191         546 :     params.set<NonlinearVariableName>("variable") = _pp_var;
     192         273 :     if (_save_component_rate_in.size() != 0)
     193          18 :       params.set<std::vector<AuxVariableName>>("save_in") = {
     194          36 :           _save_component_rate_in[_num_mass_fraction_vars]};
     195         273 :     _problem->addKernel(kernel_type, kernel_name, params);
     196         273 :   }
     197             : 
     198         294 :   if (_mechanical && _transient)
     199             :   {
     200          87 :     std::string kernel_name = "PorousFlowFullySaturated_MassVolumetricExpansion";
     201          87 :     std::string kernel_type = "PorousFlowMassVolumetricExpansion";
     202          87 :     InputParameters params = _factory.getValidParams(kernel_type);
     203         174 :     params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
     204          87 :     params.set<bool>("multiply_by_density") = _multiply_by_density;
     205          87 :     params.set<bool>("strain_at_nearest_qp") = _strain_at_nearest_qp;
     206             : 
     207          87 :     for (unsigned i = 0; i < _num_mass_fraction_vars; ++i)
     208             :     {
     209           0 :       kernel_name = "PorousFlowFullySaturated_MassVolumetricExpansion" + Moose::stringify(i);
     210           0 :       params.set<unsigned>("fluid_component") = i;
     211           0 :       params.set<NonlinearVariableName>("variable") = _mass_fraction_vars[i];
     212           0 :       _problem->addKernel(kernel_type, kernel_name, params);
     213             :     }
     214             : 
     215          87 :     kernel_name = "PorousFlowFullySaturated_MassVolumetricExpansion" +
     216          87 :                   Moose::stringify(_num_mass_fraction_vars);
     217          87 :     params.set<unsigned>("fluid_component") = _num_mass_fraction_vars;
     218         174 :     params.set<NonlinearVariableName>("variable") = _pp_var;
     219          87 :     _problem->addKernel(kernel_type, kernel_name, params);
     220          87 :   }
     221             : 
     222         294 :   if (_thermal)
     223             :   {
     224         129 :     if (_stabilization == StabilizationEnum::None)
     225             :     {
     226          36 :       std::string kernel_name = "PorousFlowFullySaturated_HeatAdvection";
     227          36 :       std::string kernel_type = "PorousFlowFullySaturatedHeatAdvection";
     228          36 :       InputParameters params = _factory.getValidParams(kernel_type);
     229          72 :       params.set<NonlinearVariableName>("variable") = _temperature_var[0];
     230          72 :       params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
     231          36 :       params.set<RealVectorValue>("gravity") = _gravity;
     232          36 :       params.set<bool>("multiply_by_density") = true;
     233          36 :       _problem->addKernel(kernel_type, kernel_name, params);
     234          36 :     }
     235          93 :     else if (_stabilization == StabilizationEnum::Full)
     236             :     {
     237          77 :       std::string kernel_name = "PorousFlowFullySaturatedUpwind_HeatAdvection";
     238          77 :       std::string kernel_type = "PorousFlowFullySaturatedUpwindHeatAdvection";
     239          77 :       InputParameters params = _factory.getValidParams(kernel_type);
     240         154 :       params.set<NonlinearVariableName>("variable") = _temperature_var[0];
     241         154 :       params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
     242          77 :       params.set<RealVectorValue>("gravity") = _gravity;
     243          77 :       _problem->addKernel(kernel_type, kernel_name, params);
     244          77 :     }
     245          16 :     else if (_stabilization == StabilizationEnum::KT)
     246             :     {
     247          16 :       const std::string kernel_name = "PorousFlowFullySaturated_HeatAdvection";
     248          16 :       const std::string kernel_type = "PorousFlowFluxLimitedTVDAdvection";
     249          16 :       InputParameters params = _factory.getValidParams(kernel_type);
     250          32 :       params.set<NonlinearVariableName>("variable") = _temperature_var[0];
     251          32 :       params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
     252          32 :       params.set<UserObjectName>("advective_flux_calculator") = "PorousFlowFullySaturatedHeat_AC";
     253          16 :       _problem->addKernel(kernel_type, kernel_name, params);
     254          16 :     }
     255             :   }
     256         294 : }
     257             : 
     258             : void
     259         294 : PorousFlowFullySaturated::addUserObjects()
     260             : {
     261         294 :   PorousFlowSinglePhaseBase::addUserObjects();
     262             : 
     263             :   // add Advective Flux calculator UserObjects, if required
     264         294 :   if (_stabilization == StabilizationEnum::KT)
     265             :   {
     266          34 :     for (unsigned i = 0; i < _num_mass_fraction_vars; ++i)
     267             :     {
     268           9 :       const std::string userobject_name = "PorousFlowFullySaturated_AC_" + Moose::stringify(i);
     269          18 :       addAdvectiveFluxCalculatorSaturatedMultiComponent(
     270           9 :           0, i, _multiply_by_density, userobject_name);
     271             :     }
     272             : 
     273             :     const std::string userobject_name =
     274          25 :         "PorousFlowFullySaturated_AC_" + Moose::stringify(_num_mass_fraction_vars);
     275             : 
     276          25 :     if (_num_mass_fraction_vars == 0)
     277          32 :       addAdvectiveFluxCalculatorSaturated(
     278          16 :           0, _multiply_by_density, userobject_name); // 1 component only
     279             :     else
     280          18 :       addAdvectiveFluxCalculatorSaturatedMultiComponent(
     281           9 :           0, _num_mass_fraction_vars, _multiply_by_density, userobject_name);
     282             : 
     283          25 :     if (_thermal)
     284             :     {
     285          16 :       const std::string userobject_name = "PorousFlowFullySaturatedHeat_AC";
     286          32 :       addAdvectiveFluxCalculatorSaturatedHeat(0, true, userobject_name);
     287             :     }
     288             :   }
     289         294 : }
     290             : 
     291             : void
     292         294 : PorousFlowFullySaturated::addMaterials()
     293             : {
     294         294 :   PorousFlowSinglePhaseBase::addMaterials();
     295             : 
     296             :   // add Materials
     297         588 :   if (_deps.dependsOn(_included_objects, "pressure_saturation_qp"))
     298             :   {
     299             :     // saturation is always unity, so is trivially calculated using PorousFlow1PhaseFullySaturated
     300         294 :     std::string material_type = "PorousFlow1PhaseFullySaturated";
     301         294 :     std::string material_name = "PorousFlowFullySaturated_1PhaseP_qp";
     302         294 :     InputParameters params = _factory.getValidParams(material_type);
     303         294 :     if (_subdomain_names_set)
     304         126 :       params.set<std::vector<SubdomainName>>("block") = _subdomain_names;
     305         588 :     params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
     306         882 :     params.set<std::vector<VariableName>>("porepressure") = {_pp_var};
     307         294 :     params.set<bool>("at_nodes") = false;
     308         294 :     _problem->addMaterial(material_type, material_name, params);
     309         294 :   }
     310             : 
     311         588 :   if (_deps.dependsOn(_included_objects, "pressure_saturation_nodal"))
     312             :   {
     313         294 :     std::string material_type = "PorousFlow1PhaseFullySaturated";
     314         294 :     std::string material_name = "PorousFlowFullySaturated_1PhaseP";
     315         294 :     InputParameters params = _factory.getValidParams(material_type);
     316         294 :     if (_subdomain_names_set)
     317         126 :       params.set<std::vector<SubdomainName>>("block") = _subdomain_names;
     318         588 :     params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
     319         882 :     params.set<std::vector<VariableName>>("porepressure") = {_pp_var};
     320         294 :     params.set<bool>("at_nodes") = true;
     321         294 :     _problem->addMaterial(material_type, material_name, params);
     322         294 :   }
     323             : 
     324         588 :   if (_deps.dependsOn(_included_objects, "volumetric_strain_qp") ||
     325         501 :       _deps.dependsOn(_included_objects, "volumetric_strain_nodal"))
     326          87 :     addVolumetricStrainMaterial(_coupled_displacements, _base_name);
     327             : 
     328             :   // Relative permeability might be needed by Darcy-velocity Aux, so add a material
     329             :   // setting kr=1
     330         588 :   if (_deps.dependsOn(_included_objects, "relative_permeability_qp"))
     331         227 :     addRelativePermeabilityConst(false, 0, 1.0);
     332             : 
     333             :   // Some obects not added by this action might have a use_mobility = true param,
     334             :   // which needs a nodal relative permeability
     335         588 :   if (_deps.dependsOn(_included_objects, "relative_permeability_nodal"))
     336          83 :     addRelativePermeabilityConst(true, 0, 1.0);
     337         294 : }

Generated by: LCOV version 1.14