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