Usage¶
Basalt transforms a Parasolid CAD assembly into a Gmsh mesh annotated for downstream DAGMC conversion. The pipeline has five distinct stages, each modelled by a small set of classes.
Stage |
Basalt entry point |
|---|---|
Parasolid → GAM |
|
GAM → SMS |
|
SMS → non-manifold |
|
Mesh |
|
Export |
Loading a Parasolid file¶
import basalt as bslt
model = bslt.Model.from_parasolid_file("geometry.x_t")
Pass load_nx_attrs=True to auto-detect a sibling *_attrs.json
sidecar (produced by the NX export journal) and apply its component
attributes — including DB_PART_NAME, used later as the material
name — to each Part and Assembly.
NX exports collapse all instances of the same base part into a single
GAM assembly. A part referenced 332 times in NX appears as one
Assembly containing 332 anonymous child Part
objects in Basalt. Per-instance NX names are not preserved.
Translating and imprinting¶
GAM is the assembly model; SMS is the model SimModSuite can mesh. Two calls bridge them:
import basalt as bslt
sms_model = model.translate()
nm_model = sms_model.make_non_manifold_model()
Model.translate() validates the geometry; invalid faces raise
here. Model.make_non_manifold_model() boolean-imprints
shared faces between adjacent volumes so the final mesh is
conformal.
Conformal meshing & overlaps¶
Model.make_non_manifold_model() resolves how adjacent bodies meet, so
the mesh is conformal regardless of how the CAD was authored:
Touching → one shared face. Coincident faces merge into a single conformal face shared by both volumes — non-manifold, not duplicated.
Overlapping → new faces and regions. Where bodies truly overlap, the imprint creates new regions at the intersection.
Coarse → still conformal. Adjacent bodies never self-intersect, even at coarse mesh sizes.
Touching bodies share one conformal face (red).¶
A true overlap imprints new regions (red).¶
The shared interface stays conformal even at coarse sizes.¶
Meshing¶
import basalt as bslt
mesh_case = bslt.MeshCase(nm_model)
mesh_case.set_size(0.1)
mesh_case.set_curvature_refinement(0.5, relative=True)
mesh_case.set_proximity_refinement(2.0)
surface_mesh = bslt.SurfaceMesh.from_model(nm_model, mesh_case)
volume_mesh = bslt.VolumeMesh.from_surface_mesh(surface_mesh)
Each refinement method accepts an optional model_item argument to
apply the setting to a single Part, Region, or
Face rather than the whole model.
See Mesh control for the full set of refinement controls.
See also
Basalt’s meshing controls wrap the Simmetrix SimModSuite mesher. For the full parameter semantics and meshing theory, consult the Simmetrix SimModSuite documentation that ships with your SimModSuite distribution.
Writing for DAGMC¶
import basalt as bslt
volume_mesh.write_msh("output.msh")
The exporter writes one Gmsh discrete entity per SMS mesh entity and encodes per-entity metadata in URL-style physical-group names:
Volumes:
tag=<N>&material=<material_name>Surfaces:
tag=<N>&forward_volume=<V>&reverse_volume=<V>
Material names are resolved per region in this order:
DB_PART_NAMEnative attribute on the relatedPart.Part.name(usuallyNonefor child bodies).Parent
Assembly.name.
A material_namer callback can override this resolution. Names
must be ≤ 28 characters — a hard MOAB limit downstream.
See Format for the full producer-side reference, including the slug-vs-material distinction and unit conventions.
Helpers¶
print_hierarchy() walks a Model and prints its
assembly/part/region tree:
import basalt as bslt
bslt.print_hierarchy(model)
load_material_metadata() reads a v6 _attrs.json sidecar
and returns {material_slug: body_record} for use when wiring up
materials downstream:
import basalt as bslt
metadata = bslt.load_material_metadata("geometry_attrs.json")