https://mooseframework.inl.gov
Loading...
Searching...
No Matches
PorousFlowFullySaturated.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
16registerMooseAction("PorousFlowApp", PorousFlowFullySaturated, "add_user_object");
17
18registerMooseAction("PorousFlowApp", PorousFlowFullySaturated, "add_kernel");
19
20registerMooseAction("PorousFlowApp", PorousFlowFullySaturated, "add_material");
21
22registerMooseAction("PorousFlowApp", PorousFlowFullySaturated, "add_aux_variable");
23
24registerMooseAction("PorousFlowApp", PorousFlowFullySaturated, "add_aux_kernel");
25
28{
30 params.addParam<bool>(
31 "multiply_by_density",
32 true,
33 "If true, then the Kernels for fluid flow are multiplied by "
34 "the fluid density. If false, this multiplication is not "
35 "performed, which means the problem becomes more linear, but care must be taken when using "
36 "other PorousFlow objects, since MOOSE will be computing volume fluxes, not mass fluxes.");
38 "Adds Kernels and fluid-property Materials necessary to simulate a "
39 "single-phase fully-saturated flow problem. Numerical stabilization options for the fluid "
40 "and heat flow are: no upwinding, full-upwinding or KT stabilization. No Kernels for "
41 "diffusion and dispersion of "
42 "fluid components are added. To run a simulation you will also "
43 "need to provide various other Materials for each mesh "
44 "block, depending on your simulation type, viz: permeability, "
45 "porosity, elasticity tensor, strain calculator, stress calculator, "
46 "matrix internal energy, thermal conductivity, diffusivity");
47 return params;
48}
49
51 : PorousFlowSinglePhaseBase(params), _multiply_by_density(getParam<bool>("multiply_by_density"))
52{
53}
54
55void
57{
59
60 // Add necessary objects to list of PorousFlow objects added by this action
62 _included_objects.push_back("PorousFlowFullySaturatedDarcyFlow");
64 _included_objects.push_back("PorousFlowFullySaturatedAdvectiveFlux");
66 _included_objects.push_back("PorousFlowFluxLimitedTVDAdvection");
67
68 if (_transient)
69 _included_objects.push_back("PorousFlowMassTimeDerivative");
70
72 _included_objects.push_back("PorousFlowMassVolumetricExpansion");
73
74 if (_thermal)
75 {
77 _included_objects.push_back("PorousFlowFullySaturatedHeatAdvection");
79 _included_objects.push_back("PorousFlowFullySaturatedUpwindHeatAdvection");
81 _included_objects.push_back("PorousFlowFluxLimitedTVDAdvection");
82 }
83
85 _included_objects.push_back("PorousFlowAdvectiveFluxCalculatorSaturatedHeat");
86
88 _included_objects.push_back("PorousFlowAdvectiveFluxCalculatorSaturatedMultiComponent");
89
91 _included_objects.push_back("PorousFlowAdvectiveFluxCalculatorSaturatedHeat");
92}
93
94void
96{
98
100 {
101 const std::string kernel_type = "PorousFlowFullySaturatedDarcyFlow";
102 InputParameters params = _factory.getValidParams(kernel_type);
103 params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
104 params.set<RealVectorValue>("gravity") = _gravity;
105 params.set<bool>("multiply_by_density") = _multiply_by_density;
106
107 for (unsigned i = 0; i < _num_mass_fraction_vars; ++i)
108 {
109 const std::string kernel_name = "PorousFlowFullySaturated_DarcyFlow" + Moose::stringify(i);
110 params.set<unsigned int>("fluid_component") = i;
111 params.set<NonlinearVariableName>("variable") = _mass_fraction_vars[i];
112 _problem->addKernel(kernel_type, kernel_name, params);
113 }
114
115 const std::string kernel_name =
116 "PorousFlowFullySaturated_DarcyFlow" + Moose::stringify(_num_mass_fraction_vars);
117 params.set<unsigned int>("fluid_component") = _num_mass_fraction_vars;
118 params.set<NonlinearVariableName>("variable") = _pp_var;
119 _problem->addKernel(kernel_type, kernel_name, params);
120 }
122 {
123 const std::string kernel_type = "PorousFlowFullySaturatedAdvectiveFlux";
124 InputParameters params = _factory.getValidParams(kernel_type);
125 params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
126 params.set<RealVectorValue>("gravity") = _gravity;
127 params.set<bool>("multiply_by_density") = _multiply_by_density;
128
129 for (unsigned i = 0; i < _num_mass_fraction_vars; ++i)
130 {
131 const std::string kernel_name =
132 "PorousFlowFullySaturated_AdvectiveFlux" + Moose::stringify(i);
133 params.set<unsigned int>("fluid_component") = i;
134 params.set<NonlinearVariableName>("variable") = _mass_fraction_vars[i];
135 _problem->addKernel(kernel_type, kernel_name, params);
136 }
137
138 const std::string kernel_name =
139 "PorousFlowFullySaturated_AdvectiveFlux" + Moose::stringify(_num_mass_fraction_vars);
140 params.set<unsigned int>("fluid_component") = _num_mass_fraction_vars;
141 params.set<NonlinearVariableName>("variable") = _pp_var;
142 _problem->addKernel(kernel_type, kernel_name, params);
143 }
145 {
146 const std::string kernel_type = "PorousFlowFluxLimitedTVDAdvection";
147 InputParameters params = _factory.getValidParams(kernel_type);
148 params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
149
150 for (unsigned i = 0; i < _num_mass_fraction_vars; ++i)
151 {
152 const std::string kernel_name = "PorousFlowFluxLimited_DarcyFlow" + Moose::stringify(i);
153 params.set<UserObjectName>("advective_flux_calculator") =
154 "PorousFlowFullySaturated_AC_" + Moose::stringify(i);
155 params.set<NonlinearVariableName>("variable") = _mass_fraction_vars[i];
156 _problem->addKernel(kernel_type, kernel_name, params);
157 }
158
159 const std::string kernel_name =
160 "PorousFlowFluxLimited_DarcyFlow" + Moose::stringify(_num_mass_fraction_vars);
161 params.set<NonlinearVariableName>("variable") = _pp_var;
162 params.set<UserObjectName>("advective_flux_calculator") =
163 "PorousFlowFullySaturated_AC_" + Moose::stringify(_num_mass_fraction_vars);
164 _problem->addKernel(kernel_type, kernel_name, params);
165 }
166
167 if (_transient)
168 {
169 std::string kernel_name = "PorousFlowFullySaturated_MassTimeDerivative";
170 std::string kernel_type = "PorousFlowMassTimeDerivative";
171 InputParameters params = _factory.getValidParams(kernel_type);
172 params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
173 params.set<bool>("multiply_by_density") = _multiply_by_density;
174 params.set<bool>("strain_at_nearest_qp") = _strain_at_nearest_qp;
175 if (!_base_name.empty())
176 params.set<std::string>("base_name") = _base_name;
177
178 for (unsigned i = 0; i < _num_mass_fraction_vars; ++i)
179 {
180 kernel_name = "PorousFlowFullySaturated_MassTimeDerivative" + Moose::stringify(i);
181 params.set<unsigned int>("fluid_component") = i;
182 params.set<NonlinearVariableName>("variable") = _mass_fraction_vars[i];
183 if (_save_component_rate_in.size() != 0)
184 params.set<std::vector<AuxVariableName>>("save_in") = {_save_component_rate_in[i]};
185 _problem->addKernel(kernel_type, kernel_name, params);
186 }
187
188 kernel_name =
189 "PorousFlowFullySaturated_MassTimeDerivative" + Moose::stringify(_num_mass_fraction_vars);
190 params.set<unsigned int>("fluid_component") = _num_mass_fraction_vars;
191 params.set<NonlinearVariableName>("variable") = _pp_var;
192 if (_save_component_rate_in.size() != 0)
193 params.set<std::vector<AuxVariableName>>("save_in") = {
195 _problem->addKernel(kernel_type, kernel_name, params);
196 }
197
198 if (_mechanical && _transient)
199 {
200 std::string kernel_name = "PorousFlowFullySaturated_MassVolumetricExpansion";
201 std::string kernel_type = "PorousFlowMassVolumetricExpansion";
202 InputParameters params = _factory.getValidParams(kernel_type);
203 params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
204 params.set<bool>("multiply_by_density") = _multiply_by_density;
205 params.set<bool>("strain_at_nearest_qp") = _strain_at_nearest_qp;
206
207 for (unsigned i = 0; i < _num_mass_fraction_vars; ++i)
208 {
209 kernel_name = "PorousFlowFullySaturated_MassVolumetricExpansion" + Moose::stringify(i);
210 params.set<unsigned>("fluid_component") = i;
211 params.set<NonlinearVariableName>("variable") = _mass_fraction_vars[i];
212 _problem->addKernel(kernel_type, kernel_name, params);
213 }
214
215 kernel_name = "PorousFlowFullySaturated_MassVolumetricExpansion" +
217 params.set<unsigned>("fluid_component") = _num_mass_fraction_vars;
218 params.set<NonlinearVariableName>("variable") = _pp_var;
219 _problem->addKernel(kernel_type, kernel_name, params);
220 }
221
222 if (_thermal)
223 {
225 {
226 std::string kernel_name = "PorousFlowFullySaturated_HeatAdvection";
227 std::string kernel_type = "PorousFlowFullySaturatedHeatAdvection";
228 InputParameters params = _factory.getValidParams(kernel_type);
229 params.set<NonlinearVariableName>("variable") = _temperature_var[0];
230 params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
231 params.set<RealVectorValue>("gravity") = _gravity;
232 params.set<bool>("multiply_by_density") = true;
233 _problem->addKernel(kernel_type, kernel_name, params);
234 }
236 {
237 std::string kernel_name = "PorousFlowFullySaturatedUpwind_HeatAdvection";
238 std::string kernel_type = "PorousFlowFullySaturatedUpwindHeatAdvection";
239 InputParameters params = _factory.getValidParams(kernel_type);
240 params.set<NonlinearVariableName>("variable") = _temperature_var[0];
241 params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
242 params.set<RealVectorValue>("gravity") = _gravity;
243 _problem->addKernel(kernel_type, kernel_name, params);
244 }
246 {
247 const std::string kernel_name = "PorousFlowFullySaturated_HeatAdvection";
248 const std::string kernel_type = "PorousFlowFluxLimitedTVDAdvection";
249 InputParameters params = _factory.getValidParams(kernel_type);
250 params.set<NonlinearVariableName>("variable") = _temperature_var[0];
251 params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
252 params.set<UserObjectName>("advective_flux_calculator") = "PorousFlowFullySaturatedHeat_AC";
253 _problem->addKernel(kernel_type, kernel_name, params);
254 }
255 }
256}
257
258void
260{
262
263 // add Advective Flux calculator UserObjects, if required
265 {
266 for (unsigned i = 0; i < _num_mass_fraction_vars; ++i)
267 {
268 const std::string userobject_name = "PorousFlowFullySaturated_AC_" + Moose::stringify(i);
270 0, i, _multiply_by_density, userobject_name);
271 }
272
273 const std::string userobject_name =
274 "PorousFlowFullySaturated_AC_" + Moose::stringify(_num_mass_fraction_vars);
275
278 0, _multiply_by_density, userobject_name); // 1 component only
279 else
281 0, _num_mass_fraction_vars, _multiply_by_density, userobject_name);
282
283 if (_thermal)
284 {
285 const std::string userobject_name = "PorousFlowFullySaturatedHeat_AC";
286 addAdvectiveFluxCalculatorSaturatedHeat(0, true, userobject_name);
287 }
288 }
289}
290
291void
293{
295
296 // add Materials
297 if (_deps.dependsOn(_included_objects, "pressure_saturation_qp"))
298 {
299 // saturation is always unity, so is trivially calculated using PorousFlow1PhaseFullySaturated
300 std::string material_type = "PorousFlow1PhaseFullySaturated";
301 std::string material_name = "PorousFlowFullySaturated_1PhaseP_qp";
302 InputParameters params = _factory.getValidParams(material_type);
304 params.set<std::vector<SubdomainName>>("block") = _subdomain_names;
305 params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
306 params.set<std::vector<VariableName>>("porepressure") = {_pp_var};
307 params.set<bool>("at_nodes") = false;
308 _problem->addMaterial(material_type, material_name, params);
309 }
310
311 if (_deps.dependsOn(_included_objects, "pressure_saturation_nodal"))
312 {
313 std::string material_type = "PorousFlow1PhaseFullySaturated";
314 std::string material_name = "PorousFlowFullySaturated_1PhaseP";
315 InputParameters params = _factory.getValidParams(material_type);
317 params.set<std::vector<SubdomainName>>("block") = _subdomain_names;
318 params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
319 params.set<std::vector<VariableName>>("porepressure") = {_pp_var};
320 params.set<bool>("at_nodes") = true;
321 _problem->addMaterial(material_type, material_name, params);
322 }
323
324 if (_deps.dependsOn(_included_objects, "volumetric_strain_qp") ||
325 _deps.dependsOn(_included_objects, "volumetric_strain_nodal"))
327
328 // Relative permeability might be needed by Darcy-velocity Aux, so add a material
329 // setting kr=1
330 if (_deps.dependsOn(_included_objects, "relative_permeability_qp"))
331 addRelativePermeabilityConst(false, 0, 1.0);
332
333 // Some obects not added by this action might have a use_mobility = true param,
334 // which needs a nodal relative permeability
335 if (_deps.dependsOn(_included_objects, "relative_permeability_nodal"))
336 addRelativePermeabilityConst(true, 0, 1.0);
337}
registerMooseAction("PorousFlowApp", PorousFlowFullySaturated, "add_user_object")
std::shared_ptr< FEProblemBase > & _problem
bool dependsOn(const T &key, const T &value)
InputParameters getValidParams(const std::string &name) const
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)
Factory & _factory
enum PorousFlowActionBase::StabilizationEnum _stabilization
void addAdvectiveFluxCalculatorSaturatedHeat(unsigned phase, bool multiply_by_density, std::string userobject_name)
void addAdvectiveFluxCalculatorSaturated(unsigned phase, bool multiply_by_density, std::string userobject_name)
void addRelativePermeabilityConst(bool at_nodes, unsigned phase, Real kr)
Adds a relative-permeability Material of the constant variety (primarily to add kr = 1 in actions tha...
std::vector< SubdomainName > _subdomain_names
if this vector is not empty the variables, kernels and materials are restricted to these subdomains
void addAdvectiveFluxCalculatorSaturatedMultiComponent(unsigned phase, unsigned fluid_component, bool multiply_by_density, std::string userobject_name)
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 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.
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.
void addVolumetricStrainMaterial(const std::vector< VariableName > &displacements, const std::string &base_name)
Adds a quadpoint volumetric strain material.
const RealVectorValue _gravity
Gravity.
virtual void addUserObjects()
Add all other UserObjects.
std::vector< std::string > _included_objects
List of Kernels, AuxKernels, Materials, etc, that are added in this input file.
DependencyResolver< std::string > _deps
All dependencies of kernels, auxkernels, materials, etc, are stored in _dependencies.
Action for simulation involving a single phase fully saturated fluid.
static InputParameters validParams()
virtual void addMaterialDependencies() override
Add all material dependencies so that the correct version of each material can be added.
PorousFlowFullySaturated(const InputParameters &params)
virtual void addMaterials() override
Add all Materials.
virtual void addUserObjects() override
Add all other UserObjects.
virtual void addKernels() override
Add all Kernels.
Base class for actions involving a single fluid phase.
const std::vector< AuxVariableName > _save_component_rate_in
Name of the variables (if any) that will record the fluid-components' rate of change.
static InputParameters validParams()
const VariableName _pp_var
Porepressure NonlinearVariable name.
virtual void addKernels() override
Add all Kernels.
const std::string _base_name
base_name used in the TensorMechanics strain calculator
virtual void addMaterials() override
Add all Materials.
virtual void addMaterialDependencies() override
Add all material dependencies so that the correct version of each material can be added.
const bool _thermal
Flags to indicate whether thermal or mechanical effects are included.
std::string stringify(const T &t)