sepehr 88620790d6 Complete Story 0.2 phantom-gradient regularization standard.
Add analytic derivatives and C1 tests for smooth_max/min/clamp, document epsilon/width guidance, and declare flow_regularization as the HX reference pattern without changing component physics.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-18 16:33:48 +02:00

Entropyk

Entropyk est un moteur de simulation thermodynamique pour cycles frigorifiques, pompes à chaleur et groupes d'eau glacée (chillers). Écrit en Rust, il assemble une machine sous forme de graphe de composants, résout le système d'équations non linéaires en régime permanent, et expose le même modèle via une ligne de commande JSON, une API Rust, des bindings Python / C / WebAssembly et une interface web.

Documentation détaillée : DOCUMENTATION.md · Tutoriel CLI : docs/CLI_TUTORIAL.md · Frontières Fixed/Free : docs/modelica-boundary-proof.md


Sommaire

  1. Ce qu'est Entropyk
  2. Installation
  3. Premier lancement
  4. Architecture du dépôt
  5. Le modèle : composants et câblage
  6. Degrés de liberté (DoF)
  7. Le solveur
  8. Catalogue des composants
  9. Frontières Fixed / Free (style Modelica)
  10. Le détendeur EXV et ses trois modes
  11. Fluides et backends
  12. La ligne de commande
  13. Interface web
  14. Bindings Python, C, WebAssembly
  15. Exemples fournis
  16. Conventions de développement

1. Ce qu'est Entropyk

Entropyk simule un cycle frigorifique, une pompe à chaleur ou un chiller en régime permanent :

  1. Vous déclarez des composants : un compresseur, un condenseur, un détendeur, un évaporateur, et les sources d'air ou d'eau qui les alimentent.
  2. Vous les câblez entre eux par des liaisons, par exemple la sortie du compresseur vers l'entrée du condenseur.
  3. Le moteur assemble automatiquement le système d'équations, calcule ses dérivées (la matrice jacobienne), et le résout par la méthode de Newton — avec repli vers des méthodes plus robustes si besoin.
  4. Vous récupérez les pressions, enthalpies, débits, puissances et COP, ainsi qu'un diagnostic indiquant si le système est bien équilibré (autant d'équations que d'inconnues).

Le COP (coefficient de performance) est le rapport entre la puissance utile (froid ou chaud) et la puissance électrique consommée par le compresseur.

Cas d'usage typiques :

  • Dimensionner un chiller à un point de fonctionnement : écrire un fichier JSON décrivant la machine, puis lancer entropyk-cli run.
  • Laisser les pressions d'aspiration et de refoulement flotter au lieu de les imposer : activer emergent_pressure sur les échangeurs et le détendeur ; les pressions résultent alors des bilans thermiques.
  • Calibrer la machine sur une cible (surchauffe, capacité, température de sortie) : ajouter une boucle de régulation qui ajuste un actionneur (ouverture du détendeur, coefficient d'échange) pour atteindre la cible.
  • Évaluer l'efficacité saisonnière selon les normes en vigueur (IPLV, SCOP, SEER) : les sous-commandes rate, scop, seer rejouent le cycle à plusieurs points de charge.
  • Qualifier un échangeur isolé : la sous-commande qualify balaye la température et le débit du fluide secondaire pour produire une fiche de performance.
  • Construire un schéma à la souris : l'interface web (apps/web) permet de dessiner le circuit et de lancer la simulation via le serveur ui-server.

2. Installation

Prérequis

  • Rust (toolchain stable, édition 2021).
  • CoolProp, la bibliothèque de propriétés thermodynamiques, livrée précompilée sous vendor/coolprop et liée via coolprop-sys.
  • Pour l'interface web : Node.js et npm.
  • Pour les bindings Python : uv (gestionnaire de paquets Python obligatoire, pas de pip direct).

Build

cargo build --release

Le binaire CLI est entropyk-cli (package entropyk-cli).


3. Premier lancement

cargo run -p entropyk-cli -- run \
  --config crates/cli/examples/chiller_aircooled_r134a.json \
  --output result.json

Sortie console : statut (converged / non-converged / timeout), résidu final, nombre d'itérations, temps de calcul, équilibre DoF, états des tronçons (pression en bar, enthalpie en kJ/kg) et performances (puissance frigorifique, puissance absorbée, COP).


4. Architecture du dépôt

Entropyk/
├── crates/
│   ├── core/          # Types physiques de base : Pression, Température, Enthalpie, Débit…
│   ├── fluids/        # Backends de propriétés : CoolProp, tabulaire, incompressible
│   ├── components/   # Tous les composants (trait Component)
│   ├── solver/        # Graphe, DoF, Newton, Picard, fallback
│   ├── entropyk/      # Façade : SystemBuilder, SimulationResult
│   ├── cli/           # Binaire entropyk-cli + exemples JSON
│   └── vendors/       # Parsers de données constructeurs (Copeland, Danfoss, SWEP, Bitzer)
├── bindings/
│   ├── python/        # PyO3
│   ├── c/            # FFI C (cbindgen)
│   └── wasm/         # WebAssembly
├── apps/web/          # Workbench diagramme (Next.js)
├── demo/             # ui-server Axum (port 3030)
├── docs/             # Manuels, Modelica, fiches composants
└── tests/fluids/     # Tests d'intégration cross-backend

Flux de données :

Config JSON / SystemBuilder / UI web
        |
        v
  create_component  ->  System (graphe)
        |
        v
   finalize() + porte DoF  ->  vecteur d'état [débit, pression, enthalpie] par tronçon
        |
        v
   Newton / Picard / fallback
        |
        v
   SimulationResult (états, énergies, COP, diagnostics)

5. Le modèle : composants et câblage

Ce que le solveur cherche

Pour chaque tuyau reliant deux composants, le solveur doit trouver trois valeurs :

Grandeur Unité SI Sens
débit massique ṁ kg/s combien de frigorigène circule
pression P Pa pression régnant dans ce tronçon
enthalpie massique h J/kg énergie portée par le fluide

Ces trois valeurs sont les inconnues du système. Le moteur en assemble une liste (le « vecteur d'état ») et cherche les valeurs qui annulent toutes les équations en même temps.

Une seule variable de débit pour toute la boucle

Dans un cycle simple, les composants sont branchés en boucle les uns derrière les autres, sans bifurcation : le frigorigène qui sort du compresseur entre intégralement dans le condenseur, puis dans le détendeur, puis dans l'évaporateur, puis revient au compresseur. Le débit est donc le même partout dans la boucle.

Plutôt que d'avoir une variable de débit par tuyau, le solveur en utilise une seule pour toute la boucle. Cela réduit le nombre d'inconnues et accélère la résolution. (S'il y a un branchement — débit qui se partage entre deux circuits — alors chaque branche reçoit sa propre variable de débit.)

Câblage

Les liaisons s'écrivent nom:port. Par exemple :

{ "from": "comp:outlet", "to": "cond:inlet" }

Le moteur construit le graphe à partir de ces liaisons, puis assemble les équations de chaque composant et leurs dérivées.


6. Degrés de liberté (DoF)

Le DoF (degrees of freedom, degrés de liberté) est le cœur du diagnostic. Un système est carré quand :

nombre d'équations  =  nombre d'inconnues
  • Trop d'équations : système sur-contraint (contradictoire).
  • Pas assez : système sous-contraint (indéterminé).

Dans les deux cas, finalize() refuse de lancer la résolution et renvoie un diagnostic détaillé (par composant : équations déclarées, inconnues consommées, rôle de chaque équation). Chaque composant déclare son nombre d'équations et le rôle de chacune : bilan d'énergie, chute de pression, condition de frontière, fermeture de sortie (surchauffe, sous-refroidissement, titre), actionneur…

Règle d'or : aucun composant ne doit fixer à la fois le débit et la pression sur le même flux. C'est l'équivalent de la règle Modelica qui interdit de fermer deux fois le même degré de liberté.


7. Le solveur

Implémentation : crates/solver.

Stratégies

Stratégie JSON Comportement
"newton" (défaut) NewtonRaphson : x ← x α·J⁻¹·r. Jacobien analytique fourni par les composants. Recherche linéaire de type Armijo activée automatiquement quand le système est sensible (contrôles, orifice, pression libre côté eau).
"picard" Substitution successive amortie : x ← (1ω)·x + ω·G(x), avec ω ≈ 0,5. Plus robuste, convergence plus lente.
"fallback" Newton d'abord ; bascule vers Picard en cas de divergence, puis retour à Newton quand le résidu redescend.

Tolérance typique : 1e-6. Itérations : 300 par défaut ; à augmenter pour les échangeurs dont le jacobien est partiellement numérique.

Boucle de résolution

Un résidu est l'écart entre le membre gauche et le membre droit d'une équation : il vaut zéro quand l'équation est satisfaite. Le but du solveur est de rendre tous les résidus nuls en même temps. La matrice jacobienne est l'ensemble des dérivées des résidus par rapport aux inconnues ; elle indique dans quelle direction corriger les inconnues.

1. Estimation initiale (frontières + pressions haute/basse initialisées par étages si emergent_pressure)
2. Calcul des résidus r(x) de tous les composants
3. Assemblage de la matrice jacobienne J(x) = ∂r/∂x
4. Résolution du système linéaire J·Δx = r
5. Mise à jour x ← clamp(x + α·Δx)  (pression bornée à un minimum, actionneurs bornés)
6. Répétition jusqu'à ce que ‖r‖ passe sous la tolérance

Limites assumées

  • Régime permanent uniquement (pas de dynamique temporelle).
  • Pas de CFD : les échangeurs sont des modèles 0D/1D (LMTD, ε-NTU, corrélations d'échange).
  • Les propriétés fluides viennent toujours du backend (CoolProp…), jamais de valeurs codées en dur.

8. Catalogue des composants

Tous les composants implémentent le trait Component : n_equations, compute_residuals, jacobian_entries, ports. La chaîne "type" du JSON correspond exactement aux bras de create_component dans crates/cli/src/run.rs.

8.1 Compresseurs

Type JSON Rôle Paramètres clés
IsentropicCompressor Compresseur à rendement isentropique + déplacement volumétrique ; mode émergent courant displacement_m3, speed_hz, volumetric_efficiency, isentropic_efficiency, emergent_pressure
Compressor Cartographie constructeur AHRI 540 (débit et puissance selon températures d'aspiration/ refoulement) coefficients m1m10 ou carte polynomiale
ScrewEconomizerCompressor / ScrewCompressor Compresseur à vis avec port économiseur, variation de fréquence, slide valve optionnel courbes selon températures de saturation, speed_hz
CentrifugalCompressor Carte polytropique (facteur de débit, nombre de Mach) diameter_m, speed_rpm, γ, R

En mode émergent, le compresseur impose la loi de débit (déplacement × masse volumique × rendement volumétrique) et l'énergie de refoulement ; les pressions haute/basse résultent des échangeurs. Si un détendeur à orifice fixe métre le débit, le CLI bascule le compresseur en mode « débit externe » (énergie seule) pour garder le système carré.

8.2 Détente et vannes

Type JSON Rôle Notes
IsenthalpicExpansionValve / EXV Détendeur isenthalpique (h_out = h_in) Sans orifice_kv, l'opening n'a aucun effet — voir §10
ExpansionValve Détendeur à orifice, modèle Cd·A ou TXV Eames flow_model, opening, beta_m2
CapillaryTube Capillaire adiabatique segmenté diameter_m, length_m, n_segments
ReversingValve / FourWayValve Vanne 4 voies pour pompe à chaleur (inversion froid/chaud) mode, pressure_drop_pa
BypassValve Bypass hydronique proportionnel opening, cv

8.3 Échangeurs frigorifiques

Type JSON Rôle Notes
Condenser / CondenserCoil Condenseur + côté secondaire (eau ou air) ua, emergent_pressure, subcooling_k, secondary_fluid, chute de pression secondaire optionnelle
Evaporator / EvaporatorCoil Évaporateur à détente directe + côté secondaire ua, superheat_k ou emergent, secondary_fluid
FloodedEvaporator Évaporateur noyé / à recirculation fermeture vapeur saturée ou quality_control
HeatExchanger Échangeur générique 4 ports (LMTD / ε-NTU) hot_fluid_id, cold_fluid_id, ua
BphxEvaporator / BphxCondenser Échangeur à plaques brasées + corrélations d'échange géométrie des plaques, corrélations Longo/Shah
AirCooledCondenser Condenseur refroidi par air (T_cond ≈ air + approach) oat_k, approach_k
FinCoilCondenser Batterie ailettée air géométrie tubes/ailettes
MchxCondenserCoil / MchxCoil Batterie à microcanaux géométrie des microcanaux
FreeCoolingExchanger / FreeCooling Free-cooling côté eau

Pressions émergentes (emergent_pressure: true) : l'échangeur ne pince plus la pression de saturation sur une température de design ; la pression flotte et est fermée par le sous-refroidissement, la surchauffe, le titre ou les bilans d'énergie.

Côté secondaire 4 ports : brancher BrineSource/AirSource → port secondary_inletsecondary_outletBrineSink/AirSink. L'échangeur propage la pression (fermeture isobare ou chute de pression quadratique issue du rating).

8.4 Tuyauterie, pompes, air

Type JSON Rôle Notes
Pipe / RefrigerantPipe / WaterPipe / AirDuct / PipeWater / PipeAir Conduits (DarcyWeisbach) length_m, diameter_m ; pressure_drop_pa = 0 → chute de pression calculée par Darcy depuis la géométrie et le débit ; > 0 → chute de pression imposée
Pump Courbes hauteur-débit + rendement, lois de similitude
Fan Courbes pression-débit + rendement, lois de similitude souvent sur boucle air
FlowSplitter / FlowMerger Jonctions de débit
Drum Séparateur liquide/vapeur (flooded)

8.5 Frontières (sources et sinks)

Type JSON Fluide Impose typiquement
RefrigerantSource / RefrigerantSink Frigorigène pression (+ titre ou enthalpie), débit optionnel
BrineSource / BrineSink Eau / glycol température, débit, pression (Fixed/Free)
AirSource / AirSink Air humide température sèche, humidité relative, débit, pression

Voir §9.

8.6 Divers

Type JSON Rôle
ThermalLoad Charge thermique Q couplée
HeatSource Injection de chaleur en ligne
Anchor / RefrigerantNode Nœud / ancre de surchauffe optionnelle
Placeholder Composant stub (tests, topologie)

8.7 Intégration d'un nouveau composant

Tout nouveau composant doit être câblé partout :

  1. Struct + trait Component + jacobien exact dans crates/components.
  2. Tests unitaires (résidus, vérification du jacobien par différences finies).
  3. Export dans crates/components/src/lib.rs et ré-export dans crates/entropyk/src/lib.rs.
  4. Bras dans create_component (crates/cli/src/run.rs).
  5. Wrapper Python (PyO3) et WASM si exposé.
  6. Métadonnées UI (apps/web/src/lib/componentMeta.ts) si visible dans le workbench.

9. Frontières Fixed / Free (style Modelica)

Entropyk reprend la sémantique des conditions aux limites Modelica. Les sources et sinks exposent trois booléens : fix_pressure, fix_temperature, fix_mass_flow.

Pattern Modelica Source Sink Conséquence
MassFlowSource_T (défaut Entropyk quand ṁ est imposé) T fixée, ṁ fixé, P libre P fixée, T_out libre La chute de pression de l'échangeur ferme le degré de liberté de pression
Boundary_pT P fixée, T fixée, ṁ libre P fixée Il faut une résistance hydraulique (conduit ou chute de pression d'échangeur) entre les deux pressions fixées
Rating T_out ṁ libre P fixée + T_out fixée Le débit devient inconnu (calibration)

Interdit : fixer à la fois le débit et la pression sur la même source sans degré de liberté ailleurs.

Chute de pression secondaire de rating (eau ou air) :

"secondary_rated_pressure_drop_pa": 40000,
"secondary_rated_m_flow_kg_s": 0.5

10. Le détendeur EXV et ses trois modes

Le composant IsenthalpicExpansionValve (alias EXV) a trois modes selon qu'on lui donne un orifice (orifice_kv) ou non.

Mode A — Isenthalpique seul (chillers classiques)

{ "type": "IsenthalpicExpansionValve", "name": "exv", "emergent_pressure": true }
  • Équation : h_out h_in = 0 (détente adiabatique sans travail).
  • Le débit est imposé par le compresseur (loi de déplacement).
  • L'opening est ignoré, même si l'UI affiche une valeur par défaut.

Mode B — Orifice fixe (ouverture = paramètre)

{
  "type": "IsenthalpicExpansionValve",
  "name": "exv",
  "emergent_pressure": true,
  "orifice_kv": 2.0e-6,
  "opening": 0.6,
  "fix_opening": true
}

Loi de débit :

ṁ = Kv · opening · √(2 · ρ_in · max(ΔP, 0))

Le CLI met alors le compresseur en mode « débit métré » (il abandonne sa loi de déplacement) pour garder le système carré.

Mode C — Orifice libre (ouverture = inconnue)

"orifice_kv": 2.0e-6,
"fix_opening": false

L'opening devient une inconnue ; il faut une boucle de régulation (par exemple surchauffe → contrôleur saturé) pour la fermer.

Piège UI : le catalogue affiche « Opening » même sans orifice_kv. Sans orifice explicite, changer l'ouverture ne change rien. Exemple dédié : crates/cli/examples/chiller_r134a_exv_orifice.json.


11. Fluides et backends

Backend Usage
CoolProp (fluid_backend: "CoolProp") Frigorigènes (R134a, R410A…), eau — défaut pour la physique sérieuse
Tabular Tables interpolées (WASM, environnements sans CoolProp)
Incompressible Glycols et liquides (masse volumique, viscosité de design)
Cached / Damped Wrappers de performance et de stabilité

Les types physiques de entropyk-core sont toujours en unités SI (Pa, K, J/kg, kg/s). Les JSON d'entrée acceptent souvent les °C et bar pour l'ergonomie ; la conversion est faite à la construction.


12. La ligne de commande

Binaire : entropyk-cli (package entropyk-cli).

Sous-commandes

Commande Rôle
run Une simulation depuis un fichier JSON
batch Dossier de configs, exécution parallèle
validate Vérifie le JSON et l'équilibre DoF (build + solve de contrôle)
qualify Qualification d'un échangeur (régime frigorigène fixe, balayage secondaire)
rate Rating saisonnier : IPLV (AHRI 550/590) ou ESEER
scop SCOP chauffage par bins EN 14825
seer SEER froid par bins EN 14825
schema Émet le JSON Schema du modèle (source unique pour CLI, UI, outils externes)

Flags globaux : -v / --verbose, -q / --quiet.

Exemples

# Build
cargo build --release -p entropyk-cli

# Simulation unique
cargo run -p entropyk-cli -- run \
  --config crates/cli/examples/chiller_aircooled_r134a.json \
  --output result.json

# Validation
cargo run -p entropyk-cli -- validate --config mon_cycle.json

# Batch
cargo run -p entropyk-cli -- batch -d ./scenarios/ -p 4 -O results.json

# Rating IPLV
cargo run -p entropyk-cli -- rate -c crates/cli/examples/rate_chiller_iplv_ahri.json

# Schéma JSON
cargo run -p entropyk-cli -- schema -o model-ir.schema.json

Schéma JSON minimal

{
  "name": "Mon chiller",
  "fluid": "R134a",
  "fluid_backend": "CoolProp",
  "circuits": [
    {
      "id": 0,
      "name": "Circuit principal",
      "components": [
        { "type": "IsentropicCompressor", "name": "comp" },
        { "type": "Condenser", "name": "cond" },
        { "type": "IsenthalpicExpansionValve", "name": "exv" },
        { "type": "Evaporator", "name": "evap" }
      ],
      "edges": [
        { "from": "comp:outlet", "to": "cond:inlet" },
        { "from": "cond:outlet", "to": "exv:inlet" },
        { "from": "exv:outlet", "to": "evap:inlet" },
        { "from": "evap:outlet", "to": "comp:inlet" }
      ]
    }
  ],
  "controls": [],
  "solver": {
    "strategy": "newton",
    "max_iterations": 300,
    "tolerance": 1e-6
  }
}

Pipeline interne de run

  1. Lecture de ScenarioConfig.
  2. Pour chaque composant : create_component(...) (CoolProp, params, modes orifice / emergent).
  3. Ajout des liaisons nommées nom:port.
  4. finalize() + contrôle DoF (système carré obligatoire).
  5. Estimation initiale (frontières + pressions par étages).
  6. Résolution selon solver.strategy.
  7. Sérialisation JSON : états des tronçons, performances, dof, failure_diagnostics en cas d'échec.

Contrôles (régulation / calibration)

Bloc optionnel controls : boucles qui lient une mesure (capacité, surchauffe…) à un actionneur (opening, z_ua, f_m…). Le solveur ajoute alors les inconnues d'actionneur et les résidus de suivi au système.


13. Interface web

Élément Chemin
Front Next.js apps/web
API Axum cargo run -p entropyk-demo --bin ui-serverhttp://localhost:3030

Fonctionnalités :

  • Palette de composants avec glyphes ISO, câblage React Flow.
  • Ledger DoF en temps réel (dofLedger.ts).
  • Coach Fixed/Free Modelica (boundaryFix.ts, dofCoach.ts).
  • Simulation via POST /api/simulate.
# Terminal 1
cargo run -q -p entropyk-demo --bin ui-server

# Terminal 2
cd apps/web && npm run dev

14. Bindings Python, C, WebAssembly

Chemins réels : bindings/python, bindings/c, bindings/wasm (pas sous crates/).

Python (uv obligatoire)

uv pip install -e ./bindings/python
uv pip install maturin
cd bindings/python && uv run maturin develop --release
uv run pytest tests/

C

cargo build --release -p entropyk-c
# header généré sous target/ (voir bindings/c/README.md)

WebAssembly

Voir bindings/wasm/README.md — adapté aux backends tabulaires côté client.

Certaines classes Python historiques sont encore des stubs (audit 2026-07) : vérifier les warnings à la construction et préférer le chemin CLI / Rust pour la physique complète.


15. Exemples fournis

Répertoire : crates/cli/examples/.

Fichier Intérêt
chiller_aircooled_r134a.json Chiller air 4 ports, emergent, air + eau glacée
chiller_watercooled_r410a.json Chiller eau R410A
chiller_flooded_4port_watercooled.json FloodedEvaporator, DoF carré
chiller_flooded_delta_t_rating.json Rating par ΔT
chiller_r134a_emergent_pressure.json Pressions émergentes
chiller_r134a_exv_orifice.json EXV avec orifice (ouverture physique)
chiller_r134a_superheat_control.json Boucle de surchauffe
chiller_r134a_slide_valve.json Slide valve compresseur à vis
chiller_r134a_dual_circuit_staging.json Double circuit en cascade
chiller_r134a_liquid_injection.json Injection liquide
chiller_r134a_flooded_headpressure.json Flooded à pression de tête
chiller_r410a_bolt_nodes.json Nœuds boulonnés
chiller_r410a_coupled_water_loop.json Boucle d'eau couplée
heatpump_airsource_r410a.json Pompe à chaleur air
heatpump_r410a_reversing_valve.json Vanne 4 voies
heatpump_r134a_fan_headpressure.json Pression de tête pilotée par ventilateur
hx_air_water_4port.json Échangeur isolé aireau
bphx_evaporator_condenser.json Plaques brasées
capillary_tube_r134a.json Capillaire
rate_chiller_iplv_ahri.json Rating IPLV
scop_heatpump_r134a.json SCOP

16. Conventions de développement

  • Langage : Rust, Result<T, E> partout — pas de panic! en production.
  • Jacobiens : analytiques et exacts ; pas de différences finies sauf chemin explicitement documenté ou temporaire.
  • Types : newtypes SI (Pressure, Enthalpy…) — pas de f64 nus aux frontières publiques.
  • Documentation technique / commits : anglais ; communication projet en français.
  • Git : branche main, messages à l'impératif en anglais.
  • BMAD : workflows sous _bmad/ — suivre les fichiers YAML/XML à la lettre si activés.

Ajouter un composant (checklist)

  1. Struct + trait Component dans crates/components.
  2. Tests unitaires (résidus, jacobien vérifié par différences finies).
  3. Export lib.rs + façade entropyk.
  4. Bras CLI create_component.
  5. Exemple JSON sous crates/cli/examples/.
  6. Métadonnées UI + bindings si besoin.

Liens utiles

Document Contenu
DOCUMENTATION.md Modèles physiques, solveur, API
EXAMPLES_FULL.md Scénarios avancés
docs/CLI_TUTORIAL.md Tutoriel CLI
docs/modelica-boundary-proof.md Preuve Fixed/Free
docs/components/ Fiches composants
AGENTS.md Instructions agents / structure
crates/cli/README.md Détails CLI
apps/web/README.md Interface web

Projet : Entropyk · Langage : Rust · Licence / version : voir Cargo.toml (v0.1.x)

Description
No description provided
Readme 6.5 MiB
Languages
Rust 80.5%
TypeScript 8.4%
Python 5.1%
HTML 2.9%
Jupyter Notebook 2.5%
Other 0.4%