Topology

MeshTopology describes the spatial discretization used by HASEonGPU. It is the user-facing replacement for manually constructing point arrays, triangle indices, derived triangle geometry, and z-level metadata.

The public import names are:

from HASEonGPU import GainMedium, Grid, MeshTopology

GainMediumGeometry is an alias for MeshTopology.

Grid

Grid is the shortest path to a usable topology for rectangular media.

grid = Grid(
    xExtent=4.0,
    yExtent=4.0,
    zExtent=0.7,
    tileSizeX=0.25,
    tileSizeZ=0.7 / 9.0,
)
topology = MeshTopology.fromGrid(grid)

tileSizeY defaults to tileSizeX. tileSizeZ defaults to tileSizeX if it is not supplied.

Useful Grid members:

  • numberOfLevels: number of z-levels generated from zExtent and tileSizeZ.

  • thickness: z-spacing \(\Delta z\) between levels. This is the value passed to HASEonGPU as the layer thickness.

  • constructPoints(): returns the transverse point array with shape (numberOfPoints, 2).

MeshTopology Construction

From a grid:

topology = MeshTopology.fromGrid(grid)

From points:

points = np.array([[0, 0], [1, 0], [0, 1], [1, 1]], dtype=float)
topology = MeshTopology.fromPoints(points, numberOfLevels=5).withThickness(0.1)

fromPoints performs a Delaunay triangulation of the 2D points.

From a file:

topology = MeshTopology.fromFile("medium.vtk")
topology = MeshTopology.fromFile("mesh.stl", numberOfLevels=5).withThickness(0.1)
topology = MeshTopology.fromFile("mesh.msh", numberOfLevels=5, thickness=0.1)

Supported mesh formats are:

  • vtk or legacy-vtk: legacy ASCII VTK unstructured grids containing wedge cells are accepted. The importer reads the wedge cells, extracts the transverse (x, y) points from the first z-level, reconstructs the base triangle connectivity from the lower three nodes of each wedge, and infers numberOfLevels and thickness from the point z-coordinates.

  • stl: ASCII STL and binary STL are supported. The STL must be planar; current import projects vertices to (x, y) and keeps triangle topology. Because STL files do not store HASEonGPU layer information, set numberOfLevels and thickness before using the topology in a run.

  • msh or gmsh: gmsh 2D triangle meshes are supported through the Python gmsh package. The mesh must be planar and must contain triangle elements. numberOfLevels and thickness are required.

MeshTopology.fromFile(...) can override auto-detection with format=. This is useful for temporary files or non-standard extensions:

topology = MeshTopology.fromFile(
    "surface.mesh",
    format="gmsh",
    numberOfLevels=8,
    thickness=0.05,
)

The topology importer only creates geometry and layer metadata. It does not populate material arrays such as betaCells or reflectivities except for metadata that can later be used by GainMedium. For VTK files that contain both geometry and HASEonGPU field data, load a full gain medium instead:

medium = GainMedium.fromVtk("medium.vtk")
medium = GainMedium.fromFile("medium.vtk")

GainMedium.fromVtk(...) reads the same legacy wedge geometry as MeshTopology.fromFile(...) and then imports recognized HASEonGPU fields. betaCells is read from point data, betaVolume from cell data, and claddingCellTypes, refractiveIndices, reflectivities, nTot, crystalTFluo, claddingNumber, and claddingAbsorption from VTK FIELD arrays when present. numberOfLevels and thickness may be passed as overrides after loading.

The gmsh importer can also map physical groups whose names contain cladding to claddingCellTypes when the topology is used by GainMedium. The stored value is the gmsh physical tag for triangles in matching two-dimensional physical groups; all other triangles keep the default cladding type 0.

Shape and Size Queries

MeshTopology exposes the dimensions needed by other objects:

topology.numberOfPoints
topology.numberOfTriangles
topology.numberOfLevels(10)        # sets levels and returns topology
topology.numberOfPrisms            # triangles * (levels - 1)
topology.levelCoordinates()        # z coordinates

numberOfLevels is both a construction parameter name and a setter method on MeshTopology. After construction, use it as:

topology.numberOfLevels(10).withThickness(0.05)

Use GainMedium property metadata for array shapes:

medium = topology.asGainMedium()
medium.get("betaCells").expectedShape       # (numberOfPoints, levels)
medium.get("betaVolume").expectedShape      # (numberOfTriangles, levels - 1)
medium.get("reflectivities").expectedShape  # (2, numberOfTriangles)

Index Utilities

These helpers convert physical coordinates to topology indices:

point_index = topology.pointIndexAt(x=0.0, y=0.0)
level_index = topology.levelIndexAt(z=0.1)
point_index, level_index = topology.betaCellIndexAt(0.0, 0.0, 0.1)
flat_index = topology.betaCellIndexAt(0.0, 0.0, 0.1, flat=True)

betaCellIndexAt is useful when initializing or inspecting one \(\beta_i\) entry in the betaCells array.

Conversion to GainMedium

medium = topology.asGainMedium()

This is equivalent to:

medium = GainMedium(topology=topology)