Loading [MathJax]/extensions/tex2jax.js
https://mooseframework.inl.gov
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends
PorousFlow2PhasePP.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 
10 #include "PorousFlow2PhasePP.h"
12 
13 registerMooseObject("PorousFlowApp", PorousFlow2PhasePP);
15 
16 template <bool is_ad>
19 {
21  params.addRequiredCoupledVar("phase0_porepressure",
22  "Variable that is the porepressure of phase "
23  "0 (eg, the water phase). It will be <= "
24  "phase1_porepressure.");
25  params.addRequiredCoupledVar("phase1_porepressure",
26  "Variable that is the porepressure of phase 1 (eg, the gas phase)");
27  params.addRequiredParam<UserObjectName>("capillary_pressure",
28  "Name of the UserObject defining the capillary pressure");
29  params.addClassDescription("This Material calculates the 2 porepressures and the 2 saturations "
30  "in a 2-phase situation, and derivatives of these with "
31  "respect to the PorousFlowVariables");
32  return params;
33 }
34 
35 template <bool is_ad>
37  : PorousFlowVariableBaseTempl<is_ad>(parameters),
38 
39  _phase0_porepressure(_nodal_material
40  ? this->template coupledGenericDofValue<is_ad>("phase0_porepressure")
41  : this->template coupledGenericValue<is_ad>("phase0_porepressure")),
42  _phase0_gradp_qp(this->template coupledGenericGradient<is_ad>("phase0_porepressure")),
43  _phase0_porepressure_varnum(coupled("phase0_porepressure")),
44  _p0var(_dictator.isPorousFlowVariable(_phase0_porepressure_varnum)
45  ? _dictator.porousFlowVariableNum(_phase0_porepressure_varnum)
46  : 0),
47 
48  _phase1_porepressure(_nodal_material
49  ? this->template coupledGenericDofValue<is_ad>("phase1_porepressure")
50  : this->template coupledGenericValue<is_ad>("phase1_porepressure")),
51  _phase1_gradp_qp(this->template coupledGenericGradient<is_ad>("phase1_porepressure")),
52  _phase1_porepressure_varnum(coupled("phase1_porepressure")),
53  _p1var(_dictator.isPorousFlowVariable(_phase1_porepressure_varnum)
54  ? _dictator.porousFlowVariableNum(_phase1_porepressure_varnum)
55  : 0),
56  _pc_uo(this->template getUserObject<PorousFlowCapillaryPressure>("capillary_pressure"))
57 {
58  if (_num_phases != 2)
59  mooseError("The Dictator announces that the number of phases is ",
60  _dictator.numPhases(),
61  " whereas PorousFlow2PhasePP can only be used for 2-phase simulation. When you "
62  "have an efficient government, you have a dictatorship.");
63 }
64 
65 template <bool is_ad>
66 void
68 {
70  buildQpPPSS();
71 }
72 
73 template <bool is_ad>
74 void
76 {
77  // size stuff correctly and prepare the derivative matrices with zeroes
79 
80  const auto pc = buildQpPPSS();
81  const auto ds = _pc_uo.dSaturation(pc); // dS/d(pc)
82 
83  if (!_nodal_material)
84  {
85  (*_gradp_qp)[_qp][0] = _phase0_gradp_qp[_qp];
86  (*_gradp_qp)[_qp][1] = _phase1_gradp_qp[_qp];
87  (*_grads_qp)[_qp][0] = ds * ((*_gradp_qp)[_qp][0] - (*_gradp_qp)[_qp][1]);
88  (*_grads_qp)[_qp][1] = -(*_grads_qp)[_qp][0];
89  }
90 
91  // the derivatives of porepressure with respect to porepressure
92  // remain fixed (at unity) throughout the simulation
93  if constexpr (!is_ad)
94  {
95  if (_dictator.isPorousFlowVariable(_phase0_porepressure_varnum))
96  {
97  (*_dporepressure_dvar)[_qp][0][_p0var] = 1.0;
98  if (!_nodal_material)
99  (*_dgradp_qp_dgradv)[_qp][0][_p0var] = 1.0;
100  }
101 
102  if (_dictator.isPorousFlowVariable(_phase1_porepressure_varnum))
103  {
104  (*_dporepressure_dvar)[_qp][1][_p1var] = 1.0;
105  if (!_nodal_material)
106  (*_dgradp_qp_dgradv)[_qp][1][_p1var] = 1.0;
107  }
108 
109  if (_dictator.isPorousFlowVariable(_phase0_porepressure_varnum))
110  {
111  (*_dsaturation_dvar)[_qp][0][_p0var] = ds;
112  (*_dsaturation_dvar)[_qp][1][_p0var] = -ds;
113  }
114 
115  if (_dictator.isPorousFlowVariable(_phase1_porepressure_varnum))
116  {
117  (*_dsaturation_dvar)[_qp][0][_p1var] = -ds;
118  (*_dsaturation_dvar)[_qp][1][_p1var] = ds;
119  }
120 
121  if (!_nodal_material)
122  {
123  const auto d2s_qp = _pc_uo.d2Saturation(pc); // d^2(S_qp)/d(pc_qp)^2
124 
125  if (_dictator.isPorousFlowVariable(_phase0_porepressure_varnum))
126  {
127  (*_dgrads_qp_dgradv)[_qp][0][_p0var] = ds;
128  (*_dgrads_qp_dv)[_qp][0][_p0var] = d2s_qp * _phase0_gradp_qp[_qp] - _phase1_gradp_qp[_qp];
129  (*_dgrads_qp_dgradv)[_qp][1][_p0var] = -ds;
130  (*_dgrads_qp_dv)[_qp][1][_p0var] = -d2s_qp * _phase0_gradp_qp[_qp] - _phase1_gradp_qp[_qp];
131  }
132 
133  if (_dictator.isPorousFlowVariable(_phase1_porepressure_varnum))
134  {
135  (*_dgrads_qp_dgradv)[_qp][0][_p1var] = -ds;
136  (*_dgrads_qp_dv)[_qp][0][_p1var] = -d2s_qp * _phase0_gradp_qp[_qp] - _phase1_gradp_qp[_qp];
137  (*_dgrads_qp_dgradv)[_qp][1][_p1var] = ds;
138  (*_dgrads_qp_dv)[_qp][1][_p1var] = d2s_qp * _phase0_gradp_qp[_qp] - _phase1_gradp_qp[_qp];
139  }
140  }
141  }
142 }
143 
144 template <bool is_ad>
147 {
148  _porepressure[_qp][0] = _phase0_porepressure[_qp];
149  _porepressure[_qp][1] = _phase1_porepressure[_qp];
150 
151  const auto pc = _phase0_porepressure[_qp] - _phase1_porepressure[_qp]; // this is <= 0
152  const auto sat = _pc_uo.saturation(pc);
153  _saturation[_qp][0] = sat;
154  _saturation[_qp][1] = 1.0 - sat;
155 
156  return pc;
157 }
158 
159 template class PorousFlow2PhasePPTempl<false>;
160 template class PorousFlow2PhasePPTempl<true>;
virtual void computeQpProperties() override
virtual void initQpStatefulProperties() override
Moose::GenericType< Real, is_ad > GenericReal
void mooseError(Args &&... args)
static InputParameters validParams()
void addRequiredParam(const std::string &name, const std::string &doc_string)
Base class for capillary pressure for multiphase flow in porous media.
static InputParameters validParams()
GenericReal< is_ad > buildQpPPSS()
Assemble std::vectors of porepressure and saturation at the nodes and quadpoints, and return the capi...
Base class for thermophysical variable materials, which assemble materials for primary variables such...
registerMooseObject("PorousFlowApp", PorousFlow2PhasePP)
virtual void initQpStatefulProperties() override
void addRequiredCoupledVar(const std::string &name, const std::string &doc_string)
const unsigned int _num_phases
Number of phases.
void addClassDescription(const std::string &doc_string)
Material designed to calculate fluid phase porepressure and saturation for the two-phase situation as...
PorousFlow2PhasePPTempl(const InputParameters &parameters)
virtual void computeQpProperties() override