Constrained Delaunay Triangulation Meshes for Spatial 'SPDE' Models.
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 boundariestulpa_mesh_sphere()- Icosahedral geodesic meshes for global-scale modelstulpa_mesh_1d()- Temporal meshes for space-time SPDEtulpa_mesh_graph()- Network meshes for river/road SPDE
FEM Assembly
fem_matrices()- Mass (C), stiffness (G), and projection (A) matricesfem_matrices(lumped = TRUE)- Diagonal mass for SPDE Q-builderfem_matrices(parallel = TRUE)- Multithreaded assembly via TBBfem_matrices(barrier = ...)- Barrier models (Bakka et al. 2019)fem_matrices_p2()- Quadratic (P2) elements for higher accuracyfem_matrices_nonstationary()- Spatially varying range and variance
Quality & Diagnostics
mesh_quality()- Per-triangle angles, aspect ratio, areamesh_summary()- Min/median/max quality statisticsplot()- Mesh visualization with optional quality coloring- Ruppert refinement via
min_angleandmax_areaparameters
Mesh Operations
subdivide_mesh()- Uniform 1-to-4 triangle subdivisionsubset_mesh()- Extract submesh from triangle indicesmesh_components()- Find disconnected componentsrefine_mesh()- Adaptive refinement from error indicatorsas_tulpa_mesh()- Convert fmesher/INLA meshesbarrier_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
- Quick Start
- Spatial Workflows — boundaries, barriers, sf integration
- Spherical and Temporal Meshes — globe, space-time, graphs, P2
- Full Reference
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.
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}
}