Line data Source code
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 :
10 : #include "PorousFlowFullySaturated.h"
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 :
26 : InputParameters
27 2907 : PorousFlowFullySaturated::validParams()
28 : {
29 2907 : InputParameters params = PorousFlowSinglePhaseBase::validParams();
30 5814 : params.addParam<bool>(
31 : "multiply_by_density",
32 5814 : 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 2907 : 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 2907 : return params;
48 0 : }
49 :
50 2907 : PorousFlowFullySaturated::PorousFlowFullySaturated(const InputParameters & params)
51 5802 : : PorousFlowSinglePhaseBase(params), _multiply_by_density(getParam<bool>("multiply_by_density"))
52 : {
53 2895 : }
54 :
55 : void
56 2895 : PorousFlowFullySaturated::addMaterialDependencies()
57 : {
58 2895 : PorousFlowSinglePhaseBase::addMaterialDependencies();
59 :
60 : // Add necessary objects to list of PorousFlow objects added by this action
61 2895 : if (_stabilization == StabilizationEnum::None)
62 1630 : _included_objects.push_back("PorousFlowFullySaturatedDarcyFlow");
63 2080 : else if (_stabilization == StabilizationEnum::Full)
64 3670 : _included_objects.push_back("PorousFlowFullySaturatedAdvectiveFlux");
65 245 : else if (_stabilization == StabilizationEnum::KT)
66 490 : _included_objects.push_back("PorousFlowFluxLimitedTVDAdvection");
67 :
68 2895 : if (_transient)
69 5360 : _included_objects.push_back("PorousFlowMassTimeDerivative");
70 :
71 2895 : if (_mechanical && _transient)
72 1790 : _included_objects.push_back("PorousFlowMassVolumetricExpansion");
73 :
74 2895 : if (_thermal)
75 : {
76 1190 : if (_stabilization == StabilizationEnum::None)
77 760 : _included_objects.push_back("PorousFlowFullySaturatedHeatAdvection");
78 810 : else if (_stabilization == StabilizationEnum::Full)
79 1320 : _included_objects.push_back("PorousFlowFullySaturatedUpwindHeatAdvection");
80 150 : else if (_stabilization == StabilizationEnum::KT)
81 300 : _included_objects.push_back("PorousFlowFluxLimitedTVDAdvection");
82 : }
83 :
84 2895 : if (_stabilization == StabilizationEnum::KT && _thermal)
85 300 : _included_objects.push_back("PorousFlowAdvectiveFluxCalculatorSaturatedHeat");
86 :
87 2895 : if (_stabilization == StabilizationEnum::KT)
88 490 : _included_objects.push_back("PorousFlowAdvectiveFluxCalculatorSaturatedMultiComponent");
89 :
90 2895 : if (_stabilization == StabilizationEnum::KT && _thermal)
91 300 : _included_objects.push_back("PorousFlowAdvectiveFluxCalculatorSaturatedHeat");
92 2895 : }
93 :
94 : void
95 579 : PorousFlowFullySaturated::addKernels()
96 : {
97 579 : PorousFlowSinglePhaseBase::addKernels();
98 :
99 579 : if (_stabilization == StabilizationEnum::None)
100 : {
101 163 : const std::string kernel_type = "PorousFlowFullySaturatedDarcyFlow";
102 163 : InputParameters params = _factory.getValidParams(kernel_type);
103 326 : params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
104 163 : params.set<RealVectorValue>("gravity") = _gravity;
105 163 : params.set<bool>("multiply_by_density") = _multiply_by_density;
106 :
107 231 : for (unsigned i = 0; i < _num_mass_fraction_vars; ++i)
108 : {
109 68 : const std::string kernel_name = "PorousFlowFullySaturated_DarcyFlow" + Moose::stringify(i);
110 68 : params.set<unsigned int>("fluid_component") = i;
111 136 : params.set<NonlinearVariableName>("variable") = _mass_fraction_vars[i];
112 68 : _problem->addKernel(kernel_type, kernel_name, params);
113 : }
114 :
115 : const std::string kernel_name =
116 163 : "PorousFlowFullySaturated_DarcyFlow" + Moose::stringify(_num_mass_fraction_vars);
117 163 : params.set<unsigned int>("fluid_component") = _num_mass_fraction_vars;
118 326 : params.set<NonlinearVariableName>("variable") = _pp_var;
119 163 : _problem->addKernel(kernel_type, kernel_name, params);
120 163 : }
121 416 : else if (_stabilization == StabilizationEnum::Full)
122 : {
123 367 : const std::string kernel_type = "PorousFlowFullySaturatedAdvectiveFlux";
124 367 : InputParameters params = _factory.getValidParams(kernel_type);
125 734 : params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
126 367 : params.set<RealVectorValue>("gravity") = _gravity;
127 367 : params.set<bool>("multiply_by_density") = _multiply_by_density;
128 :
129 486 : for (unsigned i = 0; i < _num_mass_fraction_vars; ++i)
130 : {
131 : const std::string kernel_name =
132 119 : "PorousFlowFullySaturated_AdvectiveFlux" + Moose::stringify(i);
133 119 : params.set<unsigned int>("fluid_component") = i;
134 238 : params.set<NonlinearVariableName>("variable") = _mass_fraction_vars[i];
135 119 : _problem->addKernel(kernel_type, kernel_name, params);
136 : }
137 :
138 : const std::string kernel_name =
139 367 : "PorousFlowFullySaturated_AdvectiveFlux" + Moose::stringify(_num_mass_fraction_vars);
140 367 : params.set<unsigned int>("fluid_component") = _num_mass_fraction_vars;
141 734 : params.set<NonlinearVariableName>("variable") = _pp_var;
142 367 : _problem->addKernel(kernel_type, kernel_name, params);
143 367 : }
144 49 : else if (_stabilization == StabilizationEnum::KT)
145 : {
146 49 : const std::string kernel_type = "PorousFlowFluxLimitedTVDAdvection";
147 49 : InputParameters params = _factory.getValidParams(kernel_type);
148 98 : params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
149 :
150 68 : for (unsigned i = 0; i < _num_mass_fraction_vars; ++i)
151 : {
152 38 : const std::string kernel_name = "PorousFlowFluxLimited_DarcyFlow" + Moose::stringify(i);
153 38 : params.set<UserObjectName>("advective_flux_calculator") =
154 19 : "PorousFlowFullySaturated_AC_" + Moose::stringify(i);
155 38 : params.set<NonlinearVariableName>("variable") = _mass_fraction_vars[i];
156 19 : _problem->addKernel(kernel_type, kernel_name, params);
157 : }
158 :
159 : const std::string kernel_name =
160 49 : "PorousFlowFluxLimited_DarcyFlow" + Moose::stringify(_num_mass_fraction_vars);
161 98 : params.set<NonlinearVariableName>("variable") = _pp_var;
162 98 : params.set<UserObjectName>("advective_flux_calculator") =
163 49 : "PorousFlowFullySaturated_AC_" + Moose::stringify(_num_mass_fraction_vars);
164 49 : _problem->addKernel(kernel_type, kernel_name, params);
165 49 : }
166 :
167 579 : if (_transient)
168 : {
169 536 : std::string kernel_name = "PorousFlowFullySaturated_MassTimeDerivative";
170 536 : std::string kernel_type = "PorousFlowMassTimeDerivative";
171 536 : InputParameters params = _factory.getValidParams(kernel_type);
172 1072 : params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
173 536 : params.set<bool>("multiply_by_density") = _multiply_by_density;
174 536 : params.set<bool>("strain_at_nearest_qp") = _strain_at_nearest_qp;
175 536 : if (!_base_name.empty())
176 0 : params.set<std::string>("base_name") = _base_name;
177 :
178 718 : for (unsigned i = 0; i < _num_mass_fraction_vars; ++i)
179 : {
180 182 : kernel_name = "PorousFlowFullySaturated_MassTimeDerivative" + Moose::stringify(i);
181 182 : params.set<unsigned int>("fluid_component") = i;
182 364 : params.set<NonlinearVariableName>("variable") = _mass_fraction_vars[i];
183 182 : if (_save_component_rate_in.size() != 0)
184 0 : params.set<std::vector<AuxVariableName>>("save_in") = {_save_component_rate_in[i]};
185 182 : _problem->addKernel(kernel_type, kernel_name, params);
186 : }
187 :
188 : kernel_name =
189 536 : "PorousFlowFullySaturated_MassTimeDerivative" + Moose::stringify(_num_mass_fraction_vars);
190 536 : params.set<unsigned int>("fluid_component") = _num_mass_fraction_vars;
191 1072 : params.set<NonlinearVariableName>("variable") = _pp_var;
192 536 : if (_save_component_rate_in.size() != 0)
193 38 : params.set<std::vector<AuxVariableName>>("save_in") = {
194 76 : _save_component_rate_in[_num_mass_fraction_vars]};
195 536 : _problem->addKernel(kernel_type, kernel_name, params);
196 536 : }
197 :
198 579 : if (_mechanical && _transient)
199 : {
200 179 : std::string kernel_name = "PorousFlowFullySaturated_MassVolumetricExpansion";
201 179 : std::string kernel_type = "PorousFlowMassVolumetricExpansion";
202 179 : InputParameters params = _factory.getValidParams(kernel_type);
203 358 : params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
204 179 : params.set<bool>("multiply_by_density") = _multiply_by_density;
205 179 : params.set<bool>("strain_at_nearest_qp") = _strain_at_nearest_qp;
206 :
207 179 : for (unsigned i = 0; i < _num_mass_fraction_vars; ++i)
208 : {
209 0 : kernel_name = "PorousFlowFullySaturated_MassVolumetricExpansion" + Moose::stringify(i);
210 0 : params.set<unsigned>("fluid_component") = i;
211 0 : params.set<NonlinearVariableName>("variable") = _mass_fraction_vars[i];
212 0 : _problem->addKernel(kernel_type, kernel_name, params);
213 : }
214 :
215 179 : kernel_name = "PorousFlowFullySaturated_MassVolumetricExpansion" +
216 179 : Moose::stringify(_num_mass_fraction_vars);
217 179 : params.set<unsigned>("fluid_component") = _num_mass_fraction_vars;
218 358 : params.set<NonlinearVariableName>("variable") = _pp_var;
219 179 : _problem->addKernel(kernel_type, kernel_name, params);
220 179 : }
221 :
222 579 : if (_thermal)
223 : {
224 238 : if (_stabilization == StabilizationEnum::None)
225 : {
226 76 : std::string kernel_name = "PorousFlowFullySaturated_HeatAdvection";
227 76 : std::string kernel_type = "PorousFlowFullySaturatedHeatAdvection";
228 76 : InputParameters params = _factory.getValidParams(kernel_type);
229 152 : params.set<NonlinearVariableName>("variable") = _temperature_var[0];
230 152 : params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
231 76 : params.set<RealVectorValue>("gravity") = _gravity;
232 76 : params.set<bool>("multiply_by_density") = true;
233 76 : _problem->addKernel(kernel_type, kernel_name, params);
234 76 : }
235 162 : else if (_stabilization == StabilizationEnum::Full)
236 : {
237 132 : std::string kernel_name = "PorousFlowFullySaturatedUpwind_HeatAdvection";
238 132 : std::string kernel_type = "PorousFlowFullySaturatedUpwindHeatAdvection";
239 132 : InputParameters params = _factory.getValidParams(kernel_type);
240 264 : params.set<NonlinearVariableName>("variable") = _temperature_var[0];
241 264 : params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
242 132 : params.set<RealVectorValue>("gravity") = _gravity;
243 132 : _problem->addKernel(kernel_type, kernel_name, params);
244 132 : }
245 30 : else if (_stabilization == StabilizationEnum::KT)
246 : {
247 30 : const std::string kernel_name = "PorousFlowFullySaturated_HeatAdvection";
248 30 : const std::string kernel_type = "PorousFlowFluxLimitedTVDAdvection";
249 30 : InputParameters params = _factory.getValidParams(kernel_type);
250 60 : params.set<NonlinearVariableName>("variable") = _temperature_var[0];
251 60 : params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
252 60 : params.set<UserObjectName>("advective_flux_calculator") = "PorousFlowFullySaturatedHeat_AC";
253 30 : _problem->addKernel(kernel_type, kernel_name, params);
254 30 : }
255 : }
256 579 : }
257 :
258 : void
259 579 : PorousFlowFullySaturated::addUserObjects()
260 : {
261 579 : PorousFlowSinglePhaseBase::addUserObjects();
262 :
263 : // add Advective Flux calculator UserObjects, if required
264 579 : if (_stabilization == StabilizationEnum::KT)
265 : {
266 68 : for (unsigned i = 0; i < _num_mass_fraction_vars; ++i)
267 : {
268 19 : const std::string userobject_name = "PorousFlowFullySaturated_AC_" + Moose::stringify(i);
269 38 : addAdvectiveFluxCalculatorSaturatedMultiComponent(
270 19 : 0, i, _multiply_by_density, userobject_name);
271 : }
272 :
273 : const std::string userobject_name =
274 49 : "PorousFlowFullySaturated_AC_" + Moose::stringify(_num_mass_fraction_vars);
275 :
276 49 : if (_num_mass_fraction_vars == 0)
277 60 : addAdvectiveFluxCalculatorSaturated(
278 30 : 0, _multiply_by_density, userobject_name); // 1 component only
279 : else
280 38 : addAdvectiveFluxCalculatorSaturatedMultiComponent(
281 19 : 0, _num_mass_fraction_vars, _multiply_by_density, userobject_name);
282 :
283 49 : if (_thermal)
284 : {
285 30 : const std::string userobject_name = "PorousFlowFullySaturatedHeat_AC";
286 60 : addAdvectiveFluxCalculatorSaturatedHeat(0, true, userobject_name);
287 : }
288 : }
289 579 : }
290 :
291 : void
292 579 : PorousFlowFullySaturated::addMaterials()
293 : {
294 579 : PorousFlowSinglePhaseBase::addMaterials();
295 :
296 : // add Materials
297 1158 : if (_deps.dependsOn(_included_objects, "pressure_saturation_qp"))
298 : {
299 : // saturation is always unity, so is trivially calculated using PorousFlow1PhaseFullySaturated
300 579 : std::string material_type = "PorousFlow1PhaseFullySaturated";
301 579 : std::string material_name = "PorousFlowFullySaturated_1PhaseP_qp";
302 579 : InputParameters params = _factory.getValidParams(material_type);
303 579 : if (_subdomain_names_set)
304 266 : params.set<std::vector<SubdomainName>>("block") = _subdomain_names;
305 1158 : params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
306 1737 : params.set<std::vector<VariableName>>("porepressure") = {_pp_var};
307 579 : params.set<bool>("at_nodes") = false;
308 579 : _problem->addMaterial(material_type, material_name, params);
309 579 : }
310 :
311 1158 : if (_deps.dependsOn(_included_objects, "pressure_saturation_nodal"))
312 : {
313 579 : std::string material_type = "PorousFlow1PhaseFullySaturated";
314 579 : std::string material_name = "PorousFlowFullySaturated_1PhaseP";
315 579 : InputParameters params = _factory.getValidParams(material_type);
316 579 : if (_subdomain_names_set)
317 266 : params.set<std::vector<SubdomainName>>("block") = _subdomain_names;
318 1158 : params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
319 1737 : params.set<std::vector<VariableName>>("porepressure") = {_pp_var};
320 579 : params.set<bool>("at_nodes") = true;
321 579 : _problem->addMaterial(material_type, material_name, params);
322 579 : }
323 :
324 1158 : if (_deps.dependsOn(_included_objects, "volumetric_strain_qp") ||
325 979 : _deps.dependsOn(_included_objects, "volumetric_strain_nodal"))
326 179 : addVolumetricStrainMaterial(_coupled_displacements, _base_name);
327 :
328 : // Relative permeability might be needed by Darcy-velocity Aux, so add a material
329 : // setting kr=1
330 1158 : if (_deps.dependsOn(_included_objects, "relative_permeability_qp"))
331 442 : 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 1158 : if (_deps.dependsOn(_included_objects, "relative_permeability_nodal"))
336 167 : addRelativePermeabilityConst(true, 0, 1.0);
337 579 : }
|