Skip to content

MatPro-IFE/pde-agents

Repository files navigation

PDE Agents

A multi-agent ecosystem built on open-source LLMs running locally to solve PDEs with the Finite Element Method, enhanced with a GraphRAG knowledge graph for physics-informed reasoning, and a document intelligence pipeline that cross-references scientific literature to simulation runs.

Hardware: 2Γ— NVIDIA RTX PRO 6000 Blackwell Server Edition (~98 GB VRAM each Β· ~196 GB total) Β· CUDA 13.1
FEM Solver: DOLFINx (FEniCSx) 0.10.0.post2


Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     ORCHESTRATOR (LangGraph)                              β”‚
β”‚               LLM: llama3.3:70b  (supervisor)                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚              β”‚               β”‚
           β–Ό              β–Ό               β–Ό
 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
 β”‚  AGENT-1         β”‚ β”‚  AGENT-2     β”‚ β”‚  AGENT-3      β”‚
 β”‚  Simulation      β”‚ β”‚  Analytics   β”‚ β”‚  Database     β”‚
 β”‚  qwen2.5-coder   β”‚ β”‚  llama3.3    β”‚ β”‚  qwen2.5-coderβ”‚
 β”‚  :32b            β”‚ β”‚  :70b        β”‚ β”‚  :14b         β”‚
 β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                   β”‚                 β”‚
         β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
         β–Ό    β–Ό                             β–Ό  β–Ό
 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
 β”‚  FEniCSx     β”‚  β”‚  NumPy       β”‚  β”‚  Neo4j Knowledge Graph (GraphRAG)  β”‚
 β”‚  DOLFINx     β”‚  β”‚  Plotly Dash β”‚  β”‚  ──────────────────────────────────│
 β”‚  2D/3D FEM   β”‚  β”‚  PostgreSQL  β”‚  β”‚  Run nodes + 768-dim embeddings    β”‚
 β”‚  Gmsh meshes β”‚  β”‚  FastAPI     β”‚  β”‚  SIMILAR_TO KNN edges              β”‚
 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚  Reference + ReferenceChunk nodes  β”‚
                                     β”‚  Document chunk vector index (HNSW) β”‚
                                     β”‚  Cross-ref chunks β†’ simulation runs β”‚
                                     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
 β”‚  Document Intelligence Pipeline (Celery + Docling)                       β”‚
 β”‚  PDFs / TXT / Markdown / Web ebooks β†’ structured chunks β†’ embeddings     β”‚
 β”‚  β†’ (:ReferenceChunk) nodes β†’ CROSS_REFS to similar :Run nodes           β”‚
 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Agents

Agent Model Role
Simulation Agent qwen2.5-coder:32b Set up, validate, run, and debug FEM simulations β€” three KG modes (see below)
Analytics Agent llama3.3:70b Analyze results, compare runs, query the knowledge graph
Database Agent qwen2.5-coder:14b Store results, run SQL queries, catalog studies, search history
Orchestrator llama3.3:70b Coordinate all agents, synthesise final report

Simulation Agent β€” KG integration modes

The Simulation Agent supports three knowledge-graph integration modes, selectable via constructor flag or API query parameter:

Mode Flag Behaviour
KG On (default) β€” Mandatory check_config_warnings + query_knowledge_graph calls before every simulation
KG Off disable_kg=True KG tools removed; agent skips straight to validate_config β†’ run_simulation
KG Smart smart_kg=True Warm-start injection of top-3 similar past runs (via HNSW) into system prompt; KG tools remain available but are only invoked after a failure or for unknown materials

KG Smart warm-start: Before the agent loop begins, the task description is embedded with nomic-embed-text and the Neo4j HNSW index is queried for the 3 most similar successful past runs. Their configurations are injected directly into the system prompt as few-shot reference examples β€” no tool call needed. This pattern is inspired by CRAG (corrective RAG) and AriGraph (episodic KG memory).

Ablation results (10 benchmark tasks, 3 difficulty tiers):

  • KG On: 60% success, avg 5.3 iterations
  • KG Off: 100% success, avg 3.0 iterations
  • KG Smart: 90% success, avg 3.8 iterations β€” recovers most KG Off performance while retaining KG access

Services

All browser-facing UIs are accessed through a single nginx reverse proxy on port 8050.

Service Host access Purpose
nginx :8050 Reverse proxy β€” single entry point for all web UIs
Dashboard :8050/ (via nginx) Plotly Dash visualization, agent chat, KG explorer
Agents API :8050/agents/ or :8000 FastAPI REST + Swagger UI
Neo4j Browser :7474 (direct) Knowledge graph browser
NeoDash :9001 (direct) Open-source graph dashboard β€” reuses ex-MinIO console port
MinIO Console :9002 β†’ SSH tunnel Object storage browser (moved to port 9002)
MinIO API :9000 S3-compatible object storage API
FEniCSx Runner :8080 DOLFINx simulation job REST API
Ollama :11434 Local LLM server (GPU-accelerated)
PostgreSQL :5432 Simulation metadata database
Redis :6379 Celery task broker (document ingestion queue)
Neo4j Bolt :7687 Graph database driver protocol

NeoDash reuses port 9001 so no new firewall rule is needed.
The MinIO S3 API on port 9000 is unaffected β€” all agent file uploads and
downloads continue normally. The MinIO web console is remapped to port 9002
(internal only β€” no firewall change required). Access it via SSH tunnel:

ssh -L 19002:localhost:9002 -N <server>   # then open http://localhost:19002

Quick Start

Prerequisites

Required: Docker 29+, NVIDIA drivers (tested: 590.48.01), NVIDIA Container Toolkit.

Install NVIDIA Container Toolkit if not present:

sudo apt-get install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker

1. One-time setup

cd ~/pde-agents
cp env.example .env        # edit passwords/model names if desired
chmod +x setup.sh
./setup.sh

This will:

  • Build the three custom Docker images (agents, fenics-runner, dashboard)
  • Start all services including Neo4j, Redis, and NeoDash
  • Initialize the PostgreSQL schema
  • Auto-seed the knowledge graph with 10 engineering materials, 6 known failure patterns, and 20 physics reference nodes
  • Start the Celery worker for asynchronous document ingestion
  • Pull LLM models in the background (~70 GB total, 30–90 min first time)

2. Pull the embedding model

The knowledge graph uses nomic-embed-text (274 MB) for semantic similarity:

docker exec pde-ollama ollama pull nomic-embed-text

3. Confirm all models are ready

docker exec pde-ollama ollama list
# Expected output once all pulls complete:
# NAME                    SIZE
# llama3.3:70b            42 GB
# qwen2.5-coder:32b       19 GB
# qwen2.5-coder:14b       9.0 GB
# nomic-embed-text:latest 274 MB

4. Check all services are healthy

make health

5. Open the dashboard

Navigate to http://localhost:8050 in your browser.

All services are accessible from the dashboard navbar or directly:

URL What you get
http://localhost:8050/ Dashboard (all tabs)
http://localhost:8050/agents/docs API Swagger UI
http://localhost:7474 Neo4j Browser
http://localhost:9001 NeoDash (graph explorer β€” reuses MinIO console port)
via SSH tunnel MinIO console (see note above)

Use Cases

All examples below can be sent to the Agents REST API at http://localhost:8000 (direct) or http://localhost:8050/agents/ (via nginx), or run via individual agent Python scripts inside the container.


Use Case 1 β€” 2D Heat Equation (Steel Plate)

A steel plate heated on the right wall, fixed temperature on the left, insulated top and bottom. Classic Dirichlet + Neumann boundary conditions.

Via Agents API (recommended):

curl -s -X POST http://localhost:8000/run \
  -H "Content-Type: application/json" \
  -d '{
    "task": "Run a 2D heat equation on a 64x64 steel plate. Left wall 300K, right wall 500K, top and bottom insulated. Use u_init=300.0, t_end=100.0, dt=0.5. Store the results and report the temperature range and wall time."
  }' | python3 -m json.tool

Direct FEniCSx REST API:

curl -s -X POST http://localhost:8080/run \
  -H "Content-Type: application/json" \
  -d '{
    "dim": 2, "nx": 64, "ny": 64,
    "k": 50.0, "rho": 7800.0, "cp": 500.0,
    "u_init": 300.0,
    "bcs": [
      {"type": "dirichlet", "value": 300.0, "location": "left"},
      {"type": "dirichlet", "value": 500.0, "location": "right"},
      {"type": "neumann",   "value": 0.0,   "location": "top"},
      {"type": "neumann",   "value": 0.0,   "location": "bottom"}
    ],
    "t_end": 100.0, "dt": 0.5,
    "run_id": "steel_plate_64x64",
    "output_dir": "/workspace/results"
  }' | python3 -m json.tool

After every successful run the system automatically:

  1. Stores metadata in PostgreSQL
  2. Uploads output files to MinIO (simulation-results/runs/<run_id>/)
  3. Adds a Run node to the Neo4j knowledge graph (material inference + rule warnings)
  4. Embeds the run summary with nomic-embed-text (768-dim vector stored on the Run node)
  5. Creates SIMILAR_TO edges to the top-5 most similar past runs (cosine β‰₯ 0.85)

Use Case 2 β€” Complex Geometry with Gmsh

FEniCSx supports 9 built-in Gmsh geometry types for non-rectangular domains. Specify "geometry" in the config with a "type" key:

curl -s -X POST http://localhost:8080/run \
  -H "Content-Type: application/json" \
  -d '{
    "dim": 2,
    "k": 50.0, "rho": 7800.0, "cp": 500.0,
    "u_init": 300.0,
    "geometry": {"type": "l_shape", "Lx": 0.08, "Ly": 0.08, "mesh_size": 0.005},
    "bcs": [
      {"type": "dirichlet", "value": 800.0, "boundary": "left"},
      {"type": "robin",     "h": 25.0,  "T_inf": 300.0, "boundary": "top"},
      {"type": "robin",     "h": 25.0,  "T_inf": 300.0, "boundary": "right"},
      {"type": "neumann",   "value": 0.0,               "boundary": "bottom"}
    ],
    "t_end": 0.5, "dt": 0.02,
    "run_id": "steel_l_shape_robin"
  }' | python3 -m json.tool

Available geometry types:

Type Description Boundaries
rectangle Standard rectangle (default) left, right, top, bottom
l_shape L-shaped domain (re-entrant corner) left, right, top, bottom, inner_h, inner_v
circle Full circular disk boundary
annulus Ring / annular domain inner_wall, outer_wall
hollow_rectangle Rectangle with rectangular hole outer_*, inner_*
t_shape T-shaped cross-section left, right, top, bottom, stem_left, stem_right
stepped_notch Stepped notch (stress concentrator) left, right, top, bottom, notch_*
box 3D rectangular box left, right, top, bottom, front, back
cylinder 3D cylinder bottom_face, top_face, lateral

For Gmsh geometries use "boundary" key in BCs (physical group name) instead of "location".


Use Case 3 β€” 3D Heat Equation (Aluminum Block with Convection)

curl -s -X POST http://localhost:8000/run \
  -H "Content-Type: application/json" \
  -d '{
    "task": "Run a 3D heat equation on a 16x16x16 aluminum block. k=237, rho=2700, cp=900. Left wall 273K, right wall 373K. Front and back surfaces have Robin convection: h=25, T_inf=293K. Top and bottom insulated. t_end=300.0, dt=2.0. Report min/max temperature."
  }' | python3 -m json.tool

Use Case 4 β€” Parametric Sweep (Thermal Conductivity Study)

curl -s -X POST http://localhost:8000/agent/simulation \
  -H "Content-Type: application/json" \
  -d '{
    "task": "Run a parametric sweep on a 2D 32x32 domain varying thermal conductivity k over [1, 10, 50, 100, 200] W/(mK). Keep rho=7800, cp=500, left wall 300K, right wall 500K, insulated top and bottom, u_init=300.0, t_end=20.0, dt=0.5."
  }' | python3 -m json.tool

Use Case 5 β€” Large-Scale Simulation Study (805 Variations)

Run the comprehensive study script to generate 805 simulation runs across 8 physics studies, varying geometry, mesh size, material, boundary conditions, initial conditions, time-dependent BCs, and solver parameters:

# Execute all 805 runs (runs inside the agents container, skips already-completed runs)
docker exec pde-agents python3 /app/scripts/sweep_full_study.py

Studies covered:

Study Variations What varies
Geometry study 45 9 geometries Γ— 5 mesh sizes
Material study 100 10 materials Γ— 10 mesh densities
BC combination study 120 12 BC combos Γ— 10 mesh densities
Initial condition study 50 10 IC values Γ— 5 mesh sizes
Time-stepping study 90 9 dt values Γ— 10 mesh densities
3D geometry study 60 3 geometries Γ— 20 runs
Robin convection study 100 10 h-values Γ— 10 mesh densities
Multi-material study 240 10 materials Γ— 8 BCs Γ— 3 meshes

All runs are automatically added to Neo4j, PostgreSQL, and MinIO, and embedded for semantic similarity. The knowledge graph grows intelligently with every run.


Use Case 6 β€” Analytics: Compare Runs

curl -s -X POST http://localhost:8000/agent/analytics \
  -H "Content-Type: application/json" \
  -d '{
    "task": "Compare the runs steel_plate_64x64 and steel_agent_final. What is the difference in temperature distribution? Which mesh resolution is sufficient and why?"
  }' | python3 -m json.tool

Use Case 7 β€” Database Queries in Natural Language

# Find the hottest simulations
curl -s -X POST http://localhost:8000/agent/database \
  -H "Content-Type: application/json" \
  -d '{"task": "Show me all runs where the maximum temperature exceeded 450K, ordered by wall time."}' \
  | python3 -m json.tool

# Material lookup via knowledge graph
curl -s -X POST http://localhost:8000/agent/database \
  -H "Content-Type: application/json" \
  -d '{"task": "What material properties does copper have? Find similar past runs that used copper-like conductivity."}' \
  | python3 -m json.tool

Use Case 8 β€” Knowledge Graph Queries

The knowledge graph accumulates information with every run and stores curated physics knowledge. Query it via the API or ask any agent.

# Graph statistics (includes embedding coverage and reference count)
curl -s http://localhost:8000/kg/stats | python3 -m json.tool

# Semantic similarity search β€” finds past runs similar to a natural language description
curl -s -X POST http://localhost:8000/kg/search \
  -H "Content-Type: application/json" \
  -d '{"query": "steel l-shape with robin convection, component-scale", "top_k": 5}' \
  | python3 -m json.tool

# Pre-run context: warnings + similar runs + physics references
curl -s -X POST http://localhost:8000/kg/check \
  -H "Content-Type: application/json" \
  -d '{"k": 50, "dim": 2, "Lx": 0.08, "Ly": 0.08,
       "bcs": [{"type": "dirichlet", "value": 800},
               {"type": "robin", "h": 25, "T_inf": 300}]}' \
  | python3 -m json.tool

# Semantic chunk search across all indexed documents
curl -s "http://localhost:8000/references/search-chunks?query=heat+equation+backward+euler&top_k=5" \
  | python3 -m json.tool

# Re-seed static knowledge (safe to call repeatedly)
curl -s -X POST http://localhost:8000/kg/seed | python3 -m json.tool

Example Cypher queries (Neo4j Browser at http://localhost:7474):

-- Semantically similar run pairs (via KNN edges)
MATCH (r:Run)-[rel:SIMILAR_TO]->(s:Run)
RETURN r.run_id, s.run_id, rel.score AS similarity
ORDER BY rel.score DESC LIMIT 10

-- Runs grouped by BC pattern with average outcomes
MATCH (r:Run)-[:USES_BC_CONFIG]->(b:BCConfig)
WHERE r.status = 'success'
RETURN b.pattern, count(r) AS runs, avg(r.t_max) AS avg_t_max
ORDER BY runs DESC

-- Document chunks cross-referenced to a specific run
MATCH (c:ReferenceChunk)-[xr:CROSS_REFS]->(r:Run {run_id: 'your_run_id'})
MATCH (ref:Reference)-[:HAS_CHUNK]->(c)
RETURN c.heading, c.text, c.classification, xr.score, ref.title, ref.url
ORDER BY xr.score DESC LIMIT 10

-- Full knowledge graph overview
MATCH (n) RETURN labels(n)[0] AS type, count(n) AS count ORDER BY count DESC

Use Case 9 β€” Pre-Run Physics Check

Ask the Simulation Agent to validate a configuration using the knowledge graph before running:

curl -s -X POST http://localhost:8000/agent/simulation \
  -H "Content-Type: application/json" \
  -d '{
    "task": "What issues might arise if I run a 2D simulation with k=50, nx=8, ny=8, theta=0.0, dt=0.5, u_init=0, and Dirichlet BCs at 300 K and 800 K? Use check_config_warnings and get_physics_references."
  }' | python3 -m json.tool

The response includes:

  • Rule violations (mesh too coarse, explicit instability, inconsistent IC)
  • Semantic similar runs with outcomes
  • Physics reference facts (h coefficients, k(T) validity, solver guidance)
  • An overall recommendation string

Use Case 10 β€” Upload External Documents to the Knowledge Base

Upload PDFs, TXT, or Markdown files and have them automatically chunked, embedded, and cross-referenced to relevant simulation runs.

Via dashboard: Open the 🧠 Knowledge Graph tab β†’ βž• Add to Knowledge Graph β†’ πŸ“Ž Upload File tab.

Via API:

# Upload a PDF paper β€” automatically queued for Docling-based structured extraction
curl -s -X POST http://localhost:8000/references/upload \
  -F "file=@paper.pdf" \
  -F "title=Thermal Conductivity of Alloys at Elevated Temperatures" \
  -F "source=ASTM E1461, 2022" \
  -F "subject=thermal conductivity steel copper titanium FEM" \
  -F "ref_type=paper" \
  -F "auto_link_top_k=10" \
  | python3 -m json.tool

# Auto-fill metadata from a DOI (CrossRef API)
# In the dashboard: paste DOI in the DOI field and press Enter

# Check processing status
curl -s http://localhost:8000/references/{ref_id}/status | python3 -m json.tool

# List all uploaded references with processing status
curl -s http://localhost:8000/references/uploaded | python3 -m json.tool

# Get structured chunks for a specific document
curl -s http://localhost:8000/references/{ref_id}/chunks | python3 -m json.tool

# Pin a document to a specific simulation run
curl -s -X POST http://localhost:8000/references/{ref_id}/link/{run_id}

What happens after upload:

  1. File stored in MinIO (reference-uploads/)
  2. (:Reference) node created in Neo4j with process_status: queued
  3. Celery worker picks up the task and begins Docling-based structured parsing
  4. Each section/paragraph extracted as a (:ReferenceChunk) node with heading, type, and classification
  5. Each chunk embedded with nomic-embed-text (768-dim vector)
  6. Chunks cross-referenced to semantically similar (:Run) nodes via CROSS_REFS edges
  7. Chunks linked to matching (:Material), (:BCConfig), (:Domain) entities via RELATES_TO edges
  8. process_status updated to completed with counts of chunks and cross-refs

Use Case 11 β€” Index Web-Based Tutorials and Ebooks

Crawl and index web resources (online tutorials, ebooks, documentation sites) so agents can cite and reason from them alongside your simulation runs.

Via dashboard: Open the 🧠 Knowledge Graph tab β†’ βž• Add to Knowledge Graph β†’ 🌐 Web Resource URL tab.

Via API:

# Index the FEniCSx tutorial (crawls up to 50 pages)
curl -s -X POST http://localhost:8000/references/fetch-url \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://jsdokken.com/dolfinx-tutorial/",
    "title": "FEniCSx Tutorial β€” Dokken",
    "subject": "FEniCSx DOLFINx FEM heat equation Poisson boundary conditions mesh",
    "max_pages": 50
  }' | python3 -m json.tool

What happens:

  1. (:Reference) parent node created with is_web: true
  2. Celery worker crawls the site (BFS, up to max_pages, polite 1s delays)
  3. Each page parsed through Docling's HTML pipeline
  4. Structured chunks extracted (text, code, equations, tables)
  5. Each page creates a child (:Reference {type: "web_page"}) with its exact URL
  6. Chunks embedded and cross-referenced to simulation runs

Example result (FEniCSx tutorial, 50 pages):

  • ~300+ chunks extracted and embedded
  • 1000+ cross-references created to simulation runs
  • Semantic search for "heat equation backward Euler time stepping" returns chunk from chapter2/heat_equation.html with score 0.871 and a clickable link to that exact page

Useful resource URLs to index:

  • FEniCSx Tutorial: https://jsdokken.com/dolfinx-tutorial/
  • FEniCS Book: https://fenicsproject.org/pub/tutorial/html/
  • OpenFOAM User Guide: https://www.openfoam.com/documentation/user-guide
  • Any HTML-based ebook or documentation site

Use Case 12 β€” Semantic Chunk Search (Dashboard)

The πŸ”¬ Semantic Chunk Search panel (bottom of the 🧠 Knowledge Graph tab) searches across all document chunks indexed from uploaded PDFs and web resources.

  • Type a query (e.g. "thermal conductivity steel at high temperature") and press Enter or click Search Chunks
  • Results show the most semantically relevant paragraphs, equations, and sections
  • Each result card shows:
    • Clickable title β†’ opens the source page (web resources) or paper (if URL/DOI provided)
    • Classification badge: material, bc, solver, domain, or general
    • Chunk type: text, code, equation, table
    • Similarity score
    • "🌐 Open page" or "πŸ“„ View source" button for direct access

Use Case 13 β€” Run Explorer (Dashboard)

The πŸ”Ž Run Explorer tab provides a visual interface to browse every simulation run:

  • Left panel: searchable, filterable run list (status, dimension, keyword)
  • Right panel: detailed view with sub-tabs for:
    • Overview β€” KPIs (T_max, T_min, wall time, DOFs) + SIMILAR_TO neighbour table
    • Agent Timeline β€” step-by-step trace of every agent reasoning and tool-call
    • Config β€” full simulation configuration used (for reproducibility)
    • Files β€” MinIO file listing with object names and sizes
    • Recommendations β€” agent suggestions from the run

Use Case 14 β€” Knowledge Graph Tab (Dashboard)

The 🧠 Knowledge Graph tab exposes all GraphRAG features:

Graph Statistics panel: Real-time counts of all node types, embedding coverage percentage, SIMILAR_TO edge count, Reference count, and ReferenceChunk count.

Semantic Run Search: Type a free-text description and the KG finds the top-5 similar past runs using the HNSW vector index. Results show similarity scores with progress bars.

Physics Reference Browser: Browse all 20 curated reference facts filtered by type:

  • πŸ“ Material Properties β€” k(T) and cp(T) dependence, phase transition limits
  • πŸ”² BC Practice β€” realistic h coefficients, heat flux magnitudes, temperature validity
  • βš™οΈ Solver Guidance β€” mesh resolution rules, Fourier number criterion, P2 vs P1
  • 🌐 Domain Physics β€” radiation at micro-scale, buoyancy at structural scale, thermal time constants

βž• Add to Knowledge Graph panel:

  • πŸ“Ž Upload File tab: DOI quick-fill (press Enter to auto-fetch from CrossRef) + file drag-and-drop
  • 🌐 Web Resource URL tab: paste any URL, set page limit, press Enter or click Fetch

πŸ”¬ Semantic Chunk Search: Full-text semantic search across all indexed document chunks with clickable source links.

NeoDash launcher: Opens the open-source graph visualization tool at port 9001.


Use Case 15 β€” Direct Python (inside containers)

Run the solver directly

# docker exec -it pde-fenics python3
import sys; sys.path.insert(0, '/workspace')
from simulations.solvers.heat_equation import HeatConfig, HeatEquationSolver

# Gmsh L-shape geometry with named boundary conditions
cfg = HeatConfig(
    dim=2,
    k=50.0, rho=7800.0, cp=500.0,
    u_init=300.0,
    geometry={"type": "l_shape", "Lx": 0.08, "Ly": 0.08, "mesh_size": 0.005},
    bcs=[
        {"type": "dirichlet", "value": 800.0, "boundary": "left"},
        {"type": "robin",     "h": 25.0, "T_inf": 300.0, "boundary": "top"},
        {"type": "neumann",   "value": 0.0,              "boundary": "right"},
    ],
    t_end=0.5, dt=0.02,
    run_id="l_shape_robin",
    output_dir="/workspace/results",
)
result = HeatEquationSolver(cfg).solve()
print(result)

Query the knowledge graph with semantic search

# docker exec -it pde-agents python3
import sys; sys.path.insert(0, '/app')
from knowledge_graph.graph import get_kg

kg = get_kg()
print("Stats:", kg.stats())
# Stats: {'total_runs': 805, 'embedded_runs': 805, 'references': 44,
#          'ref_chunks': 325, 'materials': 10, 'bc_configs': 4, 'domains': 4, ...}

# Semantic similarity search using vector embeddings
similar = kg.get_similar_runs_semantic({
    "k": 50.0, "dim": 2, "Lx": 0.08, "Ly": 0.08,
    "bcs": [{"type": "dirichlet"}, {"type": "robin", "h": 25}],
    "geometry": {"type": "l_shape"},
}, top_k=5)
for r in similar:
    print(f"  {r['run_id'][:16]}  score={r['similarity_score']:.4f}  T_max={r['t_max']:.0f}K")

# Semantic chunk search across all documents
from knowledge_graph.embeddings import get_embedder
vec = get_embedder().embed_text("backward Euler time stepping heat equation stability")
chunks = kg.search_chunks_by_query(vec, top_k=5)
for c in chunks:
    print(f"  [{c['score']:.3f}] {c['ref_title']} β€” {c['heading'][:60]}")

Backfill embeddings and build KNN edges

# docker exec -it pde-agents python3
import sys; sys.path.insert(0, '/app')
from knowledge_graph.graph import get_kg
kg = get_kg()

# Embed all runs that don't yet have a vector
result = kg.backfill_embeddings(batch_size=50)
print(result)  # {'newly_embedded': 0, 'failed': 0, ...}

# Build / refresh SIMILAR_TO KNN edges for all embedded runs
result = kg.build_all_similar_to_edges(k=5, min_score=0.85)
print(result)  # {'processed': 805, 'total_similar_to_in_graph': 4025}

Physics: Heat Equation

Mathematical Formulation

Strong form (transient heat conduction with source):

ρ c_p βˆ‚u/βˆ‚t βˆ’ βˆ‡Β·(k βˆ‡u) = f    in Ξ© Γ— (0, T]

Boundary conditions:

  • Dirichlet: u = g on Ξ“_D (prescribed temperature)
  • Neumann (flux): k βˆ‚u/βˆ‚n = h on Ξ“_N (insulated: h=0)
  • Robin (convective): k βˆ‚u/βˆ‚n = Ξ±(u_∞ βˆ’ u) on Ξ“_R

Weak form β€” ΞΈ-scheme (Backward Euler ΞΈ=1, Crank-Nicolson ΞΈ=0.5):

(ρc_p/dt)(u^{n+1} βˆ’ u^n, v)_Ξ©
  + ΞΈ   [ k(βˆ‡u^{n+1}, βˆ‡v)_Ξ© + Ξ±(u^{n+1}, v)_Ξ“R ]
  + (1βˆ’ΞΈ)[ k(βˆ‡u^n, βˆ‡v)_Ξ©    + Ξ±(u^n, v)_Ξ“R     ]
= ∫_Ξ© f v dx + ∫_Ξ“N h v ds + Ξ±(u_∞, v)_Ξ“R

Configuration Reference

Parameter Type Description Example
dim int Spatial dimension (2 or 3) 2
nx, ny, nz int Mesh divisions (built-in meshes) 64, 64
k float Thermal conductivity [W/(mΒ·K)] 50.0 (steel)
rho float Density [kg/mΒ³] 7800.0
cp float Specific heat [J/(kgΒ·K)] 500.0
source float Volumetric heat source [W/mΒ³] 0.0
u_init float Initial temperature [K] β€” set close to BCs 300.0
t_end float Simulation end time [s] 100.0
dt float Time step [s] 0.5
theta float Time integration: 1.0=BE, 0.5=CN 1.0
geometry dict Gmsh geometry spec β€” see table above {"type": "l_shape"}
bcs list Boundary condition specs β€”
run_id str Unique run identifier "steel_plate_01"
output_dir str Directory for XDMF/VTK output "/workspace/results"

Boundary condition spec:

// Built-in mesh (location key)
{"type": "dirichlet", "value": 300.0, "location": "left"}
{"type": "neumann",   "value": 0.0,   "location": "top"}
{"type": "robin",     "alpha": 10.0,  "u_inf": 293.0, "location": "front"}

// Gmsh mesh (boundary key β€” matches physical group name)
{"type": "dirichlet", "value": 800.0, "boundary": "left"}
{"type": "robin",     "h": 25.0, "T_inf": 300.0, "boundary": "outer_wall"}

Important: Always set u_init close to the Dirichlet boundary values. The knowledge graph will automatically warn you with INCONSISTENT_IC if a large temperature jump is detected.

Material Parameters (seeded in Knowledge Graph)

Material k [W/(m·K)] ρ [kg/m³] c_p [J/(kg·K)] α [m²/s]
Steel (carbon) 50 7800 500 1.28e-5
Stainless Steel 316 16 8000 500 4.00e-6
Aluminium 6061 200 2700 900 8.23e-5
Copper 385 8960 385 1.12e-4
Titanium Ti-6Al-4V 6.7 4430 526 2.88e-6
Silicon 150 2330 700 9.22e-5
Concrete 1.7 2300 880 8.40e-7
Glass (borosilicate) 1.0 2230 830 5.40e-7
Water 0.6 1000 4182 1.43e-7
Air 0.026 1.2 1005 2.16e-5

Knowledge Graph β€” GraphRAG Features

The Neo4j knowledge graph is the system's long-term physics memory. Each simulation run is stored as a graph node and connected to typed context nodes, enabling agents to reason with both accumulated experience and curated domain knowledge.

Graph Schema

(:Run {
    run_id, name, dim, status, k, rho, cp,
    nx, ny, nz, Lx, Ly, Lz, bc_types,
    t_end, dt, theta, source, u_init,
    t_max, t_min, t_mean, l2_norm,
    wall_time, n_dofs, created_at,
    embedding   ← 768-dim nomic-embed-text vector
})

(:Material { name, k, rho, cp, alpha, k_min, k_max, description, typical_uses })
(:KnownIssue { code, severity, condition, description, recommendation, observed_in })
(:BCConfig { pattern, description, has_dirichlet, has_neumann, has_robin, has_source })
(:Domain { label, description, Lx_ref, Ly_ref, char_len })
(:ThermalClass { name, description, k_threshold })

(:Reference {
    ref_id, title, type, subject, source, url, tags,
    is_uploaded, is_web, process_status,
    n_pages, n_chunks, n_tables, parse_method,
    chunks_stored, chunks_embedded, cross_refs
})
  Types: material_property | bc_practice | solver_guidance | domain_physics
       | paper | report | handbook | standard | web_resource | web_page

(:ReferenceChunk {
    chunk_id, ref_id, chunk_index, heading, text,
    chunk_type,        ← text | code | equation | table | list
    classification,    ← material | bc | solver | domain | general
    confidence, page,
    embedding          ← 768-dim nomic-embed-text vector
})

Relationships:
  (:Run)-[:USES_MATERIAL {confidence}]->(:Material)
  (:Run)-[:TRIGGERED {detected_at}]->(:KnownIssue)
  (:Run)-[:USES_BC_CONFIG]->(:BCConfig)
  (:Run)-[:ON_DOMAIN]->(:Domain)
  (:Material)-[:HAS_THERMAL_CLASS]->(:ThermalClass)
  (:Run)-[:SIMILAR_TO {score, updated_at}]->(:Run)   β€” KNN semantic edges
  (:Run)-[:SPAWNED_FROM]->(:Run)                     β€” created from agent suggestion
  (:Material)-[:HAS_REFERENCE]->(:Reference)
  (:BCConfig)-[:HAS_REFERENCE]->(:Reference)
  (:Domain)-[:HAS_REFERENCE]->(:Reference)
  (:Run)-[:CITES]->(:Reference)                      β€” manually pinned or auto-linked
  (:Reference)-[:HAS_CHUNK]->(:ReferenceChunk)       β€” document sections
  (:Reference)-[:HAS_PAGE]->(:Reference)             β€” web resource β†’ page hierarchy
  (:ReferenceChunk)-[:CROSS_REFS {score}]->(:Run)    β€” chunk ↔ similar run
  (:ReferenceChunk)-[:RELATES_TO]->(:Material)       β€” entity linking
  (:ReferenceChunk)-[:RELATES_TO]->(:BCConfig)
  (:ReferenceChunk)-[:RELATES_TO]->(:Domain)

HNSW Vector Indexes:
  run_embedding_index   β€” on (:Run).embedding    (768-dim, cosine)
  chunk_embedding_index β€” on (:ReferenceChunk).embedding  (768-dim, cosine)

Feature 1 β€” Vector Embeddings + Semantic Search

Every Run node stores a 768-dimensional embedding computed by nomic-embed-text. A Neo4j HNSW vector index enables sub-millisecond semantic similarity search.

Every ReferenceChunk node also stores a 768-dim embedding, enabling semantic search across all indexed literature and web resources through a second HNSW index.

Feature 2 β€” SIMILAR_TO KNN Edges

After every run, up to 5 SIMILAR_TO edges are created to the most similar embedded neighbours (cosine β‰₯ 0.85). These precompute the neighbourhood graph for fast agent traversal.

Feature 3 β€” Physics Reference Nodes (Curated)

20 curated reference facts are seeded at startup and linked to Material, BCConfig, and Domain nodes:

Type Count Examples
material_property 8 Steel k(T) dependence, Curie point anomaly, copper melting, silicon k drop
bc_practice 5 h = 5–25 W/(mΒ²Β·K) natural air, h = 500–10,000 water cooling, heat flux ranges
solver_guidance 4 Min 10 elements, Fourier criterion, P2 vs P1, CG vs GMRES
domain_physics 3 Radiation at micro-scale, convection at structural scale, Ο„ = ρc_pLΒ²/(π²k)

Feature 4 β€” Document Intelligence Pipeline (Docling + Celery)

Uploaded documents and web resources are processed asynchronously:

  1. Docling parses PDFs/HTML/DOCX into structured sections with headings and types
  2. HybridChunker produces overlapping, context-aware chunks (max 256 tokens)
  3. Classification labels each chunk: material, bc, solver, domain, or general
  4. nomic-embed-text embeds each chunk (768-dim vector)
  5. CROSS_REFS edges link chunks to semantically similar Run nodes (score β‰₯ 0.78)
  6. RELATES_TO edges link chunks to matching Material/BCConfig/Domain entities
  7. Web crawls discover all linked pages within the same domain path (BFS, polite 1s delays)

Project Structure

pde-agents/
β”œβ”€β”€ agents/
β”‚   β”œβ”€β”€ base_agent.py          # LangGraph ReAct base: reason β†’ act loop + tool-call parser
β”‚   β”œβ”€β”€ simulation_agent.py    # Agent-1: KG-aware setup, run, debug FEM simulations
β”‚   β”œβ”€β”€ analytics_agent.py     # Agent-2: analysis, comparison, KG pattern queries
β”‚   └── database_agent.py      # Agent-3: DB storage, SQL queries, catalog studies, search history
β”‚
β”œβ”€β”€ tools/                     # LangChain @tool functions (agent "hands")
β”‚   β”œβ”€β”€ simulation_tools.py    # run_simulation, validate_config, run_parametric_sweep
β”‚   β”œβ”€β”€ analytics_tools.py     # analyze_run, compare_runs, list_runs_for_analysis
β”‚   β”œβ”€β”€ database_tools.py      # search_history, get_run_summary, query_runs
β”‚   └── knowledge_tools.py     # check_config_warnings, query_knowledge_graph,
β”‚                              #   get_physics_references
β”‚
β”œβ”€β”€ knowledge_graph/
β”‚   β”œβ”€β”€ graph.py               # SimulationKnowledgeGraph: full schema, both HNSW
β”‚   β”‚                          #   vector indexes, semantic search, SIMILAR_TO edges,
β”‚   β”‚                          #   Reference + ReferenceChunk management, chunk search,
β”‚   β”‚                          #   cross-ref linking, web resource ingestion
β”‚   β”œβ”€β”€ embeddings.py          # OllamaEmbedder: nomic-embed-text 768-dim, run_to_text()
β”‚   β”œβ”€β”€ references.py          # 20 curated physics reference entries
β”‚   β”œβ”€β”€ rules.py               # Pure-Python rule engine (9 rules: IC, CFL, mesh, BCs…)
β”‚   β”œβ”€β”€ seeder.py              # Static knowledge: 10 materials + 6 failure patterns
β”‚   β”œβ”€β”€ document_processor.py  # Docling-based structured PDF/HTML extraction pipeline:
β”‚   β”‚                          #   DocumentChunk, ParsedDocument, parse_document(),
β”‚   β”‚                          #   _classify_chunk(), embed_chunks(); pypdf fallback
β”‚   β”œβ”€β”€ tasks.py               # Celery async tasks: ingest_document_task (PDF/file),
β”‚   β”‚                          #   ingest_web_resource_task (site crawl + index)
β”‚   └── web_fetcher.py         # BFS web crawler: discover_pages(), fetch_page(),
β”‚                              #   parse_html_with_docling(), fetch_and_parse_site()
β”‚
β”œβ”€β”€ orchestrator/
β”‚   β”œβ”€β”€ graph.py               # Multi-agent supervisor graph (LangGraph)
β”‚   └── api.py                 # FastAPI REST interface + /kg/* + /references/* endpoints
β”‚
β”œβ”€β”€ simulations/
β”‚   β”œβ”€β”€ solvers/
β”‚   β”‚   └── heat_equation.py   # DOLFINx 0.10 FEM solver (2D/3D, all BC types,
β”‚   β”‚                          #   built-in + Gmsh mesh dispatch)
β”‚   β”œβ”€β”€ geometry/
β”‚   β”‚   β”œβ”€β”€ __init__.py
β”‚   β”‚   └── gmsh_geometries.py # 9 Gmsh geometry builders (rectangle, l_shape, circle,
β”‚   β”‚                          #   annulus, hollow_rectangle, t_shape, stepped_notch,
β”‚   β”‚                          #   box, cylinder) + GmshMeshResult dataclass
β”‚   └── configs/
β”‚       β”œβ”€β”€ heat_2d.json       # Steel plate example config
β”‚       └── heat_3d.json       # Aluminum block with convection config
β”‚
β”œβ”€β”€ database/
β”‚   β”œβ”€β”€ models.py              # SQLAlchemy ORM (SimulationRun, AgentRunLog, …)
β”‚   β”œβ”€β”€ operations.py          # CRUD, log_agent_step, search_runs, get_agent_logs
β”‚   └── init.sql               # PostgreSQL init (extensions, permissions)
β”‚
β”œβ”€β”€ visualization/
β”‚   └── dashboard.py           # Plotly Dash: Overview, Field Viewer, Convergence,
β”‚                              #   Parametric, Agent Chat, 🧠 Knowledge Graph,
β”‚                              #   πŸ”Ž Run Explorer; Enter-key on all search fields
β”‚
β”œβ”€β”€ scripts/
β”‚   β”œβ”€β”€ sweep_full_study.py    # 805-run comprehensive parameter sweep (8 studies)
β”‚   β”œβ”€β”€ migrate_kg_schema_v2.py  # One-off: add BCConfig/Domain/ThermalClass to existing runs
β”‚   β”œβ”€β”€ seed_knowledge_graph.py  # 23 representative simulations for KG bootstrapping
β”‚   β”œβ”€β”€ seed_bc_geometry_study.py  # BC + geometry parametric study
β”‚   └── ollama-init.sh         # Pull all required Ollama models
β”‚
β”œβ”€β”€ docker/
β”‚   β”œβ”€β”€ Dockerfile.fenics      # dolfinx/dolfinx:stable + Gmsh + uvicorn API
β”‚   β”œβ”€β”€ Dockerfile.agents      # Python 3.11 + LangGraph + FastAPI + neo4j + Docling
β”‚   β”œβ”€β”€ Dockerfile.dashboard   # Python 3.11 + Dash + pandas + neo4j driver
β”‚   └── fenics_runner_api.py   # FastAPI server inside the FEniCSx container
β”‚
β”œβ”€β”€ nginx/
β”‚   └── nginx.conf             # Nginx reverse proxy (subpath routing, WebSocket)
β”‚
β”œβ”€β”€ evaluation/                # Research paper evaluation framework
β”‚   β”œβ”€β”€ benchmarks/
β”‚   β”‚   β”œβ”€β”€ analytical_solutions.py  # 3 closed-form V&V benchmark cases
β”‚   β”‚   └── vv_runner.py             # V&V convergence study (5 mesh resolutions)
β”‚   β”œβ”€β”€ ablation/
β”‚   β”‚   β”œβ”€β”€ benchmark_tasks.py       # 10 NL benchmark tasks (easy/medium/hard)
β”‚   β”‚   └── run_ablation.py          # 3-way KG ablation runner (--include-smart)
β”‚   β”œβ”€β”€ metrics/
β”‚   β”‚   └── agent_quality.py         # Production metrics from PostgreSQL
β”‚   β”œβ”€β”€ generate_tables.py           # LaTeX table generator from JSON results
β”‚   └── results/                     # JSON outputs + generated LaTeX tables
β”‚
β”œβ”€β”€ paper/                     # Research paper (LaTeX)
β”‚   β”œβ”€β”€ main.tex               # Main document (compile with pdflatex + bibtex)
β”‚   β”œβ”€β”€ references.bib         # BibTeX (29 entries incl. CRAG, AriGraph)
β”‚   β”œβ”€β”€ figs/                  # TikZ/PGFPlots figures
β”‚   └── tables/                # LaTeX table fragments (\input{} in main.tex)
β”‚
β”œβ”€β”€ docker-compose.yml         # Full service stack incl. NeoDash (port 9001), Celery worker
β”œβ”€β”€ CLAUDE.md                  # Comprehensive project context file
β”œβ”€β”€ env.example                # Environment variable template (copy to .env)
β”œβ”€β”€ requirements.txt           # Python deps: LangGraph, FastAPI, neo4j, Docling, Celery, pypdf
β”œβ”€β”€ Makefile                   # Common commands (incl. eval-* and paper-* targets)
└── setup.sh                   # One-time setup script

LLM Models

Model Params VRAM Role
qwen2.5-coder:14b 14B ~9 GB Database Agent β€” fast structured queries
qwen2.5-coder:32b 32B ~19 GB Simulation Agent β€” code generation & debugging
llama3.3:70b 70B ~42 GB Analytics Agent + Orchestrator β€” reasoning
nomic-embed-text 137M <1 GB Embedding β€” 768-dim vectors for runs and document chunks

All LLMs fit simultaneously (~70 GB out of 196 GB available VRAM).

# Pull all required models (including embedding model)
make pull-models

# Optional: use alternative models β€” edit .env:
SIM_MODEL=qwen2.5-coder:72b      # ~40 GB, premium code generation
ANALYTICS_MODEL=deepseek-r1:70b  # strong chain-of-thought reasoning
EMBED_MODEL=nomic-embed-text      # default embedding model (274 MB)

Makefile Reference

make setup           # one-time setup (build images, start services, pull models)
make run             # start all services
make stop            # stop all services
make infra           # start only postgres, redis, minio, neo4j, ollama

make simulate-2d     # run 2D steel plate benchmark via agents API
make simulate-3d     # run 3D aluminum block benchmark via agents API
make sweep           # parametric sweep: k=[1..200], analyze, find optimal
make analyze RUN_ID=<id>            # analyze a specific run
make query Q="<natural language>"   # database natural-language query

make pull-models            # pull all required LLM + embedding models
make list-models            # list available Ollama models

make db-init         # initialize database tables
make db-shell        # psql shell into pde_simulations
make db-stats        # show run count and avg wall time by status

make shell-fenics    # bash inside fenics-runner container
make shell-agents    # bash inside agents container
make logs            # tail all service logs
make health          # check all service HTTP endpoints

make test-solver     # quick FEniCSx solver smoke test (8Γ—8 mesh)
make clean           # ⚠ stop, DELETE all volumes, wipe results/

# ── Evaluation (paper experiments) ──────────────────────────────────────────
make eval-vv                # V&V convergence benchmarks (runs inside fenics container)
make eval-ablation          # 2-way KG ablation: KG On vs KG Off
make eval-ablation-smart    # 3-way KG ablation: KG On vs KG Off vs KG Smart
make eval-metrics           # production agent quality metrics from PostgreSQL
make eval-tables            # generate LaTeX tables from JSON results
make eval-all               # run V&V + 2-way ablation + metrics + tables

# ── Paper (Overleaf sync via GitHub subtree) ─────────────────────────────────
# Setup (one-time): git remote add paper-origin git@github.com:ORG/pde-agents-paper.git
make paper-push             # push local paper/ edits β†’ GitHub β†’ Overleaf pulls
make paper-pull             # pull Overleaf edits ← GitHub β†’ local paper/
make paper-status           # show uncommitted paper changes + commits ahead of remote
make paper-pdf              # compile paper/main.tex locally (requires texlive)

Troubleshooting

Knowledge Graph tab shows "Knowledge graph unavailable"

# Recreate the container (picks up updated docker-compose.yml)
docker compose up dashboard -d --force-recreate

# Verify
docker exec pde-dashboard python3 -c "
import sys; sys.path.insert(0, '/app')
from knowledge_graph.graph import get_kg
kg = get_kg()
print('Available:', kg.available)
print('Stats:', kg.stats())
"

Document upload stuck in "queued" status β€” Celery worker not running

# Check worker is alive
docker exec pde-agents cat /tmp/celery.log | tail -5

# Restart Celery worker manually
docker exec pde-agents bash -c "
kill \$(cat /tmp/celery.pid 2>/dev/null) 2>/dev/null; sleep 2
celery -A knowledge_graph.tasks:celery_app worker --loglevel=info \
  --concurrency=2 -Q document_ingestion,celery \
  --detach --pidfile=/tmp/celery.pid --logfile=/tmp/celery.log
"

NeoDash not reachable at port 9001

docker compose up neodash -d
docker logs pde-neodash --tail=20

MinIO console access

The MinIO console is on host port 9002 (port 9001 is now NeoDash). Access via SSH tunnel:

ssh -L 19002:localhost:9002 -N <server>   # then open http://localhost:19002

Embedding model not available (semantic search returns empty)

docker exec pde-ollama ollama pull nomic-embed-text
docker exec pde-agents python3 -c "
import sys; sys.path.insert(0, '/app')
from knowledge_graph.graph import get_kg
kg = get_kg()
print(kg.backfill_embeddings(batch_size=50))
print(kg.build_all_similar_to_edges(k=5, min_score=0.85))
"

Knowledge graph is empty after restart

# Seed static knowledge (materials + failure patterns + references)
curl -s -X POST http://localhost:8000/kg/seed | python3 -m json.tool

# Re-run representative simulations to rebuild Run nodes
docker exec pde-agents python3 /app/scripts/seed_knowledge_graph.py

# Backfill embeddings and KNN edges
docker exec pde-agents python3 -c "
import sys; sys.path.insert(0, '/app')
from knowledge_graph.graph import get_kg
kg = get_kg()
kg.backfill_embeddings()
kg.build_all_similar_to_edges()
print(kg.stats())
"

FEniCSx API returns 500 errors

docker exec pde-fenics find /workspace/simulations -name "*.pyc" -delete
docker compose restart fenics-runner

Data Persistence and Volume Management

What persists across restarts

Normal stop/start operations preserve all data β€” Docker named volumes are kept on disk.

docker compose stop && docker compose start   # safe, all data preserved
docker compose down && docker compose up -d   # safe β€” no -v flag

What a clean wipe removes

docker compose down -v   # or: make clean
Volume Contents lost
neo4j_data All Run nodes, ReferenceChunk nodes, embeddings, SIMILAR_TO edges, Reference links
postgres_data All simulation records, agent logs
minio_data All uploaded XDMF/NPY result files and reference documents
redis_data Any queued Celery document ingestion jobs

Extending to Other PDEs

To add a new PDE solver:

  1. Create simulations/solvers/my_pde.py with the same interface as heat_equation.py
  2. Add corresponding tools in tools/simulation_tools.py
  3. Register the new tool in the relevant agent's tool list
  4. Update the Simulation Agent's system prompt with PDE-specific guidance
  5. Add a visualization tab in visualization/dashboard.py
  6. Extend knowledge_graph/seeder.py and knowledge_graph/references.py with PDE-specific failure patterns and physics knowledge

Planned extensions:

  • Poisson equation β€” electrostatics, groundwater pressure
  • Linear elasticity β€” structural mechanics, thermal stress
  • Navier-Stokes β€” incompressible laminar flow
  • Coupled thermo-mechanical β€” heat + stress

Integration with NVIDIA PhysicsNemo

The existing physicsnemo-25_11 container (at ~/physicsnemo-work) can run alongside this system for hybrid FEM + PINN workflows:

Use case Approach
Validation Run FEniCSx (ground truth) + PhysicsNemo (PINN), compare fields
Surrogate models Generate FEM training data β†’ train PhysicsNemo surrogate
Fast parametric scans FEM at sparse reference points, PINN to interpolate
KG-guided training Use KG similar-run search to find best FEM training seeds
# Add to docker-compose.yml under services:
physicsnemo:
  image: nvcr.io/nvidia/physicsnemo/physicsnemo:25.11
  volumes:
    - simulation_results:/workspace/fem
  networks: [pde-net]
  deploy:
    resources:
      reservations:
        devices:
          - driver: nvidia
            count: all
            capabilities: [gpu]

About

Multi-agent system for automated PDE simulation using LLMs and knowledge graphs

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors