www.mooseframework.org
Q2PAction.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 
10 #include "Q2PAction.h"
11 
12 #include "Factory.h"
13 #include "FEProblem.h"
14 #include "Parser.h"
15 #include "AddVariableAction.h"
16 #include "libmesh/string_to_enum.h"
17 
18 registerMooseAction("RichardsApp", Q2PAction, "add_kernel");
19 
20 registerMooseAction("RichardsApp", Q2PAction, "add_aux_variable");
21 
22 registerMooseAction("RichardsApp", Q2PAction, "add_function");
23 
24 registerMooseAction("RichardsApp", Q2PAction, "add_postprocessor");
25 
28 {
29  MooseEnum orders("CONSTANT FIRST SECOND THIRD FOURTH", "FIRST");
30 
32  params.addRequiredParam<NonlinearVariableName>("porepressure", "The porepressure variable");
33  params.addRequiredParam<NonlinearVariableName>("saturation", "The water saturation variable");
34  params.addRequiredParam<UserObjectName>(
35  "water_density",
36  "A RichardsDensity UserObject that defines the water density as a function of porepressure.");
37  params.addRequiredParam<UserObjectName>(
38  "water_relperm",
39  "A RichardsRelPerm UserObject that defines the water relative permeability "
40  "as a function of water saturation (eg RichardsRelPermPower).");
41  params.addParam<UserObjectName>(
42  "water_relperm_for_diffusion",
43  "A RichardsRelPerm UserObject that defines the water relative permeability as a function of "
44  "water saturation that will be used in the diffusivity Kernel (eg RichardsRelPermPower). If "
45  "not given, water_relperm will be used instead, which is the most common use-case.");
46  params.addRequiredParam<Real>("water_viscosity", "The water viscosity");
47  params.addRequiredParam<UserObjectName>(
48  "gas_density",
49  "A RichardsDensity UserObject that defines the gas density as a function of porepressure.");
50  params.addRequiredParam<UserObjectName>(
51  "gas_relperm",
52  "A RichardsRelPerm UserObject that defines the gas relative permeability as a "
53  "function of water saturation (eg Q2PRelPermPowerGas).");
54  params.addRequiredParam<Real>("gas_viscosity", "The gas viscosity");
55  params.addRequiredParam<Real>("diffusivity", "The diffusivity");
56  params.addParam<std::vector<OutputName>>("output_nodal_masses_to",
57  {},
58  "Output Nodal masses to this Output object. If you "
59  "don't want any outputs, don't input anything here");
60  params.addParam<std::vector<OutputName>>(
61  "output_total_masses_to",
62  {},
63  "Output total water and gas mass to this Output object. If you "
64  "don't want any outputs, don't input anything here");
65  params.addParam<bool>("save_gas_flux_in_Q2PGasFluxResidual",
66  false,
67  "Save the residual for the "
68  "Q2PPorepressureFlux into "
69  "the AuxVariable called "
70  "Q2PGasFluxResidual");
71  params.addParam<bool>("save_water_flux_in_Q2PWaterFluxResidual",
72  false,
73  "Save the residual for the Q2PSaturationFlux into the AuxVariable called "
74  "Q2PWaterFluxResidual");
75  params.addParam<bool>("save_gas_Jacobian_in_Q2PGasJacobian",
76  false,
77  "Save the diagonal component of the Q2PPorepressureFlux Jacobian into the "
78  "AuxVariable called Q2PGasJacobian");
79  params.addParam<bool>("save_water_Jacobian_in_Q2PWaterJacobian",
80  false,
81  "Save the diagonal component of the Q2PSaturationFlux Jacobian into the "
82  "AuxVariable called Q2PWaterJacobian");
83  params.addParam<MooseEnum>(
84  "ORDER",
85  orders,
86  "The order for the porepressure and saturation: " + orders.getRawNames() +
87  " (only needed if you're calculating masses)");
88  return params;
89 }
90 
92  : Action(params),
93  _pp_var(getParam<NonlinearVariableName>("porepressure")),
94  _sat_var(getParam<NonlinearVariableName>("saturation")),
95  _water_density(getParam<UserObjectName>("water_density")),
96  _water_relperm(getParam<UserObjectName>("water_relperm")),
97  _water_relperm_for_diffusivity(isParamValid("water_relperm_for_diffusivity")
98  ? getParam<UserObjectName>("water_relperm_for_diffusivity")
99  : getParam<UserObjectName>("water_relperm")),
100  _water_viscosity(getParam<Real>("water_viscosity")),
101  _gas_density(getParam<UserObjectName>("gas_density")),
102  _gas_relperm(getParam<UserObjectName>("gas_relperm")),
103  _gas_viscosity(getParam<Real>("gas_viscosity")),
104  _diffusivity(getParam<Real>("diffusivity")),
105  _output_nodal_masses_to(getParam<std::vector<OutputName>>("output_nodal_masses_to")),
106  _output_total_masses_to(getParam<std::vector<OutputName>>("output_total_masses_to")),
107  _save_gas_flux_in_Q2PGasFluxResidual(getParam<bool>("save_gas_flux_in_Q2PGasFluxResidual")),
108  _save_water_flux_in_Q2PWaterFluxResidual(
109  getParam<bool>("save_water_flux_in_Q2PWaterFluxResidual")),
110  _save_gas_Jacobian_in_Q2PGasJacobian(getParam<bool>("save_gas_Jacobian_in_Q2PGasJacobian")),
111  _save_water_Jacobian_in_Q2PWaterJacobian(
112  getParam<bool>("save_water_Jacobian_in_Q2PWaterJacobian"))
113 {
115  if (_output_nodal_masses_to.size() == 0)
117 
119  if (_output_total_masses_to.size() == 0)
121 
123 }
124 
125 void
127 {
128  // add the kernels
129  if (_current_task == "add_kernel")
130  {
131  std::string kernel_name;
132  std::string kernel_type;
133  InputParameters params = _factory.getValidParams("Q2PNodalMass");
134 
135  kernel_name = "Q2P_nodal_water_mass";
136  kernel_type = "Q2PNodalMass";
137  params = _factory.getValidParams(kernel_type);
138  params.set<NonlinearVariableName>("variable") = _sat_var;
139  params.set<std::vector<VariableName>>("other_var") = {_pp_var};
140  params.set<bool>("var_is_porepressure") = false;
142  params.set<std::vector<AuxVariableName>>("save_in") = {"Q2P_nodal_water_mass_divided_by_dt"};
143  params.set<UserObjectName>("fluid_density") = _water_density;
144  _problem->addKernel(kernel_type, kernel_name, params);
145 
146  kernel_name = "Q2P_nodal_gas_mass";
147  kernel_type = "Q2PNodalMass";
148  params = _factory.getValidParams(kernel_type);
149  params.set<NonlinearVariableName>("variable") = _pp_var;
150  params.set<std::vector<VariableName>>("other_var") = {_sat_var};
151  params.set<bool>("var_is_porepressure") = true;
153  params.set<std::vector<AuxVariableName>>("save_in") = {"Q2P_nodal_gas_mass_divided_by_dt"};
154  params.set<UserObjectName>("fluid_density") = _gas_density;
155  _problem->addKernel(kernel_type, kernel_name, params);
156 
157  kernel_name = "Q2P_nodal_water_mass_old";
158  kernel_type = "Q2PNegativeNodalMassOld";
159  params = _factory.getValidParams(kernel_type);
160  params.set<NonlinearVariableName>("variable") = _sat_var;
161  params.set<std::vector<VariableName>>("other_var") = {_pp_var};
162  params.set<bool>("var_is_porepressure") = false;
163  params.set<UserObjectName>("fluid_density") = _water_density;
164  _problem->addKernel(kernel_type, kernel_name, params);
165 
166  kernel_name = "Q2P_nodal_gas_mass_old";
167  kernel_type = "Q2PNegativeNodalMassOld";
168  params = _factory.getValidParams(kernel_type);
169  params.set<NonlinearVariableName>("variable") = _pp_var;
170  params.set<std::vector<VariableName>>("other_var") = {_sat_var};
171  params.set<bool>("var_is_porepressure") = true;
172  params.set<UserObjectName>("fluid_density") = _gas_density;
173  _problem->addKernel(kernel_type, kernel_name, params);
174 
175  kernel_name = "Q2P_water_flux";
176  kernel_type = "Q2PSaturationFlux";
177  params = _factory.getValidParams(kernel_type);
178  params.set<NonlinearVariableName>("variable") = _sat_var;
179  params.set<std::vector<VariableName>>("porepressure_variable") = {_pp_var};
180  params.set<UserObjectName>("fluid_density") = _water_density;
181  params.set<UserObjectName>("fluid_relperm") = _water_relperm;
182  params.set<Real>("fluid_viscosity") = _water_viscosity;
184  params.set<std::vector<AuxVariableName>>("save_in") = {"Q2PWaterFluxResidual"};
186  params.set<std::vector<AuxVariableName>>("diag_save_in") = {"Q2PWaterJacobian"};
187  _problem->addKernel(kernel_type, kernel_name, params);
188 
189  kernel_name = "Q2P_gas_flux";
190  kernel_type = "Q2PPorepressureFlux";
191  params = _factory.getValidParams(kernel_type);
192  params.set<NonlinearVariableName>("variable") = _pp_var;
193  params.set<std::vector<VariableName>>("saturation_variable") = {_sat_var};
194  params.set<UserObjectName>("fluid_density") = _gas_density;
195  params.set<UserObjectName>("fluid_relperm") = _gas_relperm;
196  params.set<Real>("fluid_viscosity") = _gas_viscosity;
198  params.set<std::vector<AuxVariableName>>("save_in") = {"Q2PGasFluxResidual"};
200  params.set<std::vector<AuxVariableName>>("diag_save_in") = {"Q2PGasJacobian"};
201  _problem->addKernel(kernel_type, kernel_name, params);
202 
203  kernel_name = "Q2P_liquid_diffusion";
204  kernel_type = "Q2PSaturationDiffusion";
205  params = _factory.getValidParams(kernel_type);
206  params.set<NonlinearVariableName>("variable") = _sat_var;
207  params.set<std::vector<VariableName>>("porepressure_variable") = {_pp_var};
208  params.set<UserObjectName>("fluid_density") = _water_density;
209  params.set<UserObjectName>("fluid_relperm") = _water_relperm_for_diffusivity;
210  params.set<Real>("fluid_viscosity") = _water_viscosity;
211  params.set<Real>("diffusivity") = _diffusivity;
212  _problem->addKernel(kernel_type, kernel_name, params);
213  }
214 
215  if (_current_task == "add_aux_variable")
216  {
217  FEType fe_type(Utility::string_to_enum<Order>(getParam<MooseEnum>("ORDER")),
218  Utility::string_to_enum<FEFamily>("LAGRANGE"));
219  auto type = AddVariableAction::variableType(fe_type);
220  auto var_params = _factory.getValidParams(type);
221  var_params.set<MooseEnum>("family") = "LAGRANGE";
222  var_params.set<MooseEnum>("order") = getParam<MooseEnum>("ORDER");
223 
225  {
226  // user wants nodal masses or total masses
227  _problem->addAuxVariable(type, "Q2P_nodal_water_mass_divided_by_dt", var_params);
228  _problem->addAuxVariable(type, "Q2P_nodal_gas_mass_divided_by_dt", var_params);
229  }
231  _problem->addAuxVariable(type, "Q2PGasFluxResidual", var_params);
233  _problem->addAuxVariable(type, "Q2PWaterFluxResidual", var_params);
235  _problem->addAuxVariable(type, "Q2PGasJacobian", var_params);
237  _problem->addAuxVariable(type, "Q2PWaterJacobian", var_params);
238  }
239 
240  if (_current_task == "add_function" && _output_total_masses_to.size() > 0)
241  {
242  // user wants total masses, so need to build Functions to do this
243  InputParameters params = _factory.getValidParams("ParsedFunction");
244 
245  params.set<std::string>("value") = "a*b";
246 
247  std::vector<std::string> vars;
248  vars.push_back("a");
249  vars.push_back("b");
250  params.set<std::vector<std::string>>("vars") = vars;
251 
252  std::vector<std::string> vals_water;
253  vals_water.push_back("Q2P_mass_water_divided_by_dt");
254  vals_water.push_back("Q2P_dt");
255  params.set<std::vector<std::string>>("vals") = vals_water;
256  _problem->addFunction("ParsedFunction", "Q2P_water_mass_fcn", params);
257 
258  std::vector<std::string> vals_gas;
259  vals_gas.push_back("Q2P_mass_gas_divided_by_dt");
260  vals_gas.push_back("Q2P_dt");
261  params.set<std::vector<std::string>>("vals") = vals_gas;
262  _problem->addFunction("ParsedFunction", "Q2P_gas_mass_fcn", params);
263  }
264 
265  if (_current_task == "add_postprocessor" && _output_total_masses_to.size() > 0)
266  {
267  // user wants total masses, so need to build Postprocessors to do this
268 
269  InputParameters params = _factory.getValidParams("TimestepSize");
270 
271  params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_BEGIN;
272  params.set<std::vector<OutputName>>("outputs") = {"none"};
273  _problem->addPostprocessor("TimestepSize", "Q2P_dt", params);
274 
275  params = _factory.getValidParams("NodalSum");
276  params.set<std::vector<OutputName>>("outputs") = {"none"};
277  params.set<std::vector<VariableName>>("variable") = {"Q2P_nodal_water_mass_divided_by_dt"};
278  _problem->addPostprocessor("NodalSum", "Q2P_mass_water_divided_by_dt", params);
279 
280  params = _factory.getValidParams("FunctionValuePostprocessor");
281  params.set<FunctionName>("function") = "Q2P_water_mass_fcn";
282  params.set<std::vector<OutputName>>("outputs") = _output_total_masses_to;
283  _problem->addPostprocessor("FunctionValuePostprocessor", "mass_water", params);
284 
285  params = _factory.getValidParams("NodalSum");
286  params.set<std::vector<OutputName>>("outputs") = {"none"};
287  params.set<std::vector<VariableName>>("variable") = {"Q2P_nodal_gas_mass_divided_by_dt"};
288  _problem->addPostprocessor("NodalSum", "Q2P_mass_gas_divided_by_dt", params);
289 
290  params = _factory.getValidParams("FunctionValuePostprocessor");
291  params.set<FunctionName>("function") = "Q2P_gas_mass_fcn";
292  params.set<std::vector<OutputName>>("outputs") = _output_total_masses_to;
293  _problem->addPostprocessor("FunctionValuePostprocessor", "mass_gas", params);
294  }
295 }
Real _diffusivity
Definition: Q2PAction.h:33
Real _gas_viscosity
Definition: Q2PAction.h:32
UserObjectName _water_density
Definition: Q2PAction.h:26
static std::string variableType(const FEType &fe_type, const bool is_fv=false, const bool is_array=false)
bool _total_masses_not_outputted
Definition: Q2PAction.h:41
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
std::vector< OutputName > _output_total_masses_to
Definition: Q2PAction.h:35
UserObjectName _water_relperm
Definition: Q2PAction.h:27
T & set(const std::string &name, bool quiet_mode=false)
InputParameters getValidParams(const std::string &name) const
registerMooseAction("RichardsApp", Q2PAction, "add_kernel")
std::vector< OutputName > _output_nodal_masses_to
Definition: Q2PAction.h:34
bool _save_gas_Jacobian_in_Q2PGasJacobian
Definition: Q2PAction.h:38
std::string getRawNames() const
void addRequiredParam(const std::string &name, const std::string &doc_string)
UserObjectName _water_relperm_for_diffusivity
Definition: Q2PAction.h:28
Factory & _factory
virtual void act()
Definition: Q2PAction.C:126
bool _save_water_Jacobian_in_Q2PWaterJacobian
Definition: Q2PAction.h:39
bool _save_water_flux_in_Q2PWaterFluxResidual
Definition: Q2PAction.h:37
static InputParameters validParams()
Definition: Q2PAction.C:27
Real _water_viscosity
Definition: Q2PAction.h:29
bool _save_gas_flux_in_Q2PGasFluxResidual
Definition: Q2PAction.h:36
static InputParameters validParams()
UserObjectName _gas_density
Definition: Q2PAction.h:30
const ExecFlagType EXEC_TIMESTEP_BEGIN
VariableName _pp_var
Definition: Q2PAction.h:24
VariableName _sat_var
Definition: Q2PAction.h:25
const std::string & type() const
const std::string & _current_task
bool _nodal_masses_not_outputted
Definition: Q2PAction.h:40
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Q2PAction(const InputParameters &params)
Definition: Q2PAction.C:91
std::shared_ptr< FEProblemBase > & _problem
bool _no_mass_calculations
Definition: Q2PAction.h:42
UserObjectName _gas_relperm
Definition: Q2PAction.h:31