www.mooseframework.org
PorousFlowSinglePhaseBase.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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);
217  params.set<NonlinearVariableName>("variable") = _displacements[i];
218  params.set<std::vector<VariableName>>("displacements") = _coupled_displacements;
219  if (_thermal)
220  {
221  params.set<std::vector<VariableName>>("temperature") = _temperature_var;
222  if (parameters().isParamValid("eigenstrain_names"))
223  {
224  params.set<std::vector<MaterialPropertyName>>("eigenstrain_names") =
225  getParam<std::vector<MaterialPropertyName>>("eigenstrain_names");
226  }
227  }
228  params.set<unsigned>("component") = i;
229  params.set<bool>("use_displaced_mesh") = getParam<bool>("use_displaced_mesh");
230  _problem->addKernel(kernel_type, kernel_name, params);
231 
232  if (_gravity(i) != 0)
233  {
234  kernel_name = "PorousFlowUnsaturated_gravity" + Moose::stringify(i);
235  kernel_type = "Gravity";
236  params = _factory.getValidParams(kernel_type);
237  params.set<NonlinearVariableName>("variable") = _displacements[i];
238  params.set<Real>("value") = _gravity(i);
239  params.set<bool>("use_displaced_mesh") = getParam<bool>("use_displaced_mesh");
240  _problem->addKernel(kernel_type, kernel_name, params);
241  }
242 
243  kernel_name = "PorousFlowUnsaturated_EffStressCoupling" + Moose::stringify(i);
244  kernel_type = "PorousFlowEffectiveStressCoupling";
245  params = _factory.getValidParams(kernel_type);
246  params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
247  params.set<NonlinearVariableName>("variable") = _displacements[i];
248  params.set<Real>("biot_coefficient") = _biot_coefficient;
249  params.set<unsigned>("component") = i;
250  params.set<bool>("use_displaced_mesh") = getParam<bool>("use_displaced_mesh");
251  _problem->addKernel(kernel_type, kernel_name, params);
252  }
253  }
254 
255  if (_thermal)
256  {
257  std::string kernel_name = "PorousFlowUnsaturated_HeatConduction";
258  std::string kernel_type = "PorousFlowHeatConduction";
259  InputParameters params = _factory.getValidParams(kernel_type);
260  params.set<NonlinearVariableName>("variable") = _temperature_var[0];
261  params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
262  _problem->addKernel(kernel_type, kernel_name, params);
263 
264  if (_transient)
265  {
266  kernel_name = "PorousFlowUnsaturated_EnergyTimeDerivative";
267  kernel_type = "PorousFlowEnergyTimeDerivative";
268  params = _factory.getValidParams(kernel_type);
269  params.set<NonlinearVariableName>("variable") = _temperature_var[0];
270  params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
271  params.set<bool>("strain_at_nearest_qp") = _strain_at_nearest_qp;
272  if (!_base_name.empty())
273  params.set<std::string>("base_name") = _base_name;
274  _problem->addKernel(kernel_type, kernel_name, params);
275  }
276  }
277 
278  if (_thermal && _mechanical && _transient)
279  {
280  std::string kernel_name = "PorousFlowUnsaturated_HeatVolumetricExpansion";
281  std::string kernel_type = "PorousFlowHeatVolumetricExpansion";
282  InputParameters params = _factory.getValidParams(kernel_type);
283  params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
284  params.set<NonlinearVariableName>("variable") = _temperature_var[0];
285  params.set<bool>("strain_at_nearest_qp") = _strain_at_nearest_qp;
286  _problem->addKernel(kernel_type, kernel_name, params);
287  }
288 }
289 
290 void
292 {
294 
295  if (_add_darcy_aux)
297 
299  addStressAux();
300 }
301 
302 void
304 {
306 
307  // add Materials
308  if (_deps.dependsOn(_included_objects, "temperature_qp"))
309  addTemperatureMaterial(false);
310 
311  if (_deps.dependsOn(_included_objects, "temperature_nodal"))
313 
314  if (_deps.dependsOn(_included_objects, "mass_fraction_qp"))
316 
317  if (_deps.dependsOn(_included_objects, "mass_fraction_nodal"))
319 
320  const bool compute_rho_mu_qp = _deps.dependsOn(_included_objects, "density_qp") ||
321  _deps.dependsOn(_included_objects, "viscosity_qp");
322  const bool compute_e_qp = _deps.dependsOn(_included_objects, "internal_energy_qp");
323  const bool compute_h_qp = _deps.dependsOn(_included_objects, "enthalpy_qp");
324 
325  if (compute_rho_mu_qp || compute_e_qp || compute_h_qp)
326  {
329  _nacl_name, false, 0, compute_rho_mu_qp, compute_e_qp, compute_h_qp, _temperature_unit);
332  0,
333  compute_rho_mu_qp,
334  compute_e_qp,
335  compute_h_qp,
336  _fp,
339  _time_unit);
340  }
341 
342  const bool compute_rho_mu_nodal = _deps.dependsOn(_included_objects, "density_nodal") ||
343  _deps.dependsOn(_included_objects, "viscosity_nodal");
344  const bool compute_e_nodal = _deps.dependsOn(_included_objects, "internal_energy_nodal");
345  const bool compute_h_nodal = _deps.dependsOn(_included_objects, "enthalpy_nodal");
346 
347  if (compute_rho_mu_nodal || compute_e_nodal || compute_h_nodal)
348  {
351  true,
352  0,
353  compute_rho_mu_nodal,
354  compute_e_nodal,
355  compute_h_nodal,
359  0,
360  compute_rho_mu_nodal,
361  compute_e_nodal,
362  compute_h_nodal,
363  _fp,
366  _time_unit);
367  }
368 
369  if (_deps.dependsOn(_included_objects, "effective_pressure_qp"))
371 
372  if (_deps.dependsOn(_included_objects, "effective_pressure_nodal"))
374 }
375 
376 void
378 {
379  const std::string uo_name = _dictator_name;
380  const std::string uo_type = "PorousFlowDictator";
381  InputParameters params = _factory.getValidParams(uo_type);
382  std::vector<VariableName> pf_vars = _mass_fraction_vars;
383  pf_vars.push_back(_pp_var);
384  if (_thermal)
385  pf_vars.push_back(_temperature_var[0]);
386  if (_mechanical)
387  pf_vars.insert(pf_vars.end(), _coupled_displacements.begin(), _coupled_displacements.end());
388  params.set<std::vector<VariableName>>("porous_flow_vars") = pf_vars;
389  params.set<unsigned int>("number_fluid_phases") = 1;
390  params.set<unsigned int>("number_fluid_components") = _num_mass_fraction_vars + 1;
391  params.set<unsigned int>("number_aqueous_equilibrium") = _num_aqueous_equilibrium;
392  params.set<unsigned int>("number_aqueous_kinetic") = _num_aqueous_kinetic;
393  _problem->addUserObject(uo_type, uo_name, params);
394 }
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)
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.
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