void BlackoilCo2PVT::computeState(BlackoilCo2PVT::SubState& ss, double zBrine, double zCO2, double pressure) const { CompositionalFluidState fluidState; fluidState.setTemperature(temperature_); fluidState.setPressure(wPhase, pressure); fluidState.setPressure(nPhase, pressure); double massH20 = surfaceDensities_[Oil]*zBrine; double massCO2 = surfaceDensities_[Gas]*zCO2; // A priori, assume presence of both phases FluidSystem::ParameterCache<double> paramCache; typedef Opm::MiscibleMultiPhaseComposition</*Scalar=*/double, FluidSystem> MMPC; MMPC::solve(fluidState, paramCache, /*setViscosity=*/false, /*setEnthalpy=*/false); ss.density[wPhase] = fluidState.density(wPhase); ss.density[nPhase] = fluidState.density(nPhase); ss.massfrac[wPhase][nComp] = fluidState.massFraction(wPhase, nComp); ss.massfrac[nPhase][wComp] = fluidState.massFraction(nPhase, wComp); ss.massfrac[wPhase][wComp] = 1.0 - ss.massfrac[wPhase][nComp]; ss.massfrac[nPhase][nComp] = 1.0 - ss.massfrac[nPhase][wComp]; double detX = ss.massfrac[wPhase][wComp]*ss.massfrac[nPhase][nComp]-ss.massfrac[wPhase][nComp]*ss.massfrac[nPhase][wComp]; ss.phaseVolume[wPhase] = (massH20*ss.massfrac[nPhase][nComp] - massCO2*ss.massfrac[nPhase][wComp])/(ss.density[wPhase]*detX); ss.phaseVolume[nPhase] = (massCO2*ss.massfrac[wPhase][wComp] - massH20*ss.massfrac[wPhase][nComp])/(ss.density[nPhase]*detX); // Determine number of phase if (ss.phaseVolume[wPhase] > 0.0 && ss.phaseVolume[nPhase] > 0.0) { // Both phases ss.saturation = ss.phaseVolume[wPhase]/(ss.phaseVolume[wPhase]+ss.phaseVolume[nPhase]); fluidState.setSaturation(wPhase, ss.saturation); fluidState.setSaturation(nPhase, 1.0 - ss.saturation); } else if (ss.phaseVolume[wPhase] <= 0.0) { // Wetting phase only ss.saturation = 0.0; // Gas phase: ss.massfrac[nPhase][nComp] = massCO2/(massCO2+massH20); ss.massfrac[nPhase][wComp] = 1.0 - ss.massfrac[nPhase][nComp]; double M1 = FluidSystem::molarMass(wComp); double M2 = FluidSystem::molarMass(nComp); double avgMolarMass = M1*M2/(M2 + ss.massfrac[nPhase][nComp]*(M1 - M2)); fluidState.setMoleFraction(nPhase, nComp, ss.massfrac[nPhase][nComp]*avgMolarMass/M2); fluidState.setMoleFraction(nPhase, wComp, ss.massfrac[nPhase][wComp]*avgMolarMass/M1); ss.density[nPhase] = brineCo2_.density(fluidState, paramCache, nPhase); fluidState.setDensity(nPhase, ss.density[nPhase]); ss.phaseVolume[nPhase] = (massH20+massCO2)/ss.density[nPhase]; fluidState.setSaturation(nPhase, 1.0 - ss.saturation); // Virtual properties of non-existing liquid phase: paramCache.updatePhase(fluidState, /*phaseIdx=*/nPhase); typedef Opm::ComputeFromReferencePhase</*Scalar=*/double, FluidSystem> CFRP; CFRP::solve(fluidState, paramCache, /*refPhaseIdx=*/nPhase, /*setViscosity=*/false, /*setEnthalpy=*/false); ss.massfrac[wPhase][wComp] = fluidState.massFraction(wPhase, wComp); ss.massfrac[wPhase][nComp] = fluidState.massFraction(wPhase, nComp); ss.density[wPhase] = fluidState.density(wPhase); ss.phaseVolume[wPhase] = 0.0; fluidState.setSaturation(wPhase, ss.saturation); } else if (ss.phaseVolume[nPhase] <= 0.0) { // Non-wetting phase only ss.saturation = 1.0; // Liquid phase: ss.massfrac[wPhase][wComp] = massH20/(massCO2+massH20); ss.massfrac[wPhase][nComp] = 1.0 - ss.massfrac[wPhase][wComp]; double M1 = FluidSystem::molarMass(wComp); double M2 = FluidSystem::molarMass(nComp); double avgMolarMass = M1*M2/(M2 + ss.massfrac[wPhase][nComp]*(M1 - M2)); fluidState.setMoleFraction(wPhase, nComp, ss.massfrac[wPhase][nComp]*avgMolarMass/M2); fluidState.setMoleFraction(wPhase, wComp, ss.massfrac[wPhase][wComp]*avgMolarMass/M1); ss.density[wPhase] = brineCo2_.density(fluidState, paramCache, wPhase); fluidState.setDensity(wPhase, ss.density[wPhase]); ss.phaseVolume[wPhase] = (massH20+massCO2)/ss.density[wPhase]; fluidState.setSaturation(wPhase, ss.saturation); // Virtual properties of non-existing gas phase: paramCache.updatePhase(fluidState, /*phaseIdx=*/nPhase); typedef ComputeFromReferencePhase</*Scalar=*/double, FluidSystem> CFRP; CFRP::solve(fluidState, paramCache, /*refPhaseIdx=*/wPhase, /*setViscosity=*/false, /*setEnthalpy=*/false); ss.massfrac[nPhase][nComp] = fluidState.massFraction(nPhase, nComp); ss.massfrac[nPhase][wComp] = fluidState.massFraction(nPhase, wComp); ss.density[nPhase] = fluidState.density(nPhase); ss.phaseVolume[nPhase] = 0.0; fluidState.setSaturation(nPhase, 1.0 - ss.saturation); } ss.phaseViscosity[wPhase] = brineCo2_.viscosity(fluidState, paramCache, wPhase); ss.phaseViscosity[nPhase] = brineCo2_.viscosity(fluidState, paramCache, nPhase); }