12 #include "FEProblem.h"
13 #include "MooseMesh.h"
14 #include "libmesh/string_to_enum.h"
15 #include "Conversion.h"
16 #include "AddKernelAction.h"
17 #include "AddPostprocessorAction.h"
18 #include "AddBCAction.h"
24 InputParameters params = validParams<Action>();
25 params.addParam<std::string>(
28 "The name of the dictator user object that is created by this Action");
29 params.addClassDescription(
"Adds the PorousFlowDictator UserObject. This class also contains "
30 "many utility functions for adding other pieces of an input file, "
31 "which may be used by derived classes.");
32 params.addParam<RealVectorValue>(
"gravity",
33 RealVectorValue(0.0, 0.0, -10.0),
34 "Gravitational acceleration vector downwards (m/s^2)");
35 params.addCoupledVar(
"temperature",
37 "For isothermal simulations, this is the temperature "
38 "at which fluid properties (and stress-free strains) "
39 "are evaluated at. Otherwise, this is the name of "
40 "the temperature variable. Units = Kelvin");
41 params.addCoupledVar(
"mass_fraction_vars",
42 "List of variables that represent the mass fractions. Format is 'f_ph0^c0 "
43 "f_ph0^c1 f_ph0^c2 ... f_ph0^c(N-1) f_ph1^c0 f_ph1^c1 fph1^c2 ... "
44 "fph1^c(N-1) ... fphP^c0 f_phP^c1 fphP^c2 ... fphP^c(N-1)' where "
45 "N=num_components and P=num_phases, and it is assumed that "
46 "f_ph^cN=1-sum(f_ph^c,{c,0,N-1}) so that f_ph^cN need not be given. If no "
47 "variables are provided then num_phases=1=num_components.");
48 params.addParam<
unsigned int>(
"number_aqueous_equilibrium",
50 "The number of secondary species in the aqueous-equilibrium "
51 "reaction system. (Leave as zero if the simulation does not "
52 "involve chemistry)");
53 params.addParam<
unsigned int>(
"number_aqueous_kinetic",
55 "The number of secondary species in the aqueous-kinetic reaction "
56 "system involved in precipitation and dissolution. (Leave as zero "
57 "if the simulation does not involve chemistry)");
58 params.addParam<std::vector<VariableName>>(
60 "The name of the displacement variables (relevant only for "
61 "mechanically-coupled simulations)");
62 params.addParam<std::string>(
"thermal_eigenstrain_name",
63 "thermal_eigenstrain",
64 "The eigenstrain_name used in the "
65 "ComputeThermalExpansionEigenstrain. Only needed for "
66 "thermally-coupled simulations with thermal expansion.");
67 params.addParam<
bool>(
68 "use_displaced_mesh",
false,
"Use displaced mesh computations in mechanical kernels");
69 MooseEnum flux_limiter_type(
"MinMod VanLeer MC superbee None",
"VanLeer");
70 params.addParam<MooseEnum>(
73 "Type of flux limiter to use if stabilization=KT. 'None' means that no antidiffusion "
74 "will be added in the Kuzmin-Turek scheme");
75 MooseEnum stabilization(
"Full KT",
"Full");
76 params.addParam<MooseEnum>(
"stabilization",
78 "Numerical stabilization used. 'Full' means full upwinding. 'KT' "
79 "means FEM-TVD stabilization of Kuzmin-Turek");
87 _dictator_name(getParam<std::string>(
"dictator_name")),
88 _num_aqueous_equilibrium(getParam<unsigned int>(
"number_aqueous_equilibrium")),
89 _num_aqueous_kinetic(getParam<unsigned int>(
"number_aqueous_kinetic")),
90 _gravity(getParam<RealVectorValue>(
"gravity")),
91 _mass_fraction_vars(getParam<std::vector<VariableName>>(
"mass_fraction_vars")),
92 _num_mass_fraction_vars(_mass_fraction_vars.size()),
93 _temperature_var(getParam<std::vector<VariableName>>(
"temperature")),
94 _displacements(getParam<std::vector<VariableName>>(
"displacements")),
95 _ndisp(_displacements.size()),
96 _coupled_displacements(_ndisp),
97 _flux_limiter_type(getParam<MooseEnum>(
"flux_limiter_type")),
101 for (
unsigned int i = 0; i <
_ndisp; ++i)
109 ? _factory.getValidParams(
"PorousFlowAdvectiveFluxCalculatorSaturated")
110 : emptyInputParameters());
121 const auto & all_subdomains = _problem->mesh().meshSubdomains();
122 if (all_subdomains.empty())
123 mooseError(
"No subdomains found");
124 _coord_system = _problem->getCoordSystem(*all_subdomains.begin());
125 for (
const auto & subdomain : all_subdomains)
128 "The PorousFlow Actions require all subdomains to have the same coordinate system.");
138 if (_current_task ==
"add_user_object")
141 if (_current_task ==
"add_aux_variable" || _current_task ==
"add_aux_kernel")
144 if (_current_task ==
"add_kernel")
147 if (_current_task ==
"add_material")
158 auto auxkernels = _awh.getActions<AddKernelAction>();
159 for (
auto & auxkernel : auxkernels)
163 auto postprocessors = _awh.getActions<AddPostprocessorAction>();
164 for (
auto & postprocessor : postprocessors)
168 auto bcs = _awh.getActions<AddBCAction>();
169 for (
auto & bc : bcs)
197 std::string phase_str = Moose::stringify(phase);
199 if (_current_task ==
"add_aux_variable")
201 auto var_params = _factory.getValidParams(
"MooseVariableConstMonomial");
202 _problem->addAuxVariable(
"MooseVariableConstMonomial",
"saturation" + phase_str, var_params);
205 if (_current_task ==
"add_aux_kernel")
207 std::string aux_kernel_type =
"MaterialStdVectorAux";
208 InputParameters params = _factory.getValidParams(aux_kernel_type);
210 std::string aux_kernel_name =
"PorousFlowActionBase_SaturationAux" + phase_str;
211 params.set<MaterialPropertyName>(
"property") =
"PorousFlow_saturation_qp";
212 params.set<
unsigned>(
"index") = phase;
213 params.set<AuxVariableName>(
"variable") =
"saturation" + phase_str;
214 params.set<ExecFlagEnum>(
"execute_on") = EXEC_TIMESTEP_END;
215 _problem->addAuxKernel(aux_kernel_type, aux_kernel_name, params);
222 if (_current_task ==
"add_aux_variable")
224 auto var_params = _factory.getValidParams(
"MooseVariableConstMonomial");
226 _problem->addAuxVariable(
"MooseVariableConstMonomial",
"darcy_vel_x", var_params);
227 _problem->addAuxVariable(
"MooseVariableConstMonomial",
"darcy_vel_y", var_params);
228 _problem->addAuxVariable(
"MooseVariableConstMonomial",
"darcy_vel_z", var_params);
231 if (_current_task ==
"add_aux_kernel")
233 std::string aux_kernel_type =
"PorousFlowDarcyVelocityComponent";
234 InputParameters params = _factory.getValidParams(aux_kernel_type);
236 params.set<RealVectorValue>(
"gravity") = gravity;
237 params.set<UserObjectName>(
"PorousFlowDictator") =
_dictator_name;
238 params.set<ExecFlagEnum>(
"execute_on") = EXEC_TIMESTEP_END;
240 std::string aux_kernel_name =
"PorousFlowActionBase_Darcy_x_Aux";
241 params.set<MooseEnum>(
"component") =
"x";
242 params.set<AuxVariableName>(
"variable") =
"darcy_vel_x";
243 _problem->addAuxKernel(aux_kernel_type, aux_kernel_name, params);
245 aux_kernel_name =
"PorousFlowActionBase_Darcy_y_Aux";
246 params.set<MooseEnum>(
"component") =
"y";
247 params.set<AuxVariableName>(
"variable") =
"darcy_vel_y";
248 _problem->addAuxKernel(aux_kernel_type, aux_kernel_name, params);
250 aux_kernel_name =
"PorousFlowActionBase_Darcy_z_Aux";
251 params.set<MooseEnum>(
"component") =
"z";
252 params.set<AuxVariableName>(
"variable") =
"darcy_vel_z";
253 _problem->addAuxKernel(aux_kernel_type, aux_kernel_name, params);
260 if (_current_task ==
"add_aux_variable")
262 auto var_params = _factory.getValidParams(
"MooseVariableConstMonomial");
263 _problem->addAuxVariable(
"MooseVariableConstMonomial",
"stress_xx", var_params);
264 _problem->addAuxVariable(
"MooseVariableConstMonomial",
"stress_xy", var_params);
265 _problem->addAuxVariable(
"MooseVariableConstMonomial",
"stress_xz", var_params);
266 _problem->addAuxVariable(
"MooseVariableConstMonomial",
"stress_yx", var_params);
267 _problem->addAuxVariable(
"MooseVariableConstMonomial",
"stress_yy", var_params);
268 _problem->addAuxVariable(
"MooseVariableConstMonomial",
"stress_yz", var_params);
269 _problem->addAuxVariable(
"MooseVariableConstMonomial",
"stress_zx", var_params);
270 _problem->addAuxVariable(
"MooseVariableConstMonomial",
"stress_zy", var_params);
271 _problem->addAuxVariable(
"MooseVariableConstMonomial",
"stress_zz", var_params);
274 if (_current_task ==
"add_aux_kernel")
276 std::string aux_kernel_type =
"RankTwoAux";
277 InputParameters params = _factory.getValidParams(aux_kernel_type);
279 params.set<MaterialPropertyName>(
"rank_two_tensor") =
"stress";
280 params.set<ExecFlagEnum>(
"execute_on") = EXEC_TIMESTEP_END;
282 std::string aux_kernel_name =
"PorousFlowAction_stress_xx";
283 params.set<AuxVariableName>(
"variable") =
"stress_xx";
284 params.set<
unsigned>(
"index_i") = 0;
285 params.set<
unsigned>(
"index_j") = 0;
286 _problem->addAuxKernel(aux_kernel_type, aux_kernel_name, params);
288 aux_kernel_name =
"PorousFlowAction_stress_xy";
289 params.set<AuxVariableName>(
"variable") =
"stress_xy";
290 params.set<
unsigned>(
"index_i") = 0;
291 params.set<
unsigned>(
"index_j") = 1;
292 _problem->addAuxKernel(aux_kernel_type, aux_kernel_name, params);
294 aux_kernel_name =
"PorousFlowAction_stress_xz";
295 params.set<AuxVariableName>(
"variable") =
"stress_xz";
296 params.set<
unsigned>(
"index_i") = 0;
297 params.set<
unsigned>(
"index_j") = 2;
298 _problem->addAuxKernel(aux_kernel_type, aux_kernel_name, params);
300 aux_kernel_name =
"PorousFlowAction_stress_yx";
301 params.set<AuxVariableName>(
"variable") =
"stress_yx";
302 params.set<
unsigned>(
"index_i") = 1;
303 params.set<
unsigned>(
"index_j") = 0;
304 _problem->addAuxKernel(aux_kernel_type, aux_kernel_name, params);
306 aux_kernel_name =
"PorousFlowAction_stress_yy";
307 params.set<AuxVariableName>(
"variable") =
"stress_yy";
308 params.set<
unsigned>(
"index_i") = 1;
309 params.set<
unsigned>(
"index_j") = 1;
310 _problem->addAuxKernel(aux_kernel_type, aux_kernel_name, params);
312 aux_kernel_name =
"PorousFlowAction_stress_yz";
313 params.set<AuxVariableName>(
"variable") =
"stress_yz";
314 params.set<
unsigned>(
"index_i") = 1;
315 params.set<
unsigned>(
"index_j") = 2;
316 _problem->addAuxKernel(aux_kernel_type, aux_kernel_name, params);
318 aux_kernel_name =
"PorousFlowAction_stress_zx";
319 params.set<AuxVariableName>(
"variable") =
"stress_zx";
320 params.set<
unsigned>(
"index_i") = 2;
321 params.set<
unsigned>(
"index_j") = 0;
322 _problem->addAuxKernel(aux_kernel_type, aux_kernel_name, params);
324 aux_kernel_name =
"PorousFlowAction_stress_zy";
325 params.set<AuxVariableName>(
"variable") =
"stress_zy";
326 params.set<
unsigned>(
"index_i") = 2;
327 params.set<
unsigned>(
"index_j") = 1;
328 _problem->addAuxKernel(aux_kernel_type, aux_kernel_name, params);
330 aux_kernel_name =
"PorousFlowAction_stress_zz";
331 params.set<AuxVariableName>(
"variable") =
"stress_zz";
332 params.set<
unsigned>(
"index_i") = 2;
333 params.set<
unsigned>(
"index_j") = 2;
334 _problem->addAuxKernel(aux_kernel_type, aux_kernel_name, params);
341 if (_current_task ==
"add_material")
343 if (!parameters().hasDefaultCoupledValue(
"temperature"))
344 mooseError(
"Attempt to add a PorousFlowTemperature material without setting a temperature "
347 std::string material_type =
"PorousFlowTemperature";
348 InputParameters params = _factory.getValidParams(material_type);
350 params.applySpecificParameters(parameters(), {
"temperature"});
351 params.set<UserObjectName>(
"PorousFlowDictator") =
_dictator_name;
353 std::string material_name =
"PorousFlowActionBase_Temperature_qp";
355 material_name =
"PorousFlowActionBase_Temperature";
357 params.set<
bool>(
"at_nodes") = at_nodes;
358 _problem->addMaterial(material_type, material_name, params);
365 if (_current_task ==
"add_material")
367 if (!(parameters().hasDefaultCoupledValue(
"mass_fraction_vars") ||
368 parameters().hasCoupledValue(
"mass_fraction_vars")))
369 mooseError(
"Attempt to add a PorousFlowMassFraction material without setting the "
370 "mass_fraction_vars");
372 std::string material_type =
"PorousFlowMassFraction";
373 InputParameters params = _factory.getValidParams(material_type);
375 params.applySpecificParameters(parameters(), {
"mass_fraction_vars"});
376 params.set<UserObjectName>(
"PorousFlowDictator") =
_dictator_name;
378 std::string material_name =
"PorousFlowActionBase_MassFraction_qp";
380 material_name =
"PorousFlowActionBase_MassFraction";
382 params.set<
bool>(
"at_nodes") = at_nodes;
383 _problem->addMaterial(material_type, material_name, params);
390 if (_current_task ==
"add_material")
392 std::string material_type =
"PorousFlowEffectiveFluidPressure";
393 InputParameters params = _factory.getValidParams(material_type);
395 params.set<UserObjectName>(
"PorousFlowDictator") =
_dictator_name;
397 std::string material_name =
"PorousFlowUnsaturated_EffectiveFluidPressure_qp";
399 material_name =
"PorousFlowUnsaturated_EffectiveFluidPressure";
401 params.set<
bool>(
"at_nodes") = at_nodes;
402 _problem->addMaterial(material_type, material_name, params);
408 bool consistent_with_displaced_mesh)
410 if (_current_task ==
"add_material")
412 std::string material_type =
"PorousFlowVolumetricStrain";
413 InputParameters params = _factory.getValidParams(material_type);
415 std::string material_name =
"PorousFlowActionBase_VolumetricStrain";
416 params.set<UserObjectName>(
"PorousFlowDictator") =
_dictator_name;
417 params.set<std::vector<VariableName>>(
"displacements") = displacements;
418 params.set<
bool>(
"consistent_with_displaced_mesh") = consistent_with_displaced_mesh;
419 _problem->addMaterial(material_type, material_name, params);
426 bool compute_density_and_viscosity,
427 bool compute_internal_energy,
428 bool compute_enthalpy,
429 const UserObjectName &
fp)
431 if (_current_task ==
"add_material")
433 std::string material_type =
"PorousFlowSingleComponentFluid";
434 InputParameters params = _factory.getValidParams(material_type);
436 params.set<UserObjectName>(
"PorousFlowDictator") =
_dictator_name;
437 params.set<
unsigned int>(
"phase") = phase;
438 params.set<
bool>(
"compute_density_and_viscosity") = compute_density_and_viscosity;
439 params.set<
bool>(
"compute_internal_energy") = compute_internal_energy;
440 params.set<
bool>(
"compute_enthalpy") = compute_enthalpy;
441 params.set<UserObjectName>(
"fp") =
fp;
443 std::string material_name =
"PorousFlowActionBase_FluidProperties_qp";
445 material_name =
"PorousFlowActionBase_FluidProperties";
447 params.set<
bool>(
"at_nodes") = at_nodes;
448 _problem->addMaterial(material_type, material_name, params);
456 bool compute_density_and_viscosity,
457 bool compute_internal_energy,
458 bool compute_enthalpy)
460 if (_current_task ==
"add_material")
462 std::string material_type =
"PorousFlowBrine";
463 InputParameters params = _factory.getValidParams(material_type);
465 params.set<std::vector<VariableName>>(
"xnacl") = {nacl_brine};
466 params.set<UserObjectName>(
"PorousFlowDictator") =
_dictator_name;
467 params.set<
unsigned int>(
"phase") = phase;
468 params.set<
bool>(
"compute_density_and_viscosity") = compute_density_and_viscosity;
469 params.set<
bool>(
"compute_internal_energy") = compute_internal_energy;
470 params.set<
bool>(
"compute_enthalpy") = compute_enthalpy;
472 std::string material_name =
"PorousFlowActionBase_FluidProperties_qp";
474 material_name =
"PorousFlowActionBase_FluidProperties";
476 params.set<
bool>(
"at_nodes") = at_nodes;
477 _problem->addMaterial(material_type, material_name, params);
483 bool at_nodes,
unsigned phase, Real n, Real s_res, Real sum_s_res)
486 if (_current_task ==
"add_material")
488 std::string material_type =
"PorousFlowRelativePermeabilityCorey";
489 InputParameters params = _factory.getValidParams(material_type);
491 params.set<UserObjectName>(
"PorousFlowDictator") =
_dictator_name;
492 params.set<Real>(
"n") = n;
493 params.set<
unsigned int>(
"phase") = phase;
494 params.set<Real>(
"s_res") = s_res;
495 params.set<Real>(
"sum_s_res") = sum_s_res;
497 std::string material_name =
"PorousFlowActionBase_RelativePermeability_qp";
499 material_name =
"PorousFlowActionBase_RelativePermeability_nodal";
501 params.set<
bool>(
"at_nodes") = at_nodes;
502 _problem->addMaterial(material_type, material_name, params);
508 bool at_nodes,
unsigned phase, Real m, Real s_res, Real sum_s_res)
510 if (_current_task ==
"add_material")
512 std::string material_type =
"PorousFlowRelativePermeabilityFLAC";
513 InputParameters params = _factory.getValidParams(material_type);
515 params.set<UserObjectName>(
"PorousFlowDictator") =
_dictator_name;
516 params.set<Real>(
"m") = m;
517 params.set<
unsigned int>(
"phase") = phase;
518 params.set<Real>(
"s_res") = s_res;
519 params.set<Real>(
"sum_s_res") = sum_s_res;
521 std::string material_name =
"PorousFlowActionBase_RelativePermeability_qp";
523 material_name =
"PorousFlowActionBase_RelativePermeability_nodal";
525 params.set<
bool>(
"at_nodes") = at_nodes;
526 _problem->addMaterial(material_type, material_name, params);
533 if (_current_task ==
"add_user_object")
535 std::string userobject_type =
"PorousFlowCapillaryPressureVG";
536 InputParameters params = _factory.getValidParams(userobject_type);
537 params.set<Real>(
"m") = m;
538 params.set<Real>(
"alpha") = alpha;
539 _problem->addUserObject(userobject_type, userobject_name, params);
545 bool multiply_by_density,
546 std::string userobject_name)
550 const std::string userobject_type =
"PorousFlowAdvectiveFluxCalculatorSaturated";
551 InputParameters params = _factory.getValidParams(userobject_type);
553 params.set<RealVectorValue>(
"gravity") =
_gravity;
554 params.set<UserObjectName>(
"PorousFlowDictator") =
_dictator_name;
555 params.set<
unsigned>(
"phase") = phase;
556 params.set<
bool>(
"multiply_by_density") = multiply_by_density;
557 _problem->addUserObject(userobject_type, userobject_name, params);
563 bool multiply_by_density,
564 std::string userobject_name)
568 const std::string userobject_type =
"PorousFlowAdvectiveFluxCalculatorUnsaturated";
569 InputParameters params = _factory.getValidParams(userobject_type);
571 params.set<RealVectorValue>(
"gravity") =
_gravity;
572 params.set<UserObjectName>(
"PorousFlowDictator") =
_dictator_name;
573 params.set<
unsigned>(
"phase") = phase;
574 params.set<
bool>(
"multiply_by_density") = multiply_by_density;
575 _problem->addUserObject(userobject_type, userobject_name, params);
581 bool multiply_by_density,
582 std::string userobject_name)
586 const std::string userobject_type =
"PorousFlowAdvectiveFluxCalculatorSaturatedHeat";
587 InputParameters params = _factory.getValidParams(userobject_type);
589 params.set<RealVectorValue>(
"gravity") =
_gravity;
590 params.set<UserObjectName>(
"PorousFlowDictator") =
_dictator_name;
591 params.set<
unsigned>(
"phase") = phase;
592 params.set<
bool>(
"multiply_by_density") = multiply_by_density;
593 _problem->addUserObject(userobject_type, userobject_name, params);
599 bool multiply_by_density,
600 std::string userobject_name)
604 const std::string userobject_type =
"PorousFlowAdvectiveFluxCalculatorUnsaturatedHeat";
605 InputParameters params = _factory.getValidParams(userobject_type);
607 params.set<RealVectorValue>(
"gravity") =
_gravity;
608 params.set<UserObjectName>(
"PorousFlowDictator") =
_dictator_name;
609 params.set<
unsigned>(
"phase") = phase;
610 params.set<
bool>(
"multiply_by_density") = multiply_by_density;
611 _problem->addUserObject(userobject_type, userobject_name, params);
617 unsigned fluid_component,
618 bool multiply_by_density,
619 std::string userobject_name)
623 const std::string userobject_type =
"PorousFlowAdvectiveFluxCalculatorSaturatedMultiComponent";
624 InputParameters params = _factory.getValidParams(userobject_type);
626 params.set<RealVectorValue>(
"gravity") =
_gravity;
627 params.set<UserObjectName>(
"PorousFlowDictator") =
_dictator_name;
628 params.set<
unsigned>(
"phase") = phase;
629 params.set<
bool>(
"multiply_by_density") = multiply_by_density;
630 params.set<
unsigned>(
"fluid_component") = fluid_component;
631 _problem->addUserObject(userobject_type, userobject_name, params);
637 unsigned phase,
unsigned fluid_component,
bool multiply_by_density, std::string userobject_name)
641 const std::string userobject_type =
642 "PorousFlowAdvectiveFluxCalculatorUnsaturatedMultiComponent";
643 InputParameters params = _factory.getValidParams(userobject_type);
645 params.set<RealVectorValue>(
"gravity") =
_gravity;
646 params.set<UserObjectName>(
"PorousFlowDictator") =
_dictator_name;
647 params.set<
unsigned>(
"phase") = phase;
648 params.set<
bool>(
"multiply_by_density") = multiply_by_density;
649 params.set<
unsigned>(
"fluid_component") = fluid_component;
650 _problem->addUserObject(userobject_type, userobject_name, params);