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 "PorousFlowWaterVapor.h"
11 : #include "SinglePhaseFluidProperties.h"
12 : #include "Conversion.h"
13 : #include "MooseUtils.h"
14 :
15 : registerMooseObject("PorousFlowApp", PorousFlowWaterVapor);
16 :
17 : InputParameters
18 270 : PorousFlowWaterVapor::validParams()
19 : {
20 270 : InputParameters params = PorousFlowFluidStateSingleComponentBase::validParams();
21 540 : params.addRequiredParam<UserObjectName>("water_fp", "The name of the user object for water");
22 270 : params.addClassDescription("Fluid state class for water and vapor");
23 270 : return params;
24 0 : }
25 :
26 135 : PorousFlowWaterVapor::PorousFlowWaterVapor(const InputParameters & parameters)
27 : : PorousFlowFluidStateSingleComponentBase(parameters),
28 135 : _water_fp(getUserObject<SinglePhaseFluidProperties>("water_fp")),
29 135 : _Mh2o(_water_fp.molarMass()),
30 135 : _p_triple(_water_fp.triplePointPressure()),
31 135 : _p_critical(_water_fp.criticalPressure()),
32 135 : _T_triple(_water_fp.triplePointTemperature()),
33 270 : _T_critical(_water_fp.criticalTemperature())
34 : {
35 : // Check that the correct FluidProperties UserObjects have been provided
36 270 : if (_water_fp.fluidName() != "water")
37 0 : paramError("water_fp", "A valid water FluidProperties UserObject must be provided in water_fp");
38 :
39 : // Set the number of phases and components, and their indexes
40 135 : _num_phases = 2;
41 135 : _num_components = 1;
42 135 : _gas_phase_number = 1 - _aqueous_phase_number;
43 :
44 : // Check that _aqueous_phase_number is <= total number of phases
45 135 : if (_aqueous_phase_number >= _num_phases)
46 0 : paramError("liquid_phase_number",
47 : "This value is larger than the possible number of phases ",
48 : _num_phases);
49 :
50 : // Check that _fluid_component is <= total number of fluid components
51 135 : if (_fluid_component >= _num_components)
52 0 : paramError("fluid_component",
53 : "This value is larger than the possible number of fluid components",
54 : _num_components);
55 :
56 135 : _empty_fsp = FluidStateProperties(_num_components);
57 135 : }
58 :
59 : std::string
60 1 : PorousFlowWaterVapor::fluidStateName() const
61 : {
62 1 : return "water-vapor";
63 : }
64 :
65 : void
66 261208 : PorousFlowWaterVapor::thermophysicalProperties(Real pressure,
67 : Real enthalpy,
68 : unsigned int qp,
69 : std::vector<FluidStateProperties> & fsp) const
70 : {
71 : // AD versions of primary variables
72 261208 : ADReal p = pressure;
73 261208 : Moose::derivInsert(p.derivatives(), _pidx, 1.0);
74 261208 : ADReal h = enthalpy;
75 261208 : Moose::derivInsert(h.derivatives(), _hidx, 1.0);
76 :
77 261208 : thermophysicalProperties(p, h, qp, fsp);
78 261208 : }
79 :
80 : void
81 261208 : PorousFlowWaterVapor::thermophysicalProperties(const ADReal & pressure,
82 : const ADReal & enthalpy,
83 : unsigned int qp,
84 : std::vector<FluidStateProperties> & fsp) const
85 : {
86 : FluidStatePhaseEnum phase_state;
87 :
88 261208 : thermophysicalProperties(pressure, enthalpy, qp, phase_state, fsp);
89 261208 : }
90 :
91 : void
92 261211 : PorousFlowWaterVapor::thermophysicalProperties(const ADReal & pressure,
93 : const ADReal & enthalpy,
94 : unsigned int qp,
95 : FluidStatePhaseEnum & phase_state,
96 : std::vector<FluidStateProperties> & fsp) const
97 : {
98 261211 : FluidStateProperties & liquid = fsp[_aqueous_phase_number];
99 261211 : FluidStateProperties & gas = fsp[_gas_phase_number];
100 :
101 261211 : ADReal Tsat = 0.0;
102 261211 : ADReal hl = 0.0;
103 261211 : ADReal hv = 0.0;
104 :
105 : // Determine the phase state of the system
106 261211 : if (pressure.value() >= _p_triple && pressure.value() <= _p_critical)
107 : {
108 : // Saturation temperature at the given pressure
109 261211 : Tsat = _water_fp.vaporTemperature(pressure);
110 :
111 : // Enthalpy of saturated liquid and saturated vapor
112 261211 : hl = _water_fp.h_from_p_T(pressure, Tsat - _dT);
113 261211 : hv = _water_fp.h_from_p_T(pressure, Tsat + _dT);
114 :
115 261211 : if (enthalpy.value() < hl.value())
116 251577 : phase_state = FluidStatePhaseEnum::LIQUID;
117 :
118 9634 : else if (enthalpy.value() >= hl.value() && enthalpy.value() <= hv.value())
119 8697 : phase_state = FluidStatePhaseEnum::TWOPHASE;
120 :
121 : else // h > hv
122 937 : phase_state = FluidStatePhaseEnum::GAS;
123 : }
124 : else // p.value() > _p_critical
125 : {
126 : // Check whether the phase point is in the liquid or vapor state
127 0 : const ADReal T = _water_fp.T_from_p_h(pressure, enthalpy);
128 :
129 0 : if (T.value() <= _T_critical)
130 0 : phase_state = FluidStatePhaseEnum::LIQUID;
131 : else
132 : {
133 : // The supercritical state is treated as a gas
134 0 : phase_state = FluidStatePhaseEnum::GAS;
135 : }
136 : }
137 :
138 : // Calculate the properties for each phase as required
139 261211 : switch (phase_state)
140 : {
141 937 : case FluidStatePhaseEnum::GAS:
142 : {
143 1874 : gas.pressure = pressure + _pc.capillaryPressure(0.0, qp);
144 937 : gas.saturation = 1.0;
145 :
146 937 : const ADReal T = _water_fp.T_from_p_h(gas.pressure, enthalpy);
147 :
148 937 : gas.temperature = T;
149 937 : liquid.temperature = T;
150 :
151 937 : gas.density = _water_fp.rho_from_p_T(gas.pressure, T);
152 937 : gas.viscosity = _water_fp.mu_from_p_T(gas.pressure, T);
153 937 : gas.enthalpy = enthalpy;
154 937 : gas.internal_energy = _water_fp.e_from_p_T(gas.pressure, T);
155 937 : gas.mass_fraction[_fluid_component] = 1.0;
156 :
157 : break;
158 : }
159 :
160 251577 : case FluidStatePhaseEnum::LIQUID:
161 : {
162 251577 : const ADReal T = _water_fp.T_from_p_h(pressure, enthalpy);
163 :
164 251577 : liquid.pressure = pressure;
165 251577 : liquid.temperature = T;
166 251577 : liquid.density = _water_fp.rho_from_p_T(pressure, T);
167 251577 : liquid.viscosity = _water_fp.mu_from_p_T(pressure, T);
168 251577 : liquid.enthalpy = enthalpy;
169 251577 : liquid.internal_energy = _water_fp.e_from_p_T(pressure, T);
170 251577 : liquid.saturation = 1.0;
171 251577 : liquid.mass_fraction[_fluid_component] = 1.0;
172 :
173 : break;
174 : }
175 :
176 8697 : case FluidStatePhaseEnum::TWOPHASE:
177 : {
178 : // Latent heat of vaporization
179 : const ADReal hvl = hv - hl;
180 :
181 : // Vapor quality
182 8697 : const ADReal X = (enthalpy - hl) / hvl;
183 :
184 : // Perturbed saturation temperature to ensure that the correct
185 : // phase properties are calculated
186 : const ADReal Tsatl = Tsat - _dT;
187 : const ADReal Tsatv = Tsat + _dT;
188 :
189 : // Density
190 8697 : const ADReal rhol = _water_fp.rho_from_p_T(pressure, Tsatl);
191 8697 : const ADReal rhov = _water_fp.rho_from_p_T(pressure, Tsatv);
192 :
193 : // Vapor (gas) saturation
194 8697 : const ADReal satv = X * rhol / (rhov + X * (rhol - rhov));
195 :
196 8697 : gas.temperature = Tsat;
197 8697 : gas.density = rhov;
198 8697 : gas.viscosity = _water_fp.mu_from_p_T(pressure, Tsatv);
199 8697 : gas.enthalpy = hv;
200 8697 : gas.internal_energy = _water_fp.e_from_p_T(pressure, Tsatv);
201 8697 : gas.saturation = satv;
202 :
203 8697 : liquid.temperature = Tsat;
204 8697 : liquid.density = rhol;
205 8697 : liquid.viscosity = _water_fp.mu_from_p_T(pressure, Tsatl);
206 8697 : liquid.enthalpy = hl;
207 8697 : liquid.internal_energy = _water_fp.e_from_p_T(pressure, Tsatl);
208 17394 : liquid.saturation = 1.0 - satv;
209 :
210 8697 : liquid.pressure = pressure;
211 17394 : gas.pressure = pressure + _pc.capillaryPressure(liquid.saturation, qp);
212 :
213 8697 : gas.mass_fraction[_fluid_component] = 1.0;
214 8697 : liquid.mass_fraction[_fluid_component] = 1.0;
215 :
216 : break;
217 : }
218 : }
219 261211 : }
|