https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
173void
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
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
203void
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
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
296void
307
308void
310{
312
313 // add Materials
314 if (_deps.dependsOn(_included_objects, "temperature_qp"))
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
382void
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 // Only couple if in the same nonlinear system
391 params.set<SolverSystemName>("solver_sys") =
392 _problem->getSystemBase(_problem->getSystem(_pp_var).name()).name();
393 if (_thermal &&
394 (_problem->getSystem(_temperature_var[0]).number() == _problem->getSystem(_pp_var).number()))
395 pf_vars.push_back(_temperature_var[0]);
396 if (_mechanical && _coupled_displacements.size() &&
397 (_problem->getSystem(_coupled_displacements[0]).number() ==
398 _problem->getSystem(_pp_var).number()))
399 pf_vars.insert(pf_vars.end(), _coupled_displacements.begin(), _coupled_displacements.end());
400 params.set<std::vector<VariableName>>("porous_flow_vars") = pf_vars;
401 params.set<unsigned int>("number_fluid_phases") = 1;
402 params.set<unsigned int>("number_fluid_components") = _num_mass_fraction_vars + 1;
403 params.set<unsigned int>("number_aqueous_equilibrium") = _num_aqueous_equilibrium;
404 params.set<unsigned int>("number_aqueous_kinetic") = _num_aqueous_kinetic;
405 _problem->addUserObject(uo_type, uo_name, params);
406}
std::shared_ptr< FEProblemBase > & _problem
bool dependsOn(const T &key, const T &value)
InputParameters getValidParams(const std::string &name) const
void addRequiredParam(const std::string &name, const std::string &doc_string)
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)
void addClassDescription(const std::string &doc_string)
T & set(const std::string &name, bool quiet_mode=false)
void addCoupledVar(const std::string &name, const std::string &doc_string)
bool isParamValid(const std::string &name) const
const InputParameters & parameters() const
const std::string & name() const
void paramError(const std::string &param, Args... args) const
void mooseError(Args &&... args) const
const T & getParam(const std::string &name) const
Factory & _factory
Base class for PorousFlow actions.
virtual void addKernels()
Add all Kernels.
Moose::CoordinateSystemType _coord_system
Coordinate system of the simulation (eg RZ, XYZ, etc)
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< VariableName > & _displacements
Displacement NonlinearVariable names (if any)
const unsigned _ndisp
Number of displacement variables supplied.
void addTemperatureMaterial(bool at_nodes)
Adds a nodal and a quadpoint Temperature material.
std::vector< SubdomainName > _subdomain_names
if this vector is not empty the variables, kernels and materials are restricted to these subdomains
static InputParameters validParams()
const bool _subdomain_names_set
indicates, if the vector of subdomain names is set (dont set block restrictions, if not)
const std::vector< VariableName > _mass_fraction_vars
Name of the mass-fraction variables (if any)
const unsigned int _num_aqueous_equilibrium
Number of aqueous-equilibrium secondary species.
const std::vector< VariableName > _temperature_var
Name of the temperature variable (if any)
bool _transient
Flag to denote if the simulation is transient.
const unsigned _num_mass_fraction_vars
Number of mass-fraction variables.
const std::string _dictator_name
The name of the PorousFlowDictator object to be added.
void addMassFractionMaterial(bool at_nodes)
Adds a nodal and a quadpoint MassFraction material.
std::vector< VariableName > _coupled_displacements
Displacement Variable names.
const bool _strain_at_nearest_qp
Evaluate strain at the nearest quadpoint for porosity that depends on strain.
const unsigned int _num_aqueous_kinetic
Number of aqeuous-kinetic secondary species that are involved in mineralisation.
void addEffectiveFluidPressureMaterial(bool at_nodes)
Adds a nodal and a quadpoint effective fluid pressure material.
void addStressAux()
Add AuxVariables and AuxKernels to compute effective stress.
void addDarcyAux(const RealVectorValue &gravity)
Add AuxVariables and AuxKernels to calculate Darcy velocity.
const RealVectorValue _gravity
Gravity.
virtual void addMaterials()
Add all Materials.
virtual void addMaterialDependencies()
Add all material dependencies so that the correct version of each material can be added.
std::vector< std::string > _included_objects
List of Kernels, AuxKernels, Materials, etc, that are added in this input file.
virtual void addAuxObjects()
Add all AuxVariables and AuxKernels.
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.
DependencyResolver< std::string > _deps
All dependencies of kernels, auxkernels, materials, etc, are stored in _dependencies.
const std::vector< AuxVariableName > _save_component_rate_in
Name of the variables (if any) that will record the fluid-components' rate of change.
CouplingTypeEnum
Determines the coupling type.
const MooseEnum _time_unit
Unit used for time.
const bool _add_darcy_aux
Add a AuxVariables to record Darcy velocity.
virtual void addAuxObjects() override
Add all AuxVariables and AuxKernels.
virtual void addDictator() override
Add the PorousFlowDictator object.
const MooseEnum _temperature_unit
Unit used for temperature.
enum PorousFlowSinglePhaseBase::FluidPropertiesTypeEnum _fluid_properties_type
VariableName _nacl_name
Name of the NaCl variable.
static InputParameters validParams()
const VariableName _pp_var
Porepressure NonlinearVariable name.
virtual void addKernels() override
Add all Kernels.
UserObjectName _fp
Name of the fluid-properties UserObject.
PorousFlowSinglePhaseBase(const InputParameters &params)
const std::string _base_name
base_name used in the TensorMechanics strain calculator
FluidPropertiesTypeEnum
Determines the fluid-properties type.
const Real _biot_coefficient
Fluid specific heat capacity at constant volume.
virtual void addMaterials() override
Add all Materials.
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.
const bool _add_stress_aux
Add AuxVariables for stress.
const bool _thermal
Flags to indicate whether thermal or mechanical effects are included.
std::string stringify(const T &t)