gustaf icon indicating copy to clipboard operation
gustaf copied to clipboard

added MFEM 3D export feature

Open mkofler96 opened this issue 1 year ago • 4 comments

Added feature to export MFEM mesh containing tetrahedra.

Small working example:

import gustaf as gus
import numpy as np

mesh = gus.Volumes(
    vertices=[
        [0.0, 0.0, 0.0],
        [1.0, 0.0, 0.0],
        [0.0, 1.0, 0.0],
        [1.0, 1.0, 0.0],
        [0.0, 0.0, 1.0],
        [1.0, 0.0, 1.0],
        [0.0, 1.0, 1.0],
        [1.0, 1.0, 1.0],
    ],
    volumes=[
        [0, 2, 7, 3],
        [0, 2, 6, 7],
        [0, 6, 4, 7],
        [5, 0, 4, 7],
        [5, 0, 7, 1],
        [7, 0, 3, 1],
    ],
)

tets = mesh.volumes
verts = mesh.vertices


faces = mesh.to_faces(False)
boundary_faces = faces.single_faces()

BC = {1: [], 2: [], 3: []} 
for i in boundary_faces:
    # mark boundaries at x = 0 with 1
    if np.max(verts[faces.const_faces[i], 0]) < 0.1:
        BC[1].append(i)
    # mark boundaries at x = 1 with 2
    elif np.min(verts[faces.const_faces[i], 0]) > 0.9:
        BC[2].append(i)
    # mark rest of the boundaries with 3
    else:
        BC[3].append(i)

gus.io.mfem.export("example_mfem.mesh", mesh, BC)

gus.io.mfem.export("example_mfem_no_bc.mesh", mesh, None)

Summary by CodeRabbit

  • New Features

    • Expanded support for exporting 3D tetrahedral meshes alongside 2D triangle and quadrilateral meshes, including configurable boundary conditions.
  • Tests

    • Implemented new test cases to validate the export functionality of various mesh data structures.
    • Enhanced testing capabilities with new fixtures for comparing stripped lines and generating temporary file paths.
  • Data

    • Introduced new mesh files defining structures for 3D tetrahedral and hexahedral elements, as well as 2D quadrilaterals and triangles.

mkofler96 avatar Jul 05 '24 05:07 mkofler96

[!IMPORTANT]

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

Refactors MFEM export in gustaf/io/mfem.py into dimension-specific routines with a shared array formatter; adds 2D/3D test fixtures, multiple MFEM ground-truth mesh files, and a parameterized test validating exported output against those files.

Changes

Cohort / File(s) Summary
MFEM export code
gustaf/io/mfem.py
Split export into dimension dispatch and internal _export_2d / _export_3d; added format_array(array: np.ndarray) -> str; construct elements and boundary arrays per-dimension and mesh type (tri/quad/tet/hexa); raise on unsupported dims.
Test fixtures & utilities
tests/conftest.py
Added 2D vertex/connectivity fixtures (vertices_2d, tri_connec_2d, quad_connec_2d), derived faces_* fixtures, volumes_hexa_222 3D fixture, helpers are_stripped_lines_same and to_tmpf; removed provide_data_to_unittest.
MFEM ground-truth data (2D)
tests/data/mfem_quadrilaterals_2d.mesh, tests/data/mfem_triangles_2d.mesh
New MFEM files: quadrilateral and triangular 2D ground-truth meshes (elements, boundary, vertices).
MFEM ground-truth data (3D)
tests/data/mfem_hexahedra_3d.mesh, tests/data/mfem_hexahedra_3d_222.mesh, tests/data/mfem_tetrahedra_3d.mesh
New MFEM files: single- and multi-element 3D hexahedral and tetrahedral ground-truth meshes (elements, boundary faces, vertices).
Tests
tests/test_export.py
New parameterized test test_mfem_export that builds mesh.BC from edges/faces, calls gustaf.io.mfem.export, and compares the exported file to ground-truth using are_stripped_lines_same.
Formatting / tooling / minor edits
.pre-commit-config.yaml, pyproject.toml, gustaf/create/faces.py, gustaf/utils/tictoc.py, tests/test_vertices_and_element_updates.py
Adjusted pre-commit hooks (removed Black, added/changed Ruff hooks), updated dev dependencies and Ruff config, minor string/format tweaks, and replaced volumes_hexa333 with volumes_hexa_222 in test parameters.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Test as Test (pytest)
  participant Mesh as Mesh (gus.*)
  participant Export as gustaf.io.mfem.export
  participant File as Output file

  Test->>Mesh: obtain fixture (2D or 3D)
  Test->>Mesh: build BC via edges/faces -> assign mesh.BC
  Test->>Export: call export(fname, mesh)
  Export->>Export: inspect vertex coordinates -> determine dim
  alt dim == 2
    Export->>Export: _export_2d(mesh) -> elementsStr, boundaryStr, verticesStr
  else dim == 3
    Export->>Export: _export_3d(mesh) -> elementsStr, boundaryStr, verticesStr
  else
    Export-->>Test: raise NotImplementedError
  end
  Export->>File: write MFEM header + dimension + elementsStr + boundaryStr + verticesStr
  File-->>Test: file saved
  Test->>Test: compare file to ground-truth (are_stripped_lines_same)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–30 minutes

  • Focus review on:
    • gustaf/io/mfem.py: index ordering, element attribute/geometry mapping, and BC geometry type selection.
    • tests/test_export.py: BC classification thresholds and that fixture outputs match ground-truth expectations.
    • New MFEM data files: confirm counts and formatting match exporter output.

Poem

I stitched triangles and quads with care,
Tetrahedra and hexahedra — a solid affair.
Boundaries labeled, vertices in place,
Exported to MFEM with tidy grace.
A rabbit hops, tests pass — code in embrace. 🐇

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'added MFEM 3D export feature' accurately captures the main objective of the pull request, which adds support for exporting MFEM mesh files in 3D format.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

coderabbitai[bot] avatar Jul 05 '24 05:07 coderabbitai[bot]

This looks very nice. The automatic code adaptations seem to be straightforward and especially the documentation remarks are good. In addition to that, could you also add the example you have given up top to the test suite and the examples?

Thanks for your work.

clemens-fricke avatar Jul 10 '24 07:07 clemens-fricke

Now that you have added the BC keyword to the function call, we need to think about how we need to include it for the other cases as well. Currently it is only implemented for the 3D case, which might produce unwanted/confusing behavior for users.

@j042 what is the status of the BC object variable? Could we not use that instead? I have no idea what the status of general BC in gustaf is, but I know that we talked about it previously...

clemens-fricke avatar Jul 10 '24 07:07 clemens-fricke

Now that you have added the BC keyword to the function call, we need to think about how we need to include it for the other cases as well. Currently it is only implemented for the 3D case, which might produce unwanted/confusing behavior for users.

@j042 what is the status of the BC object variable? Could we not use that instead? I have no idea what the status of general BC in gustaf is, but I know that we talked about it previously...

We talked about having general helper class to handle subset of elements/subelements - no progress on that. However, Faces and Volumes have member called BC and we should use that interface instead of an additional argument

j042 avatar Jul 10 '24 10:07 j042

@mkofler96 after applying the last commit (removing print()) test fails. Can you please check / update?

j042 avatar May 27 '25 19:05 j042

@mkofler96 after applying the last commit (removing print()) test fails. Can you please check / update?

I don't know exactly what caused the issue, but it seems to be related to which mesh is used for testing. At some point we used to test on the hexa333 mesh, but I think we switched to the single element test. The other 3 tests are passing, so I don't think it is a bigger issue.

We could also think of adding the hexa333 as a test for this. The test fixtures are still a bit all over the place. @clemens-fricke should we maybe check the fixtures and see if we should refactor some?

mkofler96 avatar May 29 '25 13:05 mkofler96

I have not really changed much but the hexa 222 test case seems to work now for me.

I have update the pre-commit a little bit since it used the legacy ruff mode.

Removed black due to it being outdated and making problems and being replicated by ruff in most ways anyway.

clemens-fricke avatar Nov 05 '25 17:11 clemens-fricke