From 77a2b067c7456787e5e6f9bbb23fc4a90624a627 Mon Sep 17 00:00:00 2001 From: Michael Ingold Date: Sun, 14 Apr 2024 11:33:18 -0400 Subject: [PATCH] Add method for integrating Tetrahedron (#41) * Add tetrahedron to tests * Add QuadGK method for integrating Tetrahedron * Fix copy/paste error * Bugfix - domain correction * Bugfix - domain correction * Bump package version * Update support matrix --- Project.toml | 2 +- README.md | 3 ++- src/integral_volume.jl | 37 +++++++++++++++++++++++++++++++++++++ test/runtests.jl | 12 +++++++----- 4 files changed, 47 insertions(+), 7 deletions(-) diff --git a/Project.toml b/Project.toml index f7bf5512..6eb4c2fd 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "MeshIntegrals" uuid = "dadec2fd-bbe0-4da4-9dbe-476c782c8e47" authors = ["Mike Ingold "] -version = "0.11.6" +version = "0.11.7" [deps] FastGaussQuadrature = "442a2c76-b920-505d-bb47-c5924d526838" diff --git a/README.md b/README.md index 00fff640..eec2f533 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ integral(f, unit_circle_bz, GaussKronrod()) |--------|---------| | :white_check_mark: | Implemented, passes tests | | :x: | Planned but not yet implemented | -| :warning: | Unable to implement until parameterization not available (see [Issue #28](https://github.com/mikeingold/MeshIntegrals.jl/issues/28)) | +| :warning: | Unable to implement: parameterization not available (see [Issue #28](https://github.com/mikeingold/MeshIntegrals.jl/issues/28)) | ### Integral | Geometry | Gauss-Legendre | Gauss-Kronrod | H-Adaptive Cubature | @@ -85,5 +85,6 @@ integral(f, unit_circle_bz, GaussKronrod()) | `SimpleMesh{Dim,T,V}` | :x: | :x: | :x: | | `Sphere{2,T}` | :white_check_mark: | :white_check_mark: | :white_check_mark: | | `Sphere{3,T}` | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| `Tetrahedron{3,T}` | :x: | :white_check_mark: | :x: | | `Triangle{T}` | :white_check_mark: | :white_check_mark: | :white_check_mark: | | `Torus{T}` | :white_check_mark: | :white_check_mark: | :white_check_mark: | diff --git a/src/integral_volume.jl b/src/integral_volume.jl index f8b993c7..70b2dba0 100644 --- a/src/integral_volume.jl +++ b/src/integral_volume.jl @@ -33,6 +33,43 @@ function _integral_3d( end +################################################################################ +# Specialized Methods for Tetrahedron +################################################################################ + +function integral( + f::F, + tetrahedron::Meshes.Tetrahedron{3,T}, + settings::GaussLegendre +) where {F<:Function, T} + error("Integrating a Tetrahedron{3,T} with GaussLegendre not supported.") +end + +function integral( + f::F, + tetrahedron::Meshes.Tetrahedron{3,T}, + settings::GaussKronrod +) where {F<:Function, T} + # Validate the provided integrand function + _validate_integrand(f,3,T) + + inner∫₂(v,w) = QuadGK.quadgk(u -> f(tetrahedron(u,v,w)), T(0), T(1-v-w); settings.kwargs...)[1] + inner∫₁(w) = QuadGK.quadgk(v -> inner∫₂(v,w), T(0), T(1-w); settings.kwargs...)[1] + outer∫ = QuadGK.quadgk(w -> inner∫₁(w), T(0), T(1); settings.kwargs...)[1] + + # Apply barycentric domain correction (volume: 1/6 → actual) + return 6 * volume(tetrahedron) * outer∫ +end + +function integral( + f::F, + tetrahedron::Meshes.Tetrahedron{3,T}, + settings::HAdaptiveCubature +) where {F<:Function, T} + error("Integrating a Tetrahedron{3,T} with HAdaptiveCubature not supported.") +end + + ################################################################################ # Unsupported Placeholders ################################################################################ diff --git a/test/runtests.jl b/test/runtests.jl index 756aa8da..58d3aede 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -102,18 +102,19 @@ end segment(T) = Segment(pt_e(T), pt_n(T)) sphere2d(T) = Sphere(origin2d(T), T(2.5)) sphere3d(T) = Sphere(origin3d(T), T(2.5)) + tetra(T) = Tetrahedron(pt_n(T), pt_w(T), pt_e(T), pt_n(T)+ẑ(T)) triangle(T) = Ngon(pt_e(T), pt_n(T), pt_w(T)) torus(T) = Torus(origin3d(T), ẑ(T), T(3.5), T(1.25)) SUPPORT_MATRIX(T) = [ # Name, T type, example, integral,line,surface,volume, GaussLegendre,GaussKronrod,HAdaptiveCubature - SupportItem("Ball{2,$T}", T, ball2d(T), 1, 0, 1, 0, 1, 1, 1), - SupportItem("Ball{3,$T}", T, ball3d(T), 1, 0, 0, 1, 1, 0, 1), + SupportItem("Ball{2,$T}", T, ball2d(T), 1, 0, 1, 0, 1, 1, 1), + SupportItem("Ball{3,$T}", T, ball3d(T), 1, 0, 0, 1, 1, 0, 1), # Ball{Dim,T} SupportItem("BezierCurve{$T}", T, bezier(T), 1, 1, 0, 0, 1, 1, 1), - SupportItem("Box{1,$T}", T, box1d(T), 1, 1, 0, 0, 1, 1, 1), - SupportItem("Box{2,$T}", T, box2d(T), 1, 0, 1, 0, 1, 1, 1), - SupportItem("Box{3,$T}", T, box3d(T), 1, 0, 0, 1, 1, 0, 1), + SupportItem("Box{1,$T}", T, box1d(T), 1, 1, 0, 0, 1, 1, 1), + SupportItem("Box{2,$T}", T, box2d(T), 1, 0, 1, 0, 1, 1, 1), + SupportItem("Box{3,$T}", T, box3d(T), 1, 0, 0, 1, 1, 0, 1), # Box{Dim,T} SupportItem("Circle{$T}", T, circle(T), 1, 1, 0, 0, 1, 1, 1), # Cone @@ -133,6 +134,7 @@ end # SimpleMesh SupportItem("Sphere{2,$T}", T, sphere2d(T), 1, 1, 0, 0, 1, 1, 1), SupportItem("Sphere{3,$T}", T, sphere3d(T), 1, 0, 1, 0, 1, 1, 1), + SupportItem("Tetrahedron", T, tetra(T), 1, 0, 0, 1, 0, 1, 0), SupportItem("Triangle{$T}", T, triangle(T), 1, 0, 1, 0, 1, 1, 1), SupportItem("Torus{$T}", T, torus(T), 1, 0, 1, 0, 1, 1, 1), ]