mirror of
https://github.com/OPM/opm-simulators.git
synced 2026-10-24 14:47:44 -05:00
Merge pull request #6522 from lechevaa/fix_hybrid_newton_python_tests
Fix hybrid newton python tests imports
This commit is contained in:
8 files changed
+66
-49
No files matched your search
@@ -525,6 +525,10 @@ if(MPI_FOUND)
|
||||
include (${CMAKE_CURRENT_SOURCE_DIR}/parallelUnitTests.cmake)
|
||||
endif()
|
||||
|
||||
if(OPM_ENABLE_PYTHON)
|
||||
include (${CMAKE_CURRENT_SOURCE_DIR}/pythonIntegrationTests.cmake)
|
||||
endif()
|
||||
|
||||
include(OpmBashCompletion)
|
||||
|
||||
if (NOT BUILD_FLOW)
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+18
-48
@@ -4,12 +4,11 @@ from pathlib import Path
|
||||
import numpy as np
|
||||
import subprocess
|
||||
|
||||
from utils import Dense, Sequential
|
||||
from utils import collect_input_features, compute_output_vars, write_config, extract_newtit_from_file, extract_unrst_variables
|
||||
from utils import (ABSOLUTE_CASES, RELATIVE_CASES, FEATURE_ENGINEERING_CASES, SCALING_CASES, MULTI_MODEL_CASES, ZERO_NEWTON_CASES, ALL_CASES)
|
||||
|
||||
import tensorflow as tf
|
||||
from kerasify import export_model
|
||||
from utils import ABSOLUTE_CASES, RELATIVE_CASES, FEATURE_ENGINEERING_CASES, SCALING_CASES, MULTI_MODEL_CASES, ZERO_NEWTON_CASES, ALL_CASES
|
||||
|
||||
from opm.ml.ml_tools.kerasify import export_model
|
||||
|
||||
class TestHybridNewton(unittest.TestCase):
|
||||
@classmethod
|
||||
@@ -24,27 +23,28 @@ class TestHybridNewton(unittest.TestCase):
|
||||
cls.times = []
|
||||
|
||||
baseline_cmd = [
|
||||
"flow",
|
||||
os.environ.get("FLOW_BINARY", default="flow"),
|
||||
str(cls.data_dir / cls.deck_file),
|
||||
"--output-extra-convergence-info=steps,iterations",
|
||||
"--newton-min-iterations=0",
|
||||
"--output-dir=.",
|
||||
"--full-time-step-initially=true",
|
||||
]
|
||||
|
||||
print("Running baseline simulation...")
|
||||
subprocess.run(baseline_cmd, cwd=cls.data_dir, stdout=subprocess.DEVNULL, check=True)
|
||||
print("Running baseline simulation... ")
|
||||
subprocess.run(baseline_cmd, stdout=subprocess.DEVNULL, check=True)
|
||||
|
||||
# Extract Newton iterations
|
||||
cls.baseline_iters = extract_newtit_from_file(cls.data_dir / Path(cls.deck_file).stem)
|
||||
cls.baseline_iters = extract_newtit_from_file(Path('.') / Path(cls.deck_file).stem)
|
||||
print(f"Baseline Newton iterations: {cls.baseline_iters}")
|
||||
|
||||
# Extract fluid state from UNRST for all timesteps
|
||||
cls.unrst, cls.times = extract_unrst_variables(cls.data_dir, cls.deck_file)
|
||||
cls.unrst, cls.times = extract_unrst_variables(".", cls.deck_file)
|
||||
cls.rd_init["PERMX"] = [10**2] * len(cls.unrst["PRESSURE"][0])
|
||||
cls.n_cells = len(cls.unrst["PRESSURE"][0])
|
||||
|
||||
def _run_cases(self, cases):
|
||||
models_dir = self.data_dir / "models"
|
||||
models_dir = Path('.') / "models"
|
||||
os.makedirs(models_dir, exist_ok=True)
|
||||
|
||||
for case in cases:
|
||||
@@ -89,9 +89,8 @@ class TestHybridNewton(unittest.TestCase):
|
||||
input_flat = input_flat.reshape(-1)
|
||||
output_flat = output_flat.reshape(-1)
|
||||
|
||||
model = tf.keras.Sequential([
|
||||
tf.keras.Input(shape=(input_flat.shape[0],)),
|
||||
tf.keras.layers.Dense(output_flat.shape[0], use_bias=True)
|
||||
model = Sequential([
|
||||
Dense(input_dim=input_flat.shape[0], output_dim=output_flat.shape[0])
|
||||
])
|
||||
model.layers[0].set_weights([np.zeros((input_flat.shape[0], output_flat.shape[0])), output_flat])
|
||||
apply_time = self.times[start_idx]
|
||||
@@ -126,21 +125,22 @@ class TestHybridNewton(unittest.TestCase):
|
||||
def _run_hybrid_newton_test(self, json_path):
|
||||
"""Run hybrid Newton via subprocess and extract Newton iterations."""
|
||||
cmd = [
|
||||
"flow",
|
||||
os.environ.get("FLOW_BINARY", default="flow"),
|
||||
str(self.data_dir / self.deck_file),
|
||||
f"--hy-ne-config-file={json_path}",
|
||||
"--use-hy-ne=true",
|
||||
"--output-extra-convergence-info=steps,iterations",
|
||||
"--newton-min-iterations=0",
|
||||
"--output-dir=.",
|
||||
"--full-time-step-initially=true"
|
||||
]
|
||||
|
||||
print(f"Running hybrid Newton simulation with config {json_path}...")
|
||||
subprocess.run(cmd, cwd=self.data_dir,
|
||||
subprocess.run(cmd,
|
||||
stdout=subprocess.DEVNULL,
|
||||
check=True)
|
||||
|
||||
hybrid_iters = extract_newtit_from_file(self.data_dir / Path(self.deck_file).stem)
|
||||
hybrid_iters = extract_newtit_from_file(Path('.') / Path(self.deck_file).stem)
|
||||
return hybrid_iters
|
||||
|
||||
def test_absolute_cases(self):
|
||||
@@ -160,42 +160,12 @@ class TestHybridNewton(unittest.TestCase):
|
||||
|
||||
def test_zero_newton_cases(self):
|
||||
hybrid_iters = self._run_cases(ZERO_NEWTON_CASES)
|
||||
|
||||
# Length must match (failed newton convergence otherwise)
|
||||
assert len(hybrid_iters) == len(self.baseline_iters), (
|
||||
f"Hybrid iterations length {len(hybrid_iters)} "
|
||||
f"does not match baseline length {len(self.baseline_iters)}"
|
||||
)
|
||||
|
||||
# First two must be 0
|
||||
assert hybrid_iters[0] == 0, f"Expected hybrid_iters[0] == 0, got {hybrid_iters[0]}"
|
||||
assert hybrid_iters[1] == 0, f"Expected hybrid_iters[1] == 0, got {hybrid_iters[1]}"
|
||||
|
||||
# Hybrid must not exceed baseline
|
||||
for i, (h, b) in enumerate(zip(hybrid_iters, self.baseline_iters)):
|
||||
assert h <= b, (
|
||||
f"Hybrid iterations exceeded baseline at index {i}: "
|
||||
f"got {h}, expected <= {b}"
|
||||
)
|
||||
print(f"Hybrid Newton iterations all_features: {hybrid_iters}")
|
||||
|
||||
def test_all_cases(self):
|
||||
hybrid_iters = self._run_cases(ALL_CASES)
|
||||
# Length must match (failed newton convergence otherwise)
|
||||
assert len(hybrid_iters) == len(self.baseline_iters), (
|
||||
f"Hybrid iterations length {len(hybrid_iters)} "
|
||||
f"does not match baseline length {len(self.baseline_iters)}"
|
||||
)
|
||||
print(f"Hybrid Newton iterations all_cases: {hybrid_iters}")
|
||||
|
||||
# First two must be 0
|
||||
assert hybrid_iters[0] == 0, f"Expected hybrid_iters[0] == 0, got {hybrid_iters[0]}"
|
||||
assert hybrid_iters[1] == 0, f"Expected hybrid_iters[1] == 0, got {hybrid_iters[1]}"
|
||||
|
||||
# Hybrid must not exceed baseline
|
||||
for i, (h, b) in enumerate(zip(hybrid_iters, self.baseline_iters)):
|
||||
assert h <= b, (
|
||||
f"Hybrid iterations exceeded baseline at index {i}: "
|
||||
f"got {h}, expected <= {b}"
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
+22
-1
@@ -5,6 +5,27 @@ from pathlib import Path
|
||||
|
||||
from opm.io.ecl import ERst, ESmry
|
||||
|
||||
# Avoid tensorflow dependency but maintain compability with kerasify export_model method
|
||||
class Dense:
|
||||
def __init__(self, input_dim, output_dim, activation='linear'):
|
||||
self.weights = np.zeros((input_dim, output_dim), dtype=np.float32)
|
||||
self.biases = np.zeros((output_dim,), dtype=np.float32)
|
||||
self.activation = activation
|
||||
|
||||
def set_weights(self, w_b):
|
||||
self.weights = w_b[0].astype(np.float32)
|
||||
self.biases = w_b[1].astype(np.float32)
|
||||
|
||||
def get_weights(self):
|
||||
return [self.weights, self.biases]
|
||||
|
||||
def get_config(self):
|
||||
return {'activation': self.activation}
|
||||
|
||||
class Sequential:
|
||||
def __init__(self, layers):
|
||||
self.layers = layers
|
||||
|
||||
|
||||
def extract_unrst_variables(data_dir, deck_file):
|
||||
"""
|
||||
@@ -220,7 +241,7 @@ def compute_output_vars(output_features, start_idx, end_idx, unrst, rd_init, fea
|
||||
return np.stack(output_data), scaling_params
|
||||
|
||||
|
||||
def extract_newtit_from_file(filename: str | Path) -> list[int]:
|
||||
def extract_newtit_from_file(filename):
|
||||
"""
|
||||
Parse an INFOSTEP file and return the values of the 'NewtIt' column.
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/tests/integration/HybridNewton)
|
||||
|
||||
add_test(NAME
|
||||
HybridNewton
|
||||
COMMAND
|
||||
${Python3_EXECUTABLE}
|
||||
-m unittest discover
|
||||
${PROJECT_SOURCE_DIR}/python/integration_tests/ml/hybrid_newton
|
||||
WORKING_DIRECTORY
|
||||
${PROJECT_BINARY_DIR}/tests/integration/HybridNewton
|
||||
)
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.22)
|
||||
set(modifications
|
||||
"PYTHONPATH=path_list_append:${opm-common_DIR}/python"
|
||||
"PYTHONPATH=path_list_append:${CMAKE_CURRENT_BINARY_DIR}/python"
|
||||
"FLOW_BINARY=set:$<TARGET_FILE:flow>"
|
||||
)
|
||||
set_tests_properties(HybridNewton PROPERTIES
|
||||
ENVIRONMENT_MODIFICATION
|
||||
"${modifications}"
|
||||
)
|
||||
endif()
|
||||
Reference in new issue
Block a user