Skip to content

Marching Cubes for EB Generation - #5607

Draft
ankithadas wants to merge 27 commits into
AMReX-Codes:developmentfrom
ankithadas:marching-cubes-eb-plan
Draft

Marching Cubes for EB Generation#5607
ankithadas wants to merge 27 commits into
AMReX-Codes:developmentfrom
ankithadas:marching-cubes-eb-plan

Conversation

@ankithadas

@ankithadas ankithadas commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR extends the Marching Cubes (#4778) algorithm to EB generation. Users can select the new generator with:

eb2.geometry_method = marching_cubes

The choice applies to every way of describing the geometry: the built-in implicit functions selected by eb2.geom_type, user-defined implicit functions passed to any of the EB2::Build overloads through EB2::makeShop, and STL files. It is ignored for eb2.geom_type = chkpt_file. The original EB2 construction (legacy) remains the default.

The marching-cubes path:

  • Builds a nodal level set from the geometry source and resolves the surface with the MC33 lookup tables.
  • Stores resolved MC33 face-connectivity decisions for use when constructing Cartesian face apertures.
  • Computes the complete single-valued EB dataset: volume and area fractions, centroids, boundary normals, and connectivity.
  • Computes exact Cartesian-edge intersections instead of relying on linear interpolation of sampled level-set values. For implicit functions the crossing of every sign-changing edge is found by Brent root finding on the function; for STL input the edge is intersected with the original triangles. An edge whose root finding fails falls back to linear interpolation.
  • Uses the same cached edge intersections for MC vertices, face apertures, edge centroids, and cell moments, including ambiguous MC33 faces.
  • Samples implicit functions without clamping the sample positions to the domain, and snaps nodes that lie on the surface within roundoff to exact zero.
  • Uses a narrow-band STL level set: exact distance values are retained on cut-cell interpolation and vertex-normal stencils, while only the inside/outside classification is retained farther from the interface.
  • Iteratively removes small cells and geometry unsupported by the single-valued representation by moving incident fluid nodes to the interface.
  • Uses eb2.cover_multiple_cuts to control whether unsupported faces and cells may be repaired.
  • Supports eb2.small_volfrac and eb2.maxiter during cleanup.
  • Handles exact-zero nodal values and surfaces aligned with grid nodes or faces.
  • Extends the level set and exact transverse-edge intersections when extend_domain_face is requested.
  • Applies to the finest level and to any coarse level that is rebuilt from the geometry description (eb2.build_coarse_level_by_coarsening = 0 or the multi-level EB2::Build overload); coarse levels obtained by coarsening are unaffected.
  • Optionally writes the MC triangulation through eb2.mc_stl_file.
  • Adds WriteEBSurfaceSTL for writing the planar EB reconstruction as an ASCII STL file.

The generator is available only in 3D on Cartesian grids with cubic cells (dx == dy == dz); a non-cubic grid is rejected even when the geometry is all regular. It is incompatible with BuildMultiValuedMultiCut.

A sampled signed-distance field is insufficient to reproduce the position where the surface crosses a Cartesian edge. Linear interpolation between its endpoint samples can place the MC vertex at a different point from the actual crossing. To avoid this inconsistency, the builder resolves each sign-changing edge against the geometry source itself — root finding for implicit functions, STLtools::fillMarchingCubesEdgeIntersections against the original triangles for STL — and stores the normalized crossing locations in each MCFab. These crossings are then shared by all downstream geometry calculations. If cleanup places the interface exactly on an edge endpoint, the exact-zero endpoint is used.

MC33 face decisions are retained in MCFab. This ensures that ambiguous Cartesian faces use the same resolved topology when building face apertures as when generating the MC triangles.

Because AMReX's EB representation is single-valued, the builder checks for:

  • faces containing more than one resolved fluid aperture;
  • cells with invalid MC topology, multiple fluid components, or MC33 "tunnel" tilings whose fluid regions would only be joined through the cell interior;
  • invalid face or cell geometry records;
  • cut cells below eb2.small_volfrac.

Small cells are repaired automatically. Other unsupported geometry requires eb2.cover_multiple_cuts = 1, matching the existing behaviour for covering geometry that cannot be represented as a single-valued cell.

The geometry-source adapters live in AMReX_EB2_Level_MC.H/.cpp: a source that provides its own MC sampling (STLtools) is used as is, and every other source is served by generic adapters that reuse the shop's fillFab and getIntercept.

Docs: Docs/sphinx_documentation/source/EB.rst gains a "Marching-Cubes Geometry Generation" section and a note on the planar EB surface output; eb2.geometry_method and eb2.mc_stl_file are documented in RuntimeParameters.rst.

The marching-cubes tests include

  • all 256 MC33 nodal sign configurations and valid triangle indices
  • ambiguous-face connectivity decisions
  • exact STL intersections and implicit-function root finding on ambiguous faces
  • narrow-band level-set values and global sign classification
  • surfaces coincident with grid nodes and faces
  • cell moments, face apertures, boundary normals, and closure consistency
  • EB cell connectivity and edge-centroid consistency
  • small-cell and unsupported-topology cleanup
  • box, sphere, gyroid, and parser implicit functions, plus the EB2::Build API paths (single level, host, multi-level, and coarse-level rebuild)
  • periodic domains, geometry crossing the domain boundary, and scale invariance
  • cube, multiple cubes, and Stanford bunny STL geometries
  • rejection of open, non-manifold, or inconsistently oriented STL input, of non-cubic grids, and of unsupported topology without eb2.cover_multiple_cuts
  • CNS Sod MarchingCubes_3d test

The proposed changes:

  • fix a bug or incorrect behavior in AMReX
  • add new capabilities to AMReX
  • changes answers in the test suite to more than roundoff level
  • are likely to significantly affect the results of downstream AMReX users
  • include documentation in the code and/or rst files, if appropriate

FYI: Parts of the main code and all of the testing code was vibe coded using codex. So some modifications and cleanup will be required.

@ankithadas
ankithadas force-pushed the marching-cubes-eb-plan branch from 84d1396 to 3faa27e Compare August 12, 2026 15:35
@ankithadas

Copy link
Copy Markdown
Contributor Author

Not sure why the clang fast math test failed. Running with ASAN didn't give any insights. Any ideas ?

@ankithadas

Copy link
Copy Markdown
Contributor Author

The EB produced by Marching Cubes (MC) is much better than the existing method (legacy).

MC EB
Screenshot 2026-08-12 at 10 19 25 pm

Legacy EB
Screenshot 2026-08-12 at 10 19 49 pm

@ankithadas ankithadas changed the title Marching Cubes for STL EB Marching Cubes for EB Generation Aug 19, 2026
@ankithadas
ankithadas force-pushed the marching-cubes-eb-plan branch from fd336a6 to bb701a0 Compare August 19, 2026 18:45
@ankithadas
ankithadas force-pushed the marching-cubes-eb-plan branch from bb701a0 to 7e32255 Compare August 19, 2026 18:51
@ankithadas

Copy link
Copy Markdown
Contributor Author

I am looking for collaborators for this PR. Email or ping me in AMReX slack if you are interested in working in this.

@ankithadas
ankithadas force-pushed the marching-cubes-eb-plan branch from 8d6f1ec to 15b9fa8 Compare September 1, 2026 10:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant