Examples and tutorials » Working with MMG » Optimizing the mesh

How to optimize a mesh using the MMG remesher.

Introduction

Mesh quality is critical for accurate finite element solutions. The MMG::Optimizer wraps MMG optimization mode: it improves poorly shaped elements while keeping the mesh close to the local size distribution already present in the input mesh. This is different from metric-driven adaptation, where an external size map prescribes where the mesh should be refined or coarsened.

Basic Usage

The simplest workflow is to create a mesh, mark its geometric features (corners and ridges), and optimize:

#include <Rodin/Geometry.h>
#include <Rodin/MMG.h>

using namespace Rodin;
using namespace Rodin::Geometry;

int main()
{
  MMG::Mesh mesh;
  mesh = mesh.UniformGrid(Polytope::Type::Triangle, { 16, 16 });

  // Mark corner vertices (preserved exactly during remeshing)
  mesh.setCorner(0);
  mesh.setCorner(15);
  mesh.setCorner(240);
  mesh.setCorner(255);

  // Mark all boundary edges as ridges (sharp features)
  for (auto it = mesh.getBoundary(); !it.end(); ++it)
    mesh.setRidge(it->getIndex());

  // Optimize with target edge length ≤ 0.5
  MMG::Optimizer().setHMax(0.5).optimize(mesh);

  mesh.save("Optimized.mesh", IO::FileFormat::MFEM);

  return 0;
}

Optimizer Parameters

The MMG::Optimizer supports several parameters:

MethodDescription
setHMax(h)Upper edge-size bound passed to MMG
setHMin(h)Lower edge-size bound passed to MMG
setHausdorff(h)Hausdorff distance for curved boundaries
setAngleDetection(b)Enable/disable automatic ridge detection

Required Entities

Required vertices, edges, triangles, and tetrahedra can be marked on MMG::Mesh before optimization. The Rodin wrapper passes them to MMG as required entities and restores the required index sets after optimization when the corresponding indices still exist in the output:

mesh.setRequiredVertex(vertexIndex);
mesh.setRequiredEdge(edgeIndex);
mesh.setRequiredTriangle(triangleIndex);
mesh.setRequiredTetrahedron(tetrahedronIndex);

MMG::Optimizer().setHMax(0.1).optimize(mesh);

See Required entity behavior for the tested preservation guarantees and the important level-set limitations.

Typical settings for shape optimization:

MMG::Optimizer()
  .setHMax(0.05)
  .setHMin(0.005)
  .setHausdorff(0.0025)
  .setAngleDetection(false)
  .optimize(mesh);

Full Source Code

See Also