Triangle Grouping and Regrouping

Before pressures can be reduced to force, moment or shape coefficients, the mesh triangles have to be partitioned into meaningful groups – one group per body, per facade, per floor, per zoning cell. cfdmod treats grouping as a first-class, composable step, and provides two disk-level companions that act on the result: regroup (rewrite a mesh + its timeseries around a new grouping) and remesh (coarsen a grouped mesh).

The Python surface is documented in the API reference (grouping, regroup and remesh sections); this page explains when to reach for which.

The grouping model

A grouping pipeline partitions or selects the triangles of a parent LnasFormat mesh into named groups. Specs are Pydantic models in a discriminated union (GroupingSpec), composed left-to-right with apply_groupings(), and a triangle may belong to zero, one, or many groups. Each spec carries a restrict_to field so a later step can scope its work to triangles already placed by an earlier one – this is how a surface -> sub-body nesting is reproduced.

The built-in kinds fall into a few intents:

  • By named geometryBySurfaceGrouping collects named LNAS surfaces into groups.

  • By a regular gridByZoningGrouping bins centroids into a Cartesian grid; ByDivisionsGrouping (n cells per axis) and BySizeGrouping (fixed cell size) are convenience wrappers over it.

  • By orientation / geometryByNormalGrouping (windward / leeward / roof / sidewall by outward normal), ByPlaneGrouping (signed distance from an oriented plane), ByCylindricalGrouping (r, theta, axial bins – towers, silos, chimneys).

  • By connectivityByConnectivityGrouping puts each shared-edge connected component in its own group (one physical body per component, no axis projection).

  • By statisticsByPercentileGrouping makes equal-count quantile bins along an axis, for stable per-cell statistics when triangle density is uneven.

  • Escape hatchCustomGrouping runs a user callback when none of the built-ins express the partition.

The force / moment / shape recipes are built on this abstraction: the body_grouping / zoning_grouping / connectivity_grouping ops attach a grouping to a SurfaceDataSource, and per-group series are aggregated onto a GroupsDataSource.

Regroup: a new mesh + aligned series

run_regroup() (module cfdmod.regroup, runnable as python -m cfdmod.regroup) takes a geometry plus a per-triangle HDF5 timeseries (Cp-style: rows are timesteps, columns are parent triangle ids), applies a chain of grouping specs, and writes two aligned outputs:

  • a new LnasFormat mesh with one named surface per group, and

  • a new HDF5 timeseries whose columns line up with the new triangle order (per_triangle) or whose values are area-weighted per-group aggregates broadcast over each group’s triangles (area_weighted_mean).

Reach for regroup when a downstream tool needs the grouping baked into the mesh on disk (one surface per region) rather than applied on the fly – for example to hand a regrouped, per-facade mesh to ParaView or to a separate coefficient run. It adds one regroup-local spec, BySizeRoundedPerComponent, that fans out per-component target-size subdivisions.

Remesh: coarsen a grouped mesh

remesh_per_group() (module cfdmod.remesh) coarsens a grouped LnasFormat – typically regroup output, where a group holds many triangles from sliced cuts. Two paths:

  • Exact coplanar-fan collapse (default) – within each group, adjacent coplanar triangles are replaced by the minimum triangulation of their joined region. Lossless, deterministic, numpy-only: a flat NxN-subdivided square collapses to 2 triangles, a curved patch is left unchanged.

  • QEM decimation (decimate_qem()) – opt-in Quadric Error Metrics decimation via the remesh extra, for curved groups where coplanar merge cannot reduce the count further.

Use remesh to shrink a mesh for faster rendering or downstream I/O once the grouping is fixed; keep the default coplanar path unless a group is curved.

See also

The grouping, regroup and remesh API sections in API Reference, and the Cf / Cm / Ce recipes in Pressure that consume groupings directly.