Save and reload a model¶
Persist a meshed model to a native model.h5 and bring it back later
without re-running geometry or meshing. Reach for this to checkpoint a
long build, hand a model to a colleague, or resume into composition on
another day.
The recipe¶
Give the session a save_to= path and apeGmsh autosaves the neutral zone
on context-exit. Reload it as a bare snapshot with FEMData.from_h5, or
as a resumable chain-phase session with apeGmsh.from_h5.
from apeGmsh import apeGmsh, FEMData
# --- Save: autosave on exit -------------------------------------------
with apeGmsh(model_name="plate", save_to="plate.h5", overwrite=True) as g:
g.model.geometry.add_box(0, 0, 0, 1.0, 1.0, 0.1, label="body")
g.physical.add_volume("body", name="body")
g.mesh.generation.generate(dim=3)
g.save() # optional explicit checkpoint mid-session
# neutral zone is written here, in __exit__ (i.e. end()), before gmsh.finalize()
# --- Reload (A): a bare snapshot, integrity-checked -------------------
fem = FEMData.from_h5("plate.h5") # raises on a tampered/corrupt file
print(fem.info.summary()) # query nodes/PGs/loads with no live gmsh
# --- Reload (B): a resumable chain-phase session (no gmsh) ------------
g2 = apeGmsh.from_h5("plate.h5") # skips the gmsh build entirely
g2.compose("bolt.h5", label="bolt", translate=(0.5, 0.5, 0.0))
g2.save("assembly.h5")
Exact signatures (verified against src/):
apeGmsh(..., *, save_to: str | Path | None = None, overwrite: bool = True) # _core.py:84
apeGmsh.save(self, path: str | Path | None = None) -> Path # _core.py:251
apeGmsh.from_h5(cls, path, *, model_name=None, verbose=False) -> apeGmsh # _core.py:142
FEMData.to_h5(self, path, *, model_name="", apegmsh_version="", ndf=0) # FEMData.py:1603
FEMData.from_h5(cls, path, *, root="/") -> FEMData # FEMData.py:1548
Notes / gotchas¶
- Autosave fires on
end(), not eagerly. Nothing is written until__exit__/g.end()runs — if the process dies mid-build, the file never lands. Callg.save()explicitly when a checkpoint matters. save_to=None(the default) disables autosave. With a path set,overwrite=Falseagainst an existing file raisesFileExistsError;g.save()with neither an argument nor asave_to=raisesRuntimeError.- Autosave catches-and-warns on write failure so gmsh still finalizes.
A silently-warned failure can lose data — prefer an explicit
g.save()when persistence is the point. - Neutral zone only.
g.save()/FEMData.to_h5write the solver-agnostic mesh (nodes, elements, PGs, labels, constraints, loads, masses, per-node ndf) — no/opensees/zone. To persist the OpenSees deck alongside it, useapeSees(fem).h5("model.h5"), which writes both the neutral and opensees zones. from_h5is fail-loud./meta/snapshot_idis re-verified against the recomputed hash on read; a mutated neutral zone raisesMalformedH5Error, a missing/metaraisesMalformedH5Error, and a wrong schema major raisesSchemaVersionError. No silent corruption.- Two different
from_h5methods — don't confuse them:FEMData.from_h5returns a snapshot you can query and emit;apeGmsh.from_h5returns a chain-phase session with no gmsh state, sog.model.*andg.mesh.generation.*will fail. Onlycompose(...),save(...), and the chain-phase interface constraints/loads/masses work there. - Composed/results files nest the layout. A standalone
model.h5reads atroot="/"; a composedresults.h5carries the same layout under/model/, so passFEMData.from_h5("results.h5", root="/model"). - Bandwidth is not stored — it is recomputed from connectivity on read, so never rely on a persisted value.
See also¶
- Concept: The FEM broker (
FEMData) — the immutable snapshot and the full native-persistence round-trip contract. - Tutorial: Save, reload, and view a model — the same workflow walked end to end.
- How-to: Compose modules into one model
— graft saved
.h5parts together viaapeGmsh.from_h5+g.compose. - API:
FEMDatanative persistence and Session persistence.