My Project
Loading...
Searching...
No Matches
GenericOilGasFluidSystem.hpp
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3/*
4 Copyright 2023 SINTEF Digital, Mathematics and Cybernetics.
5
6 This file is part of the Open Porous Media project (OPM).
7
8 OPM is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 2 of the License, or
11 (at your option) any later version.
12
13 OPM is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with OPM. If not, see <http://www.gnu.org/licenses/>.
20
21 Consult the COPYING file in the top-level source directory of this
22 module for the precise wording of the license and the list of
23 copyright holders.
24*/
25
26#ifndef OPM_GENERICOILGASFLUIDSYSTEM_HPP
27#define OPM_GENERICOILGASFLUIDSYSTEM_HPP
28
29#include <opm/common/OpmLog/OpmLog.hpp>
30
31#if HAVE_ECL_INPUT
32#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
33#include <opm/input/eclipse/Schedule/Schedule.hpp>
34#endif
35
38#include <opm/material/fluidsystems/PTFlashParameterCache.hpp> // TODO: this is something else need to check
40
41#include <cassert>
42#include <cstddef>
43#include <string>
44#include <string_view>
45
46#include <fmt/format.h>
47
48namespace Opm {
49
58 template<class Scalar, int NumComp>
59 class GenericOilGasFluidSystem : public BaseFluidSystem<Scalar, GenericOilGasFluidSystem<Scalar, NumComp> > {
60 public:
61 // TODO: I do not think these should be constant in fluidsystem, will try to make it non-constant later
62 static constexpr int numPhases = 2;
63 static constexpr int numComponents = NumComp;
64 static constexpr int numMisciblePhases = 2;
65 // \Note: not totally sure when we should distinguish numMiscibleComponents and numComponents.
66 // Possibly when with a dummy phase like water?
67 static constexpr int numMiscibleComponents = NumComp;
68 // TODO: phase location should be more general
69 static constexpr int waterPhaseIdx = -1;
70 static constexpr int oilPhaseIdx = 0;
71 static constexpr int gasPhaseIdx = 1;
72
73 static constexpr int waterCompIdx = -1;
74 static constexpr int oilCompIdx = 0;
75 static constexpr int gasCompIdx = 1;
76 static constexpr int compositionSwitchIdx = -1; // equil initializer
77
78 template <class ValueType>
82
84 std::string name;
85 Scalar molar_mass; // unit: g/mol
86 Scalar critic_temp; // unit: K
87 Scalar critic_pres; // unit: parscal
88 Scalar critic_vol; // unit: m^3/kmol
89 Scalar acentric_factor; // unit: dimension less
90
91 ComponentParam(const std::string_view name_, const Scalar molar_mass_, const Scalar critic_temp_,
92 const Scalar critic_pres_, const Scalar critic_vol_, const Scalar acentric_factor_)
93 : name(name_),
94 molar_mass(molar_mass_),
95 critic_temp(critic_temp_),
96 critic_pres(critic_pres_),
97 critic_vol(critic_vol_),
98 acentric_factor(acentric_factor_)
99 {}
100 };
101
102 static bool phaseIsActive(unsigned phaseIdx)
103 {
104 return phaseIdx == oilPhaseIdx || phaseIdx == gasPhaseIdx;
105 }
106
107 template<typename Param>
108 static void addComponent(const Param& param)
109 {
110 // Check if the current size is less than the maximum allowed components.
111 if (component_param_.size() < numComponents) {
112 component_param_.push_back(param);
113 } else {
114 // Adding another component would exceed the limit.
115 const std::string msg = fmt::format("The fluid system has reached its maximum capacity of {} components,"
116 "the component '{}' will not be added.", NumComp, param.name);
117 OpmLog::note(msg);
118 // Optionally, throw an exception?
119 }
120 }
121
122#if HAVE_ECL_INPUT
126 static void initFromState(const EclipseState& eclState, const Schedule& /* schedule */)
127 {
128 // TODO: we are not considering the EOS region for now
129 const auto& comp_config = eclState.compositionalConfig();
130 // how should we utilize the numComps from the CompositionalConfig?
131 using FluidSystem = GenericOilGasFluidSystem<Scalar, NumComp>;
132 const std::size_t num_comps = comp_config.numComps();
133 // const std::size_t num_eos_region = comp_config.
134 assert(num_comps == NumComp);
135 const auto& names = comp_config.compName();
136 // const auto& eos_type = comp_config.eosType(0);
137 const auto& molar_weight = comp_config.molecularWeights(0);
138 const auto& acentric_factor = comp_config.acentricFactors(0);
139 const auto& critic_pressure = comp_config.criticalPressure(0);
140 const auto& critic_temp = comp_config.criticalTemperature(0);
141 const auto& critic_volume = comp_config.criticalVolume(0);
142 FluidSystem::init();
143 using CompParm = typename FluidSystem::ComponentParam;
144 for (std::size_t c = 0; c < num_comps; ++c) {
145 // we use m^3/kmol for the critic volume in the flash calculation, so we multiply 1.e3 for the critic volume
146 FluidSystem::addComponent(CompParm{names[c], molar_weight[c], critic_temp[c], critic_pressure[c],
147 critic_volume[c] * 1.e3, acentric_factor[c]});
148 }
149 FluidSystem::printComponentParams();
150 interaction_coefficients_ = comp_config.binaryInteractionCoefficient(0);
151 }
152#endif // HAVE_ECL_INPUT
153
154 static void init()
155 {
156 component_param_.reserve(numComponents);
157 }
158
164 static Scalar acentricFactor(unsigned compIdx)
165 {
166 assert(isConsistent());
167 assert(compIdx < numComponents);
168
169 return component_param_[compIdx].acentric_factor;
170 }
176 static Scalar criticalTemperature(unsigned compIdx)
177 {
178 assert(isConsistent());
179 assert(compIdx < numComponents);
180
181 return component_param_[compIdx].critic_temp;
182 }
188 static Scalar criticalPressure(unsigned compIdx)
189 {
190 assert(isConsistent());
191 assert(compIdx < numComponents);
192
193 return component_param_[compIdx].critic_pres;
194 }
200 static Scalar criticalVolume(unsigned compIdx)
201 {
202 assert(isConsistent());
203 assert(compIdx < numComponents);
204
205 return component_param_[compIdx].critic_vol;
206 }
207
209 static Scalar molarMass(unsigned compIdx)
210 {
211 assert(isConsistent());
212 assert(compIdx < numComponents);
213
214 return component_param_[compIdx].molar_mass;
215 }
216
221 static Scalar interactionCoefficient(unsigned comp1Idx, unsigned comp2Idx)
222 {
223 assert(isConsistent());
224 assert(comp1Idx < numComponents);
225 assert(comp2Idx < numComponents);
226 if (interaction_coefficients_.empty() || comp2Idx == comp1Idx) {
227 return 0.0;
228 }
229 // make sure row is the bigger value compared to column number
230 const auto [column, row] = std::minmax(comp1Idx, comp2Idx);
231 const unsigned index = (row * (row - 1) / 2 + column); // it is the current understanding
232 return interaction_coefficients_[index];
233 }
234
236 static std::string_view phaseName(unsigned phaseIdx)
237 {
238 static const std::string_view name[] = {"o", // oleic phase
239 "g"}; // gas phase
240
241 assert(phaseIdx < numPhases);
242 return name[phaseIdx];
243 }
244
246 static std::string_view componentName(unsigned compIdx)
247 {
248 assert(isConsistent());
249 assert(compIdx < numComponents);
250
251 return component_param_[compIdx].name;
252 }
253
257 template <class FluidState, class LhsEval = typename FluidState::Scalar, class ParamCacheEval = LhsEval>
258 static LhsEval density(const FluidState& fluidState,
259 const ParameterCache<ParamCacheEval>& paramCache,
260 unsigned phaseIdx)
261 {
262 assert(isConsistent());
263 assert(phaseIdx < numPhases);
264
265 if (phaseIdx == oilPhaseIdx || phaseIdx == gasPhaseIdx) {
266 return decay<LhsEval>(fluidState.averageMolarMass(phaseIdx) / paramCache.molarVolume(phaseIdx));
267 }
268
269 return {};
270 }
271
273 template <class FluidState, class LhsEval = typename FluidState::Scalar, class ParamCacheEval = LhsEval>
274 static LhsEval viscosity(const FluidState& fluidState,
275 const ParameterCache<ParamCacheEval>& paramCache,
276 unsigned phaseIdx)
277 {
278 assert(isConsistent());
279 assert(phaseIdx < numPhases);
280 // Use LBC method to calculate viscosity
281 return decay<LhsEval>(ViscosityModel::LBC(fluidState, paramCache, phaseIdx));
282 }
283
285 template <class FluidState, class LhsEval = typename FluidState::Scalar, class ParamCacheEval = LhsEval>
286 static LhsEval fugacityCoefficient(const FluidState& fluidState,
287 const ParameterCache<ParamCacheEval>& paramCache,
288 unsigned phaseIdx,
289 unsigned compIdx)
290 {
291 assert(isConsistent());
292 assert(phaseIdx < numPhases);
293 assert(compIdx < numComponents);
294
295 return decay<LhsEval>(PengRobinsonMixture::computeFugacityCoefficient(fluidState, paramCache, phaseIdx, compIdx));
296 }
297
298 // TODO: the following interfaces are needed by function checkFluidSystem()
300 static bool isCompressible([[maybe_unused]] unsigned phaseIdx)
301 {
302 assert(phaseIdx < numPhases);
303
304 return true;
305 }
306
308 static bool isIdealMixture([[maybe_unused]] unsigned phaseIdx)
309 {
310 assert(phaseIdx < numPhases);
311
312 return false;
313 }
314
316 static bool isLiquid(unsigned phaseIdx)
317 {
318 assert(phaseIdx < numPhases);
319
320 return (phaseIdx == 0);
321 }
322
324 static bool isIdealGas(unsigned phaseIdx)
325 {
326 assert(phaseIdx < numPhases);
327
328 return (phaseIdx == 1);
329 }
330
331 private:
332 static bool isConsistent() {
333 return component_param_.size() == NumComp;
334 }
335
336 static std::vector<ComponentParam> component_param_;
337 static std::vector<Scalar> interaction_coefficients_;
338
339 public:
340 static std::string printComponentParams() {
341 std::string result = "Components Information:\n";
342 for (const auto& param : component_param_) {
343 result += fmt::format("Name: {}\n", param.name);
344 result += fmt::format("Molar Mass: {} g/mol\n", param.molar_mass);
345 result += fmt::format("Critical Temperature: {} K\n", param.critic_temp);
346 result += fmt::format("Critical Pressure: {} Pascal\n", param.critic_pres);
347 result += fmt::format("Critical Volume: {} m^3/kmol\n", param.critic_vol);
348 result += fmt::format("Acentric Factor: {}\n", param.acentric_factor);
349 result += "---------------------------------\n";
350 }
351 return result;
352 }
353 };
354
355 template <class Scalar, int NumComp>
356 std::vector<typename GenericOilGasFluidSystem<Scalar, NumComp>::ComponentParam>
357 GenericOilGasFluidSystem<Scalar, NumComp>::component_param_;
358
359 template <class Scalar, int NumComp>
360 std::vector<Scalar>
361 GenericOilGasFluidSystem<Scalar, NumComp>::interaction_coefficients_;
362}
363#endif // OPM_GENERICOILGASFLUIDSYSTEM_HPP
The base class for all fluid systems.
Specifies the parameter cache used by the SPE-5 fluid system.
Implements the Peng-Robinson equation of state for a mixture.
The base class for all fluid systems.
Definition BaseFluidSystem.hpp:43
Scalar Scalar
The type used for scalar quantities.
Definition BaseFluidSystem.hpp:48
A two phase system that can contain NumComp components.
Definition GenericOilGasFluidSystem.hpp:59
static bool isIdealMixture(unsigned phaseIdx)
Returns true if and only if a fluid phase is assumed to be an ideal mixture.
Definition GenericOilGasFluidSystem.hpp:308
static LhsEval fugacityCoefficient(const FluidState &fluidState, const ParameterCache< ParamCacheEval > &paramCache, unsigned phaseIdx, unsigned compIdx)
Calculate the fugacity coefficient [Pa] of an individual component in a fluid phase.
Definition GenericOilGasFluidSystem.hpp:286
static Scalar criticalTemperature(unsigned compIdx)
Critical temperature of a component [K].
Definition GenericOilGasFluidSystem.hpp:176
static bool isCompressible(unsigned phaseIdx)
Returns true if and only if a fluid phase is assumed to be compressible.
Definition GenericOilGasFluidSystem.hpp:300
static Scalar criticalVolume(unsigned compIdx)
Critical volume of a component [m3].
Definition GenericOilGasFluidSystem.hpp:200
static Scalar interactionCoefficient(unsigned comp1Idx, unsigned comp2Idx)
Returns the interaction coefficient for two components.
Definition GenericOilGasFluidSystem.hpp:221
static Scalar criticalPressure(unsigned compIdx)
Critical pressure of a component [Pa].
Definition GenericOilGasFluidSystem.hpp:188
static bool isIdealGas(unsigned phaseIdx)
Returns true if and only if a fluid phase is assumed to be an ideal gas.
Definition GenericOilGasFluidSystem.hpp:324
static LhsEval density(const FluidState &fluidState, const ParameterCache< ParamCacheEval > &paramCache, unsigned phaseIdx)
Calculate the density [kg/m^3] of a fluid phase.
Definition GenericOilGasFluidSystem.hpp:258
static bool isLiquid(unsigned phaseIdx)
Return whether a phase is liquid.
Definition GenericOilGasFluidSystem.hpp:316
static std::string_view phaseName(unsigned phaseIdx)
Return the human readable name of a fluid phase.
Definition GenericOilGasFluidSystem.hpp:236
static Scalar acentricFactor(unsigned compIdx)
The acentric factor of a component [].
Definition GenericOilGasFluidSystem.hpp:164
static Scalar molarMass(unsigned compIdx)
Return the molar mass of a component in [kg/mol].
Definition GenericOilGasFluidSystem.hpp:209
static LhsEval viscosity(const FluidState &fluidState, const ParameterCache< ParamCacheEval > &paramCache, unsigned phaseIdx)
Calculate the dynamic viscosity of a fluid phase [Pa*s].
Definition GenericOilGasFluidSystem.hpp:274
static std::string_view componentName(unsigned compIdx)
Return the human readable name of a component.
Definition GenericOilGasFluidSystem.hpp:246
Specifies the parameter cache used by the SPE-5 fluid system.
Definition PTFlashParameterCache.hpp:48
Scalar molarVolume(unsigned phaseIdx) const
Returns the molar volume of a phase [m^3/mol].
Definition PTFlashParameterCache.hpp:210
Implements the Peng-Robinson equation of state for a mixture.
Definition PengRobinsonMixture.hpp:41
static LhsEval computeFugacityCoefficient(const FluidState &fs, const Params &params, unsigned phaseIdx, unsigned compIdx)
Returns the fugacity coefficient of an individual component in the phase.
Definition PengRobinsonMixture.hpp:74
Definition LBC.hpp:40
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition Exceptions.hpp:30
Definition GenericOilGasFluidSystem.hpp:83