Files
ResInsight/GrpcInterface/Python/rips/tests/test_surfaces.py
T
Magne Sjaastad ebf75c09a1 #14411 Enforce name uniqueness for surfaces, polygons and folders
* #14411 Enforce name uniqueness for surfaces, polygons and folders

Names must be unique among siblings sharing the same parent folder. Items in different folders may keep identical names, and comparison is case sensitive.

Siblings are the objects held by the same caf::PdmChildArrayField. Items and folders live in two distinct child arrays in caf::PdmNestedCollection, so a folder and an item may share a name under the same parent.

The Python API gets an OnNameConflict flag on AddFolder, CreatePolygon, ImportSurface and NewRegularSurface, supporting FAIL (default), AUTO_RENAME and OVERWRITE. NewSurface is left out, as grid case surfaces derive their tree label from the case and K index and carry no name of their own.
2026-08-07 08:34:58 +02:00

194 lines
6.5 KiB
Python

import sys
import os
import tempfile
import pytest
from pathlib import Path
sys.path.insert(1, os.path.join(sys.path[0], "../../"))
import rips
import dataroot
def test_create_and_export_surface(rips_instance, initialize_test):
case_path = dataroot.PATH + "/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID"
case = rips_instance.project.load_case(path=case_path)
assert len(case.grids()) == 1
surface_collection = rips_instance.project.descendants(rips.SurfaceCollection)[0]
surface = surface_collection.new_surface(case, 5)
assert surface
with tempfile.TemporaryDirectory(prefix="rips") as tmpdirname:
path = Path(tmpdirname, "mysurface.ts")
print("Temporary folder: ", path.as_posix())
surface.export_to_file(path.as_posix())
assert path.exists()
def test_create_regular_surface(rips_instance, initialize_test):
case_path = dataroot.PATH + "/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID"
c = rips_instance.project.load_case(path=case_path)
assert len(c.grids()) == 1
surface_collection = rips_instance.project.descendants(rips.SurfaceCollection)[0]
bbox = c.reservoir_boundingbox()
depth = bbox.max_z - ((bbox.max_z - bbox.min_z) / 2.0)
origin_x = bbox.min_x
origin_y = bbox.min_y
name = "test surface name"
nx = 20
ny = 10
increment_x = (bbox.max_x - bbox.min_x) / float(nx)
increment_y = (bbox.max_y - bbox.min_y) / float(ny)
rotation = 23.4
s = surface_collection.new_regular_surface(
name=name,
origin_x=origin_x,
origin_y=origin_y,
depth=-depth,
nx=nx,
ny=ny,
increment_x=increment_x,
increment_y=increment_y,
rotation=rotation,
)
assert s.origin_x == origin_x
assert s.origin_y == origin_y
assert s.increment_x == increment_x
assert s.increment_y == increment_y
assert s.rotation == rotation
assert s.nx == nx
assert s.ny == ny
with pytest.raises(
rips.RipsError, match="Failed to set property: incorrect dimensions."
):
s.set_property("property_too_big", [i for i in range(nx * ny * 2)])
# Successfully set the depth property
s.set_property("depth", [i for i in range(nx * ny)])
s.set_property_as_depth("depth")
# Change the dimensions of the surface: should invalidate the properties
s.nx = 30
s.update()
def test_get_property(rips_instance, initialize_test):
case_path = dataroot.PATH + "/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID"
c = rips_instance.project.load_case(path=case_path)
assert len(c.grids()) == 1
surface_collection = rips_instance.project.descendants(rips.SurfaceCollection)[0]
nx = 5
ny = 4
s = surface_collection.new_regular_surface(nx=nx, ny=ny)
input_values = [float(i) for i in range(nx * ny)]
s.set_property("test_prop", input_values)
output_values = s.get_property("test_prop")
assert len(output_values) == nx * ny
for i in range(len(input_values)):
assert abs(output_values[i] - input_values[i]) < 1e-6
# Getting a non-existent property should raise an error
with pytest.raises(rips.RipsError, match="not found"):
s.get_property("non_existent_property")
def test_available_properties(rips_instance, initialize_test):
case_path = dataroot.PATH + "/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID"
c = rips_instance.project.load_case(path=case_path)
assert len(c.grids()) == 1
surface_collection = rips_instance.project.descendants(rips.SurfaceCollection)[0]
nx = 5
ny = 4
s = surface_collection.new_regular_surface(nx=nx, ny=ny)
# Empty property list initially
props = s.available_properties()
assert props == []
# Property names after setting one property
s.set_property("prop_a", [float(i) for i in range(nx * ny)])
props = s.available_properties()
assert "prop_a" in props
assert len(props) == 1
# Property names persist after setting multiple properties
s.set_property("prop_b", [float(i) for i in range(nx * ny)])
props = s.available_properties()
assert len(props) == 2
assert "prop_a" in props
assert "prop_b" in props
def test_create_regular_surface_invalid_values(rips_instance, initialize_test):
case_path = dataroot.PATH + "/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID"
c = rips_instance.project.load_case(path=case_path)
assert len(c.grids()) == 1
surface_collection = rips_instance.project.descendants(rips.SurfaceCollection)[0]
with pytest.raises(rips.RipsError, match="Invalid nx"):
surface_collection.new_regular_surface(nx=-1)
with pytest.raises(rips.RipsError, match="Invalid ny"):
surface_collection.new_regular_surface(ny=-1)
with pytest.raises(rips.RipsError, match="Invalid increment X. Must be positive."):
surface_collection.new_regular_surface(increment_x=-1.0)
with pytest.raises(rips.RipsError, match="Invalid increment Y. Must be positive."):
surface_collection.new_regular_surface(increment_y=-1.0)
with pytest.raises(rips.RipsError, match="Invalid rotation."):
surface_collection.new_regular_surface(rotation=-1.0)
def test_surface_name_uniqueness(rips_instance, initialize_test):
case_path = dataroot.PATH + "/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID"
rips_instance.project.load_case(path=case_path)
surface_collection = rips_instance.project.descendants(rips.SurfaceCollection)[0]
surface_collection.new_regular_surface(name="Top")
# The default policy is to fail on a name already used in the same folder
with pytest.raises(rips.RipsError, match="already exists"):
surface_collection.new_regular_surface(name="Top")
renamed = surface_collection.new_regular_surface(
name="Top", on_name_conflict=rips.NameConflictPolicy.AUTO_RENAME
)
assert renamed.surface_user_description == "Top_1"
# Names are case sensitive, so this is not a conflict
other_case = surface_collection.new_regular_surface(name="top")
assert other_case.surface_user_description == "top"
overwritten = surface_collection.new_regular_surface(
name="Top", on_name_conflict=rips.NameConflictPolicy.OVERWRITE
)
assert overwritten.surface_user_description == "Top"
names = [s.surface_user_description for s in surface_collection.surfaces_field()]
assert names.count("Top") == 1
# A different folder is a separate namespace
folder = surface_collection.add_folder(folder_name="Folder A")
in_folder = folder.new_regular_surface(name="Top")
assert in_folder.surface_user_description == "Top"