https://mooseframework.inl.gov
PorousFlowSinglePhaseBase.C
Go to the documentation of this file.
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 
11 
12 #include "FEProblem.h"
13 #include "Conversion.h"
14 #include "libmesh/string_to_enum.h"
15 
18 {
20  params.addParam<bool>("add_darcy_aux", true, "Add AuxVariables that record Darcy velocity");
21  params.addParam<bool>("add_stress_aux", true, "Add AuxVariables that record effective stress");
22  params.addDeprecatedParam<bool>("use_brine",
23  false,
24  "Whether to use a PorousFlowBrine Material",
25  "This parameter should no longer be used. Instead use "
26  "fluid_properties_type = PorousFlowBrine");
27  params.addRequiredParam<VariableName>("porepressure", "The name of the porepressure variable");
28  MooseEnum coupling_type("Hydro ThermoHydro HydroMechanical ThermoHydroMechanical", "Hydro");
29  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  "PorousFlowSingleComponentFluid");
37  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  MooseEnum simulation_type_choice("steady transient", "transient");
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  params.addParam<UserObjectName>(
52  "fp",
53  "The name of the user object for fluid "
54  "properties. Only needed if fluid_properties_type = PorousFlowSingleComponentFluid");
55  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  params.addDeprecatedParam<unsigned>(
67  "nacl_index",
68  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  params.addParam<VariableName>(
73  "nacl_name",
74  "Name of the NaCl variable. Only required if fluid_properties_type = PorousFlowBrine");
75  params.addParam<Real>(
76  "biot_coefficient",
77  1.0,
78  "The Biot coefficient (relevant only for mechanically-coupled simulations)");
79  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  MooseEnum temp_unit_choice("Kelvin Celsius", "Kelvin");
88  params.addParam<MooseEnum>(
89  "temperature_unit", temp_unit_choice, "The unit of the temperature variable");
90  MooseEnum p_unit_choice("Pa MPa", "Pa");
91  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  MooseEnum time_unit_choice("seconds hours days years", "seconds");
98  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  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  params.addClassDescription("Base class for single-phase simulations");
108  return params;
109 }
110 
112  : PorousFlowActionBase(params),
113  _pp_var(getParam<VariableName>("porepressure")),
114  _coupling_type(getParam<MooseEnum>("coupling_type").getEnum<CouplingTypeEnum>()),
115  _thermal(_coupling_type == CouplingTypeEnum::ThermoHydro ||
116  _coupling_type == CouplingTypeEnum::ThermoHydroMechanical),
117  _mechanical(_coupling_type == CouplingTypeEnum::HydroMechanical ||
118  _coupling_type == CouplingTypeEnum::ThermoHydroMechanical),
119  _fluid_properties_type(
120  getParam<MooseEnum>("fluid_properties_type").getEnum<FluidPropertiesTypeEnum>()),
121  _biot_coefficient(getParam<Real>("biot_coefficient")),
122  _add_darcy_aux(getParam<bool>("add_darcy_aux")),
123  _add_stress_aux(getParam<bool>("add_stress_aux")),
124  _save_component_rate_in(getParam<std::vector<AuxVariableName>>("save_component_rate_in")),
125  _temperature_unit(getParam<MooseEnum>("temperature_unit")),
126  _pressure_unit(getParam<MooseEnum>("pressure_unit")),
127  _time_unit(getParam<MooseEnum>("time_unit")),
128  _base_name(isParamValid("base_name") ? getParam<std::string>("base_name") + "_" : "")
129 {
130  if (_thermal && _temperature_var.size() != 1)
131  mooseError("PorousFlowSinglePhaseBase: You need to specify a temperature variable to perform "
132  "non-isothermal simulations");
133 
135  {
136  if (params.isParamValid("nacl_name"))
137  paramError("nacl_name",
138  "PorousFlowSinglePhaseBase: You should not specify a nacl_name when "
139  "fluid_properties_type = PorousFlowSingleComponentFluid");
140  if (!params.isParamValid("fp"))
141  paramError("fp",
142  "PorousFlowSinglePhaseBase: You must specify fp when fluid_properties_type = "
143  "PorousFlowSingleComponentFluid");
144  _fp = getParam<UserObjectName>("fp");
145  }
146 
148  {
149  if (!params.isParamValid("nacl_name"))
150  paramError("nacl_name",
151  "PorousFlowSinglePhaseBase: You must specify nacl_name when "
152  "fluid_properties_type = PorousFlowBrine");
153  if (params.isParamValid("fp"))
154  paramError("fp",
155  "PorousFlowSinglePhaseBase: You should not specify fp when "
156  "fluid_properties_type = PorousFlowBrine");
157  if (_pressure_unit != "Pa")
158  paramError("pressure_unit",
159  "Must use pressure_unit = Pa for fluid_properties_type = PorousFlowBrine");
160  if (_time_unit != "seconds")
161  paramError("time_unit",
162  "Must use time_unit = seconds for fluid_properties_type = PorousFlowBrine");
163  _nacl_name = getParam<VariableName>("nacl_name");
164  }
165 
166  auto save_component_rate_in_size = _save_component_rate_in.size();
167  if (save_component_rate_in_size && save_component_rate_in_size != _num_mass_fraction_vars + 1)
168  paramError("save_component_rate_in",
169  "The number of save_component_rate_in variables must be the number of fluid "
170  "components + 1");
171 }
172 
173 void
175 {
177 
178  // Add necessary objects to list of PorousFlow objects added by this action
179  if (_mechanical)
180  {
181  _included_objects.push_back("StressDivergenceTensors");
182  _included_objects.push_back("Gravity");
183  _included_objects.push_back("PorousFlowEffectiveStressCoupling");
184  }
185 
186  if (_thermal)
187  {
188  _included_objects.push_back("PorousFlowHeatConduction");
189  if (_transient)
190  _included_objects.push_back("PorousFlowEnergyTimeDerivative");
191  }
192 
193  if (_thermal && _mechanical && _transient)
194  _included_objects.push_back("PorousFlowHeatVolumetricExpansion");
195 
196  if (_add_darcy_aux)
197  _included_objects.push_back("PorousFlowDarcyVelocityComponent");
198 
200  _included_objects.push_back("StressAux");
201 }
202 
203 void
205 {
207 
208  if (_mechanical)
209  {
210  for (unsigned i = 0; i < _ndisp; ++i)
211  {
212  std::string kernel_name = "PorousFlowUnsaturated_grad_stress" + Moose::stringify(i);
213  std::string kernel_type = "StressDivergenceTensors";
215  kernel_type = "StressDivergenceRZTensors";
216  InputParameters params = _factory.getValidParams(kernel_type);
218  params.set<std::vector<SubdomainName>>("block") = _subdomain_names;
219  params.set<NonlinearVariableName>("variable") = _displacements[i];
220  params.set<std::vector<VariableName>>("displacements") = _coupled_displacements;
221  if (_thermal)
222  {
223  params.set<std::vector<VariableName>>("temperature") = _temperature_var;
224  if (parameters().isParamValid("eigenstrain_names"))
225  {
226  params.set<std::vector<MaterialPropertyName>>("eigenstrain_names") =
227  getParam<std::vector<MaterialPropertyName>>("eigenstrain_names");
228  }
229  }
230  params.set<unsigned>("component") = i;
231  params.set<bool>("use_displaced_mesh") = getParam<bool>("use_displaced_mesh");
232  _problem->addKernel(kernel_type, kernel_name, params);
233 
234  if (_gravity(i) != 0)
235  {
236  kernel_name = "PorousFlowUnsaturated_gravity" + Moose::stringify(i);
237  kernel_type = "Gravity";
238  params = _factory.getValidParams(kernel_type);
240  params.set<std::vector<SubdomainName>>("block") = _subdomain_names;
241  params.set<NonlinearVariableName>("variable") = _displacements[i];
242  params.set<Real>("value") = _gravity(i);
243  params.set<bool>("use_displaced_mesh") = getParam<bool>("use_displaced_mesh");
244  _problem->addKernel(kernel_type, kernel_name, params);
245  }
246 
247  kernel_name = "PorousFlowUnsaturated_EffStressCoupling" + Moose::stringify(i);
248  kernel_type = "PorousFlowEffectiveStressCoupling";
249  params = _factory.getValidParams(kernel_type);
251  params.set<std::vector<SubdomainName>>("block") = _subdomain_names;
252  params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
253  params.set<NonlinearVariableName>("variable") = _displacements[i];
254  params.set<Real>("biot_coefficient") = _biot_coefficient;
255  params.set<unsigned>("component") = i;
256  params.set<bool>("use_displaced_mesh") = getParam<bool>("use_displaced_mesh");
257  _problem->addKernel(kernel_type, kernel_name, params);
258  }
259  }
260 
261  if (_thermal)
262  {
263  std::string kernel_name = "PorousFlowUnsaturated_HeatConduction";
264  std::string kernel_type = "PorousFlowHeatConduction";
265  InputParameters params = _factory.getValidParams(kernel_type);
266  params.set<NonlinearVariableName>("variable") = _temperature_var[0];
267  params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
268  _problem->addKernel(kernel_type, kernel_name, params);
269 
270  if (_transient)
271  {
272  kernel_name = "PorousFlowUnsaturated_EnergyTimeDerivative";
273  kernel_type = "PorousFlowEnergyTimeDerivative";
274  params = _factory.getValidParams(kernel_type);
275  params.set<NonlinearVariableName>("variable") = _temperature_var[0];
276  params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
277  params.set<bool>("strain_at_nearest_qp") = _strain_at_nearest_qp;
278  if (!_base_name.empty())
279  params.set<std::string>("base_name") = _base_name;
280  _problem->addKernel(kernel_type, kernel_name, params);
281  }
282  }
283 
284  if (_thermal && _mechanical && _transient)
285  {
286  std::string kernel_name = "PorousFlowUnsaturated_HeatVolumetricExpansion";
287  std::string kernel_type = "PorousFlowHeatVolumetricExpansion";
288  InputParameters params = _factory.getValidParams(kernel_type);
289  params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
290  params.set<NonlinearVariableName>("variable") = _temperature_var[0];
291  params.set<bool>("strain_at_nearest_qp") = _strain_at_nearest_qp;
292  _problem->addKernel(kernel_type, kernel_name, params);
293  }
294 }
295 
296 void
298 {
300 
301  if (_add_darcy_aux)
303 
305  addStressAux();
306 }
307 
308 void
310 {
312 
313  // add Materials
314  if (_deps.dependsOn(_included_objects, "temperature_qp"))
315  addTemperatureMaterial(false);
316 
317  if (_deps.dependsOn(_included_objects, "temperature_nodal"))
319 
320  if (_deps.dependsOn(_included_objects, "mass_fraction_qp"))
322 
323  if (_deps.dependsOn(_included_objects, "mass_fraction_nodal"))
325 
326  const bool compute_rho_mu_qp = _deps.dependsOn(_included_objects, "density_qp") ||
327  _deps.dependsOn(_included_objects, "viscosity_qp");
328  const bool compute_e_qp = _deps.dependsOn(_included_objects, "internal_energy_qp");
329  const bool compute_h_qp = _deps.dependsOn(_included_objects, "enthalpy_qp");
330 
331  if (compute_rho_mu_qp || compute_e_qp || compute_h_qp)
332  {
335  _nacl_name, false, 0, compute_rho_mu_qp, compute_e_qp, compute_h_qp, _temperature_unit);
338  0,
339  compute_rho_mu_qp,
340  compute_e_qp,
341  compute_h_qp,
342  _fp,
345  _time_unit);
346  }
347 
348  const bool compute_rho_mu_nodal = _deps.dependsOn(_included_objects, "density_nodal") ||
349  _deps.dependsOn(_included_objects, "viscosity_nodal");
350  const bool compute_e_nodal = _deps.dependsOn(_included_objects, "internal_energy_nodal");
351  const bool compute_h_nodal = _deps.dependsOn(_included_objects, "enthalpy_nodal");
352 
353  if (compute_rho_mu_nodal || compute_e_nodal || compute_h_nodal)
354  {
357  true,
358  0,
359  compute_rho_mu_nodal,
360  compute_e_nodal,
361  compute_h_nodal,
365  0,
366  compute_rho_mu_nodal,
367  compute_e_nodal,
368  compute_h_nodal,
369  _fp,
372  _time_unit);
373  }
374 
375  if (_deps.dependsOn(_included_objects, "effective_pressure_qp"))
377 
378  if (_deps.dependsOn(_included_objects, "effective_pressure_nodal"))
380 }
381 
382 void
384 {
385  const std::string uo_name = _dictator_name;
386  const std::string uo_type = "PorousFlowDictator";
387  InputParameters params = _factory.getValidParams(uo_type);
388  std::vector<VariableName> pf_vars = _mass_fraction_vars;
389  pf_vars.push_back(_pp_var);
390  if (_thermal)
391  pf_vars.push_back(_temperature_var[0]);
392  if (_mechanical)
393  pf_vars.insert(pf_vars.end(), _coupled_displacements.begin(), _coupled_displacements.end());
394  params.set<std::vector<VariableName>>("porous_flow_vars") = pf_vars;
395  params.set<unsigned int>("number_fluid_phases") = 1;
396  params.set<unsigned int>("number_fluid_components") = _num_mass_fraction_vars + 1;
397  params.set<unsigned int>("number_aqueous_equilibrium") = _num_aqueous_equilibrium;
398  params.set<unsigned int>("number_aqueous_kinetic") = _num_aqueous_kinetic;
399  _problem->addUserObject(uo_type, uo_name, params);
400 }
Moose::CoordinateSystemType _coord_system
Coordinate system of the simulation (eg RZ, XYZ, etc)
UserObjectName _fp
Name of the fluid-properties UserObject.
virtual void addKernels()
Add all Kernels.
FluidPropertiesTypeEnum
Determines the fluid-properties type.
void addStressAux()
Add AuxVariables and AuxKernels to compute effective stress.
virtual void addMaterials() override
Add all Materials.
void addDeprecatedParam(const std::string &name, const T &value, const std::string &doc_string, const std::string &deprecation_message)
const bool _subdomain_names_set
indicates, if the vector of subdomain names is set (dont set block restrictions, if not) ...
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
const Real _biot_coefficient
Fluid specific heat capacity at constant volume.
const bool _add_stress_aux
Add AuxVariables for stress.
T & set(const std::string &name, bool quiet_mode=false)
const MooseEnum _temperature_unit
Unit used for temperature.
void addEffectiveFluidPressureMaterial(bool at_nodes)
Adds a nodal and a quadpoint effective fluid pressure material.
InputParameters getValidParams(const std::string &name) const
bool dependsOn(const std::string &key, const std::string &value)
const VariableName _pp_var
Porepressure NonlinearVariable name.
std::vector< VariableName > _coupled_displacements
Displacement Variable names.
std::vector< std::string > _included_objects
List of Kernels, AuxKernels, Materials, etc, that are added in this input file.
virtual void addMaterials()
Add all Materials.
void addSingleComponentFluidMaterial(bool at_nodes, unsigned phase, bool compute_density_and_viscosity, bool compute_internal_energy, bool compute_enthalpy, const UserObjectName &fp, const MooseEnum &temperature_unit, const MooseEnum &pressure_unit, const MooseEnum &time_unit)
Adds a single-component fluid Material.
const std::vector< AuxVariableName > _save_component_rate_in
Name of the variables (if any) that will record the fluid-components&#39; rate of change.
const unsigned int _num_aqueous_kinetic
Number of aqeuous-kinetic secondary species that are involved in mineralisation.
void addRequiredParam(const std::string &name, const std::string &doc_string)
const bool _thermal
Flags to indicate whether thermal or mechanical effects are included.
VariableName _nacl_name
Name of the NaCl variable.
Factory & _factory
const bool _add_darcy_aux
Add a AuxVariables to record Darcy velocity.
std::vector< SubdomainName > _subdomain_names
if this vector is not empty the variables, kernels and materials are restricted to these subdomains ...
void addBrineMaterial(const VariableName xnacl, bool at_nodes, unsigned phase, bool compute_density_and_viscosity, bool compute_internal_energy, bool compute_enthalpy, const MooseEnum &temperature_unit)
Adds a brine fluid Material.
const unsigned _ndisp
Number of displacement variables supplied.
CouplingTypeEnum
Determines the coupling type.
static InputParameters validParams()
void addDarcyAux(const RealVectorValue &gravity)
Add AuxVariables and AuxKernels to calculate Darcy velocity.
Base class for PorousFlow actions.
const T & getParam(const std::string &name) const
const MooseEnum _time_unit
Unit used for time.
virtual void addKernels() override
Add all Kernels.
void paramError(const std::string &param, Args... args) const
static InputParameters validParams()
std::string stringify(const T &t)
void addTemperatureMaterial(bool at_nodes)
Adds a nodal and a quadpoint Temperature material.
const RealVectorValue _gravity
Gravity.
void addMassFractionMaterial(bool at_nodes)
Adds a nodal and a quadpoint MassFraction material.
void addCoupledVar(const std::string &name, const std::string &doc_string)
const std::vector< VariableName > _temperature_var
Name of the temperature variable (if any)
bool _transient
Flag to denote if the simulation is transient.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
PorousFlowSinglePhaseBase(const InputParameters &params)
const MooseEnum _pressure_unit
Unit used for porepressure.
virtual void addMaterialDependencies() override
Add all material dependencies so that the correct version of each material can be added...
virtual void addAuxObjects() override
Add all AuxVariables and AuxKernels.
const std::string _dictator_name
The name of the PorousFlowDictator object to be added.
const bool _strain_at_nearest_qp
Evaluate strain at the nearest quadpoint for porosity that depends on strain.
virtual void addAuxObjects()
Add all AuxVariables and AuxKernels.
const unsigned _num_mass_fraction_vars
Number of mass-fraction variables.
void mooseError(Args &&... args) const
void addClassDescription(const std::string &doc_string)
std::shared_ptr< FEProblemBase > & _problem
const InputParameters & parameters() const
const std::vector< VariableName > & _displacements
Displacement NonlinearVariable names (if any)
virtual void addDictator() override
Add the PorousFlowDictator object.
enum PorousFlowSinglePhaseBase::FluidPropertiesTypeEnum _fluid_properties_type
const std::string _base_name
base_name used in the TensorMechanics strain calculator
virtual void addMaterialDependencies()
Add all material dependencies so that the correct version of each material can be added...
const unsigned int _num_aqueous_equilibrium
Number of aqueous-equilibrium secondary species.
const std::vector< VariableName > _mass_fraction_vars
Name of the mass-fraction variables (if any)
DependencyResolver< std::string > _deps
All dependencies of kernels, auxkernels, materials, etc, are stored in _dependencies.
bool isParamValid(const std::string &name) const