LCOV - code coverage report
Current view: top level - src/actions - PorousFlowFullySaturated.C (source / functions) Hit Total Coverage
Test: idaholab/moose porous_flow: #31405 (292dce) with base fef103 Lines: 200 207 96.6 %
Date: 2025-09-04 07:55: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        2907 : PorousFlowFullySaturated::validParams()
      28             : {
      29        2907 :   InputParameters params = PorousFlowSinglePhaseBase::validParams();
      30        5814 :   params.addParam<bool>(
      31             :       "multiply_by_density",
      32        5814 :       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        2907 :   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        2907 :   return params;
      48           0 : }
      49             : 
      50        2907 : PorousFlowFullySaturated::PorousFlowFullySaturated(const InputParameters & params)
      51        5802 :   : PorousFlowSinglePhaseBase(params), _multiply_by_density(getParam<bool>("multiply_by_density"))
      52             : {
      53        2895 : }
      54             : 
      55             : void
      56        2895 : PorousFlowFullySaturated::addMaterialDependencies()
      57             : {
      58        2895 :   PorousFlowSinglePhaseBase::addMaterialDependencies();
      59             : 
      60             :   // Add necessary objects to list of PorousFlow objects added by this action
      61        2895 :   if (_stabilization == StabilizationEnum::None)
      62        1630 :     _included_objects.push_back("PorousFlowFullySaturatedDarcyFlow");
      63        2080 :   else if (_stabilization == StabilizationEnum::Full)
      64        3670 :     _included_objects.push_back("PorousFlowFullySaturatedAdvectiveFlux");
      65         245 :   else if (_stabilization == StabilizationEnum::KT)
      66         490 :     _included_objects.push_back("PorousFlowFluxLimitedTVDAdvection");
      67             : 
      68        2895 :   if (_transient)
      69        5360 :     _included_objects.push_back("PorousFlowMassTimeDerivative");
      70             : 
      71        2895 :   if (_mechanical && _transient)
      72        1790 :     _included_objects.push_back("PorousFlowMassVolumetricExpansion");
      73             : 
      74        2895 :   if (_thermal)
      75             :   {
      76        1190 :     if (_stabilization == StabilizationEnum::None)
      77         760 :       _included_objects.push_back("PorousFlowFullySaturatedHeatAdvection");
      78         810 :     else if (_stabilization == StabilizationEnum::Full)
      79        1320 :       _included_objects.push_back("PorousFlowFullySaturatedUpwindHeatAdvection");
      80         150 :     else if (_stabilization == StabilizationEnum::KT)
      81         300 :       _included_objects.push_back("PorousFlowFluxLimitedTVDAdvection");
      82             :   }
      83             : 
      84        2895 :   if (_stabilization == StabilizationEnum::KT && _thermal)
      85         300 :     _included_objects.push_back("PorousFlowAdvectiveFluxCalculatorSaturatedHeat");
      86             : 
      87        2895 :   if (_stabilization == StabilizationEnum::KT)
      88         490 :     _included_objects.push_back("PorousFlowAdvectiveFluxCalculatorSaturatedMultiComponent");
      89             : 
      90        2895 :   if (_stabilization == StabilizationEnum::KT && _thermal)
      91         300 :     _included_objects.push_back("PorousFlowAdvectiveFluxCalculatorSaturatedHeat");
      92        2895 : }
      93             : 
      94             : void
      95         579 : PorousFlowFullySaturated::addKernels()
      96             : {
      97         579 :   PorousFlowSinglePhaseBase::addKernels();
      98             : 
      99         579 :   if (_stabilization == StabilizationEnum::None)
     100             :   {
     101         163 :     const std::string kernel_type = "PorousFlowFullySaturatedDarcyFlow";
     102         163 :     InputParameters params = _factory.getValidParams(kernel_type);
     103         326 :     params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
     104         163 :     params.set<RealVectorValue>("gravity") = _gravity;
     105         163 :     params.set<bool>("multiply_by_density") = _multiply_by_density;
     106             : 
     107         231 :     for (unsigned i = 0; i < _num_mass_fraction_vars; ++i)
     108             :     {
     109          68 :       const std::string kernel_name = "PorousFlowFullySaturated_DarcyFlow" + Moose::stringify(i);
     110          68 :       params.set<unsigned int>("fluid_component") = i;
     111         136 :       params.set<NonlinearVariableName>("variable") = _mass_fraction_vars[i];
     112          68 :       _problem->addKernel(kernel_type, kernel_name, params);
     113             :     }
     114             : 
     115             :     const std::string kernel_name =
     116         163 :         "PorousFlowFullySaturated_DarcyFlow" + Moose::stringify(_num_mass_fraction_vars);
     117         163 :     params.set<unsigned int>("fluid_component") = _num_mass_fraction_vars;
     118         326 :     params.set<NonlinearVariableName>("variable") = _pp_var;
     119         163 :     _problem->addKernel(kernel_type, kernel_name, params);
     120         163 :   }
     121         416 :   else if (_stabilization == StabilizationEnum::Full)
     122             :   {
     123         367 :     const std::string kernel_type = "PorousFlowFullySaturatedAdvectiveFlux";
     124         367 :     InputParameters params = _factory.getValidParams(kernel_type);
     125         734 :     params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
     126         367 :     params.set<RealVectorValue>("gravity") = _gravity;
     127         367 :     params.set<bool>("multiply_by_density") = _multiply_by_density;
     128             : 
     129         486 :     for (unsigned i = 0; i < _num_mass_fraction_vars; ++i)
     130             :     {
     131             :       const std::string kernel_name =
     132         119 :           "PorousFlowFullySaturated_AdvectiveFlux" + Moose::stringify(i);
     133         119 :       params.set<unsigned int>("fluid_component") = i;
     134         238 :       params.set<NonlinearVariableName>("variable") = _mass_fraction_vars[i];
     135         119 :       _problem->addKernel(kernel_type, kernel_name, params);
     136             :     }
     137             : 
     138             :     const std::string kernel_name =
     139         367 :         "PorousFlowFullySaturated_AdvectiveFlux" + Moose::stringify(_num_mass_fraction_vars);
     140         367 :     params.set<unsigned int>("fluid_component") = _num_mass_fraction_vars;
     141         734 :     params.set<NonlinearVariableName>("variable") = _pp_var;
     142         367 :     _problem->addKernel(kernel_type, kernel_name, params);
     143         367 :   }
     144          49 :   else if (_stabilization == StabilizationEnum::KT)
     145             :   {
     146          49 :     const std::string kernel_type = "PorousFlowFluxLimitedTVDAdvection";
     147          49 :     InputParameters params = _factory.getValidParams(kernel_type);
     148          98 :     params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
     149             : 
     150          68 :     for (unsigned i = 0; i < _num_mass_fraction_vars; ++i)
     151             :     {
     152          38 :       const std::string kernel_name = "PorousFlowFluxLimited_DarcyFlow" + Moose::stringify(i);
     153          38 :       params.set<UserObjectName>("advective_flux_calculator") =
     154          19 :           "PorousFlowFullySaturated_AC_" + Moose::stringify(i);
     155          38 :       params.set<NonlinearVariableName>("variable") = _mass_fraction_vars[i];
     156          19 :       _problem->addKernel(kernel_type, kernel_name, params);
     157             :     }
     158             : 
     159             :     const std::string kernel_name =
     160          49 :         "PorousFlowFluxLimited_DarcyFlow" + Moose::stringify(_num_mass_fraction_vars);
     161          98 :     params.set<NonlinearVariableName>("variable") = _pp_var;
     162          98 :     params.set<UserObjectName>("advective_flux_calculator") =
     163          49 :         "PorousFlowFullySaturated_AC_" + Moose::stringify(_num_mass_fraction_vars);
     164          49 :     _problem->addKernel(kernel_type, kernel_name, params);
     165          49 :   }
     166             : 
     167         579 :   if (_transient)
     168             :   {
     169         536 :     std::string kernel_name = "PorousFlowFullySaturated_MassTimeDerivative";
     170         536 :     std::string kernel_type = "PorousFlowMassTimeDerivative";
     171         536 :     InputParameters params = _factory.getValidParams(kernel_type);
     172        1072 :     params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
     173         536 :     params.set<bool>("multiply_by_density") = _multiply_by_density;
     174         536 :     params.set<bool>("strain_at_nearest_qp") = _strain_at_nearest_qp;
     175         536 :     if (!_base_name.empty())
     176           0 :       params.set<std::string>("base_name") = _base_name;
     177             : 
     178         718 :     for (unsigned i = 0; i < _num_mass_fraction_vars; ++i)
     179             :     {
     180         182 :       kernel_name = "PorousFlowFullySaturated_MassTimeDerivative" + Moose::stringify(i);
     181         182 :       params.set<unsigned int>("fluid_component") = i;
     182         364 :       params.set<NonlinearVariableName>("variable") = _mass_fraction_vars[i];
     183         182 :       if (_save_component_rate_in.size() != 0)
     184           0 :         params.set<std::vector<AuxVariableName>>("save_in") = {_save_component_rate_in[i]};
     185         182 :       _problem->addKernel(kernel_type, kernel_name, params);
     186             :     }
     187             : 
     188             :     kernel_name =
     189         536 :         "PorousFlowFullySaturated_MassTimeDerivative" + Moose::stringify(_num_mass_fraction_vars);
     190         536 :     params.set<unsigned int>("fluid_component") = _num_mass_fraction_vars;
     191        1072 :     params.set<NonlinearVariableName>("variable") = _pp_var;
     192         536 :     if (_save_component_rate_in.size() != 0)
     193          38 :       params.set<std::vector<AuxVariableName>>("save_in") = {
     194          76 :           _save_component_rate_in[_num_mass_fraction_vars]};
     195         536 :     _problem->addKernel(kernel_type, kernel_name, params);
     196         536 :   }
     197             : 
     198         579 :   if (_mechanical && _transient)
     199             :   {
     200         179 :     std::string kernel_name = "PorousFlowFullySaturated_MassVolumetricExpansion";
     201         179 :     std::string kernel_type = "PorousFlowMassVolumetricExpansion";
     202         179 :     InputParameters params = _factory.getValidParams(kernel_type);
     203         358 :     params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
     204         179 :     params.set<bool>("multiply_by_density") = _multiply_by_density;
     205         179 :     params.set<bool>("strain_at_nearest_qp") = _strain_at_nearest_qp;
     206             : 
     207         179 :     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         179 :     kernel_name = "PorousFlowFullySaturated_MassVolumetricExpansion" +
     216         179 :                   Moose::stringify(_num_mass_fraction_vars);
     217         179 :     params.set<unsigned>("fluid_component") = _num_mass_fraction_vars;
     218         358 :     params.set<NonlinearVariableName>("variable") = _pp_var;
     219         179 :     _problem->addKernel(kernel_type, kernel_name, params);
     220         179 :   }
     221             : 
     222         579 :   if (_thermal)
     223             :   {
     224         238 :     if (_stabilization == StabilizationEnum::None)
     225             :     {
     226          76 :       std::string kernel_name = "PorousFlowFullySaturated_HeatAdvection";
     227          76 :       std::string kernel_type = "PorousFlowFullySaturatedHeatAdvection";
     228          76 :       InputParameters params = _factory.getValidParams(kernel_type);
     229         152 :       params.set<NonlinearVariableName>("variable") = _temperature_var[0];
     230         152 :       params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
     231          76 :       params.set<RealVectorValue>("gravity") = _gravity;
     232          76 :       params.set<bool>("multiply_by_density") = true;
     233          76 :       _problem->addKernel(kernel_type, kernel_name, params);
     234          76 :     }
     235         162 :     else if (_stabilization == StabilizationEnum::Full)
     236             :     {
     237         132 :       std::string kernel_name = "PorousFlowFullySaturatedUpwind_HeatAdvection";
     238         132 :       std::string kernel_type = "PorousFlowFullySaturatedUpwindHeatAdvection";
     239         132 :       InputParameters params = _factory.getValidParams(kernel_type);
     240         264 :       params.set<NonlinearVariableName>("variable") = _temperature_var[0];
     241         264 :       params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
     242         132 :       params.set<RealVectorValue>("gravity") = _gravity;
     243         132 :       _problem->addKernel(kernel_type, kernel_name, params);
     244         132 :     }
     245          30 :     else if (_stabilization == StabilizationEnum::KT)
     246             :     {
     247          30 :       const std::string kernel_name = "PorousFlowFullySaturated_HeatAdvection";
     248          30 :       const std::string kernel_type = "PorousFlowFluxLimitedTVDAdvection";
     249          30 :       InputParameters params = _factory.getValidParams(kernel_type);
     250          60 :       params.set<NonlinearVariableName>("variable") = _temperature_var[0];
     251          60 :       params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
     252          60 :       params.set<UserObjectName>("advective_flux_calculator") = "PorousFlowFullySaturatedHeat_AC";
     253          30 :       _problem->addKernel(kernel_type, kernel_name, params);
     254          30 :     }
     255             :   }
     256         579 : }
     257             : 
     258             : void
     259         579 : PorousFlowFullySaturated::addUserObjects()
     260             : {
     261         579 :   PorousFlowSinglePhaseBase::addUserObjects();
     262             : 
     263             :   // add Advective Flux calculator UserObjects, if required
     264         579 :   if (_stabilization == StabilizationEnum::KT)
     265             :   {
     266          68 :     for (unsigned i = 0; i < _num_mass_fraction_vars; ++i)
     267             :     {
     268          19 :       const std::string userobject_name = "PorousFlowFullySaturated_AC_" + Moose::stringify(i);
     269          38 :       addAdvectiveFluxCalculatorSaturatedMultiComponent(
     270          19 :           0, i, _multiply_by_density, userobject_name);
     271             :     }
     272             : 
     273             :     const std::string userobject_name =
     274          49 :         "PorousFlowFullySaturated_AC_" + Moose::stringify(_num_mass_fraction_vars);
     275             : 
     276          49 :     if (_num_mass_fraction_vars == 0)
     277          60 :       addAdvectiveFluxCalculatorSaturated(
     278          30 :           0, _multiply_by_density, userobject_name); // 1 component only
     279             :     else
     280          38 :       addAdvectiveFluxCalculatorSaturatedMultiComponent(
     281          19 :           0, _num_mass_fraction_vars, _multiply_by_density, userobject_name);
     282             : 
     283          49 :     if (_thermal)
     284             :     {
     285          30 :       const std::string userobject_name = "PorousFlowFullySaturatedHeat_AC";
     286          60 :       addAdvectiveFluxCalculatorSaturatedHeat(0, true, userobject_name);
     287             :     }
     288             :   }
     289         579 : }
     290             : 
     291             : void
     292         579 : PorousFlowFullySaturated::addMaterials()
     293             : {
     294         579 :   PorousFlowSinglePhaseBase::addMaterials();
     295             : 
     296             :   // add Materials
     297        1158 :   if (_deps.dependsOn(_included_objects, "pressure_saturation_qp"))
     298             :   {
     299             :     // saturation is always unity, so is trivially calculated using PorousFlow1PhaseFullySaturated
     300         579 :     std::string material_type = "PorousFlow1PhaseFullySaturated";
     301         579 :     std::string material_name = "PorousFlowFullySaturated_1PhaseP_qp";
     302         579 :     InputParameters params = _factory.getValidParams(material_type);
     303         579 :     if (_subdomain_names_set)
     304         266 :       params.set<std::vector<SubdomainName>>("block") = _subdomain_names;
     305        1158 :     params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
     306        1737 :     params.set<std::vector<VariableName>>("porepressure") = {_pp_var};
     307         579 :     params.set<bool>("at_nodes") = false;
     308         579 :     _problem->addMaterial(material_type, material_name, params);
     309         579 :   }
     310             : 
     311        1158 :   if (_deps.dependsOn(_included_objects, "pressure_saturation_nodal"))
     312             :   {
     313         579 :     std::string material_type = "PorousFlow1PhaseFullySaturated";
     314         579 :     std::string material_name = "PorousFlowFullySaturated_1PhaseP";
     315         579 :     InputParameters params = _factory.getValidParams(material_type);
     316         579 :     if (_subdomain_names_set)
     317         266 :       params.set<std::vector<SubdomainName>>("block") = _subdomain_names;
     318        1158 :     params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
     319        1737 :     params.set<std::vector<VariableName>>("porepressure") = {_pp_var};
     320         579 :     params.set<bool>("at_nodes") = true;
     321         579 :     _problem->addMaterial(material_type, material_name, params);
     322         579 :   }
     323             : 
     324        1158 :   if (_deps.dependsOn(_included_objects, "volumetric_strain_qp") ||
     325         979 :       _deps.dependsOn(_included_objects, "volumetric_strain_nodal"))
     326         179 :     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        1158 :   if (_deps.dependsOn(_included_objects, "relative_permeability_qp"))
     331         442 :     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        1158 :   if (_deps.dependsOn(_included_objects, "relative_permeability_nodal"))
     336         167 :     addRelativePermeabilityConst(true, 0, 1.0);
     337         579 : }

Generated by: LCOV version 1.14