Line data Source code
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 "PorousFlow2PhasePS.h" 11 : #include "PorousFlowCapillaryPressure.h" 12 : 13 : registerMooseObject("PorousFlowApp", PorousFlow2PhasePS); 14 : registerMooseObject("PorousFlowApp", ADPorousFlow2PhasePS); 15 : 16 : template <bool is_ad> 17 : InputParameters 18 5464 : PorousFlow2PhasePSTempl<is_ad>::validParams() 19 : { 20 5464 : InputParameters params = PorousFlowVariableBaseTempl<is_ad>::validParams(); 21 10928 : params.addRequiredCoupledVar("phase0_porepressure", 22 : "Variable that is the porepressure of phase 0 (the liquid phase)"); 23 10928 : params.addRequiredCoupledVar("phase1_saturation", 24 : "Variable that is the saturation of phase 1 (the gas phase)"); 25 10928 : params.addRequiredParam<UserObjectName>("capillary_pressure", 26 : "Name of the UserObject defining the capillary pressure"); 27 5464 : params.addClassDescription("This Material calculates the 2 porepressures and the 2 saturations " 28 : "in a 2-phase situation, and derivatives of these with " 29 : "respect to the PorousFlowVariables."); 30 5464 : return params; 31 0 : } 32 : 33 : template <bool is_ad> 34 4257 : PorousFlow2PhasePSTempl<is_ad>::PorousFlow2PhasePSTempl(const InputParameters & parameters) 35 : : PorousFlowVariableBaseTempl<is_ad>(parameters), 36 8514 : _phase0_porepressure(_nodal_material 37 1602 : ? this->template coupledGenericDofValue<is_ad>("phase0_porepressure") 38 6912 : : this->template coupledGenericValue<is_ad>("phase0_porepressure")), 39 4257 : _phase0_gradp_qp(this->template coupledGenericGradient<is_ad>("phase0_porepressure")), 40 4257 : _phase0_porepressure_varnum(coupled("phase0_porepressure")), 41 4257 : _pvar(_dictator.isPorousFlowVariable(_phase0_porepressure_varnum) 42 4257 : ? _dictator.porousFlowVariableNum(_phase0_porepressure_varnum) 43 : : 0), 44 : 45 8514 : _phase1_saturation(_nodal_material 46 4257 : ? this->template coupledGenericDofValue<is_ad>("phase1_saturation") 47 6912 : : this->template coupledGenericValue<is_ad>("phase1_saturation")), 48 4257 : _phase1_grads_qp(this->template coupledGenericGradient<is_ad>("phase1_saturation")), 49 4257 : _phase1_saturation_varnum(coupled("phase1_saturation")), 50 4257 : _svar(_dictator.isPorousFlowVariable(_phase1_saturation_varnum) 51 4257 : ? _dictator.porousFlowVariableNum(_phase1_saturation_varnum) 52 : : 0), 53 : 54 8514 : _pc_uo(this->template getUserObject<PorousFlowCapillaryPressure>("capillary_pressure")) 55 : { 56 4257 : if (_dictator.numPhases() != 2) 57 0 : mooseError("The Dictator proclaims that the number of phases is ", 58 0 : _dictator.numPhases(), 59 : " whereas PorousFlow2PhasePS can only be used for 2-phase simulation. Be aware " 60 : "that the Dictator has noted your mistake."); 61 4257 : } 62 : 63 : template <bool is_ad> 64 : void 65 21366 : PorousFlow2PhasePSTempl<is_ad>::initQpStatefulProperties() 66 : { 67 21366 : PorousFlowVariableBaseTempl<is_ad>::initQpStatefulProperties(); 68 21366 : buildQpPPSS(); 69 21366 : } 70 : 71 : template <bool is_ad> 72 : void 73 1692468 : PorousFlow2PhasePSTempl<is_ad>::computeQpProperties() 74 : { 75 : // size stuff correctly and prepare the derivative matrices with zeroes 76 1692468 : PorousFlowVariableBaseTempl<is_ad>::computeQpProperties(); 77 : 78 1692468 : buildQpPPSS(); 79 1726528 : const auto dpc = _pc_uo.dCapillaryPressure(1.0 - _phase1_saturation[_qp]); 80 : 81 1692468 : if (!_nodal_material) 82 : { 83 975154 : (*_grads_qp)[_qp][0] = -_phase1_grads_qp[_qp]; 84 941094 : (*_grads_qp)[_qp][1] = _phase1_grads_qp[_qp]; 85 941094 : (*_gradp_qp)[_qp][0] = _phase0_gradp_qp[_qp]; 86 975154 : (*_gradp_qp)[_qp][1] = _phase0_gradp_qp[_qp] - dpc * (*_grads_qp)[_qp][1]; 87 : } 88 : 89 : if constexpr (!is_ad) 90 : { 91 : // _porepressure depends on _phase0_porepressure, and its derivative is 1 92 1658408 : if (_dictator.isPorousFlowVariable(_phase0_porepressure_varnum)) 93 : { 94 : // _phase0_porepressure is a PorousFlow variable 95 4328052 : for (unsigned phase = 0; phase < _num_phases; ++phase) 96 : { 97 2885368 : (*_dporepressure_dvar)[_qp][phase][_pvar] = 1.0; 98 2885368 : if (!_nodal_material) 99 1595824 : (*_dgradp_qp_dgradv)[_qp][phase][_pvar] = 1.0; 100 : } 101 : } 102 : 103 : // _saturation is only dependent on _phase1_saturation, and its derivative is +/- 1 104 1658408 : if (_dictator.isPorousFlowVariable(_phase1_saturation_varnum)) 105 : { 106 : // _phase1_saturation is a PorousFlow variable 107 : // _phase1_porepressure depends on saturation through the capillary pressure function 108 1445204 : (*_dsaturation_dvar)[_qp][0][_svar] = -1.0; 109 1445204 : (*_dsaturation_dvar)[_qp][1][_svar] = 1.0; 110 1445204 : (*_dporepressure_dvar)[_qp][1][_svar] = -dpc; 111 : 112 1445204 : if (!_nodal_material) 113 : { 114 800432 : (*_dgrads_qp_dgradv)[_qp][0][_svar] = -1.0; 115 800432 : (*_dgrads_qp_dgradv)[_qp][1][_svar] = 1.0; 116 : 117 800432 : const auto d2pc_qp = _pc_uo.d2CapillaryPressure(1.0 - _phase1_saturation[_qp]); 118 : 119 800432 : (*_dgradp_qp_dv)[_qp][1][_svar] = d2pc_qp * (*_grads_qp)[_qp][1]; 120 800432 : (*_dgradp_qp_dgradv)[_qp][1][_svar] = -dpc; 121 : } 122 : } 123 : } 124 1692468 : } 125 : 126 : template <bool is_ad> 127 : void 128 1713834 : PorousFlow2PhasePSTempl<is_ad>::buildQpPPSS() 129 : { 130 1748524 : _saturation[_qp][0] = 1.0 - _phase1_saturation[_qp]; 131 1713834 : _saturation[_qp][1] = _phase1_saturation[_qp]; 132 : 133 1748524 : const auto pc = _pc_uo.capillaryPressure(1.0 - _phase1_saturation[_qp]); 134 1713834 : _porepressure[_qp][0] = _phase0_porepressure[_qp]; 135 1748524 : _porepressure[_qp][1] = _phase0_porepressure[_qp] + pc; 136 1713834 : } 137 : 138 : template class PorousFlow2PhasePSTempl<false>; 139 : template class PorousFlow2PhasePSTempl<true>;