Feature Request: Python API for High-Order Curving of Externally Imported Meshes

Feature Request: Python API for High-Order Curving of Externally Imported Meshes

Summary

I would like to use hexahedral (hex) high-order elements in NGSolve for improved accuracy in FEM simulations. Since Netgen does not generate hex meshes, I need to import meshes from external mesh generators. However, I discovered that mesh.Curve(order) does not work correctly with externally imported meshes (order ≥ 2).

I would like to request a Python API that enables proper high-order curving for meshes imported from external sources.

Motivation: Hexahedral High-Order Elements

Hex elements offer several advantages over tetrahedral elements:

  • Better accuracy per degree of freedom
  • More efficient for structured geometries
  • Required for certain physics (e.g., large deformation, incompressibility)

To use hex meshes in NGSolve, I need to:

  1. Generate hex mesh in an external mesh generator
  2. Import the mesh into NGSolve
  3. Apply high-order curving for curved boundaries

Step 3 is currently problematic.

Problem Description

Current Behavior

When importing meshes from external sources, mesh.Curve(order) produces incorrect results for order ≥ 2:

| Method                        | Area Error | Volume Error |
|-------------------------------|-----------|--------------|
| Pure Netgen + Curve(4)        | 0.000003% | 0.000004%    |
| External mesh + Curve(2)      | ~56%      | ~6%          |
| External mesh + Curve(3)      | ~64%      | ~8%          |
| External mesh + Curve(4)      | ~69%      | ~9%          |

Root Cause

mesh.Curve(order) requires Element2D.geominfo which contains UV parametric coordinates (surfnr, u, v). These UV parameters are only set when Netgen generates the mesh directly. When importing meshes from external sources, geominfo is not populated, causing Curve(2+) to produce incorrect (inflated) results.

Current Workaround: SetDeformation

I am currently using SetDeformation to manually project boundary elements onto the exact geometry:

from ngsolve import VectorH1, GridFunction, CF, sqrt, x, y, IfPos, Mesh
from netgen.occ import OCCGeometry

# Import external mesh and attach OCC geometry
ngmesh = import_external_mesh(...)  # Custom import function
ngmesh.SetGeometry(occ_geometry)
mesh = Mesh(ngmesh)
mesh.Curve(1)  # Linear mesh ONLY

# Apply SetDeformation for cylinder surface (radius R)
fes = VectorH1(mesh, order=4)
deform = GridFunction(fes)
r_xy = sqrt(x*x + y*y)
scale = IfPos(r_xy - 0.01, R/r_xy - 1, 0)
deform.Set(CF((scale*x, scale*y, 0)), definedon=mesh.Boundaries('cylinder_surface'))
mesh.SetDeformation(deform)

Results with SetDeformation

| Method                              | Area Error  | Volume Error |
|-------------------------------------|-------------|--------------|
| Pure Netgen + Curve(4)              | 0.000003%   | 0.000004%    |
| External mesh + SetDeformation(4)   | 0.000044%   | 0.000065%    |
| External mesh + SetDeformation(6)   | 0.000000%   | 0.000000%    |

SetDeformation achieves excellent accuracy, but:

  • Requires manual implementation for each geometry type (cylinder, sphere, cone, torus, etc.)
  • Cannot handle arbitrary CAD geometry automatically
  • The mesh visually appears as 1st-order elements (deformation is applied at integration level)

Feature Request

Option 1: API to Set geominfo for External Meshes

Provide a Python API to set Element2D.geominfo for boundary elements:

# Proposed API
for el in ngmesh.Elements2D():
    # Compute UV coordinates from OCC geometry
    face = geo.GetFace(el.surfnr)
    u, v = face.GetUV(el.center)
    el.SetGeomInfo(surfnr=el.surfnr, u=u, v=v)

mesh = Mesh(ngmesh)
mesh.Curve(4)  # Now works correctly

Option 2: Alternative Curving Method Without geominfo

Provide a method that curves the mesh by projecting boundary nodes directly onto the OCC geometry surface, without requiring UV parameters:

# Proposed API
mesh.CurveFromGeometry(geo, order=4)  # Projects boundary nodes onto geo surfaces

Option 3: Enhanced Mesh Import with Geometry Binding

Provide an import method that properly binds external mesh vertices to OCC geometry and computes geominfo automatically:

# Proposed API
from netgen import ImportExternalMesh

ngmesh = ImportExternalMesh(
    vertices=node_coords,
    elements3d=hex_connectivity,  # or tet, wedge, pyramid
    elements2d=quad_connectivity,  # or tri
    geometry=occ_geometry,
    compute_geominfo=True  # Automatically compute UV parameters
)

mesh = Mesh(ngmesh)
mesh.Curve(4)  # Works correctly

Minimal Test Case

from netgen import occ
from netgen.occ import OCCGeometry
from ngsolve import Mesh, Integrate, CF, BND
import math

# Create cylinder geometry
R, H = 0.5, 2.0
cyl = occ.Cylinder(occ.Pnt(0, 0, -1), occ.Vec(0, 0, 1), r=R, h=H)
geo = OCCGeometry(cyl)

# Generate mesh with Netgen (works correctly)
ngmesh = geo.GenerateMesh(maxh=0.2)
mesh = Mesh(ngmesh)

expected_area = 2*math.pi*R*H + 2*math.pi*R*R

print("Netgen-generated mesh:")
for order in [1, 2, 3, 4]:
    mesh.Curve(order)
    area = Integrate(CF(1), mesh, VOL_or_BND=BND)
    error = abs(area - expected_area) / expected_area * 100
    print(f"  Curve({order}): Area error = {error:.4f}%")

# Output:
# Curve(1): Area error = 0.5630%
# Curve(2): Area error = 0.0034%
# Curve(3): Area error = 0.0003%
# Curve(4): Area error = 0.0000%

When the same geometry is meshed externally and imported (even attaching the same OCC geometry), Curve(2+) produces 50-70% errors because geominfo is not set.

Use Cases

This feature would enable:

  1. Hex mesh support: Use external mesh generators for hex meshing, then apply high-order curving in NGSolve
  2. Complex CAD workflows: Import meshes from industrial CAD/CAE software with proper curved boundary representation
  3. Hybrid element types: Mixed hex/tet/wedge/pyramid meshes with high-order curving
  4. Legacy mesh reuse: Apply high-order curving to existing mesh libraries

Environment

  • NGSolve version: 6.2.2404
  • Python version: 3.12
  • OS: Windows 10/11

Thank you for considering this feature request. High-order hex elements would significantly expand NGSolve’s capabilities for industrial and research applications.