https://mooseframework.inl.gov
Loading...
Searching...
No Matches
PorousFlowHystereticInfo.C
Go to the documentation of this file.
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
11
13
16{
18 params.addCoupledVar("pc_var",
19 0,
20 "Variable that represents capillary pressure. Depending on info_required, "
21 "this may not be used to compute the info");
23 "sat_var",
24 "Variable that represent liquid saturation. This is always needed to "
25 "ensure the hysteretic order is computed correctly");
26 MooseEnum property_enum("pc sat sat_given_pc dS_dPc_err dPc_dS_err d2S_dPc2_err d2Pc_dS2_err",
27 "pc");
28 params.addParam<MooseEnum>(
29 "info_required",
30 property_enum,
31 "The type of information required. pc: capillary pressure given the saturation (pc_var is "
32 "not used in this case). sat: given the liquid saturation, compute the capillary pressure, "
33 "then invert the relationship to yield liquid saturation again (pc_var is not used in this "
34 "case). This is useful to understand the non-invertibility of the hysteretic relationships. "
35 " sat_given_pc: given the capillary pressure, compute the saturation. dS_dPc_err: relative "
36 "error in d(sat)/d(pc) calculation, ie (S(Pc + fd_eps) - S(Pc - fd_eps))/(2 * eps * S'(Pc)) "
37 "- 1, where S' is the coded derivative (Pc is computed from sat in this case: pc_var is not "
38 "used). This is useful for checking derivatives. dPc_dS_err: relative error in "
39 "d(pc)/d(sat) calculation, ie (Pc(S + fd_eps) - Pc(S - fd_eps)) / (2 * eps * Pc'(S)) - 1, "
40 "where Pc' is the coded derative (pc_var is not used in this case). d2S_dPc2_err: relative "
41 "error in d^2(sat)/d(pc)^2 (Pc is computed from sat in this case: pc_var is not used). "
42 "d2Pc_dS2_err: relative error in d^2(pc)/d(sat)^2.");
43 params.addParam<Real>(
44 "fd_eps",
45 1E-8,
46 "Small quantity used in computing the finite-difference approximations to derivatives");
48 "This Material computes capillary pressure or saturation, etc. It is primarily "
49 "of use when users desire to compute hysteretic quantities such as capillary pressure for "
50 "visualisation purposes. The "
51 "result is written into PorousFlow_hysteretic_info_nodal or "
52 "PorousFlow_hysteretic_info_qp (depending on the at_nodes flag). It "
53 "does not "
54 "compute porepressure and should not be used in simulations that employ "
55 "PorousFlow*PhaseHys* "
56 "Materials.");
57 return params;
58}
59
62 _pc(_nodal_material ? declareProperty<Real>("PorousFlow_hysteretic_capillary_pressure_nodal")
63 : declareProperty<Real>("PorousFlow_hysteretic_capillary_pressure_qp")),
64 _info(_nodal_material ? declareProperty<Real>("PorousFlow_hysteretic_info_nodal")
65 : declareProperty<Real>("PorousFlow_hysteretic_info_qp")),
66 _pc_val(nodalOrQpValue("pc_var")),
67 _sat_val(nodalOrQpValue("sat_var")),
68 _fd_eps(getParam<Real>("fd_eps")),
69 _info_enum(getParam<MooseEnum>("info_required").getEnum<InfoTypeEnum>())
70{
71 // note that _num_phases must be positive, otherwise get a problem with using
72 // PorousFlowHysteresisOrder, so _num_phases > 0 needn't be checked here
73}
74
75void
83
84void
92
93void
95{
96 switch (_info_enum)
97 {
100 break;
102 {
103 const Real pc = capillaryPressureQp(_sat_val[_qp]);
104 _info[_qp] = liquidSaturationQp(pc);
105 break;
106 }
108 _info[_qp] = liquidSaturationQp(_pc_val[_qp]);
109 break;
111 {
112 const Real pc = capillaryPressureQp(_sat_val[_qp]);
113 const Real fd =
116 break;
117 }
119 {
120 const Real fd = 0.5 *
123 _fd_eps;
125 break;
126 }
128 {
129 const Real pc = capillaryPressureQp(_sat_val[_qp]);
130 const Real fd =
133 break;
134 }
136 {
137 const Real fd = 0.5 *
140 _fd_eps;
142 break;
143 }
144 }
145}
146
147Real
148PorousFlowHystereticInfo::relativeError(Real finite_difference, Real hand_coded)
149{
150 if (finite_difference == 0.0 && hand_coded == 0.0)
151 return 0.0;
152 else if (finite_difference > 0.0 && hand_coded == 0.0)
153 return std::numeric_limits<Real>::max();
154 else if (finite_difference < 0.0 && hand_coded == 0.0)
155 return std::numeric_limits<Real>::min();
156 return finite_difference / hand_coded - 1.0;
157}
registerMooseObject("PorousFlowApp", PorousFlowHystereticInfo)
void addRequiredCoupledVar(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
void addCoupledVar(const std::string &name, const std::string &doc_string)
Base material designed to calculate and store quantities relevant for hysteretic capillary pressure c...
Material designed to calculate the capillary pressure as a function of saturation,...
const VariableValue & _sat_val
Nodal or quadpoint value of liquid saturation.
void computeQpInfo()
Fill _info with the required information.
const VariableValue & _pc_val
Nodal or quadpoint value of capillary pressure.
static InputParameters validParams()
Real relativeError(Real finite_difference, Real hand_coded)
Computes the relative error between a finite-difference approximation to the derivative and a hand-co...
MaterialProperty< Real > & _info
Computed nodal or quadpoint value: the meaning of this depends on info_enum.
virtual void computeQpProperties() override
MaterialProperty< Real > & _pc
Computed nodal or quadpoint value of capillary pressure (needed for hysteretic order computation)
InfoTypeEnum
Type of info required.
virtual void initQpStatefulProperties() override
PorousFlowHystereticInfo(const InputParameters &parameters)
enum PorousFlowHystereticInfo::InfoTypeEnum _info_enum
const Real _fd_eps
small parameter to use in the finite-difference approximations to the derivative
GenericMaterialProperty< std::vector< Real >, is_ad > & _saturation
Computed nodal or qp saturation of the phases.