Skip to content

About

Steady-state 1D network solver (SIMPLE) for HVAC hydronic circuits: hydraulics + thermal, graphical schematic editor with built-in solver. Provides machine-readable hydronic schematics for AI agents (human-in-the-loop validated input) and benchmark tests for building services engineering.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

hydraulik

Stationäre hydraulisch-thermische Berechnung von HVAC-Hydraulikschaltungen (Heizung/Kühlung) als generisches 1D-Netzwerk. Inkompressibles Fluid mit konstanten Stoffwerten (ρ, μ, cp); SIMPLE-artiger Druckkorrektur-Solver plus sequentiell gelöste Energiegleichung — mit zwei grafischen Schema-Editoren (Hydraulik und Lüftung/VKA) inklusive integriertem Solver: Rechnen direkt im GUI, Ergebnisse per Mouse-Over in der Zeichnung.

Schaltbild-Editor mit integriertem Solver

Maschinenlesbare Strangschemas für KI-Agenten: Strangschemas sind für KI-Agenten bislang schwer zugänglich, weil ihre Vision-Fähigkeiten für das zuverlässige Interpretieren von Anlagenschemata nicht ausreichen. Dieses Tool löst das Eingabeproblem konstruktiv: Das Schema wird im Editor gezeichnet und liegt damit von Anfang an maschinenlesbar als YAML vor — die Zeichnung ist das Modell, es gibt keinen Interpretationsschritt. Über den integrierten Solver (▶ Rechnen) wird die Eingabe per Human in the Loop geprüft (Volumenströme, Drücke, Temperaturen direkt im Schema), bevor ein KI-Agent das validierte YAML für Analyse- und Optimierungsstudien übernimmt. Das Paket dient zugleich der Entwicklung von Benchmark-Tests für KI-Agenten in der technischen Gebäudeausrüstung.

Installation

git clone https://github.com/AI4Buildings/HVAC-Hydronic-Network-Solver.git
cd HVAC-Hydronic-Network-Solver
pip install -e ".[dev]"
pytest            # 1287 Tests (analytische Referenzen + Validierung gegen Musterlösungen)

Tool starten

editor server        # startet beide Editoren: http://127.0.0.1:8091/

Die Startseite verlinkt den Hydraulikschema-Editor (/hydraulik) und den Lüftungsschema-Editor (/lueftung); gerechnet wird direkt im GUI (lokaler Endpunkt, nur 127.0.0.1). editor serve, kurz editor oder das ältere hydraulik serve tun dasselbe; --port/--no-open optional. Daneben gibt es das CLI hydraulik (run = YAML/JSON rechnen, export --json = geprüftes Modell als kanonisches JSON, schema = JSON Schema des Eingabeformats, editor = statische HTML-Datei erzeugen, serve).

Schnellstart

hydraulik run examples/04_heatpump_separator.yaml

oder in Python:

import hydraulik as h

net = h.Network(fluid=h.water_at(45))
net.add(h.HeatPump("wp1", mode="target_t_out", t_out_set_C=45, q_max_kW=12, q_nom_m3h=1.4))
net.add(h.Pump("pu1", mode="constant_flow", q_m3h=1.4))
net.add(h.Radiator("hk1", q_nom_kW=7.5, t_sup_nom_C=45, t_ret_nom_C=40, t_room_C=21))
net.connect("wp1.out", "pu1.in")
net.connect("pu1.out", "hk1.in")
net.connect("hk1.out", "wp1.in")

result = net.solve()
print(result.report())
print(result["hk1"].q_dot_kW)      # Wärmestrom ins Wasser [kW]

Schaltbild-Editor (grafische Eingabe, Human in the Loop)

editor server                                # Editor MIT Rechen-Endpunkt (empfohlen)
hydraulik editor --out hydraulik_editor.html   # nur Zeichnen (statische Datei)

Workflow: Schaltung zeichnen → ▶ Rechnen direkt im GUI (lokaler Endpunkt POST /solve, nur 127.0.0.1) → Ergebnisse erscheinen in der Zeichnung: Werte­zeile unter jeder Komponente (V̇, T ein→aus) und Mouse-Over-Tooltips (Komponenten: V̇, Δp, T, Q̇, v; Leitungen/Ports: Knotendruck in kPa(ü) und Temperatur) → prüfen, korrigieren, neu rechnen (jede Änderung verwirft die Ergebnisse automatisch) → YAML als Datei exportieren → Analyse-/Optimierungsstudien mit dem Solver skripten (z.B. durch einen Coding-Agenten — der das Anlagenschema dann nicht mehr aus Abbildungen interpretieren muss, sondern das validierte YAML erhält).

Eigenständige HTML-Datei (kein Server, keine Internetverbindung): Komponenten aus der Palette platzieren; jede gezogene Linie ist eine Verbindungsleitung (conduit): standardmäßig ideal, per Inspector wahlweise C-Wert, Auslegungspunkt (dp + q) oder Rohrmodell (length + d_inner …, inkl. Wärmeverlust) — mit eigenem Namen (sichtbar bei Selektion), ts-Label und eigenen Ergebniswerten im Hover (V̇, Δp, T, v). Leitungsführung mit Knickpunkten (Doppelklick auf Leitung setzt eine Umlenkung, Griffe ziehen, Doppelklick auf Griff entfernt; ohne Knick automatisch gerade bzw. abgewinkelt), Vorlagen für Standardschaltungen (Palette-Register „Vorlagen“: mitgeliefert sind die sieben Grundschaltungen Beimischschaltung einfach/doppelt/doppelt-differenzdruckarm, Drossel-, Umlenk- sowie Einspritzschaltung mit Durchgangs- bzw. Dreiwegeventil; eigene Vorlagen: Bereich auswählen → „Als Vorlage speichern" → per Klick platzieren und Parameter anpassen; im Browser gespeichert, als JSON-Datei export-/importierbar zum Teilen), Mehrfachauswahl (Auswahlrechteck aufziehen oder Shift+Klick) mit gemeinsamem Verschieben und Kopieren/Einfügen ganzer Teilschaltungen (Strg+C/V/D — interne Leitungen werden mitkopiert, Namen automatisch hochgezählt), Undo/Redo (Strg+Z / Strg+Shift+Z oder ↶/↷), Zoom (Strg+Mausrad an der Cursorposition oder −/+/1:1-Buttons, 25–300 %, Zeichenfläche wächst automatisch mit), Drehen in 90°-Schritten (Taste r — Ports rotieren mit), Parameter im Inspector (mit Einheitenwahl und Bereichsanzeige), Leitungsfarben Heizung (VL rot / RL blau) und Kälte (VL hellgrün / RL dunkelgrün), ts-Labels, Live-Prüfliste (unverbundene Ports, fehlende Pflichtparameter, Wertebereiche; klicken wählt die betroffene Komponente aus). Export erzeugt direkt rechenbares YAML inkl. layout:-Block (Zeichnungskoordinaten) für den Re-Import — die Zeichnung ist damit das Modell, es gibt keinen Interpretationsschritt. Editor und Solver lesen YAML identisch (YAML 1.2, siehe unten): Unter editor server importiert der Server-Parser jede YAML-Form samt Loader-Hinweisen in der Statuszeile; die statische HTML-Datei nutzt einen lokalen YAML-1.2-Parser (Block- und Flow-Stil) mit derselben Semantik, der Anker, Tags und Block-Skalare mit Meldung ablehnt statt sie anders zu lesen. Ein Import ohne components-Abschnitt wird abgelehnt (die Zeichnung bleibt stehen); settings und der Fluidname einer Datei bleiben über Import/Export erhalten und gelten beim Rechnen. Zahlenfelder nehmen Dezimalpunkt oder -komma. Der Server antwortet nur auf Anfragen an 127.0.0.1/localhost vom eigenen Ursprung und begrenzt den Anfragekörper auf 5 MB. Palette, Ports und Formulare werden aus der Komponenten-Registry generiert (Single Source of Truth): Nach neuen Komponenten einfach den Editor neu erzeugen.

YAML-Eingabeformat (KI-/LLM-freundlich)

fluid: {preset: water, t_C: 45}      # oder {rho: 998, mu: 1.0e-3, cp: 4180}
settings: {max_iter: 400}            # optional (siehe SolverSettings)
                                     # uniqueness_starts: 16 – Eindeutigkeitsprüfung bei
                                     # Idelchik-T-Stücken (0 = aus)

components:
  wp1:  {type: heat_pump, mode: target_t_out, t_out_set_C: 45, q_max_kW: 12, q_nom_m3h: 1.4}
  pu1:  {type: pump, mode: constant_flow, q_m3h: 1.4}
  hk1:  {type: radiator, q_nom_kW: 7.5, t_sup_nom_C: 45, t_ret_nom_C: 40, t_room_C: 21}

connections:                          # 'komponente.port'; ≥3 Einträge = Verzweigung
  - [wp1.out, pu1.in]
  - [pu1.out, hk1.in]
  - [hk1.out, wp1.in]

Regeln:

  • Einheiten über Suffixe: dp_kPa/dp_Pa/dp_bar, q_m3h/q_l_s/q_m3s, t_..._C, ..._kW/..._W, length_m/..._mm, kvs_m3h, ua_W_K, u_linear_W_mK, k_W_m2K, m_dot_air_kg_s. Intern strikt SI.
  • Jeder Port muss in mindestens einer Verbindung vorkommen. Ein Port in mehreren Verbindungen (oder ≥3 Ports je Eintrag) bildet eine ideale Mischstelle (Verzweigung).
  • Validierungsfehler werden gesammelt als nummerierte Liste gemeldet (mit Korrekturvorschlägen), sodass eine Datei in einem Durchgang korrigierbar ist: hydraulik run/export, der Editor-Server und hydraulik.load_checked() fassen Parameter-, settings- und Verbindungsfehler in EINER Liste zusammen.

YAML 1.2 – überall gleich gelesen

Solver, CLI, Server und beide Editoren lesen Dateien nach dem YAML 1.2 Core Schema (eine zentrale Ladefunktion hydraulik.load_document, im Editor yaml_core.js mit identischer Semantik — per Paritätstest abgesichert):

Schreibweise gelesen als
1.4e0, 14e-1, 1e3, 5e-7, .5 Zahl
08, 010 Ganzzahl 8 bzw. 10 (keine Oktalzahl; Oktal 0o17, Hex 0x1F)
true/false (auch True, TRUE) Wahrheitswert
yes, no, on, off, y, n Zeichenkette (YAML 1.1 las sie als Wahrheitswert)
null, ~, leer null
1_000, 0b101, 2026-10-05, 12:30 Zeichenkette
.inf, .nan gelesen, vom Loader aber abgelehnt (nur endliche Zahlen)
  • Schlüssel sind immer Zeichenketten im Originaltext: no:, off: oder true: sind gültige Komponentennamen.
  • Komponentennamen dürfen Punkte enthalten ("HK 1.OG", TS1.1): eine Portreferenz wird am letzten Punkt getrennt ("HK 1.OG.in" → Komponente HK 1.OG, Port in); Portnamen enthalten nie einen Punkt.
  • Doppelte Schlüssel sind ein Fehler (mit Zeilennummer). Anker/Aliase (&name/*name) sind erlaubt, solange sie nicht rekursiv sind; YAML-1.1-Merge-Schlüssel << und Tags wie !!binary/!!timestamp nicht.
  • Grenzen der Eingabe (jeweils mit eigener Fehlermeldung): höchstens 200 000 Werte je Dokument (Aliase aufgelöst gezählt), keine rohen Steuerzeichen (in doppelten Anführungszeichen als \uXXXX schreiben), eine %YAML-Direktive nur in Version 1.2. Leerraum ist nur Leerzeichen und Tabulator — ein geschütztes Leerzeichen gehört zum Wert.
  • Bool-Parameter (z.B. closed am Kugelhahn) nur mit true/false — yes/no meldet der Loader mit dem Hinweis „bitte true/false verwenden".
  • Ganzzahl-Parameter akzeptieren auch 2.0 bzw. 1e3 (wie JSON Schema).

Quoting-Regeln (für von Hand oder per LLM geschriebene Dateien):

  • Labels quoten: ts: "08", BEMS-Felder id: "…". Ungequotet liest YAML 1.2 ts: 08 als Zahl 8 (Label „8"); ts: 1.10 ist ein Fehler, weil daraus still „1.1" würde. Ganzzahlen (ts: 4) sind erlaubt.
  • Strings, die wie Zahl, Wahrheitswert oder null aussehen, quoten: "1e3", "true", "null".
  • # nach einem Leerzeichen beginnt einen Kommentar — Texte mit # oder : quoten: description: "Kreis #2: Vorlauf".
  • Der Editor-Export quotet selbsttätig (missverständliche Strings, Namen, ts immer) und schreibt Exponentenzahlen stets mit Punkt und Vorzeichen (5.0e-7), sodass auch YAML-1.1-Werkzeuge eine Zahl lesen.

JSON-Eingabe, JSON-Export und JSON Schema

  • JSON ist gleichwertig: hydraulik run schaltung.json, h.load("schaltung.json"). .json-Dateien werden strikt gelesen (doppelte Schlüssel, NaN/Infinity und Kommentare sind Fehler).
  • Kanonisches JSON: hydraulik export --json schaltung.yaml [--out schaltung.json] prüft das Modell vollständig (Parameter, settings, Einbindung der Ports — bei Fehlern wird nichts geschrieben) und schreibt es mit denselben Schlüsseln (Einheiten-Suffixe bleiben) in stabiler Reihenfolge (oberste Ebene fest, Komponenten in Dateireihenfolge mit type zuerst; Kommentare entfallen). YAML → JSON → identische Lösung ist für alle Beispiele getestet.
  • JSON Schema: hydraulik schema [--luft] [--out hydraulik.schema.json] erzeugt ein Schema (Draft 2020-12) ausschließlich aus der Komponenten-Registry — alle Typen mit allen Suffix-Schlüsseln, Pflichtparametern, „genau eine Einheit" (z.B. dp_kPa ODER dp_Pa), Wertebereichen in der Einheit des Schlüssels, Auswahllisten (enum), reservierten Feldern (ts, bems, description, pipes, layout) und Port-Referenzen komponente.port. Nutzbar für Autovervollständigung im Editor (VS Code, YAML-Erweiterung: erste Zeile # yaml-language-server: $schema=hydraulik.schema.json) und als Vorgabe für LLM-Ausgaben. Was ein Schema nicht ausdrücken kann (Existenz der Ports, Portanzahl, Betriebsart ↔ Parameter, endliche Zahlen), prüft weiterhin der Loader — im Schema per description gekennzeichnet.

Lüftungsschema-Editor (VKA nach EN 16798-5-1)

Zweites GUI unter editor server → http://127.0.0.1:8091/lueftung (Hydraulik: /hydraulik; die Startseite / verlinkt beide): Lüftungsanlagen als zwei Ketten zeichnen (Zuluft: AUL → … → ZUL oben, Abluft: ABL → … → FOL unten; die WRG verbindet beide Stränge) und mit dem integrierten VKA-Rechenkern (energieoptimale Regelung, aus dem Skill vka-effizienz-en16798) rechnen. Komponenten: WRG (Sorptions-/Enthalpie-/ Kondensationsrotor, KVS, Platte), Frostschutz, Vor-/Nachheizer, Kühler, Befeuchter (Dampf/Sprüh), Ventilatoren (SFP), Umluft, Filter, Schalldämpfer und Luft-Sensoren (Kombifühler T+rF, T, rF, Δp, p, V̇, Energiezähler, Stromzähler — als Anzapfungen mit dünner Messleitung an beliebige Kanal-Anschlüsse, ohne die Stränge zu berühren; alle mit BEMS-Messpunktlisten). Nach dem Rechnen zeigen Mouseover-Tooltips auf jeder Kanalleitung den Luftzustand des Abschnitts (ϑ, φ, x, V̇); Fühler zeigen den Zustand an ihrer Messstelle. Regelungsart an der Zuluft wählbar: Zustand fest gepinnt, Sollband oder raumgekoppelt mit Feuchtelast (simulate_room); der Abluft-Volumenstrom wird praxisgerecht an der Abluft angegeben (leer = balancierte Anlage); der WRG-Auslegungs- volumenstrom v_nom ist ohne Angabe der Zuluftvolumenstrom. Ventilator-SFP werden je Strang summiert (P_el mit dem jeweiligen Volumenstrom); aktive Komponenten gehören in den Zuluftstrang. Ergebnisse (Heiz-/Kühl-/ Befeuchterleistung, WRG-Kennwerte, Zuluftzustand, Ventilatorstrom) erscheinen im Ergebnispanel, als Tooltip und unter jeder Komponente. Drei Vorlagen liegen bei: Vollklima mit Sorptionsrotor, KVS-Anlage sowie die reale Anlage „GEA Vollklima Energetikum" (CAIRplus SX 096.064 IVBV) — fertig parametriert mit dem Winter-Auslegungsfall aus der Gerätedokumentation und per Regressionstest gegen die Datenblattwerte abgesichert. Die Ventilatorposition wird rechnerisch am Stranganfang bilanziert (validierte Modellkonvention); Rotor-Übertragungsgrade sind physikalisch auf ε ≤ 1 begrenzt (Hinweis bei stark unbalancierten Volumenströmen).

Modellkonventionen der Reihenfolge: Der Vorheizer ist das Register NACH der WRG (davor gezeichnet wird er abgelehnt; für den Frostschutz der WRG gibt es die Komponente Frostschutz). Bei Anlagen mit Umluft sitzt der Zuluftventilator rechnerisch nach der Mischkammer (Außenluft → Mischkammer → Ventilator → Zuluft): er fördert den vollen Zuluftstrom, seine Wärme geht vollständig in die Zuluft. Der Kühler hat die Kaltwasser-Vorlauftemperatur t_kw_C (Standard 6 °C) als tiefsten erreichbaren Taupunkt; verlangt die Sollfeuchte einen tieferen, entfeuchtet er bis zu dieser Grenze und meldet es. Die Rückfeuchtzahl des Rotors richtet sich nach dem Feuchtegefälle (Spender ist der Strom mit der höheren Wasserbeladung).

Plausibilität: Je Zuluftstrang rechnet der Kern genau ein Register je Typ (doppelte Vorheizer/Kühler/Nachheizer/Befeuchter werden abgelehnt); nicht angeschlossene Komponenten werden mit Hinweis übergangen. Eine KVS-Auslegung, die mit dem angegebenen Sole-Volumenstrom nicht möglich ist, wird mit dem nötigen Mindestwert gemeldet. Erreicht die Anlage das Zuluft-Sollband nicht (z.B. Feuchteband ohne Befeuchter), steht das als Hinweis im Ergebnis. Im raumgekoppelten Modus ist die ausgegebene Raumfeuchte immer bilanzkonsistent (Raumfeuchte = Abluftfeuchte); ist das Raumfeuchteband nicht erreichbar, wird der sich einstellende Zustand mit Hinweis ausgegeben.

Lüftungsschema-Editor mit integriertem VKA-Solver

Sensoren & BEMS-Integration (Betriebsdatenanalyse)

Das maschinenlesbare Strangschema ist nicht nur Rechenmodell, sondern auch semantische Karte für die Betriebsdatenanalyse eines Building Energy Management Systems (BEMS, z.B. Aedifion). Die Palette-Rubrik SENSOREN (unterste Gruppe im Register „Komponenten“) stellt dafür Temperatur-, Druck-, Differenzdruck-, Volumenstromsensoren und Wärmemengenzähler bereit:

  • Rückwirkungsfrei: Fühler zapfen den Messknoten nur an (Messleitung = dünne Linie, reine Knotenverschmelzung, keine Rohrleitung); V̇-Sensor und WMZ sitzen quasi-ideal in der Leitung. Die Hydraulik bleibt unverändert.
  • Mitwachsende Zeichenfläche: das Canvas vergrößert sich automatisch, sobald Komponenten oder Knickpunkte an den Rand rücken (immer ~600 px Reserve hinter dem äußersten Element) — beliebig große Strangschemas ohne Einstellungen; beim Löschen schrumpft es auf die Standardgröße zurück.
  • Strömungsrichtung im Bild: nach erfolgreicher Rechnung zeigt jede Verbindungsleitung in ihrer Mitte ein schlankes Richtungsdreieck in Linienfarbe (V̇ ≈ 0 oder zu kurze Stücke bleiben pfeilfrei; bei jeder Änderung verschwinden die Pfeile mit dem Ergebnis).
  • Messwerte per Mouseover: nach dem Rechnen zeigt der Tooltip die simulierten Sensorwerte (ϑ, p, Δp, V̇, WMZ zusätzlich Q̇ aus ṁ·cp·Δϑ) samt BEMS-Zuordnung; im Python-Ergebnis stehen sie unter result.sensors bzw. to_dict()["sensors"].
  • BEMS-Datenpunkte (generisch): JEDE Komponente trägt eine frei lange Messpunktliste bems: [{id, key, description}, …] — id ist die abfragbare Datenpunkt-ID, key der sprechende Alias (z.B. EXP_HP_SEK_T_VL), description die Semantik. So bildet ein WMZ seine fünf realen Datenpunkte (V̇, Q̇, Q_kum, ϑ_VL, ϑ_RL) ab, ein Speicher mehrere Fühler, ein Stellventil sein Stellsignal, eine Pumpe Cmd + kWh-Zähler. Zusätzlich hat jede Komponente ein freies description-Feld. Im Editor sind die Eingaben in zwei Register getrennt: Fluid-Info (Simulationsparameter) und BEMS-Info (Beschreibung + Messpunkte, „+ Messpunkt hinzufügen").
  • Zweck: Ein LLM, das die YAML-Datei liest, erhält damit beides zugleich — die Netzwerktopologie (wo sitzt der Sensor, was liegt strom­auf/-ab) und den Schlüssel zu den realen Zeitreihen. Simulation und Messdaten lassen sich so automatisiert verknüpfen (Soll-Ist-Vergleich, Performance-Gap-Analyse).

Komponententypen

type Ports Wichtigste Parameter
pipe in, out length_m, d_inner_mm, roughness_mm, zeta, u_linear_W_mK, t_amb_C
flow_resistance in, out c_Pa_m3h2 (C-Wert, z.B. aus REGuA) oder c_Pa_m3s2 oder Auslegungspunkt dp_kPa + q_m3h; optional a_Pa_m3h (linearer Anteil). Genau eine Widerstandsangabe. Dichteunabhängig (anders als Kv!)
pump in, out mode: constant_dp|constant_flow, dp_kPa bzw. q_m3h, q_nom_m3h
control_valve in, out kvs_m3h, opening (0…1), characteristic: equal_percentage|linear
balancing_valve in, out kvs_m3h, opening (Voreinstellung)
ball_valve in, out Kugelhahn (Absperrarmatur): Default offen und druckverlustfrei (1 Pa Referenzverlust bei q_nom_m3h, wie link); optional realer kvs_m3h; closed: true = Revisionsfall, sperrt exakt (V̇ = 0)
temperature_sensor port Temperaturfühler (Messstelle anzapfen, keine Kante): liest ϑ des Knotens
pressure_sensor port Drucksensor: statischer Überdruck an der Messstelle (p_Knoten − ρw²/2, p_dyn_kPa); optional d_inner_mm
pressure_diff_sensor plus, minus Differenzdrucksensor: Δp der statischen Drücke p(plus) − p(minus), z.B. über Pumpe/Ventil; optional d_inner_plus_mm/d_inner_minus_mm
flow_sensor in, out Volumenstromsensor in der Leitung (quasi-ideal, 1 Pa bei q_nom_m3h)
energy_meter in, out, t_ref Wärmemengenzähler: Durchflussteil in der Leitung + Fühler t_ref in der Gegenleitung; misst V̇, beide ϑ und Q̇ = ṁ·cp·(ϑ_ref − ϑ_Leitung) (Einbau im RL → Q̇ > 0 = Kreisabgabe); die 5 realen Datenpunkte als bems-Einträge
check_valve in, out Rückschlagklappe: kvs_m3h (Durchlassrichtung in→out); sperrt rückwärts (Restleckage kvs/1000, über block_factor einstellbar)
mixing_valve_3way a, b, ab kvs_m3h, opening (A-Pfad), characteristic (A–AB, Default gleichprozentig), characteristic_b (B–AB, Default linear)
radiator in, out q_nom_kW, t_sup_nom_C, t_ret_nom_C, t_room_C, n, q_prescribed_kW; Hydraulik: kv_m3h ODER c_Pa_m3h2 (Default 10 kPa bei Nennstrom)
floor_heating in, out area_m2, k_W_m2K, t_room_C; Hydraulik: length_m (+ d_inner_mm, Rohrmodell) ODER c_Pa_m3h2
heating_coil / cooling_coil in, out ε-NTU mit Teillast-UA nach Gl. 4.2 (ua_ref_W_K, n Default 0.4, Referenzen q_w_ref_m3h/m_dot_air_ref_kg_s; ohne Referenzen UA konstant); m_dot_air_kg_s, t_air_in_C, arrangement; ODER feste Leistung q_prescribed_kW (dann kein UA nötig); Hydraulik: kv_m3h ODER c_Pa_m3h2. Kühlregister zusätzlich Greybox MIT Kondensation: ua_star_wet_kg_s + rh_air_in (0…1) → Q̇ = max(trocken, nass), Kondensatrate/Luftaustritt in extras
heat_pump / chiller in, out mode: prescribed_q|target_t_out, q_dot_kW bzw. t_out_set_C + q_max_kW, dp_nom_kPa, q_nom_m3h
buffer_storage p1…pN n_ports, ua_W_K, t_amb_C (ideal durchmischt)
inflow (Zulauf) port t_set_C + ENTWEDER q_m3h (Zulauf-V̇) ODER p_kPa (statischer Überdruck gauge, optional d_inner_mm)
outflow (Austritt) port ENTWEDER p_kPa (statischer Überdruck gauge; Auslauf ins Freie: 0; optional d_inner_mm) ODER q_m3h (Entnahme-V̇); Austrittstemperatur ist Ergebnis
ideal_storage in, out t_set_C (Vorlauf fest; Rücklauf und Leistung sind Ergebnis); optional q_m3h (eingeprägter Volumenstrom, Δp ist Ergebnis) und/oder p_out_kPa (Überdruck am Austritt = Druckanker); dp_nom_kPa + q_nom_m3h
conduit (Verbindungsleitung) in, out universelle Leitung (im Editor als Linie): ohne Angabe ideal; c_Pa_m3h2 ODER dp_kPa+q_m3h ODER Rohrmodell — ein Abschnitt via length_m (+ d_inner_mm, …) ODER beliebig viele Abschnitte in Reihe via pipes: [{length_m, d_inner_mm, roughness_mm, zeta}, …] (im Editor: Abschnittsliste mit +/−); Wärmeverlust u_linear_W_mK/t_amb_C über die Gesamtlänge
link in, out q_nom_m3h. Widerstandsfreie Verbindung (Δp ≈ 1 Pa), die zwei Knoten thermisch trennt — für Anschlüsse entlang eines Sammlers, damit Zapfstellen nicht stromab eingemischtes Wasser „sehen"
hydraulic_separator prim_in, prim_out, sec_in, sec_out q_nom_m3h, dp_nom_Pa, ua_W_K
manifold main, s1…sN n_ports
tee a, b, c T-Stück 90° (a–b gerader Strang, c Abzweig): Default idealer Knoten; mit d_run_mm + d_branch_mm Druckverlust nach Idelchik (Diagramme 7-10/7-21, ζ = f(V̇-Verhältnis, Flächenverhältnis), Vereinigung UND Trennung automatisch aus der Strömungsrichtung, stetig über die Regimewechsel; im Netz Totaldruckverlust wie bei allen Bauteilen, statische Anschlussdrücke als Ergebnis p_static_port_kPa; zwei Schenkel am selben Punkt werden abgelehnt — direkt verbunden oder nur über widerstandsfreie Verbindungen wie ideale Linien, link, Kugelhahn ohne Kvs, Volumenstromsensor; mehrdeutige Lösungen werden gemeldet)
open_end port bc: pressure|flow, p_kPa (statisch, optional d_inner_mm) bzw. q_m3h, t_supply_C
cap port dichtes Endstück (Blindstopfen): V̇ = 0 — zum Verschließen von Anschlüssen bei Teilbereichstests; keine Parameter

Alle wärmeübertragenden Komponenten akzeptieren q_prescribed_kW (feste Leistung statt physikalischem Modell; Default im Editor). Das Kühlregister rechnet wahlweise trocken (ε-NTU) oder als Greybox mit Kondensation (ua_star_wet_kg_s + Eintrittsfeuchte).

Teilstrecken-Gruppierung: Jede Komponente kann ein Label ts: <nummer> tragen (YAML wie Python-API). Der Bericht enthält dann eine Teilstrecken- Tabelle, die je Gruppe die Kette(n) in Strömungsrichtung auswertet: V̇, ΣΔp sowie p und T an Anfang und Ende jedes Abschnitts (eine klassische TS mit Vor- + Rücklauf unter einer Nummer zerfällt in zwei Abschnitte). Konsistenz wird geprüft: uneinheitliche Volumenströme oder Verzweigungen innerhalb einer Gruppe (= Teilstrecke falsch geschnitten) erzeugen einen Hinweis.

Modellierungsrichtlinie — Teilstrecken-Widerstände aufteilen: C-Werte aus Handrechnungen enthalten meist Vor- UND Rücklauf. Empfohlen ist die hälftige Aufteilung (C/2 als eigene flow_resistance je Richtung — die Leitungen sind in der Praxis parallel und gleich lang verlegt): Für die Kreisvolumenströme ist das äquivalent zum konzentrierten Wert, liefert aber korrekte Druckniveaus an allen Knoten, und die Rücklaufäste sind eigene Kanten — die thermische Mischreihenfolge an Sammlern stimmt dann von selbst. Konzentriert man dagegen alles in den Vorlauf, verschmelzen widerstandsfreie Rücklaufanschlüsse zu EINEM Mischknoten (Zapfstellen „sehen" stromab eingemischtes Wasser); dann Knoten mit link trennen. Beispiel: examples/07_twe_heizkreisverteiler.py.

Ventile: opening: 0 (bzw. die Endlagen des 3-Wege-Ventils) sperrt exakt — die Kante wird zur Randbedingung V̇ = 0, der abgesperrte Netzteil erhält automatisch einen Referenzdruck. Im Regelbereich (0 < opening < 1) begrenzt das Stellverhältnis (rangeability) den kleinsten Kv auf Kvs/R.

Randbedingungen

  • Pumpen: konstante Druckdifferenz (constant_dp) oder konstanter Volumenstrom (constant_flow, Druckerhöhung ist dann Ergebnis).
  • Offene Rohrenden (open_end): Druck ODER Volumenstrom vorgebbar, plus Zulauftemperatur.
  • Alle Drücke sind Überdrücke (gauge). Bei inkompressiblem Fluid ohne Verdampfung/Kondensation ist nur das Druckniveau relativ zur Atmosphäre relevant; Randbedingungen und Ergebnisse sind einheitlich als Überdruck zu lesen (Auslauf ins Freie: p_kPa: 0).
  • Druckbegriff – statisch vs. total. Alle Bauteile rechnen ihren Druckabfall als Totaldruckverlust; die Knotendrücke im Ergebnis sind daher Totaldrücke. Was man misst bzw. vorgibt, ist dagegen der statische Überdruck: p_statisch = p_Knoten − ρw²/2.
    • Druckrandbedingungen (inflow/outflow/open_end mit p_kPa) sind der statische Überdruck am Anschluss. Sitzt der Rand am Ende genau einer Leitung mit bekanntem Querschnitt (Rohr, Verbindungsleitung im Rohrmodell, Idelchik-T-Stück) oder ist d_inner_mm angegeben, liegt der Netzknoten um ρw²/2 darüber (Übergangskante <name>:dyn im Ergebnis). An einem Knotenpunkt mehrerer Bauteile ist die Geschwindigkeit am Rand nicht definiert; dort gilt der Wert als Knotendruck (mit Hinweis), ebenso ohne bekannten Querschnitt (Behälter, ideale Verbindung).
    • Drucksensoren zeigen den statischen Überdruck an der Messstelle, p_dyn_kPa ist der abgezogene dynamische Anteil. w stammt aus dem Querschnitt des Anschlusses, an dem die Messleitung hängt; hat dieser keinen (Pumpe, Ventil, Rand – im Editor der Regelfall, weil Leitungen eigene Verbindungen sind), gilt wie beim Druckrand die einzige Leitung mit bekanntem Querschnitt an der Messstelle; mit d_inner_mm der angegebene Querschnitt. An einem Knotenpunkt mehrerer Leitungen oder ohne bekannten Querschnitt zeigt der Sensor den Knotendruck (dann ohne p_dyn_kPa; der Bericht weist ihn als Knotendruck aus). Differenzdrucksensoren zeigen die statische Differenz; bei gleicher Nennweite beidseits ist sie gleich der Totaldruckdifferenz.
    • Fühleranschlüsse (Temperatur-/Drucksensoren, t_ref des Wärmemengenzählers) sind rückwirkungsfrei: sie zählen bei der Frage, ob ein Druckrand am Ende genau einer Leitung sitzt, nicht mit.
    • Der Druckanker p_out eines Speichers ist der Behälterdruck; im Behälter ruht das Wasser, statisch = total.
    • Größenordnung von ρw²/2 bei Wasser: 0,5 kPa bei 1 m/s, 2 kPa bei 2 m/s.
  • Geschlossene Kreise ohne Druckvorgabe erhalten automatisch einen Referenzdruck (150 kPa(ü) ≈ typischer Anlagenfülldruck, einstellbar über p_ref) – nur Druckdifferenzen sind dann physikalisch relevant; ein Hinweis erscheint im Bericht. Alternativ verankert eine Quelle mit p_out das Niveau explizit (wie ein Ausdehnungsgefäß am Erzeuger).
  • Inflow/Outflow (je ein Anschlusspunkt): Zulauf mit Temperatur + (V̇ ODER Überdruck); Austritt mit (Überdruck ODER Entnahme-V̇), die Austrittstemperatur ist Ergebnis — die Randbedingungen offener Systeme. Speicher (ideal_storage, Zweitor für geschlossene Kreise): Vorlauftemperatur fest, Rücklauf/Leistung Ergebnis; optional eingeprägter Volumenstrom und/oder Druckanker p_out.
  • Rein hydraulische Rechnung: net.solve(thermal=False) überspringt die Energiegleichung — nützlich für Kennlinienstudien und für Fälle ohne stationäre Temperaturlösung (z.B. thermisch isolierter Umlauf mit fest vorgegebener Leistung; wird sonst erkannt und verständlich gemeldet).

Numerik

  • Hydraulik: SIMPLE-artige Druckkorrektur auf dem Netzgraphen. Knoten tragen p und T, Komponenten sind Kanten mit Δp = a·Q + b·Q·|Q| − Δp_Quelle. Der Impulsprädiktor in Newton-Inkrementform und die Druckkorrektur K = A·diag(1/J)·Aᵀ (J = a + 2b|Q|) machen den Schritt bei α = 1 zu einem exakten Newton-Schritt (Schur-Komplement) → typisch 3–6 Iterationen. Robustheit: Churchill-Reibungskorrelation (glatt über alle Re-Bereiche), Widerstands-Floor für Q → 0, Kv-Leckage-Floor für fast geschlossene Ventile, Divergenz-Wächter mit automatischer Relaxationshalbierung, Jacobi-Skalierung. Kompilierzeit-Checks: Druckinsel-Analyse, Bilanz fester Volumenströme.
  • Thermik: nach Hydraulik-Konvergenz Upwind-Advektion; Newton-Verfahren auf der Knotenbilanz F(T) = G(T) − T (dünne Jacobi-Matrix, Kantensteigung per Differenzenquotient aus dem Komponentenmodell) mit Levenberg-Marquardt- Vertrauensbereich und Armijo-Liniensuche — lineare Netze in einem Schritt, nichtlineare quadratisch, unabhängig vom Rezirkulationsverhältnis (docs/numerik.md §2). Ideale Mischung an Knoten, UA-Verluste, Heizkörper- Exponentenmodell (Brent-Verfahren), ε-NTU-Register, exponentielle Rohr-/FBH-Modelle. Globale Energiebilanz wird geprüft und im Bericht ausgewiesen. Strömungsumkehr ist zulässig (Upwind folgt dem Vorzeichen). Robustheit: Klemmen (z.B. Erzeuger an q_max) werden über den singulären Unterraum verlassen; thermisch isolierte Umläufe mit fester Leistung (keine stationäre Lösung) werden erkannt und mit Knoten und Abhilfevorschlägen gemeldet; unplausible Austrittstemperaturen (feste Leistung bei Kleinstdurchfluss) erscheinen als Hinweis im Bericht.

Beispiele

Datei Inhalt
examples/01_single_loop.yaml WP + Pumpe + Heizkörper (Einzelkreis)
examples/02_parallel_radiators.yaml 3 parallele HK-Stränge mit Strangregulierventilen
examples/03_mixed_floorheating.yaml Beimischschaltung (3-Wege-Ventil) für FBH
examples/04_heatpump_separator.yaml WP + hydraulische Weiche + HK-Kreis + FBH-Beimischkreis
examples/05_umlenk_einspritz.yaml Umlenk- + Einspritzschaltung, Teilstrecken als Kvs-Äquivalente
examples/06_umlenk_einspritz_flow_resistance.yaml wie 05, Teilstrecken direkt als C-Werte (REGuA)
examples/07_twe_heizkreisverteiler.py TWE (Durchlaufprinzip) + Verteiler mit Einspritz-Regelgruppen: Auslegung (RG-Ventil, SRVs, Pumpen) + Solver-Verifikation + Abschaltfall; TS-Labels, hälftige Widerstandsaufteilung

Validierung gegen unabhängige Referenzlösungen (FH-Burgenland-Übungen):

Datei Inhalt
examples/validation_fh_verteiler.py Kennlinien-Plots (Ventilhub-Sweeps) zu Bsp 05/06 mit Referenzankern aus den Lösungsplots
examples/08_ventilautoritaet.py Wirkung der Ventilautorität: installierte Kennlinien (linear/gleichprozentig) für a_V = 0.1…0.9
examples/09_energetikum_lueftungsregister.yaml + .py Reale Anlage (Energetikum-Lüftung): VE/NE-Register als Einspritzschaltung mit Durchgangsventil im Rücklauf, echte Aedifion-BEMS-IDs; Analyse: Datenblatt-Reproduktion, Einregulierung (STAD-Voreinstellung), Ventilautorität
examples/referenzwerte_fh_verteiler.txt alle aus dem Lösungs-PDF extrahierten Referenzwerte (exakt vs. abgelesen)
tests/test_validation_fh_verteiler.py Volllast-Volumenströme < 0.1 %, Ventilautoritäten, Kennlinien-Anker
python3 examples/run_examples.py     # alle YAML-Beispiele mit Bericht
hydraulik run <datei.yaml> --json    # maschinenlesbares Ergebnis

Entwicklerdokumentation

Datei Inhalt
CLAUDE.md Projektleitfaden: Befehle, Struktur, Konventionen
docs/architektur.md Graphmodell, Solver-Verträge, Kompilierung, Parametersystem
docs/numerik.md Herleitung des Solvers (SIMPLE ≡ Newton via Schur-Komplement), Robustheitsmaßnahmen, Thermik, Testabdeckung
docs/erweitern.md Anleitung: neue Komponenten hinzufügen (mit Codegerüst)
docs/roadmap.md Stand, bewusste v1-Grenzen, v2-Ideen, Wiedereinstieg
docs/solver_pruefung_2026-10.md Prüfbericht des Solvers (Befunde, Korrekturen, offene Punkte, Kampagnenwirkung)
docs/fehlerbehebung_2026-11.md Fehleranalyse des ganzen Projekts 2026-11: Befunde, Korrekturen, Nutzerentscheidungen (inkl. Luftseite L13–L19), offene Punkte
tools/README.md Prüfwerkzeuge außerhalb der Testsuite: Zufallsnetz-Kampagne, Eindeutigkeit/Stabilität, Browser-E2E

Auf einem anderen Rechner weiterarbeiten

git clone https://github.com/AI4Buildings/HVAC-Hydronic-Network-Solver.git hydraulik
cd hydraulik
python3 -m venv .venv && source .venv/bin/activate      # Python ≥ 3.10
pip install -e ".[dev]"                                  # optional: ".[dev,e2e]"
pytest                                                   # alle Tests grün
editor server                                            # GUIs: http://127.0.0.1:8091/
  • Node.js: Die Paritätstests JS ↔ Python (tests/test_editor_paritaet.py) laufen nur, wenn node installiert ist; sonst werden sie übersprungen.
  • Nicht im Repository: Die Referenzunterlagen (Übungs-PDFs, Idelchik-Scans, GEA-Datenblatt) sind urheberrechtlich geschützt und werden nicht committet. Zum Rechnen und Testen werden sie nicht gebraucht.
  • Skill-Kopie: Die Skill-Kopie vka-effizienz-en16798 liegt außerhalb (~/.claude/skills) und ist nicht versioniert. Der Lüftungskern im Repo (src/hydraulik/air/vka/) ist eigenständig und maßgebend. Ob die Skill-Kopie eines Rechners auf dem Stand des Repos ist, zeigt python3 tools/vka_skill_abgleich.py; … --schreiben erzeugt ihre Kern-Dateien aus dem Repo neu (danach im Skill python3 validate_vka.py). Die SKILL.md und die Hilfsskripte des Skills liegen nur dort — auf einem Rechner mit älterem Skill fehlen in der SKILL.md die Beschreibungen der Korrekturen L13–L19 und der neuen Schlüssel (T_KW, KR_dew_limited).
  • Stand und offene Punkte: oberster Block in docs/roadmap.md, Details in docs/fehlerbehebung_2026-11.md (was entschieden ist, was offen ist).
  • Browsertests (optional): pip install -e ".[dev,e2e]", python -m playwright install chromium, dann die Skripte in tools/e2e/.

About

Steady-state 1D network solver (SIMPLE) for HVAC hydronic circuits: hydraulics + thermal, graphical schematic editor with built-in solver. Provides machine-readable hydronic schematics for AI agents (human-in-the-loop validated input) and benchmark tests for building services engineering.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages