Triangle Mesh Generator GUI and CLI Integration with FEATool

Banner - Triangle Mesh Generator GUI and CLI Integration with FEATool

FEATool-Triangle Mesh Generator Integration

This update fully integrates J.R. Shewchuk’s fast and efficient 2D mesh and grid generator Triangle with FEATool [1][2][3]. Both Matlab and Octave command line interface (CLI) usage is supported with the gridgen_triangle function, as well as FEATool GUI usage with the new dedicated Tri button available in 2D grid mode.

Advantages of using Triangle compared to the built-in (DistMesh based) grid generation function is firstly the overall speed, as it is one of the fastest 2D unstructured mesh generators available (completely written in C code). Moreover, Triangle also supports control for specifying the grid size in different subdomains and geometry regions, as well as on boundaries, allowing for greater flexibility and higher quality grids adapted to specific problems and geometries.

Matlab Grid and Mesh Generation with Triangle and the FEATool GUI

To evaluate the performance of Triangle and compare it to the built-in DistMesh based grid generator a simple benchmark test case was employed. The test case consisted of generating a uniform mesh for a unit circle with average grid sizes hmax = [0.1 0.05 0.025 0.0125 0.00625]. The normalized timings for using gridgen

tic
geom.objects = { gobj_circle() };
grid = gridgen( geom, 'hmax', hmax );
t = toc

to mesh the circle in Matlab and Octave, as well as the new gridgen_triangle function are plotted as log scale curves in the figure below.

Matlab, Octave, and Triangle Grid Generation Benchmark and Comparison

The results show that for the finest grid (hmax = 0.00625, consisting of approximately 185000 triangles) required 10 seconds for Triangle, 1 minute for DistMesh and Matlab, and close to 7 minutes for Octave (suffering from lack of Just-In-Time JIT compilation). Also note that the Triangle timings also includes time taken for IO export and import, that is the total time the user might typically see. Thus it is clear that Triangle can offer magnitudes of speed improvements for two-dimensional unstructured grid generation.

Installation

First please ensure you have the latest FEATool version 1.7 installed with either Matlab or Octave, and download the Triangle update and integration patch from the link below

FEATool-Triangle Integration and Update Patch

Extract the contents of the featool-triangle-patch.zip archive into the FEATool installation directory, or alternatively manually copy the two files listed below

gridgen_triangle.m  >  featool/gridgen_triangle.m
grid_mode.m         >  featool/gui/grid_mode.m

If the Triangle mesh generator binary is not present or cannot be found in the featool/lib/triangle folder, then the gridgen_triangle function will attempt to automatically download, (compile if required), and install it by itself.

Should the Triangle installation or compilation fail, please manually download, compile, and install Triangle from the original source reference [1].

GUI Usage

Once installed, the updated GUI will in 2D grid mode show a new button labeled Tri (short for Triangle). Pressing this opens the Triangle Grid Generation dialog box with three edit fields for entering hmax, hmaxe, and q, respectively.

  • The Subdomain Grid Size, hmax, indicates the target grid cell diameter, and can either be a single scalar prescribing the grid size for the entire geometry, or a space separated string of numbers (array) where the hmax values correspond to the generated subdomains.

  • Boundary Grid Size, hmaxe, is analogous to hmax but related to boundaries (edges). hmaxe can consist of a single scalar applicable to all boundaries, for example

    0.1
    

    prescribing a mean cell edge length of 0.1 on every boundary. hmaxe can also be a numeric array with entries corresponding to individual boundaries, for example

    [ 0.1  0.2  0.3  0.4 ]
    

    specifying cell edge length 0.1 for boundary 1, 0.2 for boundary 2 etc. Lastly, hmaxe can also be given as a cell array where each entry and boundary can be prescribed a single value for the mean cell edge size or a numeric array of grid point distributions (spanning 0 to 1) along the boundary. For example

    { 0.1  [0 0.1 0.5 1]  0.3  [1 0.8 0.2 0] }
    

    where here boundaries 1 and 3 are prescribed mean edge lengths 0.1 and 0.3, respectively. Boundary 2 is assigned nodes at parametrized positions 0, 0.1, 0.5, and 1 while boundary 4 the nodes are assigned in reverse.

  • The Minimum Angle, q parameter (default 28 degrees) specifies a minimum target angle (values less than 33 are generally acceptable, while higher values might prevent Triangle convergence).

The Generate Grid button effectively calls the gridgen_triangle function, and in turn Triangle from the GUI, after which the generated grid is automatically imported and displayed.

CLI Usage

On the Matlab and Octave command lines the gridgen_triangle function is used to call Triangle to generate an unstructured 2D triangular grid. The following syntax is used (analogous to the regular gridgen function)

grid = gridgen_triangle( SIN, VARARGIN )

where SIN is a valid FEATool fea problem struct or cell array of geometry objects. gridgen_triangle also accepts the following property/value pairs (VARARGIN).

Property    Value/{Default}            Description
-----------------------------------------------------------------------------------
hmax        scal/arr {0.1}             Target grid size for geometry/subdomains
hmaxe       scal/arr {[]}              Target grid size for boundary edges
q           scalar   {28}              Minimum target angle (quality)
nsm         scalar   {0}               Number of (post) grid smoothing steps
syscmd      string   {'default'}       Triangle system call command (default
                                       'triangle -I -q%f -j -e -a -A %s.poly')
compcmd     string   {'default'}       Triangle unix/linux compilation command
                                       ('cc -O triangle.c -lm -o triangle')
fname       string   {'fea_tri_UID'}   Triangle imp/exp file name (root)
clean       boolean  {true}            Delete (clean) Triangle help files
instdir     string   {'lib/triangle'}  Triangle installation directory

As also discussed above, among the properties hmax indicates target grid cell diameters, and is either a numeric scalar valid for the entire geometry or an array with hmax values corresponding to the subdomains. hmaxe is similar to hmax but a numeric array with a hmaxe values corresponding to the boundaries (including internal boundaries). q (default 28 degrees) specifies a minimum target grid size (values less than 33 are generally acceptable, while higher values might prevent convergence). nsm (default 0) the number of gridsmooth smoothing steps to perform. More detailed information regarding the mesh generation options can be found in the documentation for Triangle [1].

For more information about CLI usage access the function help by entering

>> help triangle_gridgen


Grid Generation Examples

Matlab Mesh Generation Triangle Grid Examples
  1. Unit square with uniform global grid size set to 0.1

    grid = gridgen_triangle( {gobj_rectangle()}, 'hmax', 0.1 );
    plotgrid( grid )
    
  2. Unit square with prescribed edge node distribution

    flog  = @(n,m) ((logspace(0,1,n)-1)/9).^m;   % Log distribution function.
    grid = gridgen_triangle( {gobj_rectangle()}, 'hmax', 0.5, ...
                   'hmaxe', {1-flog(50,2) flog(50,2) 1-flog(15,1.5) flog(15,1.5)} );
    plotgrid( grid )
    
  3. Domain with fine grid along curved boundaries (number 5 and 6)

    geom.objects = {gobj_rectangle() gobj_circle([0 0],.6) gobj_circle([1 1],.3,'C2')};
    geom = geom_apply_formula( geom, 'R1-C1-C2' );
    grid = gridgen_triangle( geom, 'hmax', .1, 'hmaxe', [.1 .1 .1 .1 .01 .01] );
    plotgrid( grid )
    
  4. Two connected subdomains with refined grid along the shared boundary (9)

    geom.objects = { gobj_rectangle(-2e-3,0,-8e-3,8e-3), ...
                     gobj_polygon([0 -6e-3;2e-3 -5e-3;2e-3 4e-3;0 6e-3]) };
    hmax  = 5e-4;
    hmaxe = hmax*ones(1,9);
    hmaxe(9) = hmax/5;
    grid  = gridgen_triangle( geom, 'hmax', hmax, 'hmaxe', hmaxe );
    plotgrid( grid )
    
  5. Component with fine grid on subdomains 2 and 3, and curved boundaries

    r1 = gobj_rectangle( 0, 0.11, 0, 0.12,  'R1' );
    c1 = gobj_circle( [ 0.065 0 ],   0.015, 'C1' );
    c2 = gobj_circle( [ 0.11 0.12 ], 0.035, 'C2' );
    c3 = gobj_circle( [ 0 0.06 ],    0.025, 'C3' );
    r2 = gobj_rectangle( 0.065, 0.16, 0.05, 0.07, 'R2' );
    c4 = gobj_circle( [ 0.065 0.06 ], 0.01, 'C4' );
    geom.objects = { r1 c1 c2 c3 r2 c4 };
    geom = geom_apply_formula( geom, 'R1-C1-C2-C3' );
    geom = geom_apply_formula( geom, 'R2+C4' );
    
    hmax  = [0.02 0.0015 0.0015];
    hmaxe = 0.02*ones(1,34);
    hmaxe([8:12]) = 0.0025;
    grid  = gridgen_triangle( geom, 'hmax', hmax, 'hmaxe', hmaxe );
    plotgrid( grid )
    
  6. Complex geometry with several holes and subdomains

    w = 10e-4; L = 3*w; H = 5*w;
    p1  = gobj_polygon( [w/10 0;L 0;L H-H/3;L H;0 H;0 H/3], 'P1' );
    r1  = gobj_rectangle( (L-w/4)/2, (L+w/4)/2, -sqrt(eps), H, 'R1' );
    c1  = gobj_circle( [2*w/3 3*w], w/3, 'C1' );
    c2  = gobj_circle( [2*w/3 2*w], w/3, 'C2' );
    c3  = gobj_circle( [2*w/3 1*w], w/3, 'C3' );
    c4  = gobj_circle( [L-w/2 4.5*w], w/8, 'C4' );
    c5  = gobj_circle( [L-w   4.5*w], w/8, 'C5' );
    c6  = gobj_circle( [L-w/2 4*w], w/8, 'C6' );
    c7  = gobj_circle( [L-w   4*w], w/8, 'C7' );
    c8  = gobj_circle( [L-w/2 3.5*w], w/8, 'C8' );
    c9  = gobj_circle( [L-w   3.5*w], w/8, 'C9' );
    c10 = gobj_circle( [L-w/2 3*w], w/8, 'C10' );
    c11 = gobj_circle( [L-w   3*w], w/8, 'C11' );
    geom.objects = { p1 r1 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 };
    geom = geom_apply_formula( geom, 'P1-C1-C2-C3-C4-C5-C6-C7-C8-C9-C10-C11' );
    
    hmaxe = w/5*ones(1,59);
    hmaxe([5 9]) = w/50;
    grid  = gridgen_triangle( geom, 'hmax', w./[5 20 5], 'hmaxe', hmaxe );
    plotgrid( grid )
    

Usage Notes

For geometries with multiple and overlapping geometry objects the actual subdomain numbering will generally not correspond to the geometry object numbering (two intersecting geometry objects will for example create three or more subdomains and several internal boundaries). In this case the actual subdomain and boundary numbering for vector valued hmax and hmaxe arrays can easiest be visualized and determined by first creating a coarse grid and switching to Equation/Subdomain and Boundary modes, respectively.

Furthermore, in contrast to the standard gridgen function, gridgen_triangle will identify and include internal boundaries. These internal boundaries can also be subject to boundary conditions, or alternatively should be assigned neutral/symmetry (homogeneous zero Neumann) boundary conditions if they are to be considered non-active boundaries (acting as if they were not present and ignored).

Lastly, even if a specific boundary node distribution has been prescribed through the cell array hmaxe parameter, Triangle may insert additional nodes if necessary in order to achieve and acceptable grid quality (depending on the prescribed q parameter).

References

[1] The Triangle Mesh Generator home page (https://www.cs.cmu.edu/~quake/triangle.html).

[2] J.R. Shewchuk, Triangle: Engineering a 2D Quality Mesh Generator and Delaunay Triangulator, in Applied Computational Geometry: Towards Geometric Engineering (Ming C. Lin and Dinesh Manocha, editors), volume 1148 of Lecture Notes in Computer Science, pages 203-222, Springer-Verlag, Berlin, May 1996. (From the First ACM Workshop on Applied Computational Geometry).

[3] J.R. Shewchuk, Delaunay Refinement Algorithms for Triangular Mesh Generation, Computational Geometry: Theory and Applications 22(1-3):21-74, May 2002.

Category: grid

Tags: external triangle

Published:

SHARE ON

Twitter LinkedIn Facebook Google+