def test_invalid_fluid_reference_on_wells(default_well):
    """
    Ensure that only declared Fluids can be used on WellDescription and AnnulusDescription.
    """
    case = case_description.CaseDescription(
        pvt_models=case_description.PvtModelsDescription(
            default_model="PVT",
            compositions={
                "PVT":
                case_description.PvtModelCompositionalDescription(
                    fluids={"Fluid 1": case_description.FluidDescription()})
            },
        ),
        wells=[
            attr.evolve(
                default_well,
                initial_conditions=attr.evolve(
                    default_well.initial_conditions,
                    fluid="acme",
                ),
                annulus=attr.evolve(
                    default_well.annulus,
                    initial_conditions=attr.evolve(
                        default_well.annulus.initial_conditions,
                        fluid="acme",
                    ),
                ),
            )
        ],
    )
    expected_error = "The following elements have an invalid fluid assigned: 'Annulus from Well 1', 'Well 1'."
    with pytest.raises(InvalidReferenceError, match=re.escape(expected_error)):
        case.ensure_valid_references()
def default_case(tmp_path) -> case_description.CaseDescription:
    """
    Minimum valid CaseDescription with pvt configured
    """
    tab_file = tmp_path / "dummy.tab"
    file_content = [
        'PVTTABLE LABEL = "PVT1",PHASE = THREE,',
        'PVTTABLE LABEL = "PVT2", PHASE = THREE,',
    ]
    tab_file.write_text("\n".join(file_content))
    return case_description.CaseDescription(
        pvt_models=case_description.PvtModelsDescription(
            default_model="PVT2",
            tables={"PVT1": f"{tab_file}"},
            correlations={
                "PVT2": case_description.PvtModelCorrelationDescription()
            },
            compositions={
                "PVT3": case_description.PvtModelCompositionalDescription()
            },
            table_parameters={
                "PVT4":
                case_description.PvtModelTableParametersDescription.
                create_empty()
            },
        ))
 def test_remove_pvt_entry_from_pvt_models_when_file_is_invalid(self):
     """
     Remove the PVT entry from case.pvt_models.tables if the file is not a file when calling ResetInvalidReferences()
     """
     case = case_description.CaseDescription(
         pvt_models=case_description.PvtModelsDescription(
             default_model="PVT1", tables={"PVT1": "SomePath"}))
     case.reset_invalid_references()
     assert case.pvt_models.tables == {}
     assert case.pvt_models.default_model is None
def test_check_pvt_model_files_handling_white_space(default_case, tmp_path):
    """
    PvtModelsDescription.tables accept which PvtModel should be included from the file by passing the argument

    """
    case = attr.evolve(
        default_case,
        pvt_models=case_description.PvtModelsDescription(
            default_model="PVT1",
            tables={"PVT1": f"{tmp_path / 'dummy.tab'}| PVT1"}),
    )
    case.ensure_valid_references()
    def test_remove_pvt_entry_from_pvt_models_when_pvt_model_is_invalid(
            self, default_case, tmp_path):
        """
        Check if the PVTModel referred from case.pvt_models.tables is inside a pvt file,
        if invalid the entry must be removed, when calling case.ResetInvalidReferences()
        """

        case = attr.evolve(
            default_case,
            pvt_models=case_description.PvtModelsDescription(
                default_model="PVT1",
                tables={"PVT1": f"{tmp_path/'dummy.tab'}|INVALID"}),
        )
        case.reset_invalid_references()
        assert case.pvt_models.tables == {}
        assert case.pvt_models.default_model is None
        case = case_description.CaseDescription(
            pvt_models=case_description.PvtModelsDescription(
                default_model="PVT2",
                tables={"PVT2": f"{tmp_path/'dummy.tab'}|PVT2"}))
        case.reset_invalid_references()
        assert case.pvt_models.default_model == "PVT2"
 def test_pvt_models_with_invalid_pvtfile(self, tmp_path):
     """
     When a PVTModel assigned on case.pvt_models.tables doesn't exist,
     a InvalidReferenceError exception must be raised when case.EnsureValidReferences is called.
     """
     case = case_description.CaseDescription(
         pvt_models=case_description.PvtModelsDescription(
             default_model="PVT1", tables={"PVT1": "SomePath|PVT1"}))
     expect_message = "Error on 'PVT1', 'SomePath' is not a valid file"
     with pytest.raises(
             InvalidReferenceError,
             match=re.escape(expect_message),
     ):
         case.ensure_valid_references()
 def test_pvt_model_from_file_is_in_valid(self, default_case, tmp_path):
     """
     When a PVTModel informed from the user on a file doesn't exist,
     a InvalidReferenceError must be raised when case.EnsureValidReferences is called.
     """
     case = attr.evolve(
         default_case,
         pvt_models=case_description.PvtModelsDescription(
             default_model="PVT1",
             tables={"PVT1": f"{tmp_path/'dummy.tab'}|INVALID"}),
     )
     expect_message = "'INVALID' could not be found on 'dummy.tab', available models are: 'PVT1, PVT2'"
     with pytest.raises(
             InvalidReferenceError,
             match=re.escape(expect_message),
     ):
         case.ensure_valid_references()
def test_invalid_fluid_reference_on_pipes():
    """
    Ensure that only declared Fluids can be used on:
       PipeDescription, MassSourceEquipmentDescription, ReservoirInflowEquipmentDescription.
    """
    case = case_description.CaseDescription(
        pvt_models=case_description.PvtModelsDescription(
            default_model="PVT",
            compositions={
                "PVT":
                case_description.PvtModelCompositionalDescription(
                    fluids={"Fluid 1": case_description.FluidDescription()})
            },
        ),
        pipes=[
            case_description.PipeDescription(
                name="Pipe 1",
                source="",
                target="",
                segments=build_simple_segment(),
                initial_conditions=case_description.
                InitialConditionsDescription(fluid="acme5"),
                equipment=case_description.EquipmentDescription(
                    mass_sources={
                        "MassSource":
                        case_description.MassSourceEquipmentDescription(
                            position=Scalar(1, "m"), fluid="a6")
                    },
                    reservoir_inflows={
                        "Reservoir":
                        case_description.ReservoirInflowEquipmentDescription(
                            start=Scalar(1, "m"),
                            length=Scalar(10, "m"),
                            fluid="a7")
                    },
                ),
            )
        ],
    )
    expected_error = "The following elements have an invalid fluid assigned: 'MassSource from Pipe 1', 'Pipe 1', 'Reservoir from Pipe 1'."
    with pytest.raises(InvalidReferenceError, match=re.escape(expected_error)):
        case.ensure_valid_references()
def test_invalid_fluid_reference_on_nodes():
    """
    Ensure that only declared Fluids can be used on NodeDescription
    """
    case = case_description.CaseDescription(
        pvt_models=case_description.PvtModelsDescription(
            default_model="PVT",
            compositional={
                "PVT": case_description.PvtModelCompositionalDescription(
                    fluids={"Fluid 1": case_description.CompositionalFluidDescription()}
                )
            },
        ),
        nodes=[
            case_description.NodeDescription(
                name="Node 1",
                node_type=NodeCellType.Internal,
                internal_properties=case_description.InternalNodePropertiesDescription(
                    fluid="Acme2"
                ),
            ),
            case_description.NodeDescription(
                name="Node 2",
                node_type=NodeCellType.Pressure,
                pressure_properties=case_description.PressureNodePropertiesDescription(
                    fluid="Acme3"
                ),
            ),
            case_description.NodeDescription(
                name="Node 3",
                node_type=NodeCellType.MassSource,
                mass_source_properties=case_description.MassSourceNodePropertiesDescription(
                    fluid="Acme4"
                ),
            ),
        ],
    )

    expected_error = "The following elements have an invalid fluid assigned: 'Node 1', 'Node 2', 'Node 3'."
    with pytest.raises(InvalidReferenceError, match=re.escape(expected_error)):
        case.ensure_valid_references()
Exemple #10
0
def test_alfacase_file_export(tmp_path):
    """
    Check that GenerateAlfacaseFile creates a alfatable file with the content from PvtModelsDescription.table_parameters
    When exporting this alfatable should be placed on PvtModelDescription.tables
    """

    alfacase_file = tmp_path / "mycase.alfacase"
    alfatable_file = tmp_path / "mycase.fluid_a_1.alfatable"

    pvt_model_table_parameter = {
        "FLUID-A 1": PvtModelTableParametersDescription.create_constant()
    }
    from alfasim_sdk._internal.alfacase import case_description

    case_description = case_description.CaseDescription(
        pvt_models=case_description.PvtModelsDescription(
            table_parameters=pvt_model_table_parameter))

    generate_alfacase_file(case_description, alfacase_file)
    assert alfacase_file.is_file()
    assert alfatable_file.is_file()
    # Load
    case = convert_alfacase_to_description(alfacase_file)
    assert case.pvt_models.tables == {"FLUID-A 1": alfatable_file}
    heavy_components=[HEAVY_COMPONENT_DESCRIPTION],
    light_components=[
        LIGH_COMPONENT_DESCRIPTION,
        LIGH_COMPONENT_DESCRIPTION_OVERWRITE_C3,
    ],
    fluids={"fluid_1": FLUID_DESCRIPTION},
)
PVT_MODEL_TABLE_PARAMETERS = (
    case_description.PvtModelTableParametersDescription.create_constant(has_water=True)
)
PVT_MODELS_DEFINITION = case_description.PvtModelsDescription(
    default_model="acme",
    compositions={
        "composition 1": PVT_MODEL_COMPOSITIONAL_DEFINITION,
        "composition 2": PVT_MODEL_COMPOSITIONAL_DEFINITION,
    },
    correlations={
        "correlation 1": PVT_MODEL_CORRELATION_DEFINITION,
        "correlation 2": PVT_MODEL_CORRELATION_DEFINITION,
    },
    tables={"acme": get_acme_tab_file_path(), "gavea_2": get_acme_tab_file_path()},
)

SPEED_CURVE_DESCRIPTION = case_description.SpeedCurveDescription(
    time=Array([0.0, 0.1], "s"), speed=Array([10.0, 50.0], "rpm")
)
COMPRESSOR_PRESSURE_TABLE_DESCRIPTION = (
    case_description.CompressorPressureTableDescription(
        speed_entries=Array(
            [25000.0, 25000.0, 25000.0, 50000.0, 50000.0, 50000.0], "rpm"
        ),
        corrected_mass_flow_rate_entries=Array([0.1, 0.2, 0.3, 0.1, 0.2, 0.3], "kg/s"),
def test_case_description_duplicate_names(default_well):
    """
    Pipes because they are reference by OutputDescription
    Nodes because they are referenced by PipeDescription, WellDescription and OutputDescription
    PVTs names, because of default_model
    Wall Names because of PipeSegmentsDescription
    Material because of WellDescription(stagnant_fluid), CasingSectionDescription, TubingDescription
    """
    well_1 = attr.evolve(default_well, name="Well 1")
    well_2 = attr.evolve(default_well, name="Well 1")

    case = case_description.CaseDescription(
        materials=[
            case_description.MaterialDescription(name="Material"),
            case_description.MaterialDescription(name="Material"),
        ],
        walls=[
            case_description.WallDescription(name="Wall A"),
            case_description.WallDescription(name="Wall A"),
        ],
        pvt_models=case_description.PvtModelsDescription(
            default_model="PVT",
            correlations={
                "PVT1": case_description.PvtModelCorrelationDescription(),
            },
            compositions={
                "PVT1":
                case_description.PvtModelCompositionalDescription(fluids={
                    "Fluid 0":
                    case_description.FluidDescription(),
                    "Fluid 1":
                    case_description.FluidDescription(),
                }, ),
                "PVT2":
                case_description.PvtModelCompositionalDescription(
                    fluids={
                        "Fluid 0": case_description.FluidDescription(),
                        "Fluid 1": case_description.FluidDescription(),
                    }),
            },
        ),
        nodes=[
            case_description.NodeDescription(name="ACME",
                                             node_type=NodeCellType.Pressure),
            case_description.NodeDescription(name="ACME",
                                             node_type=NodeCellType.Pressure),
            case_description.NodeDescription(name="Node1",
                                             node_type=NodeCellType.Pressure),
            case_description.NodeDescription(name="FOO",
                                             node_type=NodeCellType.Pressure),
            case_description.NodeDescription(name="FOO",
                                             node_type=NodeCellType.Pressure),
        ],
        pipes=[
            case_description.PipeDescription(
                name="Pipe 1",
                source="ACME",
                target="ACME",
                segments=build_simple_segment(),
            ),
            case_description.PipeDescription(
                name="Pipe 1",
                source="ACME",
                target="ACME",
                segments=build_simple_segment(),
            ),
        ],
        wells=[well_1, well_2],
    )

    expected_msg = dedent("""\
        Elements that can be referenced must have a unique name, found multiples definitions of the following items:
        Fluids:
            - Fluid 0
            - Fluid 1
        Materials:
            - Material
        Nodes:
            - ACME
            - FOO
        PVT:
            - PVT1
        Pipes:
            - Pipe 1
        Walls:
            - Wall A
        Wells:
            - Well 1""")

    with pytest.raises(InvalidReferenceError, match=re.escape(expected_msg)):
        case.ensure_unique_names()
            default_case,
            pvt_models=case_description.PvtModelsDescription(
                default_model="PVT1",
                tables={"PVT1": f"{tmp_path/'dummy.tab'}|INVALID"}),
        )
        expect_message = "'INVALID' could not be found on 'dummy.tab', available models are: 'PVT1, PVT2'"
        with pytest.raises(
                InvalidReferenceError,
                match=re.escape(expect_message),
        ):
            case.ensure_valid_references()

        # Ensure the test finishes in a valid state
        case = case_description.CaseDescription(
            pvt_models=case_description.PvtModelsDescription(
                default_model="PVT2",
                tables={"PVT2": f"{tmp_path/'dummy.tab'}|PVT2"}))
        case.ensure_valid_references()
        assert case.pvt_models.default_model == "PVT2"

    def test_pvt_models_with_invalid_pvtfile(self, tmp_path):
        """
        When a PVTModel assigned on case.pvt_models.tables doesn't exist,
        a InvalidReferenceError exception must be raised when case.EnsureValidReferences is called.
        """
        case = case_description.CaseDescription(
            pvt_models=case_description.PvtModelsDescription(
                default_model="PVT1", tables={"PVT1": "SomePath|PVT1"}))
        expect_message = "Error on 'PVT1', 'SomePath' is not a valid file"
        with pytest.raises(
                InvalidReferenceError,
    mass_source_node_properties = load_mass_source_node_properties_description(
        document)

    assert (mass_source_node_properties.volumetric_flow_rates_std_input_type ==
            MultiInputType.Constant)
    assert (mass_source_node_properties.mass_flow_rates_input_type ==
            MultiInputType.Constant)
    assert (mass_source_node_properties.total_mass_flow_rate_input_type ==
            MultiInputType.Curve)
    assert mass_source_node_properties.water_cut_input_type == MultiInputType.Curve


@pytest.fixture()
def description_document_for_pvt_tables_test(tmp_path):
    case = case_description.PvtModelsDescription(tables={
        "acme": "acme.tab",
        "acme_2": "acme.tab"
    })
    alfacase_string = convert_description_to_alfacase(case)
    alfacase_file_path = tmp_path / "test_case.alfacase"
    shutil.copy2(get_acme_tab_file_path(), tmp_path)
    alfacase_content = strictyaml.dirty_load(
        alfacase_string,
        schema=schema.pvt_models_description_schema,
        allow_flow_style=True,
    )
    return DescriptionDocument(content=alfacase_content,
                               file_path=alfacase_file_path)


def test_load_pvt_tables_with_relative_file(
        description_document_for_pvt_tables_test, tmp_path):