from typing import List, Optional, Union, cast, TYPE_CHECKING
from .pseudo_pressures_results import PseudoPressuresResults
from .._private._tech_objects_api import TechObjectsAPI
from ..pvt_type_enum import PVTTypeEnum
from ..pvt_fluid_type_enum import PVTFluidTypeEnum
from .._private._tech_objects_dto import PVTQueryDto, BlackOilPvtQueryDto
from .black_oil_flash_results import BlackOilFlashResults
from .eos_flash_results import EosFlashResults
from .black_oil_pvt_property import BlackOilPvtProperty
from .rate_conversion_results import RateConversionResults
if TYPE_CHECKING:
from .._private.dto_converters._pvt_dto_converter import PVTDtoConverter
[docs]
class PVT:
def __init__(self, field_id: str, well_id: Optional[str], id: str, name: str, technical_object_id: str, labels: Optional[List[str]], tech_objects_api: TechObjectsAPI, pvt_dto_converter: 'PVTDtoConverter') -> None:
self.__field_id = field_id
self.__well_id = well_id
self.__id = id
self.__name = name
self.__technical_object_id = technical_object_id
self.__labels = labels
self.__tech_objects_api = tech_objects_api
self.__pvt_dto_converter = pvt_dto_converter
self.__pvt_dto: Optional[Union[BlackOilPvtQueryDto, PVTQueryDto]] = None
@property
def field_id(self) -> str:
"""Gets the id of the field that contains this :class:`PVT`."""
return self.__field_id
@property
def well_id(self) -> Optional[str]:
"""Gets the id of the well associated with this :class:`PVT`."""
return self.__well_id
@property
def id(self) -> str:
"""Gets the unique id of this :class:`PVT`."""
return self.__id
@property
def name(self) -> str:
"""Gets the name of this :class:`PVT`."""
return self.__name
@property
def technical_object_id(self) -> str:
"""Gets the technical object id associated with this :class:`PVT`."""
return self.__technical_object_id
@property
def labels(self) -> Optional[List[str]]:
"""Gets the labels associated with this :class:`PVT`."""
return self.__labels
@property
def type(self) -> PVTTypeEnum:
"""Gets the type of this :class:`PVT`."""
return self.__get_pvt_dto().pvtType
def __get_pvt_dto(self) -> Union[BlackOilPvtQueryDto, PVTQueryDto]:
if self.__pvt_dto is None:
self.__pvt_dto = self.__tech_objects_api.get_pvt_properties(self.__technical_object_id)
return self.__pvt_dto
@property
def properties(self) -> List[BlackOilPvtProperty]:
if self.type is PVTTypeEnum.black_oil:
return self.__pvt_dto_converter.build_pvt_properties(cast(BlackOilPvtQueryDto, self.__get_pvt_dto()).properties)
else:
raise ValueError("Properties are only available for black oil PVT types")
@property
def fluid_type(self) -> PVTFluidTypeEnum:
if self.type is PVTTypeEnum.black_oil:
return cast(BlackOilPvtQueryDto, self.__get_pvt_dto()).fluidType
else:
raise ValueError("Fluid type is only available for black oil PVT types")
@property
def reference_pressure(self) -> float:
if self.type is PVTTypeEnum.black_oil:
return cast(BlackOilPvtQueryDto, self.__get_pvt_dto()).parameters.referencePressure
else:
raise ValueError("Reference pressure is only available for black oil PVT types")
@property
def reference_temperature(self) -> float:
if self.type is PVTTypeEnum.black_oil:
return cast(BlackOilPvtQueryDto, self.__get_pvt_dto()).parameters.referenceTemperature
else:
raise ValueError("Reference temperature is only available for black oil PVT types")
def flash_black_oil_process(self, temperature: float, pressure: float, pb_imposed: bool, gor_or_pb: Optional[float] = None) -> BlackOilFlashResults:
"""Compute a flash on black oil PVT"""
if self.type is PVTTypeEnum.black_oil:
dto = self.__pvt_dto_converter.get_flash_black_oil_pvt_command_dto(temperature, pressure, pb_imposed, gor_or_pb)
response = self.__tech_objects_api.flash_black_oil_pvt(self.__technical_object_id, dto)
return self.__pvt_dto_converter.build_black_oil_flash_results(response)
else:
raise ValueError("This is not a black oil PVT")
def flash_eos_process(self, temperature: float, pressure: float, extended: bool, water_molar_fraction: Optional[float] = None, salinity: Optional[float] = None) -> EosFlashResults:
"""Compute a flash on EoS PVT"""
if self.type is PVTTypeEnum.eos:
if (water_molar_fraction is None and salinity is None) or (water_molar_fraction is not None and salinity is not None):
dto = self.__pvt_dto_converter.get_flash_eos_pvt_command_dto(temperature, pressure, extended, water_molar_fraction, salinity)
else:
raise ValueError("You must define water molar fraction and salinity")
response = self.__tech_objects_api.flash_eos_pvt(self.__technical_object_id, dto)
return self.__pvt_dto_converter.build_eos_flash_results(response)
else:
raise ValueError("This is not a EoS PVT")
def compute_pseudo_pressures(self, temperature: float, rock_compressibility: float, pressure_range_min: float, pressure_range_max: float, pressure_range_steps: int, sw: Optional[float] = None) -> PseudoPressuresResults:
dto = self.__pvt_dto_converter.get_compute_pseudo_pressures_command_dto(temperature, rock_compressibility, sw, pressure_range_min, pressure_range_max, pressure_range_steps=pressure_range_steps)
pseudo_pressure_query_dto = self.__tech_objects_api.compute_pseudo_pressures(self.__technical_object_id, dto)
return self.__pvt_dto_converter.build_pseudo_pressures_results(pseudo_pressure_query_dto)
def convert_rates(self, field_pressures: List[List[float]], field_temperatures: List[List[float]], surface_pressures: List[List[float]], surface_temperatures: List[List[float]],
standard_oil_rates: List[float], standard_gas_rates: List[float]) -> RateConversionResults:
dto = self.__pvt_dto_converter.get_rate_conversion_command_dto(field_pressures, field_temperatures, surface_pressures, surface_temperatures, standard_oil_rates, standard_gas_rates)
rate_conversion_query_dto = self.__tech_objects_api.convert_rates(self.__technical_object_id, dto)
return self.__pvt_dto_converter.build_rate_conversion_results(rate_conversion_query_dto)