MyNixOS website logo
Description

Constrained Delaunay Triangulation Meshes for Spatial 'SPDE' Models.

Generate constrained Delaunay triangulation meshes for use with stochastic partial differential equation (SPDE) spatial models (Lindgren, Rue and Lindstroem 2011 <doi:10.1111/j.1467-9868.2011.00777.x>). Provides automatic mesh generation from point coordinates with boundary constraints, Ruppert refinement for mesh quality, finite element method (FEM) matrix assembly (mass, stiffness, projection), barrier models, spherical meshes via icosahedral subdivision, and metric graph meshes for network geometries. Built on the 'CDT' header-only C++ library (Amirkhanov 2024 <https://github.com/artem-ogre/CDT>). Designed as the mesh backend for the 'tulpa' Bayesian hierarchical modelling engine but usable standalone for any spatial triangulation task.

R-CMD-check Codecov test coverage License: MIT

tulpaMesh

Spatial meshes and FEM matrices for SPDE models, from point clouds to precision matrices in three lines.

Quick Start

library(tulpaMesh)

coords <- cbind(runif(200), runif(200))
mesh <- tulpa_mesh(coords, max_edge = 0.1)
fem  <- fem_matrices(mesh, obs_coords = coords)
# fem$C (mass), fem$G (stiffness), fem$A (projection) ready for SPDE

Statement of Need

Spatial models based on the SPDE approach (Lindgren, Rue & Lindstrom 2011) need a triangulated mesh and finite element matrices. tulpaMesh handles mesh generation, quality refinement, and FEM matrix assembly with no external dependencies beyond Rcpp and Matrix.

Common applications:

  • Species distribution models with spatial random effects
  • Geostatistical models with Matern covariance via SPDE
  • Occupancy models with spatially structured detection
  • Any Bayesian hierarchical model needing a spatial mesh

Features

Mesh Generation

  • tulpa_mesh() - Constrained Delaunay from points, formulas, or sf boundaries
  • tulpa_mesh_sphere() - Icosahedral geodesic meshes for global-scale models
  • tulpa_mesh_1d() - Temporal meshes for space-time SPDE
  • tulpa_mesh_graph() - Network meshes for river/road SPDE

FEM Assembly

  • fem_matrices() - Mass (C), stiffness (G), and projection (A) matrices
  • fem_matrices(lumped = TRUE) - Diagonal mass for SPDE Q-builder
  • fem_matrices(parallel = TRUE) - Multithreaded assembly via TBB
  • fem_matrices(barrier = ...) - Barrier models (Bakka et al. 2019)
  • fem_matrices_p2() - Quadratic (P2) elements for higher accuracy
  • fem_matrices_nonstationary() - Spatially varying range and variance

Quality & Diagnostics

  • mesh_quality() - Per-triangle angles, aspect ratio, area
  • mesh_summary() - Min/median/max quality statistics
  • plot() - Mesh visualization with optional quality coloring
  • Ruppert refinement via min_angle and max_area parameters

Mesh Operations

  • subdivide_mesh() - Uniform 1-to-4 triangle subdivision
  • subset_mesh() - Extract submesh from triangle indices
  • mesh_components() - Find disconnected components
  • refine_mesh() - Adaptive refinement from error indicators
  • as_tulpa_mesh() - Convert fmesher/INLA meshes
  • barrier_triangles() - Identify barrier regions from polygons

Installation

Install from CRAN:

install.packages("tulpaMesh")

Development version:

# install.packages("pak")
pak::pak("gcol33/tulpaMesh")

Usage Examples

Mesh with Ruppert Refinement

library(tulpaMesh)

set.seed(42)
coords <- cbind(runif(100), runif(100))
mesh <- tulpa_mesh(coords, min_angle = 25, max_edge = 0.15)
mesh_summary(mesh)
plot(mesh, color = "quality", vertex_col = "black")

Barrier Model (Coastline)

library(sf)

# Barrier polygon (e.g., land mass that field can't cross)
barrier <- st_polygon(list(rbind(c(3,3), c(7,3), c(7,7), c(3,7), c(3,3))))
bt <- barrier_triangles(mesh, st_sfc(barrier))
fem <- fem_matrices(mesh, barrier = bt)
# fem$G has zero stiffness across barrier triangles

Spherical Mesh for Global Models

globe <- tulpa_mesh_sphere(subdivisions = 4)
globe
#> tulpa_mesh (sphere, radius = 1):
#>   Vertices:   2562
#>   Triangles:  5120
#>   Edges:      7680
fem <- fem_matrices(globe, lumped = TRUE)
# Total surface area approximates 4*pi
sum(fem$va)

Migrate from fmesher

library(fmesher)
fm <- fm_mesh_2d(loc = coords, max.edge = c(0.3, 0.6))
tm <- as_tulpa_mesh(fm)  # direct conversion
fem <- fem_matrices(tm)  # same C, G, A as fmesher

Documentation

Support

"Software is like sex: it's better when it's free." — Linus Torvalds

I'm a PhD student who builds R packages in my free time because I believe good tools should be free and open. I started these projects for my own work and figured others might find them useful too.

If this package saved you some time, buying me a coffee is a nice way to say thanks. It helps with my coffee addiction.

Buy Me A Coffee

License

MIT (see the LICENSE.md file)

Citation

@software{tulpaMesh,
  author = {Colling, Gilles},
  title = {tulpaMesh: Constrained Delaunay Triangulation Meshes for Spatial SPDE Models},
  year = {2026},
  url = {https://CRAN.R-project.org/package=tulpaMesh},
  doi = {10.32614/CRAN.package.tulpaMesh}
}
Metadata

Version

0.1.1

License

Unknown

Platforms (80)

    Darwin
    FreeBSD
    Genode
    GHCJS
    Linux
    MMIXware
    NetBSD
    none
    OpenBSD
    Redox
    Solaris
    uefi
    WASI
    Windows
Show all
  • aarch64-darwin
  • aarch64-freebsd
  • aarch64-genode
  • aarch64-linux
  • aarch64-netbsd
  • aarch64-none
  • aarch64-uefi
  • aarch64-windows
  • aarch64_be-none
  • arc-linux
  • arm-none
  • armv5tel-linux
  • armv6l-linux
  • armv6l-netbsd
  • armv6l-none
  • armv7a-linux
  • armv7a-netbsd
  • armv7l-linux
  • armv7l-netbsd
  • avr-none
  • i686-cygwin
  • i686-freebsd
  • i686-genode
  • i686-linux
  • i686-netbsd
  • i686-none
  • i686-openbsd
  • i686-windows
  • javascript-ghcjs
  • loongarch64-linux
  • m68k-linux
  • m68k-netbsd
  • m68k-none
  • microblaze-linux
  • microblaze-none
  • microblazeel-linux
  • microblazeel-none
  • mips-linux
  • mips-none
  • mips64-linux
  • mips64-none
  • mips64el-linux
  • mipsel-linux
  • mipsel-netbsd
  • mmix-mmixware
  • msp430-none
  • or1k-none
  • powerpc-linux
  • powerpc-netbsd
  • powerpc-none
  • powerpc64-linux
  • powerpc64le-linux
  • powerpcle-none
  • riscv32-linux
  • riscv32-netbsd
  • riscv32-none
  • riscv64-linux
  • riscv64-netbsd
  • riscv64-none
  • rx-none
  • s390-linux
  • s390-none
  • s390x-linux
  • s390x-none
  • sh4-linux
  • vc4-none
  • wasm32-wasi
  • wasm64-wasi
  • x86_64-cygwin
  • x86_64-darwin
  • x86_64-freebsd
  • x86_64-genode
  • x86_64-linux
  • x86_64-netbsd
  • x86_64-none
  • x86_64-openbsd
  • x86_64-redox
  • x86_64-solaris
  • x86_64-uefi
  • x86_64-windows