www.mooseframework.org
PorousFlowFullySaturated.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 
16 registerMooseAction("PorousFlowApp", PorousFlowFullySaturated, "add_user_object");
17 
18 registerMooseAction("PorousFlowApp", PorousFlowFullySaturated, "add_kernel");
19 
20 registerMooseAction("PorousFlowApp", PorousFlowFullySaturated, "add_material");
21 
22 registerMooseAction("PorousFlowApp", PorousFlowFullySaturated, "add_aux_variable");
23 
24 registerMooseAction("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.");
37  params.addClassDescription(
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 
55 void
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 
71  if (_mechanical && _transient)
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 
94 void
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 
258 void
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 
276  if (_num_mass_fraction_vars == 0)
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 
291 void
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  InputParameters params = _factory.getValidParams(material_type);
302  std::string material_name = "PorousFlowFullySaturated_1PhaseP_qp";
303  params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
304  params.set<std::vector<VariableName>>("porepressure") = {_pp_var};
305  params.set<bool>("at_nodes") = false;
306  _problem->addMaterial(material_type, material_name, params);
307  }
308 
309  if (_deps.dependsOn(_included_objects, "pressure_saturation_nodal"))
310  {
311  std::string material_type = "PorousFlow1PhaseFullySaturated";
312  InputParameters params = _factory.getValidParams(material_type);
313  std::string material_name = "PorousFlowFullySaturated_1PhaseP";
314  params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
315  params.set<std::vector<VariableName>>("porepressure") = {_pp_var};
316  params.set<bool>("at_nodes") = true;
317  _problem->addMaterial(material_type, material_name, params);
318  }
319 
320  if (_deps.dependsOn(_included_objects, "volumetric_strain_qp") ||
321  _deps.dependsOn(_included_objects, "volumetric_strain_nodal"))
323 
324  // Relative permeability might be needed by Darcy-velocity Aux, so add a material
325  // setting kr=1
326  if (_deps.dependsOn(_included_objects, "relative_permeability_qp"))
327  addRelativePermeabilityConst(false, 0, 1.0);
328 
329  // Some obects not added by this action might have a use_mobility = true param,
330  // which needs a nodal relative permeability
331  if (_deps.dependsOn(_included_objects, "relative_permeability_nodal"))
332  addRelativePermeabilityConst(true, 0, 1.0);
333 }
static InputParameters validParams()
virtual void addKernels() override
Add all Kernels.
virtual void addMaterials() override
Add all Materials.
virtual void addUserObjects() override
Add all other UserObjects.
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
T & set(const std::string &name, bool quiet_mode=false)
InputParameters getValidParams(const std::string &name) const
bool dependsOn(const std::string &key, const std::string &value)
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...
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.
registerMooseAction("PorousFlowApp", PorousFlowFullySaturated, "add_user_object")
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 bool _thermal
Flags to indicate whether thermal or mechanical effects are included.
void addAdvectiveFluxCalculatorSaturated(unsigned phase, bool multiply_by_density, std::string userobject_name)
Factory & _factory
Action for simulation involving a single phase fully saturated fluid.
void addAdvectiveFluxCalculatorSaturatedMultiComponent(unsigned phase, unsigned fluid_component, bool multiply_by_density, std::string userobject_name)
Base class for actions involving a single fluid phase.
virtual void addKernels() override
Add all Kernels.
virtual void addMaterials() override
Add all Materials.
static InputParameters validParams()
std::string stringify(const T &t)
PorousFlowFullySaturated(const InputParameters &params)
const RealVectorValue _gravity
Gravity.
const std::vector< VariableName > _temperature_var
Name of the temperature variable (if any)
bool _transient
Flag to denote if the simulation is transient.
virtual void addMaterialDependencies() override
Add all material dependencies so that the correct version of each material can be added...
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.
void addVolumetricStrainMaterial(const std::vector< VariableName > &displacements, const std::string &base_name)
Adds a quadpoint volumetric strain material.
const unsigned _num_mass_fraction_vars
Number of mass-fraction variables.
void addClassDescription(const std::string &doc_string)
std::shared_ptr< FEProblemBase > & _problem
virtual void addMaterialDependencies() override
Add all material dependencies so that the correct version of each material can be added...
virtual void addUserObjects()
Add all other UserObjects.
void addAdvectiveFluxCalculatorSaturatedHeat(unsigned phase, bool multiply_by_density, std::string userobject_name)
const std::string _base_name
base_name used in the TensorMechanics strain calculator
enum PorousFlowActionBase::StabilizationEnum _stabilization
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.