https://mooseframework.inl.gov
Public Types | Public Member Functions | Static Public Member Functions | Protected Attributes | List of all members
PorousFlowHysteresisOrder Class Reference

Computes the hysteresis order for use by the hysteretic capillary pressure and relative-permeability objects. More...

#include <PorousFlowHysteresisOrder.h>

Inheritance diagram for PorousFlowHysteresisOrder:
[legend]

Public Types

typedef DerivativeMaterialPropertyNameInterface::SymbolName SymbolName
 

Public Member Functions

 PorousFlowHysteresisOrder (const InputParameters &parameters)
 
virtual void initQpStatefulProperties () override
 
virtual void computeQpProperties () override
 
const GenericMaterialProperty< U, is_ad > & getDefaultMaterialProperty (const std::string &name)
 
const GenericMaterialProperty< U, is_ad > & getDefaultMaterialPropertyByName (const std::string &name)
 
void validateDerivativeMaterialPropertyBase (const std::string &base)
 
const MaterialPropertyName derivativePropertyName (const MaterialPropertyName &base, const std::vector< SymbolName > &c) const
 
const MaterialPropertyName derivativePropertyNameFirst (const MaterialPropertyName &base, const SymbolName &c1) const
 
const MaterialPropertyName derivativePropertyNameSecond (const MaterialPropertyName &base, const SymbolName &c1, const SymbolName &c2) const
 
const MaterialPropertyName derivativePropertyNameThird (const MaterialPropertyName &base, const SymbolName &c1, const SymbolName &c2, const SymbolName &c3) const
 
GenericMaterialProperty< U, is_ad > & declarePropertyDerivative (const std::string &base, const std::vector< VariableName > &c)
 
GenericMaterialProperty< U, is_ad > & declarePropertyDerivative (const std::string &base, const std::vector< SymbolName > &c)
 
GenericMaterialProperty< U, is_ad > & declarePropertyDerivative (const std::string &base, const SymbolName &c1, const SymbolName &c2="", const SymbolName &c3="")
 
GenericMaterialProperty< U, is_ad > & declarePropertyDerivative (const std::string &base, const std::vector< VariableName > &c)
 
GenericMaterialProperty< U, is_ad > & declarePropertyDerivative (const std::string &base, const std::vector< SymbolName > &c)
 
GenericMaterialProperty< U, is_ad > & declarePropertyDerivative (const std::string &base, const SymbolName &c1, const SymbolName &c2="", const SymbolName &c3="")
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivative (const std::string &base, const std::vector< VariableName > &c)
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivative (const std::string &base, const std::vector< SymbolName > &c)
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivative (const std::string &base, const SymbolName &c1, const SymbolName &c2="", const SymbolName &c3="")
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivative (const std::string &base, const SymbolName &c1, unsigned int v2, unsigned int v3=libMesh::invalid_uint)
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivative (const std::string &base, unsigned int v1, unsigned int v2=libMesh::invalid_uint, unsigned int v3=libMesh::invalid_uint)
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivative (const std::string &base, const std::vector< VariableName > &c)
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivative (const std::string &base, const std::vector< SymbolName > &c)
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivative (const std::string &base, const SymbolName &c1, const SymbolName &c2="", const SymbolName &c3="")
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivative (const std::string &base, const SymbolName &c1, unsigned int v2, unsigned int v3=libMesh::invalid_uint)
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivative (const std::string &base, unsigned int v1, unsigned int v2=libMesh::invalid_uint, unsigned int v3=libMesh::invalid_uint)
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivativeByName (const MaterialPropertyName &base, const std::vector< VariableName > &c)
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivativeByName (const MaterialPropertyName &base, const std::vector< SymbolName > &c)
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivativeByName (const MaterialPropertyName &base, const SymbolName &c1, const SymbolName &c2="", const SymbolName &c3="")
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivativeByName (const MaterialPropertyName &base, const std::vector< VariableName > &c)
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivativeByName (const MaterialPropertyName &base, const std::vector< SymbolName > &c)
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivativeByName (const MaterialPropertyName &base, const SymbolName &c1, const SymbolName &c2="", const SymbolName &c3="")
 
void validateCoupling (const MaterialPropertyName &base, const std::vector< VariableName > &c, bool validate_aux=true)
 
void validateCoupling (const MaterialPropertyName &base, const VariableName &c1="", const VariableName &c2="", const VariableName &c3="")
 
void validateCoupling (const MaterialPropertyName &base, const std::vector< VariableName > &c, bool validate_aux=true)
 
void validateCoupling (const MaterialPropertyName &base, const VariableName &c1="", const VariableName &c2="", const VariableName &c3="")
 
void validateNonlinearCoupling (const MaterialPropertyName &base, const VariableName &c1="", const VariableName &c2="", const VariableName &c3="")
 
void validateNonlinearCoupling (const MaterialPropertyName &base, const VariableName &c1="", const VariableName &c2="", const VariableName &c3="")
 
const MaterialPropertyName propertyName (const MaterialPropertyName &base, const std::vector< SymbolName > &c) const
 
const MaterialPropertyName propertyName (const MaterialPropertyName &base, const std::vector< SymbolName > &c) const
 
const MaterialPropertyName propertyNameFirst (const MaterialPropertyName &base, const SymbolName &c1) const
 
const MaterialPropertyName propertyNameFirst (const MaterialPropertyName &base, const SymbolName &c1) const
 
const MaterialPropertyName propertyNameSecond (const MaterialPropertyName &base, const SymbolName &c1, const SymbolName &c2) const
 
const MaterialPropertyName propertyNameSecond (const MaterialPropertyName &base, const SymbolName &c1, const SymbolName &c2) const
 
const MaterialPropertyName propertyNameThird (const MaterialPropertyName &base, const SymbolName &c1, const SymbolName &c2, const SymbolName &c3) const
 
const MaterialPropertyName propertyNameThird (const MaterialPropertyName &base, const SymbolName &c1, const SymbolName &c2, const SymbolName &c3) const
 

Static Public Member Functions

static InputParameters validParams ()
 

Protected Attributes

const unsigned _liquid_ph_num
 Liquid phase number. More...
 
const std::string _liquid_phase
 Stringified liquid phase number. More...
 
const unsigned _initial_order
 Initial order. More...
 
const std::vector< Real_previous_turning_points
 Previous turning points that were encountered prior to the simulation. More...
 
const MaterialProperty< std::vector< Real > > & _sat_old
 Old value of saturation. More...
 
const MaterialProperty< std::vector< Real > > & _sat_older
 Older value of saturation. More...
 
MaterialProperty< unsigned > & _hys_order
 Computed hysteresis order at the nodes or quadpoints. More...
 
const MaterialProperty< unsigned > & _hys_order_old
 Old value of hysteresis order at the nodes or quadpoints. More...
 
MaterialProperty< std::array< Real, PorousFlowConstants::MAX_HYSTERESIS_ORDER > > & _hys_sat_tps
 Recorded saturation values at the turning points. More...
 
const MaterialProperty< std::array< Real, PorousFlowConstants::MAX_HYSTERESIS_ORDER > > & _hys_sat_tps_old
 Old value of recorded saturation values at the turning points. More...
 

Detailed Description

Computes the hysteresis order for use by the hysteretic capillary pressure and relative-permeability objects.

Definition at line 20 of file PorousFlowHysteresisOrder.h.

Constructor & Destructor Documentation

◆ PorousFlowHysteresisOrder()

PorousFlowHysteresisOrder::PorousFlowHysteresisOrder ( const InputParameters parameters)

Definition at line 41 of file PorousFlowHysteresisOrder.C.

43  _liquid_ph_num(getParam<unsigned>("liquid_phase")),
45  _initial_order(getParam<unsigned>("initial_order")),
46  _previous_turning_points(getParam<std::vector<Real>>("previous_turning_points")),
47  _sat_old(_nodal_material
48  ? getMaterialPropertyOld<std::vector<Real>>("PorousFlow_saturation_nodal")
49  : getMaterialPropertyOld<std::vector<Real>>("PorousFlow_saturation_qp")),
50  _sat_older(_nodal_material
51  ? getMaterialPropertyOlder<std::vector<Real>>("PorousFlow_saturation_nodal")
52  : getMaterialPropertyOlder<std::vector<Real>>("PorousFlow_saturation_qp")),
53  _hys_order(_nodal_material ? declareProperty<unsigned>("PorousFlow_hysteresis_order_nodal")
54  : declareProperty<unsigned>("PorousFlow_hysteresis_order_qp")),
55  _hys_order_old(_nodal_material
56  ? getMaterialPropertyOld<unsigned>("PorousFlow_hysteresis_order_nodal")
57  : getMaterialPropertyOld<unsigned>("PorousFlow_hysteresis_order_qp")),
58  _hys_sat_tps(_nodal_material
59  ? declareProperty<std::array<Real, PorousFlowConstants::MAX_HYSTERESIS_ORDER>>(
60  "PorousFlow_hysteresis_saturation_tps_nodal")
61  : declareProperty<std::array<Real, PorousFlowConstants::MAX_HYSTERESIS_ORDER>>(
62  "PorousFlow_hysteresis_saturation_tps_qp")),
64  _nodal_material
65  ? getMaterialPropertyOld<std::array<Real, PorousFlowConstants::MAX_HYSTERESIS_ORDER>>(
66  "PorousFlow_hysteresis_saturation_tps_nodal")
67  : getMaterialPropertyOld<std::array<Real, PorousFlowConstants::MAX_HYSTERESIS_ORDER>>(
68  "PorousFlow_hysteresis_saturation_tps_qp"))
69 {
70  if (_liquid_ph_num >= _dictator.numPhases())
71  paramError("liquid_phase",
72  "The Dictator proclaims that the number of fluid phases is ",
73  _dictator.numPhases(),
74  " while you have foolishly entered ",
76  " for your liquid phase number. Remember that indexing starts at 0. Be aware that "
77  "the Dictator does not tolerate mistakes.");
79  paramError("initial_order",
80  "The initial order must be less than the max order, which is hard-coded to ",
83  paramError("previous_turning_points",
84  "initial_order is ",
86  " so there must be this many previous_turning_points");
87  for (const auto & tp : _previous_turning_points)
88  if (tp < 0.0 || tp > 1.0)
89  paramError("previous_turning_points",
90  "Each previous_turning_point must lie in the range [0.0, 1.0]");
91  // check that the previous_turning_points are ordered correctly
92  Real previous_tp = 1.0;
93  Real previous_jump = std::numeric_limits<Real>::max();
94  bool drying = true;
95  for (unsigned i = 0; i < _initial_order; ++i)
96  {
97  const Real this_jump = _previous_turning_points[i] - previous_tp;
98  if (drying)
99  {
100  if (this_jump >= 0)
101  paramError("previous_turning_points",
102  "The previous_turning_points vector, {a, b, c, ...}, must be obey the following "
103  "order: a < 1; b > a; a < c < b, etc");
104  }
105  else
106  {
107  if (this_jump <= 0)
108  paramError("previous_turning_points",
109  "The previous_turning_points vector, {a, b, c, ...}, must be obey the following "
110  "order: a < 1; b > a; a < c < b, etc");
111  }
112  if (std::abs(this_jump) >= previous_jump)
113  paramError("previous_turning_points",
114  "The previous_turning_points vector, {a, b, c, ...}, must be obey the following "
115  "order: a < 1; b > a; a < c < b, etc");
116  drying = !drying;
117  previous_tp = _previous_turning_points[i];
118  previous_jump = std::abs(this_jump);
119  }
120 }
const MaterialProperty< std::array< Real, PorousFlowConstants::MAX_HYSTERESIS_ORDER > > & _hys_sat_tps_old
Old value of recorded saturation values at the turning points.
MaterialProperty< std::array< Real, PorousFlowConstants::MAX_HYSTERESIS_ORDER > > & _hys_sat_tps
Recorded saturation values at the turning points.
MaterialProperty< unsigned > & _hys_order
Computed hysteresis order at the nodes or quadpoints.
const std::vector< Real > _previous_turning_points
Previous turning points that were encountered prior to the simulation.
constexpr unsigned MAX_HYSTERESIS_ORDER
const MaterialProperty< std::vector< Real > > & _sat_older
Older value of saturation.
std::string stringify(const T &t)
const MaterialProperty< std::vector< Real > > & _sat_old
Old value of saturation.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const unsigned _liquid_ph_num
Liquid phase number.
const MaterialProperty< unsigned > & _hys_order_old
Old value of hysteresis order at the nodes or quadpoints.
const std::string _liquid_phase
Stringified liquid phase number.
const unsigned _initial_order
Initial order.

Member Function Documentation

◆ computeQpProperties()

void PorousFlowHysteresisOrder::computeQpProperties ( )
overridevirtual

Definition at line 131 of file PorousFlowHysteresisOrder.C.

132 {
133  // NOTE to readers: the computed properties depend on old and older quantities only. Hence, it
134  // would be nice if we could compute them only at the start of each timestep instead of every
135  // nonlinear iteration
136 
137  // For finite elements involved in boundary-condition calculations, number of nodes > number of
138  // quadpoints. Material values on these elements are not computed during initial setup, which
139  // means that for timestep = 1, _sat_older.size() = number of quadpoints. Since
140  // computeQpProperties() is computed with 0 <= _qp < number of nodes (for nodal materials), this
141  // results in an out-of-bounds error on _sat_older. PorousFlow's implementation of hysteresis
142  // lags one timestep behind, and assumes that _sat_older = _sat_old at timestep = 1 anyway, so
143  // just use it:
144  const MaterialProperty<std::vector<Real>> & sat_older =
145  (_nodal_material && _sat_old.size() != _sat_older.size()) ? _sat_old : _sat_older;
146 
147  // whether saturation has been reducing ("drying" or "draining"):
148  const bool drying = (_hys_order_old[_qp] % 2 == 0);
149  // whether have been drying but are now increasing saturation ("wetting" or "imbibing"):
150  const bool dry2wet = drying && (_sat_old[_qp][_liquid_ph_num] > sat_older[_qp][_liquid_ph_num]);
151  // whether have been wetting but are now decreasing saturation:
152  const bool wet2dry = !drying && (_sat_old[_qp][_liquid_ph_num] < sat_older[_qp][_liquid_ph_num]);
153  if ((dry2wet || wet2dry) && _hys_order_old[_qp] < PorousFlowConstants::MAX_HYSTERESIS_ORDER)
154  {
155  _hys_order[_qp] = _hys_order_old[_qp] + 1;
156  _hys_sat_tps[_qp] = _hys_sat_tps_old[_qp];
157  _hys_sat_tps[_qp].at(_hys_order_old[_qp]) = sat_older[_qp][_liquid_ph_num];
158  }
159  else
160  {
161  // no change in wetting/drying direction
162  _hys_order[_qp] = _hys_order_old[_qp];
163  _hys_sat_tps[_qp] = _hys_sat_tps_old[_qp];
164  }
165  if (_sat_old[_qp][_liquid_ph_num] >= 1.0)
166  _hys_order[_qp] = 0; // assume the system gets back to the original drying curve
167 
168  // reduce order by 1 if _hys_order = max and saturation exceeds bounds of last turning-point
170  {
171  // the maxiumum-order curve is a drying curve, and the saturation exceeds the previous turning
172  // point:
173  const bool drying_and_high_sat =
174  (_hys_order[_qp] % 2 == 0) &&
175  (_sat_old[_qp][_liquid_ph_num] >= _hys_sat_tps[_qp].at(_hys_order[_qp] - 1));
176  // the maxiumum-order curve is a wetting curve, and the saturation is less than the previous
177  // turning point:
178  const bool wetting_and_low_sat =
179  (_hys_order[_qp] % 2 == 1) &&
180  (_sat_old[_qp][_liquid_ph_num] <= _hys_sat_tps[_qp].at(_hys_order[_qp] - 1));
181  if (drying_and_high_sat || wetting_and_low_sat)
182  _hys_order[_qp] -= 1;
183  }
184 
185  // reduce order by 2 if saturation exceeds the bounds of the second-to-last turning-point
186  // encountered
187  bool can_reduce_order = (_hys_order[_qp] > 1);
188  while (can_reduce_order)
189  {
190  can_reduce_order = false;
191  // are drying and the saturation is <= a previously-encountered turning point:
192  const bool drying_and_low_sat =
193  (_hys_order[_qp] % 2 == 0) &&
194  (_sat_old[_qp][_liquid_ph_num] <= _hys_sat_tps[_qp].at(_hys_order[_qp] - 2));
195  // are wetting and the saturation is >= a previously-encountered turning point:
196  const bool wetting_and_high_sat =
197  (_hys_order[_qp] % 2 == 1) &&
198  (_sat_old[_qp][_liquid_ph_num] >= _hys_sat_tps[_qp].at(_hys_order[_qp] - 2));
199  if (drying_and_low_sat || wetting_and_high_sat)
200  {
201  _hys_order[_qp] -= 2;
202  can_reduce_order = (_hys_order[_qp] > 1);
203  }
204  }
205 }
const MaterialProperty< std::array< Real, PorousFlowConstants::MAX_HYSTERESIS_ORDER > > & _hys_sat_tps_old
Old value of recorded saturation values at the turning points.
MaterialProperty< std::array< Real, PorousFlowConstants::MAX_HYSTERESIS_ORDER > > & _hys_sat_tps
Recorded saturation values at the turning points.
MaterialProperty< unsigned > & _hys_order
Computed hysteresis order at the nodes or quadpoints.
constexpr unsigned MAX_HYSTERESIS_ORDER
const MaterialProperty< std::vector< Real > > & _sat_older
Older value of saturation.
virtual unsigned int size() const override final
const MaterialProperty< std::vector< Real > > & _sat_old
Old value of saturation.
const unsigned _liquid_ph_num
Liquid phase number.
const MaterialProperty< unsigned > & _hys_order_old
Old value of hysteresis order at the nodes or quadpoints.

◆ initQpStatefulProperties()

void PorousFlowHysteresisOrder::initQpStatefulProperties ( )
overridevirtual

Definition at line 123 of file PorousFlowHysteresisOrder.C.

124 {
125  _hys_order[_qp] = _initial_order;
126  for (unsigned i = 0; i < _initial_order; ++i)
127  _hys_sat_tps[_qp].at(i) = _previous_turning_points[i];
128 }
MaterialProperty< std::array< Real, PorousFlowConstants::MAX_HYSTERESIS_ORDER > > & _hys_sat_tps
Recorded saturation values at the turning points.
MaterialProperty< unsigned > & _hys_order
Computed hysteresis order at the nodes or quadpoints.
const std::vector< Real > _previous_turning_points
Previous turning points that were encountered prior to the simulation.
const unsigned _initial_order
Initial order.

◆ validParams()

InputParameters PorousFlowHysteresisOrder::validParams ( )
static

Definition at line 16 of file PorousFlowHysteresisOrder.C.

17 {
19  params.addPrivateParam<std::string>("pf_material_type", "hysteresis_order");
20  params.addParam<unsigned>("liquid_phase", 0, "The phase number of the liquid phase");
21  params.addParam<unsigned>(
22  "initial_order",
23  0,
24  "The initial order. 0 means the simulation will begin on the primary drying curve. 1 means "
25  "the simulation will begin on the first-order wetting curve. 2 means the simulation will "
26  "begin on the second-order drying curve, etc.");
27  params.addParam<std::vector<Real>>(
28  "previous_turning_points",
29  std::vector<Real>(),
30  "The turning points (liquid saturation values) at occured prior to the simulation. There "
31  "must be exactly initial_order of these values. The first value is the liquid saturation at "
32  "the transition from primary-drying to first-order-wetting; the second value is the liquid "
33  "saturation at the transition from first-order-wetting to second-order-drying; and so on. "
34  "You must ensure that your initial saturation field is commensurate with the "
35  "previous_turning_points.");
36  params.addClassDescription("Computes hysteresis order for use in hysteretic capillary pressures "
37  "and relative permeabilities");
38  return params;
39 }
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addPrivateParam(const std::string &name, const T &value)
static InputParameters validParams()

Member Data Documentation

◆ _hys_order

MaterialProperty<unsigned>& PorousFlowHysteresisOrder::_hys_order
protected

Computed hysteresis order at the nodes or quadpoints.

Definition at line 50 of file PorousFlowHysteresisOrder.h.

Referenced by computeQpProperties(), and initQpStatefulProperties().

◆ _hys_order_old

const MaterialProperty<unsigned>& PorousFlowHysteresisOrder::_hys_order_old
protected

Old value of hysteresis order at the nodes or quadpoints.

Definition at line 53 of file PorousFlowHysteresisOrder.h.

Referenced by computeQpProperties().

◆ _hys_sat_tps

MaterialProperty<std::array<Real, PorousFlowConstants::MAX_HYSTERESIS_ORDER> >& PorousFlowHysteresisOrder::_hys_sat_tps
protected

Recorded saturation values at the turning points.

Definition at line 56 of file PorousFlowHysteresisOrder.h.

Referenced by computeQpProperties(), and initQpStatefulProperties().

◆ _hys_sat_tps_old

const MaterialProperty<std::array<Real, PorousFlowConstants::MAX_HYSTERESIS_ORDER> >& PorousFlowHysteresisOrder::_hys_sat_tps_old
protected

Old value of recorded saturation values at the turning points.

Definition at line 60 of file PorousFlowHysteresisOrder.h.

Referenced by computeQpProperties().

◆ _initial_order

const unsigned PorousFlowHysteresisOrder::_initial_order
protected

Initial order.

Definition at line 38 of file PorousFlowHysteresisOrder.h.

Referenced by initQpStatefulProperties(), and PorousFlowHysteresisOrder().

◆ _liquid_ph_num

const unsigned PorousFlowHysteresisOrder::_liquid_ph_num
protected

Liquid phase number.

Definition at line 32 of file PorousFlowHysteresisOrder.h.

Referenced by computeQpProperties(), and PorousFlowHysteresisOrder().

◆ _liquid_phase

const std::string PorousFlowHysteresisOrder::_liquid_phase
protected

Stringified liquid phase number.

Definition at line 35 of file PorousFlowHysteresisOrder.h.

◆ _previous_turning_points

const std::vector<Real> PorousFlowHysteresisOrder::_previous_turning_points
protected

Previous turning points that were encountered prior to the simulation.

Definition at line 41 of file PorousFlowHysteresisOrder.h.

Referenced by initQpStatefulProperties(), and PorousFlowHysteresisOrder().

◆ _sat_old

const MaterialProperty<std::vector<Real> >& PorousFlowHysteresisOrder::_sat_old
protected

Old value of saturation.

Definition at line 44 of file PorousFlowHysteresisOrder.h.

Referenced by computeQpProperties().

◆ _sat_older

const MaterialProperty<std::vector<Real> >& PorousFlowHysteresisOrder::_sat_older
protected

Older value of saturation.

Definition at line 47 of file PorousFlowHysteresisOrder.h.

Referenced by computeQpProperties().


The documentation for this class was generated from the following files: