Architecture at a glance¶
This page gives you two views of MoCSI:
a big picture for getting oriented, and
a detailed view for when you want to know which class does what.
Both show the same run, at different zoom levels. They tie together the core structure (grid, simulation class, solver, snapshots) and the module system. The whole thing in one sentence:
Inputs → setup builds the grid and picks modules → modules fill the field map → the time loop solves the heat equation each step → results stream out.
The big picture¶
Every MoCSI run passes through five stages. The fourth one — the time loop — repeats until the simulation finishes.
%%{init: {'theme':'base', 'flowchart': {'curve':'basis','nodeSpacing':40,'rankSpacing':48}}}%%
flowchart LR
classDef stage fill:#eaf3fb,stroke:#1f7fc7,color:#10324a,stroke-width:1.5px;
classDef loop fill:#e9f6ee,stroke:#2e9e5b,color:#11331f,stroke-width:1.5px;
classDef out fill:#f2ecfb,stroke:#7b52c7,color:#2c1a4a,stroke-width:1.5px;
A("📥 Inputs<br/><small>config, shape, kernels</small>") --> B("⚙️ Setup<br/><small>build grid, pick modules</small>")
B --> C("🧩 Physics modules<br/><small>fill the field map</small>")
C --> D("🔁 Time loop<br/><small>assemble + solve each step<br/>↻ repeats until finished</small>")
D --> E("📤 Outputs<br/><small>snapshots + CSV</small>")
class A,B,C stage;
class D loop;
class E out;
Tip
Want a styled, standalone version for a slide or screen-share? Open the interactive overview poster (opens in a new tab) — the same five stages as gradient cards with hover descriptions.
The detailed view¶
The same flow, now naming the real classes — including the boundary conditions, the module registry, submodule nesting, and the optional build-time features (VTK, SPICE, MPI) and where they plug in.
Show the full architecture diagram
%%{init: {'theme':'base', 'flowchart': {'curve':'basis','nodeSpacing':45,'rankSpacing':60,'subGraphTitleMargin':{'top':8,'bottom':18}}, 'themeVariables': {'clusterBkg':'#fbfcfe','clusterBorder':'#d9e1ec'}}}%%
flowchart TB
classDef inNode fill:#d6ebf7,stroke:#1f7fc7,color:#10324a;
classDef setupNode fill:#eef4fb,stroke:#1f7fc7,color:#10324a;
classDef modNode fill:#fde9d6,stroke:#ef7b11,color:#5a3206;
classDef subNode fill:#fff6ec,stroke:#ef7b11,color:#7a4408,stroke-dasharray:3 2;
classDef coreNode fill:#e9f6ee,stroke:#2e9e5b,color:#11331f;
classDef outNode fill:#f1eafb,stroke:#7b52c7,color:#2c1a4a;
classDef store fill:#fff5e6,stroke:#ef7b11,color:#5a3206,stroke-width:2px;
classDef optNode fill:#fbeef0,stroke:#c0405a,color:#5a1320,stroke-dasharray:5 3;
subgraph IN [" 📥 Inputs "]
ini(".ini files<br/><small>default · run · per-module</small>")
shape("Shape model mesh")
spice("SPICE kernels")
snapin("Snapshot<br/><small>resume</small>")
end
subgraph SETUP [" ⚙️ Setup and build — runs once "]
input("InputManager<br/><small>+ IniParser</small>")
shapef("ShapeFactory<br/>→ ShapeBase")
gridf("GridFactory → GridOneDim<br/><small>OneDimLinearElement</small>")
matf("MatrixFactory<br/>→ Csr / DenseMatrix")
reg("ModuleFactory <i>registry</i><br/><small>StaticModuleContainer</small>")
end
subgraph MOD [" 🧩 Physics modules — one slot each "]
direction TB
sub("submodules — do the calculation<br/><small>nestable, e.g. HeatConductivityTwoLayers,<br/>AlbedoConstantCustom</small>")
mods("Managing modules <i>(examples — more available)</i><br/><small>Albedo · Emissivity · Density · HeatCapacity ·<br/>HeatConductivity · HeliocentricDistance · SolarVector · HeatSource · …</small>")
fieldmap[("Field map<br/>Temperature + properties")]
sub --> mods --> fieldmap
end
subgraph CORE [" 🔁 Time loop and solver core "]
chains("ChainManager — 5 insertion points<br/><small>Init · PreTimeStep · PostNonLinIter · PostTimeStep · Output</small>")
elem("ElementManager<br/><small>FEM assembly: C, K, F</small>")
bcreg("BoundaryConditionRegistry")
bc("Boundary conditions<br/><small>BCTopSurfaceEnergyBalance ·<br/>BCSinusoidalTemperature · BCConstantHeatFlux</small>")
mmgr("MatrixManager<br/><small>global system (C + KΔt)·T = …</small>")
solver("TridiagonalMatrixSolver<br/><small>TDMA</small>")
end
subgraph OUT [" 📤 Outputs "]
snapout("SnapshotCreator")
csv("OutputCsvTool")
prog("RuntimeProgressTool")
end
subgraph OPT [" 🧪 Optional build-time features "]
vtk("VTK<br/><small>mesh I/O · VtkRayCasting</small>")
spicelib("SPICE<br/><small>HeliocentricDistanceSpice · SolarVectorSpice</small>")
mpi("MPI<br/><small>MpiDomainDecomposition</small>")
end
ini --> input
snapin --> input
shape --> shapef
spice --> spicelib
input --> reg
input --> gridf
shapef --> gridf
gridf --> matf
reg --> mods
matf --> elem
fieldmap --> bc
bcreg --> bc
chains -. drives .-> mods
chains -. drives .-> elem
elem --> mmgr
bc --> mmgr
mmgr --> solver
solver --> fieldmap
fieldmap --> snapout & csv & prog
vtk -.->|"shape I/O"| shapef
spicelib -.->|"ephemeris"| mods
mpi -.->|"parallelism"| solver
class ini,shape,spice,snapin inNode;
class input,shapef,gridf,matf,reg setupNode;
class mods modNode;
class sub subNode;
class fieldmap store;
class chains,elem,bcreg,bc,mmgr,solver coreNode;
class snapout,csv,prog outNode;
class vtk,spicelib,mpi optNode;
The five stages¶
1. Inputs. A run is described entirely by .ini files — a global default.ini, a per-run file (-i run.ini), and one file per module under ini_files/. A shape model and SPICE kernels are optional, as is a prior snapshot to resume from.
2. Setup (once). InputManager (with IniParser) parses every .ini into typed parameters. Factories then build the run’s machinery: ShapeFactory → the surface, GridFactory → the depth discretization (GridOneDim), MatrixFactory → the global matrix. The ModuleFactory registry is the key idea: every module registers itself at startup, and only the modules you list in chain_insertion are instantiated.
3. Modules fill the field map. Each managing module owns exactly one slot in the field map and keeps it current; its submodules do the actual calculation and feed results up — see Modules for the split. The modules named in the diagram are only examples: MoCSI ships more than these, and you can add your own — the Modules page has the complete, current list.
4. Time loop and solver core. ChainManager runs modules at defined module insertion points; of these, PreTimeStep, PostNonLinIter and PostTimeStep fire inside the time loop, while Init and Output run once before and after it. On each step the loop assembles and solves: ElementManager builds the FEM matrices (capacitance C, stiffness K, forcing F); the boundary conditions write into them; MatrixManager builds the global linear system; TridiagonalMatrixSolver (TDMA) solves it and writes the new temperature back into the field map.
5. Outputs. SnapshotCreator writes a complete restore point (final field plus every .ini value); OutputCsvTool streams field values during the run; RuntimeProgressTool reports progress.
Boundary conditions¶
Boundary conditions are applied during FEM assembly, where they modify the matrix rows for boundary nodes. They are selected through the BoundaryConditionRegistry. The default is BCTopSurfaceEnergyBalance — the surface energy balance that reads solar flux, emissivity and albedo each step. BCSinusoidalTemperature and BCConstantHeatFlux are available for analytical/validation cases. See boundary conditions for the maths.
Optional build-time features¶
These are compiled in only when their library is present; the diagram shows them as dashed plug-ins:
Feature |
Plugs into |
What it unlocks |
|---|---|---|
VTK |
|
Loading shape-model meshes; |
SPICE |
|
|
MPI |
grid, snapshots |
Domain decomposition across processes and parallel snapshot I/O |
See Installation → optional libraries for how to enable each.
Where to go next¶
Core structure — the four core systems (grid, simulation class, solver, snapshots) in depth.
Modules — managing modules vs. submodules, the five insertion points, and the full module list.
Mathematical background — the FEM discretization, TDMA solver, and boundary conditions behind the solver core.