LCOV - code coverage report
Current view: top level - src/actions - PorousFlowSinglePhaseBase.C (source / functions) Hit Total Coverage
Test: idaholab/moose porous_flow: #31405 (292dce) with base fef103 Lines: 220 222 99.1 %
Date: 2025-09-04 07:55:56 Functions: 7 7 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 "PorousFlowSinglePhaseBase.h"
      11             : 
      12             : #include "FEProblem.h"
      13             : #include "Conversion.h"
      14             : #include "libmesh/string_to_enum.h"
      15             : 
      16             : InputParameters
      17        6401 : PorousFlowSinglePhaseBase::validParams()
      18             : {
      19        6401 :   InputParameters params = PorousFlowActionBase::validParams();
      20       12802 :   params.addParam<bool>("add_darcy_aux", true, "Add AuxVariables that record Darcy velocity");
      21       12802 :   params.addParam<bool>("add_stress_aux", true, "Add AuxVariables that record effective stress");
      22       19203 :   params.addDeprecatedParam<bool>("use_brine",
      23       12802 :                                   false,
      24             :                                   "Whether to use a PorousFlowBrine Material",
      25             :                                   "This parameter should no longer be used.  Instead use "
      26             :                                   "fluid_properties_type = PorousFlowBrine");
      27       12802 :   params.addRequiredParam<VariableName>("porepressure", "The name of the porepressure variable");
      28       12802 :   MooseEnum coupling_type("Hydro ThermoHydro HydroMechanical ThermoHydroMechanical", "Hydro");
      29       12802 :   params.addParam<MooseEnum>("coupling_type",
      30             :                              coupling_type,
      31             :                              "The type of simulation.  For simulations involving Mechanical "
      32             :                              "deformations, you will need to supply the correct Biot coefficient.  "
      33             :                              "For simulations involving Thermal flows, you will need an associated "
      34             :                              "ConstantThermalExpansionCoefficient Material");
      35             :   MooseEnum fluid_properties_type("PorousFlowSingleComponentFluid PorousFlowBrine Custom",
      36       12802 :                                   "PorousFlowSingleComponentFluid");
      37       12802 :   params.addParam<MooseEnum>(
      38             :       "fluid_properties_type",
      39             :       fluid_properties_type,
      40             :       "Type of fluid properties to use.  For 'PorousFlowSingleComponentFluid' you must provide a "
      41             :       "fp UserObject.  For 'PorousFlowBrine' you must supply a nacl_name.  For "
      42             :       "'Custom' your input file must include a Material that provides fluid properties such as "
      43             :       "density, viscosity, enthalpy and internal energy");
      44       12802 :   MooseEnum simulation_type_choice("steady transient", "transient");
      45       12802 :   params.addDeprecatedParam<MooseEnum>(
      46             :       "simulation_type",
      47             :       simulation_type_choice,
      48             :       "Whether a transient or steady-state simulation is being performed",
      49             :       "The execution type is now determined automatically. This parameter should no longer be "
      50             :       "used");
      51       12802 :   params.addParam<UserObjectName>(
      52             :       "fp",
      53             :       "The name of the user object for fluid "
      54             :       "properties. Only needed if fluid_properties_type = PorousFlowSingleComponentFluid");
      55       12802 :   params.addCoupledVar("mass_fraction_vars",
      56             :                        {},
      57             :                        "List of variables that represent the mass fractions.  With only one fluid "
      58             :                        "component, this may be left empty.  With N fluid components, the format is "
      59             :                        "'f_0 f_1 f_2 ... f_(N-1)'.  That is, the N^th component need not be "
      60             :                        "specified because f_N = 1 - (f_0 + f_1 + ... + f_(N-1)).  It is best "
      61             :                        "numerically to choose the N-1 mass fraction variables so that they "
      62             :                        "represent the fluid components with small concentrations.  This Action "
      63             :                        "will associated the i^th mass fraction variable to the equation for the "
      64             :                        "i^th fluid component, and the pressure variable to the N^th fluid "
      65             :                        "component.");
      66       19203 :   params.addDeprecatedParam<unsigned>(
      67             :       "nacl_index",
      68       12802 :       0,
      69             :       "Index of NaCl variable in mass_fraction_vars, for "
      70             :       "calculating brine properties. Only required if use_brine is true.",
      71             :       "This parameter should no longer be used.  Instead use nacl_name = the_nacl_variable_name");
      72       12802 :   params.addParam<VariableName>(
      73             :       "nacl_name",
      74             :       "Name of the NaCl variable.  Only required if fluid_properties_type = PorousFlowBrine");
      75       12802 :   params.addParam<Real>(
      76             :       "biot_coefficient",
      77       12802 :       1.0,
      78             :       "The Biot coefficient (relevant only for mechanically-coupled simulations)");
      79       12802 :   params.addParam<std::vector<AuxVariableName>>(
      80             :       "save_component_rate_in",
      81             :       {},
      82             :       "List of AuxVariables into which the rate-of-change of each fluid component at each node "
      83             :       "will be saved.  There must be exactly N of these to match the N fluid components.  The "
      84             :       "result will be measured in kg/s, where the kg is the mass of the fluid component at the "
      85             :       "node (or m^3/s if multiply_by_density=false).  Note that this saves the result from the "
      86             :       "MassTimeDerivative Kernels, but NOT from the MassVolumetricExpansion Kernels.");
      87       12802 :   MooseEnum temp_unit_choice("Kelvin Celsius", "Kelvin");
      88       12802 :   params.addParam<MooseEnum>(
      89             :       "temperature_unit", temp_unit_choice, "The unit of the temperature variable");
      90       12802 :   MooseEnum p_unit_choice("Pa MPa", "Pa");
      91       12802 :   params.addParam<MooseEnum>(
      92             :       "pressure_unit",
      93             :       p_unit_choice,
      94             :       "The unit of the pressure variable used everywhere in the input file "
      95             :       "except for in the FluidProperties-module objects.  This can be set to the non-default value "
      96             :       "only for fluid_properties_type = PorousFlowSingleComponentFluid");
      97       12802 :   MooseEnum time_unit_choice("seconds hours days years", "seconds");
      98       12802 :   params.addParam<MooseEnum>(
      99             :       "time_unit",
     100             :       time_unit_choice,
     101             :       "The unit of time used everywhere in the input file except for in the "
     102             :       "FluidProperties-module objects.  This can be set to the non-default value only for "
     103             :       "fluid_properties_type = PorousFlowSingleComponentFluid");
     104       12802 :   params.addParam<std::string>("base_name",
     105             :                                "The base_name used in the TensorMechanics strain calculator.  This "
     106             :                                "is only relevant for mechanically-coupled models.");
     107        6401 :   params.addClassDescription("Base class for single-phase simulations");
     108        6401 :   return params;
     109        6401 : }
     110             : 
     111        6401 : PorousFlowSinglePhaseBase::PorousFlowSinglePhaseBase(const InputParameters & params)
     112             :   : PorousFlowActionBase(params),
     113       12802 :     _pp_var(getParam<VariableName>("porepressure")),
     114       12802 :     _coupling_type(getParam<MooseEnum>("coupling_type").getEnum<CouplingTypeEnum>()),
     115        6401 :     _thermal(_coupling_type == CouplingTypeEnum::ThermoHydro ||
     116             :              _coupling_type == CouplingTypeEnum::ThermoHydroMechanical),
     117        6401 :     _mechanical(_coupling_type == CouplingTypeEnum::HydroMechanical ||
     118             :                 _coupling_type == CouplingTypeEnum::ThermoHydroMechanical),
     119        6401 :     _fluid_properties_type(
     120       12802 :         getParam<MooseEnum>("fluid_properties_type").getEnum<FluidPropertiesTypeEnum>()),
     121       12802 :     _biot_coefficient(getParam<Real>("biot_coefficient")),
     122       12802 :     _add_darcy_aux(getParam<bool>("add_darcy_aux")),
     123       12802 :     _add_stress_aux(getParam<bool>("add_stress_aux")),
     124       12802 :     _save_component_rate_in(getParam<std::vector<AuxVariableName>>("save_component_rate_in")),
     125       12802 :     _temperature_unit(getParam<MooseEnum>("temperature_unit")),
     126       12802 :     _pressure_unit(getParam<MooseEnum>("pressure_unit")),
     127       12802 :     _time_unit(getParam<MooseEnum>("time_unit")),
     128       19203 :     _base_name(isParamValid("base_name") ? getParam<std::string>("base_name") + "_" : "")
     129             : {
     130        6401 :   if (_thermal && _temperature_var.size() != 1)
     131           0 :     mooseError("PorousFlowSinglePhaseBase: You need to specify a temperature variable to perform "
     132             :                "non-isothermal simulations");
     133             : 
     134        6401 :   if (_fluid_properties_type == FluidPropertiesTypeEnum::PorousFlowSingleComponentFluid)
     135             :   {
     136       12596 :     if (params.isParamValid("nacl_name"))
     137           2 :       paramError("nacl_name",
     138             :                  "PorousFlowSinglePhaseBase: You should not specify a nacl_name when "
     139             :                  "fluid_properties_type = PorousFlowSingleComponentFluid");
     140       12592 :     if (!params.isParamValid("fp"))
     141           2 :       paramError("fp",
     142             :                  "PorousFlowSinglePhaseBase: You must specify fp when fluid_properties_type = "
     143             :                  "PorousFlowSingleComponentFluid");
     144       12588 :     _fp = getParam<UserObjectName>("fp");
     145             :   }
     146             : 
     147        6397 :   if (_fluid_properties_type == FluidPropertiesTypeEnum::PorousFlowBrine)
     148             :   {
     149         206 :     if (!params.isParamValid("nacl_name"))
     150           2 :       paramError("nacl_name",
     151             :                  "PorousFlowSinglePhaseBase: You must specify nacl_name when "
     152             :                  "fluid_properties_type = PorousFlowBrine");
     153         202 :     if (params.isParamValid("fp"))
     154           2 :       paramError("fp",
     155             :                  "PorousFlowSinglePhaseBase: You should not specify fp when "
     156             :                  "fluid_properties_type = PorousFlowBrine");
     157          99 :     if (_pressure_unit != "Pa")
     158           2 :       paramError("pressure_unit",
     159             :                  "Must use pressure_unit = Pa for fluid_properties_type = PorousFlowBrine");
     160          97 :     if (_time_unit != "seconds")
     161           2 :       paramError("time_unit",
     162             :                  "Must use time_unit = seconds for fluid_properties_type = PorousFlowBrine");
     163         190 :     _nacl_name = getParam<VariableName>("nacl_name");
     164             :   }
     165             : 
     166             :   auto save_component_rate_in_size = _save_component_rate_in.size();
     167        6389 :   if (save_component_rate_in_size && save_component_rate_in_size != _num_mass_fraction_vars + 1)
     168           2 :     paramError("save_component_rate_in",
     169             :                "The number of save_component_rate_in variables must be the number of fluid "
     170             :                "components + 1");
     171        6387 : }
     172             : 
     173             : void
     174        6321 : PorousFlowSinglePhaseBase::addMaterialDependencies()
     175             : {
     176        6321 :   PorousFlowActionBase::addMaterialDependencies();
     177             : 
     178             :   // Add necessary objects to list of PorousFlow objects added by this action
     179        6321 :   if (_mechanical)
     180             :   {
     181        2320 :     _included_objects.push_back("StressDivergenceTensors");
     182        2320 :     _included_objects.push_back("Gravity");
     183        4640 :     _included_objects.push_back("PorousFlowEffectiveStressCoupling");
     184             :   }
     185             : 
     186        6321 :   if (_thermal)
     187             :   {
     188        2015 :     _included_objects.push_back("PorousFlowHeatConduction");
     189        2015 :     if (_transient)
     190        3460 :       _included_objects.push_back("PorousFlowEnergyTimeDerivative");
     191             :   }
     192             : 
     193        6321 :   if (_thermal && _mechanical && _transient)
     194        1220 :     _included_objects.push_back("PorousFlowHeatVolumetricExpansion");
     195             : 
     196        6321 :   if (_add_darcy_aux)
     197       10872 :     _included_objects.push_back("PorousFlowDarcyVelocityComponent");
     198             : 
     199        6321 :   if (_add_stress_aux && _mechanical)
     200        4070 :     _included_objects.push_back("StressAux");
     201        6321 : }
     202             : 
     203             : void
     204        1249 : PorousFlowSinglePhaseBase::addKernels()
     205             : {
     206        1249 :   PorousFlowActionBase::addKernels();
     207             : 
     208        1249 :   if (_mechanical)
     209             :   {
     210        1761 :     for (unsigned i = 0; i < _ndisp; ++i)
     211             :     {
     212        1297 :       std::string kernel_name = "PorousFlowUnsaturated_grad_stress" + Moose::stringify(i);
     213        1297 :       std::string kernel_type = "StressDivergenceTensors";
     214        1297 :       if (_coord_system == Moose::COORD_RZ)
     215             :         kernel_type = "StressDivergenceRZTensors";
     216        1297 :       InputParameters params = _factory.getValidParams(kernel_type);
     217        1297 :       if (_subdomain_names_set)
     218        1634 :         params.set<std::vector<SubdomainName>>("block") = _subdomain_names;
     219        2594 :       params.set<NonlinearVariableName>("variable") = _displacements[i];
     220        1297 :       params.set<std::vector<VariableName>>("displacements") = _coupled_displacements;
     221        1297 :       if (_thermal)
     222             :       {
     223         922 :         params.set<std::vector<VariableName>>("temperature") = _temperature_var;
     224         922 :         if (parameters().isParamValid("eigenstrain_names"))
     225             :         {
     226         922 :           params.set<std::vector<MaterialPropertyName>>("eigenstrain_names") =
     227        1383 :               getParam<std::vector<MaterialPropertyName>>("eigenstrain_names");
     228             :         }
     229             :       }
     230        1297 :       params.set<unsigned>("component") = i;
     231        2594 :       params.set<bool>("use_displaced_mesh") = getParam<bool>("use_displaced_mesh");
     232        1297 :       _problem->addKernel(kernel_type, kernel_name, params);
     233             : 
     234        1297 :       if (_gravity(i) != 0)
     235             :       {
     236         130 :         kernel_name = "PorousFlowUnsaturated_gravity" + Moose::stringify(i);
     237             :         kernel_type = "Gravity";
     238          65 :         params = _factory.getValidParams(kernel_type);
     239          65 :         if (_subdomain_names_set)
     240          76 :           params.set<std::vector<SubdomainName>>("block") = _subdomain_names;
     241         130 :         params.set<NonlinearVariableName>("variable") = _displacements[i];
     242          65 :         params.set<Real>("value") = _gravity(i);
     243         130 :         params.set<bool>("use_displaced_mesh") = getParam<bool>("use_displaced_mesh");
     244          65 :         _problem->addKernel(kernel_type, kernel_name, params);
     245             :       }
     246             : 
     247        2594 :       kernel_name = "PorousFlowUnsaturated_EffStressCoupling" + Moose::stringify(i);
     248             :       kernel_type = "PorousFlowEffectiveStressCoupling";
     249        1297 :       params = _factory.getValidParams(kernel_type);
     250        1297 :       if (_subdomain_names_set)
     251        1634 :         params.set<std::vector<SubdomainName>>("block") = _subdomain_names;
     252        2594 :       params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
     253        2594 :       params.set<NonlinearVariableName>("variable") = _displacements[i];
     254        1297 :       params.set<Real>("biot_coefficient") = _biot_coefficient;
     255        1297 :       params.set<unsigned>("component") = i;
     256        2594 :       params.set<bool>("use_displaced_mesh") = getParam<bool>("use_displaced_mesh");
     257        1297 :       _problem->addKernel(kernel_type, kernel_name, params);
     258        1297 :     }
     259             :   }
     260             : 
     261        1249 :   if (_thermal)
     262             :   {
     263         403 :     std::string kernel_name = "PorousFlowUnsaturated_HeatConduction";
     264         403 :     std::string kernel_type = "PorousFlowHeatConduction";
     265         403 :     InputParameters params = _factory.getValidParams(kernel_type);
     266         806 :     params.set<NonlinearVariableName>("variable") = _temperature_var[0];
     267         806 :     params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
     268         403 :     _problem->addKernel(kernel_type, kernel_name, params);
     269             : 
     270         403 :     if (_transient)
     271             :     {
     272             :       kernel_name = "PorousFlowUnsaturated_EnergyTimeDerivative";
     273             :       kernel_type = "PorousFlowEnergyTimeDerivative";
     274         346 :       params = _factory.getValidParams(kernel_type);
     275         692 :       params.set<NonlinearVariableName>("variable") = _temperature_var[0];
     276         692 :       params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
     277         346 :       params.set<bool>("strain_at_nearest_qp") = _strain_at_nearest_qp;
     278         346 :       if (!_base_name.empty())
     279           0 :         params.set<std::string>("base_name") = _base_name;
     280         346 :       _problem->addKernel(kernel_type, kernel_name, params);
     281             :     }
     282         403 :   }
     283             : 
     284        1249 :   if (_thermal && _mechanical && _transient)
     285             :   {
     286         122 :     std::string kernel_name = "PorousFlowUnsaturated_HeatVolumetricExpansion";
     287         122 :     std::string kernel_type = "PorousFlowHeatVolumetricExpansion";
     288         122 :     InputParameters params = _factory.getValidParams(kernel_type);
     289         244 :     params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
     290         244 :     params.set<NonlinearVariableName>("variable") = _temperature_var[0];
     291         122 :     params.set<bool>("strain_at_nearest_qp") = _strain_at_nearest_qp;
     292         122 :     _problem->addKernel(kernel_type, kernel_name, params);
     293         122 :   }
     294        1249 : }
     295             : 
     296             : void
     297        2528 : PorousFlowSinglePhaseBase::addAuxObjects()
     298             : {
     299        2528 :   PorousFlowActionBase::addAuxObjects();
     300             : 
     301        2528 :   if (_add_darcy_aux)
     302        2174 :     addDarcyAux(_gravity);
     303             : 
     304        2528 :   if (_add_stress_aux && _mechanical)
     305         814 :     addStressAux();
     306        2528 : }
     307             : 
     308             : void
     309        1267 : PorousFlowSinglePhaseBase::addMaterials()
     310             : {
     311        1267 :   PorousFlowActionBase::addMaterials();
     312             : 
     313             :   // add Materials
     314        2534 :   if (_deps.dependsOn(_included_objects, "temperature_qp"))
     315        1267 :     addTemperatureMaterial(false);
     316             : 
     317        2534 :   if (_deps.dependsOn(_included_objects, "temperature_nodal"))
     318        1029 :     addTemperatureMaterial(true);
     319             : 
     320        2534 :   if (_deps.dependsOn(_included_objects, "mass_fraction_qp"))
     321         439 :     addMassFractionMaterial(false);
     322             : 
     323        2534 :   if (_deps.dependsOn(_included_objects, "mass_fraction_nodal"))
     324        1018 :     addMassFractionMaterial(true);
     325             : 
     326        1267 :   const bool compute_rho_mu_qp = _deps.dependsOn(_included_objects, "density_qp") ||
     327        1267 :                                  _deps.dependsOn(_included_objects, "viscosity_qp");
     328        1267 :   const bool compute_e_qp = _deps.dependsOn(_included_objects, "internal_energy_qp");
     329        1267 :   const bool compute_h_qp = _deps.dependsOn(_included_objects, "enthalpy_qp");
     330             : 
     331        1267 :   if (compute_rho_mu_qp || compute_e_qp || compute_h_qp)
     332             :   {
     333        1267 :     if (_fluid_properties_type == FluidPropertiesTypeEnum::PorousFlowBrine)
     334          38 :       addBrineMaterial(
     335          19 :           _nacl_name, false, 0, compute_rho_mu_qp, compute_e_qp, compute_h_qp, _temperature_unit);
     336        1248 :     else if (_fluid_properties_type == FluidPropertiesTypeEnum::PorousFlowSingleComponentFluid)
     337        1248 :       addSingleComponentFluidMaterial(false,
     338             :                                       0,
     339             :                                       compute_rho_mu_qp,
     340             :                                       compute_e_qp,
     341             :                                       compute_h_qp,
     342        1248 :                                       _fp,
     343        1248 :                                       _temperature_unit,
     344        1248 :                                       _pressure_unit,
     345        1248 :                                       _time_unit);
     346             :   }
     347             : 
     348        1267 :   const bool compute_rho_mu_nodal = _deps.dependsOn(_included_objects, "density_nodal") ||
     349        1562 :                                     _deps.dependsOn(_included_objects, "viscosity_nodal");
     350        1267 :   const bool compute_e_nodal = _deps.dependsOn(_included_objects, "internal_energy_nodal");
     351        1267 :   const bool compute_h_nodal = _deps.dependsOn(_included_objects, "enthalpy_nodal");
     352             : 
     353        1267 :   if (compute_rho_mu_nodal || compute_e_nodal || compute_h_nodal)
     354             :   {
     355        1029 :     if (_fluid_properties_type == FluidPropertiesTypeEnum::PorousFlowBrine)
     356          38 :       addBrineMaterial(_nacl_name,
     357             :                        true,
     358             :                        0,
     359             :                        compute_rho_mu_nodal,
     360             :                        compute_e_nodal,
     361             :                        compute_h_nodal,
     362          19 :                        _temperature_unit);
     363        1010 :     else if (_fluid_properties_type == FluidPropertiesTypeEnum::PorousFlowSingleComponentFluid)
     364        1010 :       addSingleComponentFluidMaterial(true,
     365             :                                       0,
     366             :                                       compute_rho_mu_nodal,
     367             :                                       compute_e_nodal,
     368             :                                       compute_h_nodal,
     369        1010 :                                       _fp,
     370        1010 :                                       _temperature_unit,
     371        1010 :                                       _pressure_unit,
     372        1010 :                                       _time_unit);
     373             :   }
     374             : 
     375        2534 :   if (_deps.dependsOn(_included_objects, "effective_pressure_qp"))
     376        1267 :     addEffectiveFluidPressureMaterial(false);
     377             : 
     378        2534 :   if (_deps.dependsOn(_included_objects, "effective_pressure_nodal"))
     379         872 :     addEffectiveFluidPressureMaterial(true);
     380        1267 : }
     381             : 
     382             : void
     383        1277 : PorousFlowSinglePhaseBase::addDictator()
     384             : {
     385        1277 :   const std::string uo_name = _dictator_name;
     386        1277 :   const std::string uo_type = "PorousFlowDictator";
     387        1277 :   InputParameters params = _factory.getValidParams(uo_type);
     388        1277 :   std::vector<VariableName> pf_vars = _mass_fraction_vars;
     389        1277 :   pf_vars.push_back(_pp_var);
     390             :   // Only couple if in the same nonlinear system
     391        2554 :   params.set<SolverSystemName>("solver_sys") =
     392        1277 :       _problem->getSystemBase(_problem->getSystem(_pp_var).name()).name();
     393        1680 :   if (_thermal &&
     394         403 :       (_problem->getSystem(_temperature_var[0]).number() == _problem->getSystem(_pp_var).number()))
     395         403 :     pf_vars.push_back(_temperature_var[0]);
     396        1741 :   if (_mechanical && _coupled_displacements.size() &&
     397         464 :       (_problem->getSystem(_coupled_displacements[0]).number() ==
     398         464 :        _problem->getSystem(_pp_var).number()))
     399         445 :     pf_vars.insert(pf_vars.end(), _coupled_displacements.begin(), _coupled_displacements.end());
     400        1277 :   params.set<std::vector<VariableName>>("porous_flow_vars") = pf_vars;
     401        1277 :   params.set<unsigned int>("number_fluid_phases") = 1;
     402        1277 :   params.set<unsigned int>("number_fluid_components") = _num_mass_fraction_vars + 1;
     403        1277 :   params.set<unsigned int>("number_aqueous_equilibrium") = _num_aqueous_equilibrium;
     404        1277 :   params.set<unsigned int>("number_aqueous_kinetic") = _num_aqueous_kinetic;
     405        1277 :   _problem->addUserObject(uo_type, uo_name, params);
     406        2554 : }

Generated by: LCOV version 1.14