BlackOilFluidSystem::internalEnergy accounts for the energy of components crossing phases using a heat-of-vaporisation term. For oil with dissolved gas (BlackOilFluidSystem_macrotemplate.hpp:1251):
const auto hVapG = gasPvt_.hVap(regionIdx);
return oilEnergy*bo*referenceDensity(oilPhaseIdx, regionIdx)
+ (gasEnergy - hVapG)*Rs*bo*referenceDensity(gasPhaseIdx, regionIdx);
and symmetrically (oilEnergy + hVapO) / (waterEnergy + hVapW) for vaporised oil and water in the gas phase (lines 1282-1311).
The accessors exist on all the thermal PVT classes. But hVap_ is only ever initialised:
GasPvtThermal.cpp:203 — hVap_.resize(numRegions, 0.0);
OilPvtThermal.cpp:194 — hVap_.resize(numRegions, 0.0);
WaterPvtThermal.cpp:215 — hVap_.resize(numRegions,0.0);
There is no setter, no deck keyword and no correlation that ever assigns it. A repo-wide grep for hVap_ returns only those three resize calls and the three getters.
Consequence: hVapG is identically zero, so gas dissolving into oil transfers its full gas-phase internal energy into the oil phase with no latent-heat correction. In a case where gas goes into solution this shows up as a large, unphysical temperature response — and it does so regardless of deck settings, since nothing can turn the term on.
This looks like a half-landed feature: the plumbing is in place and reads as if enthalpy of solution is handled, which is arguably worse than not having it, because the code gives no hint that the term is inert.
Questions:
- Was
hVap intended to be populated from a keyword, or computed from a correlation?
- If it is deliberately zero for now, could the getters be commented to say so, so readers do not assume the term is active?
Also missing: there is no test coverage for this path. A grep across opm-common/tests and opm-simulators/tests finds no reference to useEnthalpy or enthalpy_eq_energy_ at all. A regression case with gas going into solution, asserting a bounded temperature response, would pin both this and the enthalpy_eq_energy_ = !useEnthalpy() default set in BlackOilFluidSystem::initFromState.
BlackOilFluidSystem::internalEnergyaccounts for the energy of components crossing phases using a heat-of-vaporisation term. For oil with dissolved gas (BlackOilFluidSystem_macrotemplate.hpp:1251):and symmetrically
(oilEnergy + hVapO)/(waterEnergy + hVapW)for vaporised oil and water in the gas phase (lines 1282-1311).The accessors exist on all the thermal PVT classes. But
hVap_is only ever initialised:GasPvtThermal.cpp:203—hVap_.resize(numRegions, 0.0);OilPvtThermal.cpp:194—hVap_.resize(numRegions, 0.0);WaterPvtThermal.cpp:215—hVap_.resize(numRegions,0.0);There is no setter, no deck keyword and no correlation that ever assigns it. A repo-wide grep for
hVap_returns only those threeresizecalls and the three getters.Consequence:
hVapGis identically zero, so gas dissolving into oil transfers its full gas-phase internal energy into the oil phase with no latent-heat correction. In a case where gas goes into solution this shows up as a large, unphysical temperature response — and it does so regardless of deck settings, since nothing can turn the term on.This looks like a half-landed feature: the plumbing is in place and reads as if enthalpy of solution is handled, which is arguably worse than not having it, because the code gives no hint that the term is inert.
Questions:
hVapintended to be populated from a keyword, or computed from a correlation?Also missing: there is no test coverage for this path. A grep across
opm-common/testsandopm-simulators/testsfinds no reference touseEnthalpyorenthalpy_eq_energy_at all. A regression case with gas going into solution, asserting a bounded temperature response, would pin both this and theenthalpy_eq_energy_ = !useEnthalpy()default set inBlackOilFluidSystem::initFromState.