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 130 : PorousFlowWaterVapor::validParams()
19 : {
20 130 : InputParameters params = PorousFlowFluidStateSingleComponentBase::validParams();
21 260 : params.addRequiredParam<UserObjectName>("water_fp", "The name of the user object for water");
22 130 : params.addClassDescription("Fluid state class for water and vapor");
23 130 : return params;
24 0 : }
25 :
26 65 : PorousFlowWaterVapor::PorousFlowWaterVapor(const InputParameters & parameters)
27 : : PorousFlowFluidStateSingleComponentBase(parameters),
28 65 : _water_fp(getUserObject<SinglePhaseFluidProperties>("water_fp")),
29 65 : _Mh2o(_water_fp.molarMass()),
30 65 : _p_triple(_water_fp.triplePointPressure()),
31 65 : _p_critical(_water_fp.criticalPressure()),
32 65 : _T_triple(_water_fp.triplePointTemperature()),
33 130 : _T_critical(_water_fp.criticalTemperature())
34 : {
35 : // Check that the correct FluidProperties UserObjects have been provided
36 130 : 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 65 : _num_phases = 2;
41 65 : _num_components = 1;
42 65 : _gas_phase_number = 1 - _aqueous_phase_number;
43 :
44 : // Check that _aqueous_phase_number is <= total number of phases
45 65 : 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 65 : 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 65 : _empty_fsp = FluidStateProperties(_num_components);
57 65 : }
58 :
59 : std::string
60 1 : PorousFlowWaterVapor::fluidStateName() const
61 : {
62 1 : return "water-vapor";
63 : }
64 :
65 : void
66 174383 : 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 174383 : ADReal p = pressure;
73 174383 : Moose::derivInsert(p.derivatives(), _pidx, 1.0);
74 174383 : ADReal h = enthalpy;
75 174383 : Moose::derivInsert(h.derivatives(), _hidx, 1.0);
76 :
77 174383 : thermophysicalProperties(p, h, qp, fsp);
78 174383 : }
79 :
80 : void
81 174383 : 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 174383 : thermophysicalProperties(pressure, enthalpy, qp, phase_state, fsp);
89 174383 : }
90 :
91 : void
92 174386 : 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 174386 : FluidStateProperties & liquid = fsp[_aqueous_phase_number];
99 174386 : FluidStateProperties & gas = fsp[_gas_phase_number];
100 :
101 174386 : ADReal Tsat = 0.0;
102 174386 : ADReal hl = 0.0;
103 174386 : ADReal hv = 0.0;
104 :
105 : // Determine the phase state of the system
106 174386 : if (pressure.value() >= _p_triple && pressure.value() <= _p_critical)
107 : {
108 : // Saturation temperature at the given pressure
109 174386 : Tsat = _water_fp.vaporTemperature(pressure);
110 :
111 : // Enthalpy of saturated liquid and saturated vapor
112 174386 : hl = _water_fp.h_from_p_T(pressure, Tsat - _dT);
113 174386 : hv = _water_fp.h_from_p_T(pressure, Tsat + _dT);
114 :
115 174386 : if (enthalpy.value() < hl.value())
116 167888 : phase_state = FluidStatePhaseEnum::LIQUID;
117 :
118 6498 : else if (enthalpy.value() >= hl.value() && enthalpy.value() <= hv.value())
119 5865 : phase_state = FluidStatePhaseEnum::TWOPHASE;
120 :
121 : else // h > hv
122 633 : 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 174386 : switch (phase_state)
140 : {
141 633 : case FluidStatePhaseEnum::GAS:
142 : {
143 1266 : gas.pressure = pressure + _pc.capillaryPressure(0.0, qp);
144 633 : gas.saturation = 1.0;
145 :
146 633 : const ADReal T = _water_fp.T_from_p_h(gas.pressure, enthalpy);
147 :
148 633 : gas.temperature = T;
149 633 : liquid.temperature = T;
150 :
151 633 : gas.density = _water_fp.rho_from_p_T(gas.pressure, T);
152 633 : gas.viscosity = _water_fp.mu_from_p_T(gas.pressure, T);
153 633 : gas.enthalpy = enthalpy;
154 633 : gas.internal_energy = _water_fp.e_from_p_T(gas.pressure, T);
155 633 : gas.mass_fraction[_fluid_component] = 1.0;
156 :
157 : break;
158 : }
159 :
160 167888 : case FluidStatePhaseEnum::LIQUID:
161 : {
162 167888 : const ADReal T = _water_fp.T_from_p_h(pressure, enthalpy);
163 :
164 167888 : liquid.pressure = pressure;
165 167888 : liquid.temperature = T;
166 167888 : liquid.density = _water_fp.rho_from_p_T(pressure, T);
167 167888 : liquid.viscosity = _water_fp.mu_from_p_T(pressure, T);
168 167888 : liquid.enthalpy = enthalpy;
169 167888 : liquid.internal_energy = _water_fp.e_from_p_T(pressure, T);
170 167888 : liquid.saturation = 1.0;
171 167888 : liquid.mass_fraction[_fluid_component] = 1.0;
172 :
173 : break;
174 : }
175 :
176 5865 : case FluidStatePhaseEnum::TWOPHASE:
177 : {
178 : // Latent heat of vaporization
179 : const ADReal hvl = hv - hl;
180 :
181 : // Vapor quality
182 5865 : 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 5865 : const ADReal rhol = _water_fp.rho_from_p_T(pressure, Tsatl);
191 5865 : const ADReal rhov = _water_fp.rho_from_p_T(pressure, Tsatv);
192 :
193 : // Vapor (gas) saturation
194 5865 : const ADReal satv = X * rhol / (rhov + X * (rhol - rhov));
195 :
196 5865 : gas.temperature = Tsat;
197 5865 : gas.density = rhov;
198 5865 : gas.viscosity = _water_fp.mu_from_p_T(pressure, Tsatv);
199 5865 : gas.enthalpy = hv;
200 5865 : gas.internal_energy = _water_fp.e_from_p_T(pressure, Tsatv);
201 5865 : gas.saturation = satv;
202 :
203 5865 : liquid.temperature = Tsat;
204 5865 : liquid.density = rhol;
205 5865 : liquid.viscosity = _water_fp.mu_from_p_T(pressure, Tsatl);
206 5865 : liquid.enthalpy = hl;
207 5865 : liquid.internal_energy = _water_fp.e_from_p_T(pressure, Tsatl);
208 11730 : liquid.saturation = 1.0 - satv;
209 :
210 5865 : liquid.pressure = pressure;
211 11730 : gas.pressure = pressure + _pc.capillaryPressure(liquid.saturation, qp);
212 :
213 5865 : gas.mass_fraction[_fluid_component] = 1.0;
214 5865 : liquid.mass_fraction[_fluid_component] = 1.0;
215 :
216 : break;
217 : }
218 : }
219 174386 : }
|