Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated conic integration methods #51

Merged
merged 26 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
13072de
Try out new generic method for integrating CylinderSurface
mikeingold Aug 19, 2024
7ddd80e
Fix ambiguity bug, add methods for ConeSurface and FrustumSurface
mikeingold Aug 19, 2024
1c7032e
Fix errors in FrustumSurface integrals
mikeingold Aug 19, 2024
1c1a05c
Update Support Matrix for Cone and ConeSurface
mikeingold Aug 27, 2024
d9e935c
Add tests for Cone
mikeingold Aug 27, 2024
b29b3e3
Update Meshes to latest version
mikeingold Aug 28, 2024
739a713
Push CRS and Meshes to newest versions
mikeingold Aug 28, 2024
9b1dfb6
Merge branch 'main' into conefrustum
mikeingold Aug 28, 2024
923b279
Attempted bugfix for currently unsatisfiable requirements
mikeingold Aug 28, 2024
31dbb14
Merge branch 'conefrustum' of github.com:mikeingold/MeshIntegrals.jl …
mikeingold Aug 28, 2024
1e49a71
Bugfix in test Project - bump Meshes version
mikeingold Aug 28, 2024
ed424b7
Add custom tests for Cone without Meshes.measure
mikeingold Aug 29, 2024
d8adfb3
Update Support Matrix
mikeingold Aug 29, 2024
5993ddf
Bugfix - wrong name
mikeingold Aug 29, 2024
c8a6aeb
Switch Cone GaussKronrod tests to test_throws since not supported
mikeingold Aug 29, 2024
ef33947
Create a generic integration method for volumes with GaussKronrod tha…
mikeingold Aug 29, 2024
ef8272c
Add ColPrac and move license to front
mikeingold Aug 30, 2024
e871dcf
Add custom tests for ConeSurface
mikeingold Aug 30, 2024
f54dd0a
Add custom tests for FrustumSurface
mikeingold Aug 30, 2024
022ab5d
Bugfix
mikeingold Aug 30, 2024
697a6db
Bugfix
mikeingold Aug 30, 2024
fdca8fa
Remove unused type spec
mikeingold Aug 30, 2024
eb02f46
Bump versions
mikeingold Aug 30, 2024
7716f0f
Bugfix
mikeingold Aug 30, 2024
a6f6b47
Remove explicit support for FrustumSurface
mikeingold Aug 30, 2024
078d54d
Remove redundant methods (never called)
mikeingold Aug 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "MeshIntegrals"
uuid = "dadec2fd-bbe0-4da4-9dbe-476c782c8e47"
authors = ["Mike Ingold <[email protected]>"]
version = "0.12.2"
version = "0.13.0"

[deps]
CoordRefSystems = "b46f11dc-f210-4604-bfba-323c1ec968cb"
Expand All @@ -13,11 +13,11 @@ QuadGK = "1fd47b50-473d-5c70-9696-f719f8f3bcdc"
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"

[compat]
CoordRefSystems = "0.10, 0.11"
CoordRefSystems = "0.12, 0.13"
FastGaussQuadrature = "1"
HCubature = "1.5"
LinearAlgebra = "1"
Meshes = "0.47 - 0.49"
Meshes = "0.50"
QuadGK = "2"
Unitful = "1"
julia = "1.6"
19 changes: 10 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
# MeshIntegrals.jl

[![License: MIT](https://img.shields.io/badge/License-MIT-success.svg)](https://opensource.org/licenses/MIT)
[![ColPrac](https://img.shields.io/badge/ColPrac-Contributor's%20Guide-blueviolet?style=flat-square)](https://github.com/SciML/ColPrac)

[![Build Status](https://github.com/mikeingold/MeshIntegrals.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/mikeingold/MeshIntegrals.jl/actions/workflows/CI.yml?query=branch%3Amain)
[![codecov](https://codecov.io/gh/mikeingold/MeshIntegrals.jl/graph/badge.svg)](https://codecov.io/gh/mikeingold/MeshIntegrals.jl)
[![Coveralls](https://coveralls.io/repos/github/mikeingold/MeshIntegrals.jl/badge.svg?branch=main)](https://coveralls.io/github/mikeingold/MeshIntegrals.jl?branch=main)
[![Aqua QA](https://raw.githubusercontent.com/JuliaTesting/Aqua.jl/master/badge.svg)](https://github.com/JuliaTesting/Aqua.jl)
[![License: MIT](https://img.shields.io/badge/License-MIT-success.svg)](https://opensource.org/licenses/MIT)


This package implements methods for numerically-computing integrals over geometric polytopes
from [**Meshes.jl**](https://github.com/JuliaGeometry/Meshes.jl) using the following `::IntegrationAlgorithms`:
Expand Down Expand Up @@ -51,8 +54,7 @@ integral(f, unit_circle_bz, GaussKronrod())
| Symbol | Meaning |
|--------|---------|
| :white_check_mark: | Implemented, passes tests |
| :x: | Planned but not yet implemented |
| :warning: | Unable to implement: parameterization not available (see [Issue #28](https://github.com/mikeingold/MeshIntegrals.jl/issues/28)) |
| :x: | Not yet supported |
| :stop_sign: | Not supported |

### Integral
Expand All @@ -64,15 +66,14 @@ integral(f, unit_circle_bz, GaussKronrod())
| `Box` in `𝔼{1}` | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| `Box` in `𝔼{2}` | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| `Box` in `𝔼{3}` | :white_check_mark: | :stop_sign: | :white_check_mark: |
| `Box` in `𝔼{N}` | :x: | :x: | :x: |
| `Circle` | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| `Cone` | :warning: | :warning: | :warning: |
| `ConeSurface` | :x: | :x: | :x: |
| `Cone` | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| `ConeSurface` | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| `Cylinder` | :white_check_mark: | :stop_sign: | :white_check_mark: |
| `CylinderSurface` | :x: | :white_check_mark: | :white_check_mark: |
| `CylinderSurface` | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| `Disk` | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| `Frustum` | :warning: | :warning: | :warning: |
| `FrustumSurface` | :x: | :x: | :x: |
| `Frustum` | :stop_sign: | :stop_sign: | :stop_sign: |
| `FrustumSurface` | :stop_sign: | :stop_sign: | :stop_sign: |
| `Line` | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| `ParaboloidSurface` | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| `Plane` | :white_check_mark: | :white_check_mark: | :white_check_mark: |
Expand Down
124 changes: 71 additions & 53 deletions src/integral_surface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,91 +33,109 @@
return QuadGK.quadgk(v -> ∫₁(v), FP(0), FP(1); settings.kwargs...)[1]
end

function _integral_2d(
f,
geometry,
settings::HAdaptiveCubature,
)
return _integral(f, geometry, settings)
end

function _integral_2d(
f,
geometry,
settings::HAdaptiveCubature,
FP::Type{T}
) where {T<:AbstractFloat}
return _integral(f, geometry, settings, FP)
end


################################################################################
# Specialized Methods for CylinderSurface
# Specialized Methods for ConeSurface, CylinderSurface, and FrustumSurface
################################################################################

function integral(
f::F,
cyl::Meshes.CylinderSurface,
settings::GaussLegendre,
settings::I,
FP::Type{T} = Float64
) where {F<:Function, T<:AbstractFloat}
error("Integrating a CylinderSurface with GaussLegendre not supported.")
# TODO Planned to support in the future
) where {F<:Function, I<:IntegrationAlgorithm, T<:AbstractFloat}
# The generic method only parameterizes the sides
sides = _integral_2d(f, cyl, settings, FP)

# Integrate the Disk at the top
disk_top = Meshes.Disk(cyl.top, cyl.radius)
top = _integral_2d(f, disk_top, settings, FP)

# Integrate the Disk at the bottom
disk_bottom = Meshes.Disk(cyl.bot, cyl.radius)
bottom = _integral_2d(f, disk_bottom, settings, FP)

return sides + top + bottom
end

function integral(
f::F,
cyl::Meshes.CylinderSurface,
settings::GaussKronrod,
settings::HAdaptiveCubature,
FP::Type{T} = Float64
) where {F<:Function, T<:AbstractFloat}
# Integrate the curved sides of the CylinderSurface
# \int ( \int f(r̄) dz ) dφ
function sides_inner∫(φ)
sidelength = norm(cyl(φ,FP(1)) - cyl(φ,FP(0)))
return sidelength * QuadGK.quadgk(z -> f(cyl(φ,z)), FP(0), FP(1); settings.kwargs...)[1]
end
sides = (FP(2π) * cyl.radius) .* QuadGK.quadgk(φ -> sides_inner∫(φ), FP(0), FP(1); settings.kwargs...)[1]
# The generic method only parameterizes the sides
sides = _integral(f, cyl, settings, FP)

# Integrate the Disk at the top of the CylinderSurface
# Integrate the Disk at the top
disk_top = Meshes.Disk(cyl.top, cyl.radius)
top = _integral_2d(f, disk_top, settings, FP)
top = _integral(f, disk_top, settings, FP)

# Integrate the Disk at the bottom of the CylinderSurface
# Integrate the Disk at the bottom
disk_bottom = Meshes.Disk(cyl.bot, cyl.radius)
bottom = _integral_2d(f, disk_bottom, settings, FP)
bottom = _integral(f, disk_bottom, settings, FP)

return sides + top + bottom
end

function integral(
f::F,
cyl::Meshes.CylinderSurface,
cone::Meshes.ConeSurface,
settings::I,
FP::Type{T} = Float64
) where {F<:Function, I<:IntegrationAlgorithm, T<:AbstractFloat}
# The generic method only parameterizes the sides
sides = _integral_2d(f, cone, settings, FP)

# Integrate the Disk at the base
base = _integral_2d(f, cone.base, settings, FP)

return sides + base
end

function integral(
f::F,
cone::Meshes.ConeSurface,
settings::HAdaptiveCubature,
FP::Type{T} = Float64
) where {F<:Function, T<:AbstractFloat}
Dim = Meshes.paramdim(cyl)
# The generic method only parameterizes the sides
sides = _integral(f, cone, settings, FP)

integrand(t) = f(cyl(t...)) * differential(cyl, t)
# Integrate the Disk at the base
base = _integral(f, cone.base, settings, FP)

# HCubature doesn't support functions that output Unitful Quantity types
# Establish the units that are output by f
testpoint_parametriccoord = fill(FP(0.5),Dim)
integrandunits = Unitful.unit.(integrand(testpoint_parametriccoord))
# Create a wrapper that returns only the value component in those units
uintegrand(uv) = Unitful.ustrip.(integrandunits, integrand(uv))
# Integrate only the unitless values
value = HCubature.hcubature(uintegrand, zeros(FP,Dim), ones(FP,Dim); settings.kwargs...)[1]
# Reapply units
sides = value .* integrandunits
return sides + base
end

# Integrate the Disk at the top of the CylinderSurface
disk_top = Meshes.Disk(cyl.top, cyl.radius)
top = _integral_2d(f, disk_top, settings, FP)
function integral(

Check warning on line 111 in src/integral_surface.jl

View check run for this annotation

Codecov / codecov/patch

src/integral_surface.jl#L111

Added line #L111 was not covered by tests
f::F,
frust::Meshes.FrustumSurface,
settings::I,
FP::Type{T} = Float64
) where {F<:Function, I<:IntegrationAlgorithm, T<:AbstractFloat}
# The generic method only parameterizes the sides
sides = _integral_2d(f, frust, settings, FP)

Check warning on line 118 in src/integral_surface.jl

View check run for this annotation

Codecov / codecov/patch

src/integral_surface.jl#L118

Added line #L118 was not covered by tests

# Integrate the Disk at the bottom of the CylinderSurface
disk_bottom = Meshes.Disk(cyl.bot, cyl.radius)
bottom = _integral_2d(f, disk_bottom, settings, FP)
# Integrate the Disks at the top and bottom
top = _integral_2d(f, frust.top, settings, FP)
bottom = _integral_2d(f, frust.bot, settings, FP)

Check warning on line 122 in src/integral_surface.jl

View check run for this annotation

Codecov / codecov/patch

src/integral_surface.jl#L121-L122

Added lines #L121 - L122 were not covered by tests

return sides + top + bottom

Check warning on line 124 in src/integral_surface.jl

View check run for this annotation

Codecov / codecov/patch

src/integral_surface.jl#L124

Added line #L124 was not covered by tests
end

function integral(

Check warning on line 127 in src/integral_surface.jl

View check run for this annotation

Codecov / codecov/patch

src/integral_surface.jl#L127

Added line #L127 was not covered by tests
f::F,
frust::Meshes.FrustumSurface,
settings::HAdaptiveCubature,
FP::Type{T} = Float64
) where {F<:Function, T<:AbstractFloat}
# The generic method only parameterizes the sides
sides = _integral(f, frust, settings, FP)

Check warning on line 134 in src/integral_surface.jl

View check run for this annotation

Codecov / codecov/patch

src/integral_surface.jl#L134

Added line #L134 was not covered by tests

# Integrate the Disks at the top and bottom
top = _integral(f, frust.top, settings, FP)
bottom = _integral(f, frust.bot, settings, FP)

Check warning on line 138 in src/integral_surface.jl

View check run for this annotation

Codecov / codecov/patch

src/integral_surface.jl#L137-L138

Added lines #L137 - L138 were not covered by tests

return sides + top + bottom
end
Expand Down
47 changes: 4 additions & 43 deletions src/integral_volume.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,14 @@ function _integral_3d(
return FP(1/8) .* sum(integrand, zip(wws,xxs))
end

# Integrating volumes with GaussKronrod not supported by default
function _integral_3d(
f,
geometry,
settings::HAdaptiveCubature,
)
return _integral(f, geometry, settings)
end

function _integral_3d(
f,
geometry,
settings::HAdaptiveCubature,
FP::Type{T}
settings::GaussKronrod,
FP::Type{T} = Float64
) where {T<:AbstractFloat}
return _integral(f, geometry, settings, FP)
error("Integrating this volume type with GaussKronrod not supported.")
end


Expand Down Expand Up @@ -77,35 +70,3 @@ function integral(
) where {F<:Function, T<:AbstractFloat}
error("Integrating a Tetrahedron with HAdaptiveCubature not supported.")
end


################################################################################
# Unsupported Placeholders
################################################################################

function integral(
f::F,
ball::Meshes.Ball{Meshes.𝔼{3},CRS,ℒ},
settings::GaussKronrod,
FP::Type{T} = Float64
) where {F<:Function, CRS, ℒ, T<:AbstractFloat}
error("Integrating a Ball in 𝔼{3} with GaussKronrod not supported.")
end

function integral(
f::F,
box::Meshes.Box{Meshes.𝔼{3},CRS},
settings::GaussKronrod,
FP::Type{T} = Float64,
) where {F<:Function, CRS, T<:AbstractFloat}
error("Integrating a Box in 𝔼{3} with GaussKronrod not supported.")
end

function integral(
f::F,
box::Meshes.Cylinder,
settings::GaussKronrod,
FP::Type{T} = Float64
) where {F<:Function, T<:AbstractFloat}
error("Integrating a Cylinder with GaussKronrod not supported.")
end
4 changes: 2 additions & 2 deletions test/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"

[compat]
Aqua = "0.8"
Meshes = "0.49"
MeshIntegrals = "0.12"
Meshes = "0.50"
MeshIntegrals = "0.13"
QuadGK = "2"
Unitful = "1"
Loading