| title | GeoForce |
|---|---|
| emoji | 🌋 |
| colorFrom | red |
| colorTo | gray |
| sdk | docker |
| app_port | 8765 |
| pinned | true |
| license | mit |
| short_description | Agent-orchestrated geothermal solver + CNN surrogate. |
AI agents orchestrate two engines — a newly-built open-source geothermal solver (GeoForce-Solver) and a deployed physics-informed CNN surrogate — to answer real Indonesian geothermal engineering questions.
by Robi Dany Riupassa (ForceX AI).
Geothermal decisions sit on a trade-off:
- Numerical solvers (TOUGH, Waiwera) are trustworthy but slow and heavy. You can't Monte-Carlo them interactively.
- Neural surrogates are instant but only as good as the distribution they were trained on, and they silently extrapolate.
A single agent that can choose between them — or run both and report the gap — is strictly more useful than either alone. That is what GeoForce does. When the solver and the surrogate disagree, the dashboard shows the Δ; when they agree, you trust the surrogate for UQ sweeps and save two orders of magnitude of compute.
+--------------------------+
user query ---> | AI orchestrator | (claude-agent-sdk)
+-----------+--------------+
|
+------------------+------------------+
| | |
v v v
+-------------+ +--------------+ +-------------+
| solver- | | surrogate- | | uq- |
| engineer | | operator | | specialist |
+------+------+ +------+-------+ +------+------+
| | |
v v v
+-------------+ +--------------+ +-------------+
| GeoForce- | | ReservoirCNN | | Monte Carlo |
| Solver | | v1.1 weights | | + OAT |
| (Darcy + | | (CPU, ~30ms) | | sensitivity |
| energy, | | | | |
| implicit) | | | | |
+------+------+ +------+-------+ +------+------+
| | |
+---------+--------+--------------------+
v
+-------------------+
| reviewer agent | physics-plausibility gate
+---------+---------+
v
+-------------------+ SSE (text / tool / result)
| FastAPI /query | --------------------------------> React UI
+-------------------+
Seven supporting subagents live under .claude/agents/ (planner,
geologist, solver-engineer, surrogate-operator, uq-specialist,
visualizer, reviewer, ui-engineer). See AGENTS.md.
Plain React 18 + Vite + TypeScript + zustand, styled entirely with the
Claude design tokens (warm paper background, Clay #CC785C accent,
Source Serif 4 headings, Inter body, JetBrains Mono for tool calls). No
component library. Canvas-based magma heatmaps for the temperature
fields so the bundle stays under 160 kB.
The UI streams the agent trace via Server-Sent Events and shows the solver and surrogate fields side-by-side with a shared color scale, so disagreement is visually obvious.
Three hand-tuned Indonesian geothermal questions in demo/scenarios.yaml:
q1_drill_temperature— "If I drill at (200 m, 100 m) what temperature will I hit after 1 year of 0.5 kg/s cold reinjection?" (solver-led, line-source-style drawdown in T.)q2_sustainable_mw— "How many MW can this doublet sustain for 20 years? Give P10/P50/P90." (surrogate-led, 200-sample Monte Carlo.)q3_well_placement— "Where should I place 3 new producers in this 400 m × 400 m field?" (surrogate-led, OAT sensitivity.)
Run all three end-to-end:
.venv/bin/python -m agent.runtime /demo# 1. Python side
python3.11 -m venv .venv
source .venv/bin/activate
pip install -e ".[agent,app,dev]"
# 2. Start the API
uvicorn agent.api:app --host 0.0.0.0 --port 8765
# 3. Dashboard (separate shell)
cd dashboard
npm install
npm run dev # http://localhost:5173 (proxies /api -> :8765)Requires an ANTHROPIC_API_KEY in .env at the repo root.
docker build -t geoforce .
docker run --rm -p 8765:8765 \
-e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY \
geoforce
# open http://localhost:8765The image serves the built React bundle and the FastAPI on the same port — no reverse proxy needed.
| Method | Path | Purpose |
|---|---|---|
| GET | /health |
Liveness ({"ok": true}) |
| GET | /scenarios |
Returns demo/scenarios.yaml |
| POST | /predict |
Run solver / surrogate / both for a scenario |
| POST | /query |
Stream agent events as SSE |
In scope: single-phase liquid water, 2-D rectangular grids,
geothermal temperatures 25–350 °C, pressures 0.1–30 MPa, per-cell
injector/producer sources, Monte-Carlo + OAT sensitivity.
Out of scope (current version):
- Two-phase flow / flashing (steam). The solver does not and will not
model this;
/queryrefuses gracefully. - Three-dimensional reservoirs.
- Fractures as discrete objects (we smear them into permeability).
- CO₂ or brine chemistry.
- Retraining the CNN surrogate — v1.1 weights are frozen.
- Solver numerics inspired by the TOUGH family (LBNL) — single-phase
subset only. See
.claude/skills/tough-reference/. - Magma colormap: matplotlib (Apache-2.0), 12-stop approximation.
- Source Serif 4, Inter, JetBrains Mono via Google Fonts.
- Built with Claude Code by ForceX AI.
MIT — see LICENSE. v1.1 surrogate weights are redistributed under the
same license; see surrogate/weights/README.md for provenance.
