void BlackoilCo2PVT::computeState(BlackoilCo2PVT::SubState& ss, double zBrine, double zCO2, double pressure) const { CompositionalFluidState state; state.setTemperature(temperature_); state.setPressure(wPhase, pressure); state.setPressure(nPhase, pressure); double massH20 = surfaceDensities_[Oil]*zBrine; double massCO2 = surfaceDensities_[Gas]*zCO2; // A priori, assume presence of both phases brineCo2_.computeEquilibrium(state); ss.density[wPhase] = state.density(wPhase); ss.density[nPhase] = state.density(nPhase); ss.massfrac[wPhase][nComp] = state.massFraction(wPhase, nComp); ss.massfrac[nPhase][wComp] = state.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]); state.setSaturation(wPhase, ss.saturation); state.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)); state.setMoleFraction(nPhase, nComp, ss.massfrac[nPhase][nComp]*avgMolarMass/M2); state.setMoleFraction(nPhase, wComp, ss.massfrac[nPhase][wComp]*avgMolarMass/M1); ss.density[nPhase] = brineCo2_.phaseDensity(nPhase, state.temperature(nPhase), state.pressure(nPhase), state); state.setDensity(nPhase, ss.density[nPhase]); ss.phaseVolume[nPhase] = (massH20+massCO2)/ss.density[nPhase]; state.setSaturation(nPhase, 1.0 - ss.saturation); // Virtual properties of non-existing liquid phase: brineCo2_.computeEquilibrium(state, nPhase); ss.massfrac[wPhase][wComp] = state.massFraction(wPhase, wComp); ss.massfrac[wPhase][nComp] = state.massFraction(wPhase, nComp); ss.density[wPhase] = state.density(wPhase); ss.phaseVolume[wPhase] = 0.0; state.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)); state.setMoleFraction(wPhase, nComp, ss.massfrac[wPhase][nComp]*avgMolarMass/M2); state.setMoleFraction(wPhase, wComp, ss.massfrac[wPhase][wComp]*avgMolarMass/M1); ss.density[wPhase] = brineCo2_.phaseDensity(wPhase, state.temperature(wPhase), state.pressure(wPhase), state); state.setDensity(wPhase, ss.density[wPhase]); ss.phaseVolume[wPhase] = (massH20+massCO2)/ss.density[wPhase]; state.setSaturation(wPhase, ss.saturation); // Virtual properties of non-existing gas phase: brineCo2_.computeEquilibrium(state, wPhase); ss.massfrac[nPhase][nComp] = state.massFraction(nPhase, nComp); ss.massfrac[nPhase][wComp] = state.massFraction(nPhase, wComp); ss.density[nPhase] = state.density(nPhase); ss.phaseVolume[nPhase] = 0.0; state.setSaturation(nPhase, 1.0 - ss.saturation); } ss.phaseViscosity[wPhase] = brineCo2_.phaseViscosity(wPhase, temperature_, pressure, state); ss.phaseViscosity[nPhase] = brineCo2_.phaseViscosity(nPhase, temperature_, pressure, state); }