geoforce / README.md
Ubuntu
Shorten HF Spaces short_description to fit 60-char limit
7d9718e
metadata
title: GeoForce
emoji: πŸŒ‹
colorFrom: red
colorTo: gray
sdk: docker
app_port: 8765
pinned: true
license: mit
short_description: Agent-orchestrated geothermal solver + CNN surrogate.

GeoForce

Opus 4.7 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.

Built for the "Built with Opus 4.7" Claude Code Hackathon (Cerebral Valley Γ— Anthropic, 2026-04-21 β†’ 2026-04-27) by Robi Dany Riupassa (ForceX AI).


Why two engines?

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.

Architecture

                 +--------------------------+
 user query ---> |    Opus 4.7 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.

Dashboard

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.

dashboard

Demo scenarios

Three hand-tuned Indonesian geothermal questions in demo/scenarios.yaml:

  1. 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.)
  2. q2_sustainable_mw β€” "How many MW can this doublet sustain for 20 years? Give P10/P50/P90." (surrogate-led, 200-sample Monte Carlo.)
  3. 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

Install & run

Native (dev)

# 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 (single-container, prod-ish)

docker build -t geoforce .
docker run --rm -p 8765:8765 \
  -e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY \
  geoforce
# open http://localhost:8765

The image serves the built React bundle and the FastAPI on the same port β€” no reverse proxy needed.

API surface

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

What's in scope vs. out

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 (hackathon discipline, documented honestly):

  • Two-phase flow / flashing (steam). The solver does not and will not model this; /query refuses 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.

If the Day-1-evening analytical-benchmark gate had failed (Theis / 1-D conduction > 5 % relative error) we would have dropped the solver and shipped surrogate-only. It didn't; both engines ship.

Credits

  • 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 and Opus 4.7.

License

MIT β€” see LICENSE. v1.1 surrogate weights are redistributed under the same license; see surrogate/weights/README.md for provenance.