Sizing Constraints¶
This page documents the sizing constraint classes for local mesh refinement.
Overview¶
Sizing constraints define regions where specific element sizes should be used. Multiple constraints can be combined - where they overlap, the minimum size wins.
Sizing Classes¶
SphereSize¶
mmgpy.SphereSize
dataclass
¶
Bases: SizingConstraint
Uniform size within a spherical region.
Parameters¶
center : array_like Center of the sphere, shape (dim,). radius : float Radius of the sphere. Must be positive. size : float Target edge size within the sphere. Must be positive.
options: show_root_heading: true
BoxSize¶
mmgpy.BoxSize
dataclass
¶
Bases: SizingConstraint
Uniform size within a box region.
Parameters¶
bounds : array_like Box bounds as [[xmin, ymin, zmin], [xmax, ymax, zmax]] for 3D or [[xmin, ymin], [xmax, ymax]] for 2D. size : float Target edge size within the box. Must be positive.
options: show_root_heading: true
CylinderSize¶
mmgpy.CylinderSize
dataclass
¶
Bases: SizingConstraint
Uniform size within a cylindrical region.
Parameters¶
point1 : array_like First endpoint of cylinder axis, shape (3,). point2 : array_like Second endpoint of cylinder axis, shape (3,). radius : float Radius of the cylinder. Must be positive. size : float Target edge size within the cylinder. Must be positive.
options: show_root_heading: true
PointSize¶
mmgpy.PointSize
dataclass
¶
Bases: SizingConstraint
Distance-based sizing from a point.
Size varies linearly from near_size at the point to far_size at influence_radius distance.
Parameters¶
point : array_like Reference point, shape (dim,). near_size : float Target size at the reference point. Must be positive. far_size : float Target size at influence_radius distance and beyond. Must be positive. influence_radius : float Distance over which size transitions from near_size to far_size. Must be positive.
options: show_root_heading: true
SizingConstraint (Base Class)¶
mmgpy.SizingConstraint
dataclass
¶
options: show_root_heading: true
Mesh Methods¶
All mesh classes have convenience methods for adding sizing constraints:
set_size_sphere¶
mesh.set_size_sphere(
center=[0.5, 0.5, 0.5], # Center of sphere
radius=0.2, # Sphere radius
size=0.01, # Target edge size
)
set_size_box¶
set_size_cylinder¶
# 3D meshes only
mesh.set_size_cylinder(
point1=[0, 0, 0], # First axis endpoint
point2=[0, 0, 1], # Second axis endpoint
radius=0.1, # Cylinder radius
size=0.01,
)
set_size_from_point¶
mesh.set_size_from_point(
point=[0.5, 0.5, 0.5],
near_size=0.01, # Size at reference point
far_size=0.1, # Size at influence_radius
influence_radius=0.5,
)
clear_local_sizing¶
get_local_sizing_count¶
apply_local_sizing¶
Utility Functions¶
mmgpy.sizing.apply_sizing_constraints
¶
apply_sizing_constraints(
mesh: MmgMesh3D | MmgMesh2D | MmgMeshS,
constraints: list[SizingConstraint],
existing_metric: NDArray[float64] | None = None,
) -> None
Apply sizing constraints to a mesh by setting its metric field.
Parameters¶
mesh : MmgMesh3D | MmgMesh2D | MmgMeshS Mesh to apply sizing to. constraints : list[SizingConstraint] List of sizing constraints. existing_metric : NDArray[np.float64] | None Existing metric field to combine with. If provided, minimum size wins.
options: show_root_heading: true
mmgpy.sizing.compute_sizes_from_constraints
¶
compute_sizes_from_constraints(
vertices: NDArray[float64], constraints: list[SizingConstraint]
) -> NDArray[np.float64]
Compute combined sizing from multiple constraints.
Multiple constraints are combined by taking the minimum size at each vertex (finest mesh wins).
Parameters¶
vertices : NDArray[np.float64] Vertex coordinates, shape (n_vertices, dim). constraints : list[SizingConstraint] List of sizing constraints.
Returns¶
NDArray[np.float64] Combined target size at each vertex, shape (n_vertices,).
options: show_root_heading: true
mmgpy.sizing.sizes_to_metric
¶
options: show_root_heading: true
Usage Examples¶
Basic Usage¶
import mmgpy
mesh = mmgpy.read("input.mesh")
# Add refinement region
mesh.set_size_sphere(center=[0.5, 0.5, 0.5], radius=0.2, size=0.01)
# Remesh (sizing constraints applied automatically)
result = mesh.remesh(hmax=0.1)
Multiple Regions¶
# Fine region
mesh.set_size_sphere(center=[0.3, 0.5, 0.5], radius=0.1, size=0.005)
# Medium region
mesh.set_size_box(bounds=[[0.5, 0, 0], [1, 1, 1]], size=0.02)
# Graded region
mesh.set_size_from_point(
point=[0.8, 0.5, 0.5],
near_size=0.01,
far_size=0.05,
influence_radius=0.3,
)
result = mesh.remesh(hmax=0.1)
Direct Class Usage¶
from mmgpy import SphereSize, BoxSize
from mmgpy.sizing import apply_sizing_constraints
import numpy as np
mesh = mmgpy.read("input.mesh")
constraints = [
SphereSize(
center=np.array([0.5, 0.5, 0.5]),
radius=0.2,
size=0.01,
),
BoxSize(
bounds=np.array([[0, 0, 0], [0.3, 0.3, 0.3]]),
size=0.02,
),
]
apply_sizing_constraints(mesh, constraints)
result = mesh.remesh(hmax=0.1)
Workflow with Validation¶
import mmgpy
mesh = mmgpy.read("input.mesh")
# Add sizing constraints
mesh.set_size_sphere(center=[0.5, 0.5, 0.5], radius=0.2, size=0.01)
# Check constraint count
print(f"Active constraints: {mesh.get_local_sizing_count()}")
# Preview metric field
mesh.apply_local_sizing()
metric = mesh["metric"]
print(f"Metric sizes: {metric.min():.4f} to {metric.max():.4f}")
# Remesh
result = mesh.remesh(hmax=0.1, verbose=-1)
# Clear for next iteration
mesh.clear_local_sizing()
How Sizing Works¶
- Constraint Definition: Each constraint defines a region and target size
- Size Computation: For each vertex, compute size from all constraints
- Minimum Selection: Where constraints overlap, minimum size wins
- Metric Conversion: Sizes are converted to isotropic metric tensors
- Remeshing: MMG uses the metric field to guide remeshing
from mmgpy.sizing import compute_sizes_from_constraints, sizes_to_metric
import numpy as np
# Get vertex coordinates
vertices = mesh.get_vertices()
# Compute sizes from constraints
constraints = [SphereSize(...), BoxSize(...)]
sizes = compute_sizes_from_constraints(vertices, constraints)
# Convert to metric field
metric = sizes_to_metric(sizes)
# Apply to mesh
mesh["metric"] = metric
Tips¶
- Constraint Order: Order doesn't matter - minimum size wins everywhere
- Performance: Many constraints have minimal overhead
- Clearing: Always clear constraints between different remeshing runs if needed
- Debugging: Use
apply_local_sizing()to preview the metric field before remeshing