Skip to content

Commit

Permalink
Refactor to configure annulus and GL in operation;
Browse files Browse the repository at this point in the history
PWPA-1990
  • Loading branch information
Gabriel Antão committed Jul 12, 2024
1 parent 1050b19 commit 0cd1327
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 80 deletions.
2 changes: 1 addition & 1 deletion src/alfasim_score/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

REFERENCE_VERTICAL_COORDINATE = Scalar(0.0, LENGTH_UNIT, "length")

# This default fluid name for packer and fluid above filler
# this default fluid name for packer and fluid above filler
FLUID_DEFAULT_NAME = "fluid_default"

# nodes data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -803,8 +803,7 @@ wells:
value: 0.1
unit: mm
annulus:
has_annulus_flow: True
pvt_model: gas_lift
has_annulus_flow: False
initial_conditions:
pressures:
position_input_type: length
Expand Down Expand Up @@ -955,22 +954,6 @@ wells:
values:
- 288.6
unit: K
equipment:
gas_lift_valves:
GAS_LIFT_VALVE_1:
position:
value: 928.0
unit: m
diameter:
value: 0.25
unit: in
valve_type: check_valve
delta_p_min:
value: 0.0
unit: psi
discharge_coefficient:
value: 0.826
unit: unitless
top_node: GAS_LIFT_MASS_NODE
formation:
reference_y_coordinate:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ pipes: []
nodes:
- name: WELLBORE_TOP_NODE
node_type: mass_source_boundary
pvt_model: base
pvt_model: DFLT_BLACK_OIL_27.40_230.00_1.17
pressure_properties:
pressure:
value: 100000.0
Expand Down Expand Up @@ -217,7 +217,7 @@ nodes:
max_rate_of_change: 1e+50
- name: WELLBORE_BOTTOM_NODE
node_type: pressure_boundary
pvt_model: base
pvt_model: DFLT_BLACK_OIL_27.40_230.00_1.17
pressure_properties:
pressure:
value: 9814.11
Expand Down Expand Up @@ -298,7 +298,7 @@ nodes:
max_rate_of_change: 1e+50
- name: GAS_LIFT_MASS_NODE
node_type: mass_source_boundary
pvt_model: gas_lift
pvt_model: DFLT_BLACK_OIL_27.40_230.00_1.17
pressure_properties:
pressure:
value: 100000.0
Expand Down Expand Up @@ -389,7 +389,7 @@ nodes:
max_rate_of_change: 1e+50
wells:
- name: WELLBORE
pvt_model: base
pvt_model: DFLT_BLACK_OIL_27.40_230.00_1.17
stagnant_fluid: fluid_default
profile:
x_and_y:
Expand Down Expand Up @@ -804,7 +804,7 @@ wells:
unit: mm
annulus:
has_annulus_flow: True
pvt_model: gas_lift
pvt_model: DFLT_BLACK_OIL_27.40_230.00_1.17
initial_conditions:
pressures:
position_input_type: length
Expand Down
61 changes: 60 additions & 1 deletion src/alfasim_score/converter/alfacase/base_operation.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,36 @@
from typing import Dict
from typing import List

import attr
from alfasim_sdk import AnnulusDescription
from alfasim_sdk import AnnulusEquipmentDescription
from alfasim_sdk import GasLiftValveEquipmentDescription
from alfasim_sdk import InitialConditionsDescription
from alfasim_sdk import InitialPressuresDescription
from alfasim_sdk import InitialTemperaturesDescription
from alfasim_sdk import InitialVelocitiesDescription
from alfasim_sdk import InitialVolumeFractionsDescription
from alfasim_sdk import MassInflowSplitType
from alfasim_sdk import MassSourceNodePropertiesDescription
from alfasim_sdk import MassSourceType
from alfasim_sdk import MultiInputType
from alfasim_sdk import NodeDescription
from alfasim_sdk import PressureContainerDescription
from alfasim_sdk import PressureNodePropertiesDescription
from alfasim_sdk import TableInputType
from alfasim_sdk import ValveType
from alfasim_sdk import WellDescription
from alfasim_sdk._internal.constants import FLUID_GAS
from alfasim_sdk._internal.constants import FLUID_OIL
from alfasim_sdk._internal.constants import FLUID_WATER

from alfasim_score.common import LiftMethod
from alfasim_score.common import ModelFluidType
from alfasim_score.constants import GAS_LIFT_MASS_NODE_NAME
from alfasim_score.constants import GAS_LIFT_VALVE_DEFAULT_DELTA_P_MIN
from alfasim_score.constants import GAS_LIFT_VALVE_DEFAULT_DIAMETER
from alfasim_score.constants import GAS_LIFT_VALVE_DEFAULT_DISCHARGE
from alfasim_score.constants import GAS_LIFT_VALVE_NAME
from alfasim_score.constants import NULL_VOLUMETRIC_FLOW_RATE
from alfasim_score.constants import WELLBORE_BOTTOM_NODE_NAME
from alfasim_score.constants import WELLBORE_TOP_NODE_NAME
Expand All @@ -23,7 +42,37 @@ class BaseOperationBuilder(ScoreAlfacaseConverter):
def __init__(self, score_reader: ScoreInputReader):
super().__init__(score_reader)

def has_gas_lift(self) -> bool:
"""Check the operation has gas lift."""
return self.score_input.read_operation_data()["lift_method"] == LiftMethod.GAS_LIFT

def _get_gas_lift_valves(self) -> Dict[str, GasLiftValveEquipmentDescription]:
"""Create the gas lift valves for the annulus."""
gas_lift_data = self.score_input.read_operation_method_data()
valves = {
f"{GAS_LIFT_VALVE_NAME}_1": GasLiftValveEquipmentDescription(
position=self._get_position_in_well(gas_lift_data["valve_depth"]),
diameter=GAS_LIFT_VALVE_DEFAULT_DIAMETER,
valve_type=ValveType.CheckValve,
delta_p_min=GAS_LIFT_VALVE_DEFAULT_DELTA_P_MIN,
discharge_coefficient=GAS_LIFT_VALVE_DEFAULT_DISCHARGE,
)
}
return valves

def build_annulus(self) -> AnnulusDescription:
"""Configure the annulus with data from SCORE operation."""
return AnnulusDescription(
has_annulus_flow=self.has_gas_lift(),
pvt_model=self.get_fluid_model_name(),
equipment=AnnulusEquipmentDescription(
gas_lift_valves=self._get_gas_lift_valves(),
),
top_node=GAS_LIFT_MASS_NODE_NAME,
)

def build_nodes(self) -> List[NodeDescription]:
""" "Configure the nodes with data from SCORE operation."""
operation_data = self.score_input.read_operation_data()
default_nodes = {node.name: node for node in super().build_nodes()}
configured_nodes = [
Expand All @@ -40,6 +89,7 @@ def build_nodes(self) -> List[NodeDescription]:
FLUID_WATER: -1.0 * operation_data["water_flow_rate"],
},
),
pvt_model=self.get_fluid_model_name(),
),
attr.evolve(
default_nodes.pop(WELLBORE_BOTTOM_NODE_NAME),
Expand All @@ -48,9 +98,10 @@ def build_nodes(self) -> List[NodeDescription]:
pressure=operation_data["flow_initial_pressure"],
split_type=MassInflowSplitType.Pvt,
),
pvt_model=self.get_fluid_model_name(),
),
]
if GAS_LIFT_MASS_NODE_NAME in default_nodes:
if self.has_gas_lift():
gas_lift_data = self.score_input.read_operation_method_data()
configured_nodes.append(
attr.evolve(
Expand All @@ -65,6 +116,14 @@ def build_nodes(self) -> List[NodeDescription]:
FLUID_WATER: NULL_VOLUMETRIC_FLOW_RATE,
},
),
pvt_model=self.get_fluid_model_name(),
)
)
return configured_nodes

def build_well(self) -> WellDescription:
"""Create the description for the well."""
return attr.evolve(
super().build_well(),
pvt_model=self.get_fluid_model_name(),
)
79 changes: 24 additions & 55 deletions src/alfasim_score/converter/alfacase/convert_alfacase.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
from typing import Dict
from typing import List

from alfasim_sdk import AnnulusDescription
from alfasim_sdk import AnnulusEquipmentDescription
from alfasim_sdk import CaseDescription
from alfasim_sdk import CasingDescription
from alfasim_sdk import CasingSectionDescription
from alfasim_sdk import EnvironmentDescription
from alfasim_sdk import EnvironmentPropertyDescription
from alfasim_sdk import FormationDescription
from alfasim_sdk import FormationLayerDescription
from alfasim_sdk import GasLiftValveEquipmentDescription
from alfasim_sdk import HydrodynamicModelType
from alfasim_sdk import MassInflowSplitType
from alfasim_sdk import MassSourceNodePropertiesDescription
Expand All @@ -31,30 +28,24 @@
from alfasim_sdk import PvtModelCorrelationDescription
from alfasim_sdk import PvtModelsDescription
from alfasim_sdk import TubingDescription
from alfasim_sdk import ValveType
from alfasim_sdk import WellDescription
from alfasim_sdk import XAndYDescription
from alfasim_sdk._internal.constants import FLUID_GAS
from alfasim_sdk._internal.constants import FLUID_OIL
from alfasim_sdk._internal.constants import FLUID_WATER
from barril.units import Scalar

from alfasim_score.common import LiftMethod
from alfasim_score.common import ModelFluidType
from alfasim_score.common import convert_api_gravity_to_oil_density
from alfasim_score.common import convert_gas_gravity_to_gas_density
from alfasim_score.common import convert_quota_to_tvd
from alfasim_score.constants import ANNULUS_TOP_NODE_NAME
from alfasim_score.constants import BASE_PVT_TABLE_NAME
from alfasim_score.constants import CASING_DEFAULT_ROUGHNESS
from alfasim_score.constants import CEMENT_NAME
from alfasim_score.constants import CO2_MOLAR_FRACTION_DEFAULT
from alfasim_score.constants import FLUID_DEFAULT_NAME
from alfasim_score.constants import GAS_LIFT_MASS_NODE_NAME
from alfasim_score.constants import GAS_LIFT_PVT_TABLE_NAME
from alfasim_score.constants import GAS_LIFT_VALVE_DEFAULT_DELTA_P_MIN
from alfasim_score.constants import GAS_LIFT_VALVE_DEFAULT_DIAMETER
from alfasim_score.constants import GAS_LIFT_VALVE_DEFAULT_DISCHARGE
from alfasim_score.constants import GAS_LIFT_VALVE_NAME
from alfasim_score.constants import H2S_MOLAR_FRACTION_DEFAULT
from alfasim_score.constants import NULL_VOLUMETRIC_FLOW_RATE
from alfasim_score.constants import REFERENCE_VERTICAL_COORDINATE
Expand All @@ -66,6 +57,7 @@
from alfasim_score.constants import WELLBORE_TOP_NODE_NAME
from alfasim_score.converter.alfacase.score_input_reader import ScoreInputReader
from alfasim_score.units import LENGTH_UNIT
from alfasim_score.units import PRESSURE_UNIT
from alfasim_score.units import TEMPERATURE_UNIT


Expand Down Expand Up @@ -98,6 +90,10 @@ def _get_position_in_well(self, position: Scalar) -> Scalar:
"""Get the position relative to the well start position."""
return position - self.well_start_position

def get_fluid_model_name(self) -> ModelFluidType:
"""Get the name of the fluid model used for this operation."""
return self.score_input.read_operation_fluid_data()["name"]

def _convert_well_trajectory(self) -> ProfileDescription:
"""
Convert the trajectory for the imported well.
Expand Down Expand Up @@ -131,18 +127,9 @@ def _convert_materials(self) -> List[MaterialDescription]:
)
return filter_duplicated_materials(material_descriptions)

def _convert_annulus(self) -> AnnulusDescription:
def build_annulus(self) -> AnnulusDescription:
"""Create the description for the annulus."""
operation_input_data = self.score_input.read_operation_data()
has_gas_lift = operation_input_data["lift_method"] == LiftMethod.GAS_LIFT
return AnnulusDescription(
has_annulus_flow=has_gas_lift,
pvt_model=GAS_LIFT_PVT_TABLE_NAME if has_gas_lift else BASE_PVT_TABLE_NAME,
equipment=AnnulusEquipmentDescription(
gas_lift_valves=self._convert_gas_lift_valves(),
),
top_node=GAS_LIFT_MASS_NODE_NAME,
)
return AnnulusDescription(has_annulus_flow=False, top_node=GAS_LIFT_MASS_NODE_NAME)

def _convert_formation(self) -> FormationDescription:
"""Create the description for the formations."""
Expand Down Expand Up @@ -276,20 +263,6 @@ def _convert_casings(self) -> CasingDescription:
open_holes=self._convert_open_hole_list(),
)

def _convert_gas_lift_valves(self) -> Dict[str, GasLiftValveEquipmentDescription]:
"""Create the gas lift valves for the annulus."""
gas_lift_data = self.score_input.read_operation_method_data()
valves = {
f"{GAS_LIFT_VALVE_NAME}_1": GasLiftValveEquipmentDescription(
position=self._get_position_in_well(gas_lift_data["valve_depth"]),
diameter=GAS_LIFT_VALVE_DEFAULT_DIAMETER,
valve_type=ValveType.CheckValve,
delta_p_min=GAS_LIFT_VALVE_DEFAULT_DELTA_P_MIN,
discharge_coefficient=GAS_LIFT_VALVE_DEFAULT_DISCHARGE,
)
}
return valves

def _convert_pvt_model(self) -> PvtModelsDescription:
"""Create the black-oil fluid for the casings."""
fluid_data = self.score_input.read_operation_fluid_data()
Expand Down Expand Up @@ -334,25 +307,21 @@ def build_nodes(self) -> List[NodeDescription]:
split_type=MassInflowSplitType.Pvt,
),
),
NodeDescription(
name=GAS_LIFT_MASS_NODE_NAME,
node_type=NodeCellType.MassSource,
pvt_model=GAS_LIFT_PVT_TABLE_NAME,
mass_source_properties=MassSourceNodePropertiesDescription(
temperature_input_type=MultiInputType.Constant,
source_type=MassSourceType.AllVolumetricFlowRates,
volumetric_flow_rates_std={
FLUID_GAS: NULL_VOLUMETRIC_FLOW_RATE,
FLUID_OIL: NULL_VOLUMETRIC_FLOW_RATE,
FLUID_WATER: NULL_VOLUMETRIC_FLOW_RATE,
},
),
),
]
operation_input_data = self.score_input.read_operation_data()
if operation_input_data["lift_method"] == LiftMethod.GAS_LIFT:
nodes.append(
NodeDescription(
name=GAS_LIFT_MASS_NODE_NAME,
node_type=NodeCellType.MassSource,
pvt_model=GAS_LIFT_PVT_TABLE_NAME,
mass_source_properties=MassSourceNodePropertiesDescription(
temperature_input_type=MultiInputType.Constant,
source_type=MassSourceType.AllVolumetricFlowRates,
volumetric_flow_rates_std={
FLUID_GAS: NULL_VOLUMETRIC_FLOW_RATE,
FLUID_OIL: NULL_VOLUMETRIC_FLOW_RATE,
FLUID_WATER: NULL_VOLUMETRIC_FLOW_RATE,
},
),
)
)
return nodes

def build_well(self) -> WellDescription:
Expand All @@ -363,15 +332,15 @@ def build_well(self) -> WellDescription:
stagnant_fluid=FLUID_DEFAULT_NAME,
profile=self._convert_well_trajectory(),
casing=self._convert_casings(),
annulus=self._convert_annulus(),
annulus=self.build_annulus(),
formation=self._convert_formation(),
top_node=WELLBORE_TOP_NODE_NAME,
bottom_node=WELLBORE_BOTTOM_NODE_NAME,
environment=self._convert_well_environment(),
)

def build_case_description(self) -> CaseDescription:
""" "Create the description for the alfacase."""
"""Create the description for the alfacase."""
return CaseDescription(
name=self.general_data["case_name"],
physics=self.build_physics(),
Expand Down

0 comments on commit 0cd1327

Please sign in to comment.