Creating Geometry from the Project Object¶
The EMProject class provides convenience methods to create geometry directly,
keeping everything managed within a single project context. This is the recommended
workflow for most simulations.
1. Create a Primitive via the Project¶
Instead of importing primitive classes directly, you can use proj.create_primitive()
which creates the geometry and automatically associates it with the project.
from cavsim3d.core.em_project import EMProject
# Create a project with a rectangular waveguide primitive
proj = EMProject(name='project_geometry_demo', base_dir='./simulations', new=True)
rwg = proj.create_primitive('RectangularWaveguide', a=0.1, L=0.2)
proj.geometry = rwg
print(f"Geometry type: {type(proj.geo).__name__}")
proj.geo.show('geometry')
proj.geo.generate_mesh(maxh=0.02)
proj.geo.show('mesh')
2. Import CAD Files via the Project¶
Similarly, proj.create_importer() creates an OCCImporter tied to the project.
proj2 = EMProject(name='project_import_demo', base_dir='./simulations', new=True)
# Import a pillbox cavity via the project
cavity = proj2.create_importer('../example_models/pillbox.step', unit='m')
proj2.geometry = cavity
print(f"Geometry type: {type(proj2.geo).__name__}")
proj2.geo.show('geometry')
proj2.geo.generate_mesh(maxh=0.02)
proj2.geo.show('mesh')
3. Import a Multi-Cell Cavity via the Project¶
The same workflow applies for more complex geometries like a 9-cell TESLA cavity.
proj3 = EMProject(name='project_tesla_demo', base_dir='./simulations', new=True)
tesla = proj3.create_importer('../example_models/tesla9cell.step', unit='m')
proj3.geometry = tesla
proj3.geo.show('geometry')
proj3.geo.generate_mesh(maxh=0.02)
proj3.geo.show('mesh')
4. Create an Assembly via the Project¶
For multi-component structures, proj.create_assembly() sets up an assembly
that can hold both primitives and imported geometries.
proj4 = EMProject(name='project_assembly_demo', base_dir='./simulations', new=True)
assembly = proj4.create_assembly(main_axis='Z')
# Mix primitives and imports in one assembly
rwg = proj4.create_primitive('RectangularWaveguide', a=0.1, L=0.2)
imported = proj4.create_importer('../example_models/rectangular_waveguide.step', unit='m')
assembly.add("primitive_section", rwg)
assembly.add("imported_section", imported, after="primitive_section")
assembly.build()
assembly.print_port_info()
assembly.generate_mesh(maxh=0.02)
assembly.show('geometry')
5. Saving and Loading¶
Projects created this way are fully persistent. Call proj.save() to save
geometry, mesh, and solver state to disk.
# Save the project
proj.save()
# Later, reload it
proj_loaded = EMProject(name='project_geometry_demo', base_dir='./simulations')
print(f"Loaded geometry: {type(proj_loaded.geo).__name__}")
proj_loaded.geo.show('geometry')
Summary¶
In this tutorial we:
- Created primitives via
proj.create_primitive() - Imported CAD files via
proj.create_importer() - Created assemblies mixing primitives and imports
- Saved and loaded projects with geometry
The project-based workflow keeps all geometry, mesh, and solver data organised under a single project directory.
Next: See the Quick Start Examples to run full simulations.