runsim 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- runsim/__init__.py +8 -0
- runsim/base.py +76 -0
- runsim/dumux.py +71 -0
- runsim/opm.py +93 -0
- runsim-0.1.0.dist-info/METADATA +259 -0
- runsim-0.1.0.dist-info/RECORD +8 -0
- runsim-0.1.0.dist-info/WHEEL +4 -0
- runsim-0.1.0.dist-info/licenses/LICENSE +21 -0
runsim/__init__.py
ADDED
runsim/base.py
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""Abstract base class for reservoir simulators."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import shutil
|
|
6
|
+
import subprocess
|
|
7
|
+
from abc import ABC, abstractmethod
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Simulator(ABC):
|
|
12
|
+
"""Base class for all simulator wrappers.
|
|
13
|
+
|
|
14
|
+
Subclasses must implement `_find_executable` and `run`.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
def __init__(self, name: str, executable: str | None = None):
|
|
18
|
+
self.name = name
|
|
19
|
+
if executable is not None:
|
|
20
|
+
self.executable = Path(executable)
|
|
21
|
+
else:
|
|
22
|
+
self.executable = self._find_executable()
|
|
23
|
+
|
|
24
|
+
@abstractmethod
|
|
25
|
+
def _find_executable(self) -> Path:
|
|
26
|
+
"""Locate the simulator binary on this system."""
|
|
27
|
+
...
|
|
28
|
+
|
|
29
|
+
@abstractmethod
|
|
30
|
+
def run(
|
|
31
|
+
self,
|
|
32
|
+
deck_file: str | Path,
|
|
33
|
+
output_dir: str | Path,
|
|
34
|
+
**kwargs,
|
|
35
|
+
) -> subprocess.CompletedProcess:
|
|
36
|
+
"""Run a simulation and return the completed process."""
|
|
37
|
+
...
|
|
38
|
+
|
|
39
|
+
def version(self) -> str:
|
|
40
|
+
"""Return the simulator version string."""
|
|
41
|
+
if not self.is_available():
|
|
42
|
+
return "not installed"
|
|
43
|
+
try:
|
|
44
|
+
result = subprocess.run(
|
|
45
|
+
[str(self.executable), "--version"],
|
|
46
|
+
capture_output=True,
|
|
47
|
+
text=True,
|
|
48
|
+
timeout=30,
|
|
49
|
+
)
|
|
50
|
+
output = result.stdout.strip() or result.stderr.strip()
|
|
51
|
+
return output.split("\n")[0] if output else "unknown"
|
|
52
|
+
except (subprocess.TimeoutExpired, OSError):
|
|
53
|
+
return "unknown"
|
|
54
|
+
|
|
55
|
+
def is_available(self) -> bool:
|
|
56
|
+
"""Check if the simulator binary exists and is executable."""
|
|
57
|
+
return self.executable is not None and self.executable.is_file()
|
|
58
|
+
|
|
59
|
+
def __repr__(self) -> str:
|
|
60
|
+
return f"{type(self).__name__}(executable={self.executable!r})"
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def find_in_paths(*candidates: str | Path) -> Path | None:
|
|
64
|
+
"""Return the first existing executable from a list of candidate paths."""
|
|
65
|
+
for p in candidates:
|
|
66
|
+
path = Path(p)
|
|
67
|
+
if path.is_file():
|
|
68
|
+
return path
|
|
69
|
+
# Fall back to PATH lookup
|
|
70
|
+
return None
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def find_on_path(name: str) -> Path | None:
|
|
74
|
+
"""Find an executable on the system PATH."""
|
|
75
|
+
found = shutil.which(name)
|
|
76
|
+
return Path(found) if found else None
|
runsim/dumux.py
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""DuMux porous media simulator wrapper (stub)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import subprocess
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
from runsim.base import Simulator
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class DuMux(Simulator):
|
|
12
|
+
"""Run DuMux simulations.
|
|
13
|
+
|
|
14
|
+
This is a stub -- DuMux executables are problem-specific (each example
|
|
15
|
+
compiles to its own binary). Full integration will be added when
|
|
16
|
+
standard DuMux workflows are established.
|
|
17
|
+
|
|
18
|
+
Usage:
|
|
19
|
+
sim = DuMux(executable="/path/to/dumux_example")
|
|
20
|
+
result = sim.run(input_file="params.input", output_dir="./output")
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def __init__(self, executable: str | None = None):
|
|
24
|
+
super().__init__(name="dumux", executable=executable)
|
|
25
|
+
|
|
26
|
+
def _find_executable(self) -> Path:
|
|
27
|
+
"""Search for a DuMux binary in common locations."""
|
|
28
|
+
pkg_dir = Path(__file__).resolve().parent # runsim/ (package)
|
|
29
|
+
project_root = pkg_dir.parent.parent # opm/
|
|
30
|
+
install_dir = project_root / "dumux-build" / "dumux-install"
|
|
31
|
+
|
|
32
|
+
# DuMux doesn't have a single binary -- check install dir exists
|
|
33
|
+
if install_dir.is_dir():
|
|
34
|
+
# Return the install bin directory as a marker
|
|
35
|
+
bin_dir = install_dir / "bin"
|
|
36
|
+
if bin_dir.is_dir():
|
|
37
|
+
# Return first executable found, if any
|
|
38
|
+
for f in sorted(bin_dir.iterdir()):
|
|
39
|
+
if f.is_file() and f.stat().st_mode & 0o111:
|
|
40
|
+
return f
|
|
41
|
+
return Path("dumux") # placeholder
|
|
42
|
+
|
|
43
|
+
def run(
|
|
44
|
+
self,
|
|
45
|
+
deck_file: str | Path = "",
|
|
46
|
+
output_dir: str | Path = ".",
|
|
47
|
+
**kwargs,
|
|
48
|
+
) -> subprocess.CompletedProcess:
|
|
49
|
+
"""Run a DuMux simulation.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
deck_file: Path to input file (DuMux uses .input parameter files).
|
|
53
|
+
output_dir: Directory for simulation output.
|
|
54
|
+
**kwargs: Additional parameters.
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
subprocess.CompletedProcess with stdout/stderr.
|
|
58
|
+
"""
|
|
59
|
+
output_dir = Path(output_dir).resolve()
|
|
60
|
+
output_dir.mkdir(parents=True, exist_ok=True)
|
|
61
|
+
|
|
62
|
+
cmd = [str(self.executable)]
|
|
63
|
+
|
|
64
|
+
if deck_file:
|
|
65
|
+
cmd.append(str(Path(deck_file).resolve()))
|
|
66
|
+
|
|
67
|
+
for key, value in kwargs.items():
|
|
68
|
+
cmd.append(f"-{key}")
|
|
69
|
+
cmd.append(str(value))
|
|
70
|
+
|
|
71
|
+
return subprocess.run(cmd, capture_output=True, text=True, cwd=output_dir)
|
runsim/opm.py
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"""OPM Flow reservoir simulator wrapper."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import subprocess
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
from runsim.base import Simulator, find_in_paths, find_on_path
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class OPMFlow(Simulator):
|
|
12
|
+
"""Run OPM Flow simulations (native or Docker).
|
|
13
|
+
|
|
14
|
+
Usage:
|
|
15
|
+
sim = OPMFlow() # auto-detect executable
|
|
16
|
+
sim = OPMFlow(mode="docker") # use Docker wrapper
|
|
17
|
+
sim = OPMFlow(executable="/path/to/flow") # explicit path
|
|
18
|
+
|
|
19
|
+
result = sim.run("SPE1CASE1.DATA", output_dir="./output")
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(
|
|
23
|
+
self,
|
|
24
|
+
mode: str = "native",
|
|
25
|
+
executable: str | None = None,
|
|
26
|
+
):
|
|
27
|
+
self.mode = mode # "native" or "docker"
|
|
28
|
+
super().__init__(name="opm-flow", executable=executable)
|
|
29
|
+
|
|
30
|
+
def _find_executable(self) -> Path:
|
|
31
|
+
"""Search for the flow binary in common locations."""
|
|
32
|
+
# Determine project paths relative to this file
|
|
33
|
+
pkg_dir = Path(__file__).resolve().parent # runsim/ (package)
|
|
34
|
+
project_dir = pkg_dir.parent # runsim/ (project root)
|
|
35
|
+
project_root = project_dir.parent # opm/
|
|
36
|
+
venv_dir = project_dir / ".venv"
|
|
37
|
+
|
|
38
|
+
if self.mode == "docker":
|
|
39
|
+
candidates = [
|
|
40
|
+
venv_dir / "bin" / "flow-docker",
|
|
41
|
+
]
|
|
42
|
+
else:
|
|
43
|
+
candidates = [
|
|
44
|
+
venv_dir / "bin" / "flow",
|
|
45
|
+
project_root / "opm-build" / "opm-install" / "bin" / "flow",
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
found = find_in_paths(*candidates)
|
|
49
|
+
if found is not None:
|
|
50
|
+
return found
|
|
51
|
+
|
|
52
|
+
# Try system PATH
|
|
53
|
+
binary_name = "flow-docker" if self.mode == "docker" else "flow"
|
|
54
|
+
on_path = find_on_path(binary_name)
|
|
55
|
+
if on_path is not None:
|
|
56
|
+
return on_path
|
|
57
|
+
|
|
58
|
+
# Return the most likely path even if it doesn't exist yet
|
|
59
|
+
return candidates[0] if candidates else Path("flow")
|
|
60
|
+
|
|
61
|
+
def run(
|
|
62
|
+
self,
|
|
63
|
+
deck_file: str | Path,
|
|
64
|
+
output_dir: str | Path,
|
|
65
|
+
**kwargs,
|
|
66
|
+
) -> subprocess.CompletedProcess:
|
|
67
|
+
"""Run an OPM Flow simulation.
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
deck_file: Path to the .DATA deck file.
|
|
71
|
+
output_dir: Directory for simulation output.
|
|
72
|
+
**kwargs: Additional flags passed as --key=value.
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
subprocess.CompletedProcess with stdout/stderr.
|
|
76
|
+
"""
|
|
77
|
+
deck_file = Path(deck_file).resolve()
|
|
78
|
+
output_dir = Path(output_dir).resolve()
|
|
79
|
+
output_dir.mkdir(parents=True, exist_ok=True)
|
|
80
|
+
|
|
81
|
+
cmd = [
|
|
82
|
+
str(self.executable),
|
|
83
|
+
f"--output-dir={output_dir}",
|
|
84
|
+
]
|
|
85
|
+
|
|
86
|
+
# Add extra keyword arguments as --key=value flags
|
|
87
|
+
for key, value in kwargs.items():
|
|
88
|
+
flag = key.replace("_", "-")
|
|
89
|
+
cmd.append(f"--{flag}={value}")
|
|
90
|
+
|
|
91
|
+
cmd.append(str(deck_file))
|
|
92
|
+
|
|
93
|
+
return subprocess.run(cmd, capture_output=True, text=True)
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: runsim
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Unified interface for running reservoir simulators
|
|
5
|
+
License-File: LICENSE
|
|
6
|
+
Requires-Python: >=3.11
|
|
7
|
+
Requires-Dist: numpy
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
|
|
10
|
+
# runsim
|
|
11
|
+
|
|
12
|
+
> **Note:** This package is under active development. APIs and CLI interfaces may change.
|
|
13
|
+
|
|
14
|
+
Unified runner for reservoir simulators, data assimilation, and optimization on macOS.
|
|
15
|
+
|
|
16
|
+
## Structure
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
runsim/
|
|
20
|
+
├── runsim.sh # Unified CLI entry point
|
|
21
|
+
├── pyproject.toml # Python package config (uv + hatchling)
|
|
22
|
+
├── runsim/ # Python package (flat layout)
|
|
23
|
+
│ ├── __init__.py
|
|
24
|
+
│ ├── base.py # Abstract Simulator class
|
|
25
|
+
│ ├── opm.py # OPM Flow wrapper
|
|
26
|
+
│ └── dumux.py # DuMux wrapper (stub)
|
|
27
|
+
├── simulators/
|
|
28
|
+
│ ├── common.sh # Shared helpers + path resolution
|
|
29
|
+
│ ├── setup_env.sh # Create venv, install packages, Docker setup
|
|
30
|
+
│ ├── opm/ # OPM Flow simulator
|
|
31
|
+
│ │ ├── README.md
|
|
32
|
+
│ │ ├── install.sh # Build from source (macOS)
|
|
33
|
+
│ │ ├── install-docker.sh # Install via Docker
|
|
34
|
+
│ │ ├── run.sh # Run bundled test suite (native)
|
|
35
|
+
│ │ ├── run-docker.sh # Run bundled test suite (Docker)
|
|
36
|
+
│ │ └── Dockerfile
|
|
37
|
+
│ ├── pet/ # Python Ensemble Toolbox
|
|
38
|
+
│ │ ├── README.md
|
|
39
|
+
│ │ ├── install.sh # Download repos + pip install
|
|
40
|
+
│ │ └── run.sh # Run PET examples (DA/optimization)
|
|
41
|
+
│ ├── jutuldarcy/ # JutulDarcy simulator
|
|
42
|
+
│ │ ├── README.md
|
|
43
|
+
│ │ ├── install.sh # Install Python/Julia mode
|
|
44
|
+
│ │ └── run.sh # Run simulations
|
|
45
|
+
│ └── dumux/ # DuMux simulator
|
|
46
|
+
│ ├── README.md
|
|
47
|
+
│ ├── install.sh # Build from source (macOS)
|
|
48
|
+
│ ├── run.sh # Run simulations
|
|
49
|
+
│ └── Dockerfile
|
|
50
|
+
└── .venv/ # Python virtual environment (auto-created)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Quick Start
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# 1. Set up environment (venv + packages + OPM Docker)
|
|
57
|
+
./runsim.sh setup
|
|
58
|
+
|
|
59
|
+
# 2. List available PET examples
|
|
60
|
+
./runsim.sh pet --list
|
|
61
|
+
|
|
62
|
+
# 3. Run an example
|
|
63
|
+
./runsim.sh pet Quadratic # Analytic (no Docker needed)
|
|
64
|
+
./runsim.sh pet 3dBox/tiny # OPM Flow (~2 min)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## CLI
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
./runsim.sh <command> [args...]
|
|
71
|
+
|
|
72
|
+
Commands:
|
|
73
|
+
flow [flow-args...] Run native OPM Flow (passthrough to binary)
|
|
74
|
+
flow-docker [flow-args...] Run OPM Flow via Docker (passthrough)
|
|
75
|
+
jutuldarcy [args...] Run JutulDarcy simulation
|
|
76
|
+
dumux [args...] Run DuMux simulation
|
|
77
|
+
dumux-docker [args...] Run DuMux via Docker
|
|
78
|
+
pet [options] <example> Run PET example (data assimilation / optimization)
|
|
79
|
+
setup Bootstrap environment (venv, PET, Docker)
|
|
80
|
+
help Show help
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Running Simulators
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
# OPM Flow (native) -- passthrough to flow binary
|
|
87
|
+
./runsim.sh flow --version
|
|
88
|
+
./runsim.sh flow --output-dir=./out SPE1CASE1.DATA
|
|
89
|
+
|
|
90
|
+
# OPM Flow (Docker)
|
|
91
|
+
./runsim.sh flow-docker --version
|
|
92
|
+
./runsim.sh flow-docker --output-dir=./out SPE1CASE1.DATA
|
|
93
|
+
|
|
94
|
+
# JutulDarcy
|
|
95
|
+
./runsim.sh jutuldarcy --test
|
|
96
|
+
./runsim.sh jutuldarcy /path/to/DECK.DATA
|
|
97
|
+
|
|
98
|
+
# DuMux
|
|
99
|
+
./runsim.sh dumux /path/to/executable
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Running PET Examples
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
./runsim.sh pet --list # List available examples
|
|
106
|
+
./runsim.sh pet LinearModel # Analytic DA
|
|
107
|
+
./runsim.sh pet 3dBox/tiny # 10x10x2 grid (~2 min)
|
|
108
|
+
./runsim.sh pet --simulator flow 3dBox/tiny # Native OPM Flow (default)
|
|
109
|
+
./runsim.sh pet --simulator flow-docker 3dBox/tiny # Docker
|
|
110
|
+
./runsim.sh pet 3SpotRobust --variant bhp # Specific variant
|
|
111
|
+
./runsim.sh pet --clean 3dBox/tiny # Clean outputs then run
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Bundled Test Suites
|
|
115
|
+
|
|
116
|
+
Per-simulator test suites are available via direct script access:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
./simulators/opm/run.sh # Native OPM, all cases
|
|
120
|
+
./simulators/opm/run-docker.sh # Docker, all cases
|
|
121
|
+
./simulators/jutuldarcy/run.sh --test # JutulDarcy SPE1
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Simulators
|
|
125
|
+
|
|
126
|
+
### OPM Flow (Docker) -- Recommended for quick start
|
|
127
|
+
|
|
128
|
+
Runs via Docker on any platform. Simplest setup.
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
./simulators/opm/install-docker.sh # Pull image + create flow wrapper
|
|
132
|
+
./simulators/opm/install-docker.sh --test # + run SPE1 validation
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
> Apple Silicon note: The Docker image is `linux/amd64` and runs under Rosetta/QEMU emulation.
|
|
136
|
+
|
|
137
|
+
### OPM Flow (Native macOS)
|
|
138
|
+
|
|
139
|
+
Full ARM-native performance. Builds Dune 2.10 + OPM from source.
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
./simulators/opm/install.sh # Full build (~30-60 min, skips if installed)
|
|
143
|
+
./simulators/opm/install.sh --deps-only # Homebrew + Dune only
|
|
144
|
+
./simulators/opm/install.sh --test # Build + SPE1 test
|
|
145
|
+
./simulators/opm/install.sh --rebuild # Force full rebuild
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Requires: Xcode CLI tools, Homebrew, cmake, boost, suite-sparse, cjson, fmt.
|
|
149
|
+
|
|
150
|
+
### JutulDarcy
|
|
151
|
+
|
|
152
|
+
Differentiable reservoir simulator (Julia). Two modes available:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
./simulators/jutuldarcy/install.sh # Python mode (pip install jutuldarcy)
|
|
156
|
+
./simulators/jutuldarcy/install.sh --julia # Julia mode (JutulDarcy.jl + juliacall)
|
|
157
|
+
./simulators/jutuldarcy/install.sh --both # Both modes
|
|
158
|
+
./simulators/jutuldarcy/install.sh --test # Install + verify
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### DuMux
|
|
162
|
+
|
|
163
|
+
DUNE-based porous media simulator. Builds from source.
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
./simulators/dumux/install.sh # Full build (shares Dune with OPM if available)
|
|
167
|
+
./simulators/dumux/install.sh --deps-only # Homebrew + Dune only
|
|
168
|
+
./simulators/dumux/install.sh --rebuild # Force full rebuild
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### PET (Python Ensemble Toolbox)
|
|
172
|
+
|
|
173
|
+
Download PET repositories and install Python packages:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
./simulators/pet/install.sh # Download repos + pip install PET/SimulatorWrap
|
|
177
|
+
./simulators/pet/install.sh --status # Show which repos/packages are present
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Verifying Installations
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
./runsim.sh flow --version # e.g. "flow 2026.04-pre"
|
|
184
|
+
./runsim.sh flow-docker --version # e.g. "flow 2025.10"
|
|
185
|
+
|
|
186
|
+
# JutulDarcy (Python mode)
|
|
187
|
+
.venv/bin/python -c "import jutuldarcy; print(jutuldarcy.__version__)"
|
|
188
|
+
|
|
189
|
+
# runsim Python package
|
|
190
|
+
.venv/bin/python -c "from runsim import OPMFlow; print(OPMFlow().version())"
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Python Package
|
|
194
|
+
|
|
195
|
+
The `runsim` package provides a programmatic interface to simulators:
|
|
196
|
+
|
|
197
|
+
```python
|
|
198
|
+
from runsim import OPMFlow
|
|
199
|
+
|
|
200
|
+
sim = OPMFlow() # auto-detect native binary
|
|
201
|
+
sim = OPMFlow(mode="docker") # use Docker wrapper
|
|
202
|
+
|
|
203
|
+
# Check availability
|
|
204
|
+
print(sim.version()) # "flow 2026.04-pre"
|
|
205
|
+
print(sim.is_available()) # True
|
|
206
|
+
|
|
207
|
+
# Run a simulation
|
|
208
|
+
result = sim.run("SPE1CASE1.DATA", output_dir="./output")
|
|
209
|
+
print(result.returncode) # 0 on success
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## PET Examples
|
|
213
|
+
|
|
214
|
+
```
|
|
215
|
+
EXAMPLE TYPE SIMULATOR NOTES
|
|
216
|
+
─────── ──── ───────── ─────
|
|
217
|
+
LinearModel DA none
|
|
218
|
+
3dBox/tiny DA flow needs data generation
|
|
219
|
+
3dBox/small DA flow needs data generation
|
|
220
|
+
3dBox/medium DA flow needs data generation
|
|
221
|
+
3dBox/large DA flow needs data generation
|
|
222
|
+
3dBox/flowrock DA flow needs data generation
|
|
223
|
+
Spe11b DA flow needs data generation
|
|
224
|
+
3Spot Opt flow
|
|
225
|
+
3SpotRobust Opt flow variants: bhp, rate
|
|
226
|
+
3SpotEcalc Opt flow
|
|
227
|
+
5SpotInverted Opt flow
|
|
228
|
+
5SpotLineSearch Opt flow
|
|
229
|
+
Rosenbrock Opt none
|
|
230
|
+
Quadratic Opt none
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Type: **DA** = Data Assimilation (ES-MDA), **Opt** = Optimization
|
|
234
|
+
|
|
235
|
+
## Dependencies
|
|
236
|
+
|
|
237
|
+
- **Python 3.11+**
|
|
238
|
+
- **uv** (recommended) or pip
|
|
239
|
+
- **Docker Desktop** (for OPM Flow Docker mode)
|
|
240
|
+
- [PET](https://github.com/Python-Ensemble-Toolbox) -- data assimilation framework
|
|
241
|
+
- [SimulatorWrap](https://github.com/Python-Ensemble-Toolbox) -- simulator wrappers
|
|
242
|
+
- [OPM Flow](https://opm-project.org/) -- reservoir simulator
|
|
243
|
+
- [JutulDarcy.jl](https://github.com/sintefmath/JutulDarcy.jl) -- differentiable simulator (optional)
|
|
244
|
+
- [DuMux](https://dumux.org/) -- porous media simulator (optional)
|
|
245
|
+
|
|
246
|
+
## Parent Repository Layout
|
|
247
|
+
|
|
248
|
+
```
|
|
249
|
+
project/
|
|
250
|
+
├── runsim/ # This project
|
|
251
|
+
├── pet-repos/
|
|
252
|
+
│ ├── PET-main/ # Python Ensemble Toolbox source
|
|
253
|
+
│ ├── SimulatorWrap-main/ # Simulator wrapper source
|
|
254
|
+
│ └── Examples-main/ # PET example cases
|
|
255
|
+
├── opm-repos/
|
|
256
|
+
│ └── opm-data-master/ # Standard OPM test data (SPE1-9, Norne)
|
|
257
|
+
├── opm-build/ # Native OPM build artifacts (if built)
|
|
258
|
+
└── dumux-build/ # Native DuMux build artifacts (if built)
|
|
259
|
+
```
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
runsim/__init__.py,sha256=MjHmKmESySDirrqpQSjs0CVN5IG1GmedPlIEqfSGFlM,232
|
|
2
|
+
runsim/base.py,sha256=bI3a_GXPpxKxWiysTggjev-TGMEfC45X2MZsrV07u3g,2254
|
|
3
|
+
runsim/dumux.py,sha256=W1-CsERb51FXFm9xZ1HCjSO2ApSHtcbLa35L1euXA5U,2362
|
|
4
|
+
runsim/opm.py,sha256=Diyc9pTb7beVDeeGHt-Md6aWfphkP6kx1Q6QWFZholw,2907
|
|
5
|
+
runsim-0.1.0.dist-info/METADATA,sha256=OTnHvDE6C_DYM96sa8ZXdSpCF6Q6zqc5XKjOpmJgkiQ,9119
|
|
6
|
+
runsim-0.1.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
7
|
+
runsim-0.1.0.dist-info/licenses/LICENSE,sha256=aGB5s5F-X6HF1RzssFMwzlq3gFgxTIx8xX8OIvrfaV8,1072
|
|
8
|
+
runsim-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Roman Manasipov
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|