Boundary Meshes (data.boundaries)

The finbound / legacy boundaries defined under MPIEMSES’s &ptcond are exposed as Python objects via data.boundaries. Each boundary produces a MeshSurface3D that you can overlay onto a 3D field plot or style individually.

Note: mesh() returns SI units by default. data.boundaries[0].mesh() gives you vertex coordinates in metres. Pass mesh(use_si=False) explicitly when you want grid-unit meshes (for example when feeding the mesh into a grid-space computation). When overlaying via plot_surfaces(), make sure the field axis units and the mesh units agree — mismatched units show up as boundaries that look slightly offset from the field.

Access

# The whole collection
data.boundaries                 # BoundaryCollection (iterable, indexable)
len(data.boundaries)
data.boundaries.types           # list of boundary_types strings
data.boundaries.skipped         # [(index, type_name, reason), ...]

# An individual boundary
data.boundaries[0]              # subclass (SphereBoundary, CylinderBoundary, ...)
data.boundaries[0].btype        # e.g. "sphere", "cylinderz"
data.boundaries[0].mesh()       # → MeshSurface3D (SI units by default)
data.boundaries[0].mesh(use_si=False)  # keep grid units

Overlay on a 3D field plot

Pass data.boundaries straight to Data3d.plot_surfaces to draw the geometries on top of isosurfaces or slices.

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(8, 6))
ax = fig.add_subplot(111, projection="3d")

data.phisp[-1].plot_surfaces(
    ax=ax,
    surfaces=data.boundaries,         # auto-wrapped into RenderItems
)
plt.show()

Overlay on PyVista

When you use the PyVista backend, add boundary meshes to the plotter returned by plot3d(show=False) with data.boundaries.plot3d(plotter=...). The same plot3d() entry point is also available on an individual boundary or MeshSurface3D.

plotter = data.phisp[-1].plot3d(mode="slice", show=False)

data.boundaries.plot3d(
    plotter=plotter,
    color="0.7",
    opacity=0.35,
    show_edges=True,
    show=True,
)

Use mesh_kwargs and per when you want to adjust boundary-mesh resolution or geometry. mesh_kwargs is broadcast to all boundaries and filtered to the arguments each boundary accepts. per overrides parameters for a specific boundary index.

data.boundaries.plot3d(
    plotter=plotter,
    mesh_kwargs={"ntheta": 64},
    per={2: {"naxial": 8}},
    color="white",
    opacity=0.4,
    show=True,
)

Resolution for Field-Coloured Planes

The default flat-surface mesh contains only its four corner vertices. Sampling a field at those vertices can miss interior variation, making a nonuniform potential look uniform. Explicitly pass resolution="grid" for (nx + 1, ny + 1) vertices when colouring the plane. In mixed collections, select the relevant boundary index with per.

mesh = data.boundaries.mesh(use_si=False, per={0: {"resolution": "grid"}})
data.phisp[-1].plot_surfaces(surfaces=mesh, use_si=False)

Numeric resolution=(nu, nv) and resolution_scale remain available. resolution="grid" is specific to flat-surface; do not broadcast it to other boundary types. The default mesh resolution remains unchanged.

Composite mesh

All boundaries can be fused into a single mesh for further processing:

composite = data.boundaries.mesh()    # → CompositeMeshSurface
V, F = composite.mesh()               # raw (vertices, faces) arrays

Composition and per-boundary styling

# Boundary + Boundary → BoundaryCollection
combined = data.boundaries[0] + data.boundaries[1]

# Different style per boundary
data.phisp[-1].plot_surfaces(
    ax=ax,
    surfaces=[
        data.boundaries[0].render(style="solid", solid_color="0.7"),
        data.boundaries[1].render(alpha=0.5),
    ],
)

Overriding mesh parameters

You can pass keyword arguments through mesh() to adjust resolution or geometry without modifying the simulation parameters:

# Higher angular resolution on a specific boundary
data.boundaries[0].mesh(ntheta=64)

# Per-boundary overrides via the collection
data.boundaries.mesh(per={0: dict(ntheta=64)})

Supported boundary types

Both boundary_type = "complex" with boundary_types(i) and the legacy single-body modes are supported.

Category

Type names

Closed solids

sphere, cuboid

Cylinders

cylinderx/y/z, open-cylinderx/y/z

Flat panels

rectangle, circlex/y/z, diskx/y/z, plane-with-circlex/y/z

Legacy single-body

flat-surface, rectangle-hole, cylinder-hole

See MPIEMSES3D Parameters.md for the full parameter specification.

Unregistered types are recorded in data.boundaries.skipped as (index, type_name, reason) tuples rather than raising an error. You can inspect this list to check whether any boundaries were silently ignored.

Available mesh surface classes

Each boundary type maps to one of these MeshSurface3D subclasses (importable from emout.plot.surface_cut):

Class

Used by

SphereMeshSurface

sphere

BoxMeshSurface

cuboid

RectangleMeshSurface

rectangle

CircleMeshSurface

circlex/y/z

CylinderMeshSurface

cylinderx/y/z, open-cylinderx/y/z

DiskMeshSurface

diskx/y/z

PlaneWithCircleMeshSurface

plane-with-circlex/y/z

HollowCylinderMeshSurface

cylinder-hole

CompositeMeshSurface

collection-level mesh() output

These classes can also be instantiated directly for standalone mesh construction without going through data.boundaries.