Skip to content

Commit

Permalink
README improvements (#70)
Browse files Browse the repository at this point in the history
* Update intro paragraph

* Major rewrite

* Add missing Unitful in demo

Co-authored-by: Joshua Lampert <[email protected]>

* Formatting consistency

Co-authored-by: Joshua Lampert <[email protected]>

* Add link to Unitful.jl

Co-authored-by: Joshua Lampert <[email protected]>

* Attempt at bug fix

* Switch to single argument ustrip

Co-authored-by: Joshua Lampert <[email protected]>

* Change demo integand function and add result

* Bump patch version

* Bugfix

---------

Co-authored-by: Joshua Lampert <[email protected]>
  • Loading branch information
mikeingold and JoshuaLampert authored Sep 12, 2024
1 parent 46d1c4a commit 8813827
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 25 deletions.
2 changes: 1 addition & 1 deletion 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.13.2"
version = "0.13.3"

[deps]
CoordRefSystems = "b46f11dc-f210-4604-bfba-323c1ec968cb"
Expand Down
61 changes: 37 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,42 +11,55 @@
[![Aqua QA](https://raw.githubusercontent.com/JuliaTesting/Aqua.jl/master/badge.svg)](https://github.com/JuliaTesting/Aqua.jl)


This package implements methods for numerically-computing integrals over geometric polytopes
from [**Meshes.jl**](https://github.com/JuliaGeometry/Meshes.jl) using the following `::IntegrationAlgorithms`:
**MeshIntegrals.jl** uses differential forms to enable fast and easy numerical integration of arbitrary integrand functions over domains defined via [**Meshes.jl**](https://github.com/JuliaGeometry/Meshes.jl) geometries. This is achieved using:
- Gauss-Legendre quadrature rules from [**FastGaussQuadrature.jl**](https://github.com/JuliaApproximation/FastGaussQuadrature.jl): `GaussLegendre(n)`
- H-adaptive Gauss-Kronrod quadrature rules from [**QuadGK.jl**](https://github.com/JuliaMath/QuadGK.jl): `GaussKronrod(kwargs...)`
- H-adaptive cubature rules from [**HCubature.jl**](https://github.com/JuliaMath/HCubature.jl): `HAdaptiveCubature(kwargs...)`

Functions available:
- `integral(f, ::Geometry, ::IntegrationAlgorithm)`: integrates a function `f` over a domain defined by `geometry` using a particular `::IntegrationAlgorithm`
- `lineintegral`, `surfaceintegral`, and `volumeintegral` are available as aliases for `integral` that first verify that `geometry` has the appropriate number of parametric dimensions
These solvers have support for integrand functions that produce scalars, vectors, and [**Unitful.jl**](https://github.com/PainterQubits/Unitful.jl) `Quantity` types. While HCubature.jl does not natively support `Quantity` type integrands, this package provides a compatibility layer to enable this feature.

# Example Usage
## Usage

```julia
integral(f, geometry)
```
Performs a numerical integration of some integrand function `f(p::Meshes.Point)` over the domain specified by `geometry`. A default integration method will be automatically selected according to the geometry: `GaussKronrod()` for 1D, and `HAdaptiveCubature()` for all others.

```julia
integral(f, geometry, algorithm, FP=Float64)
```
Performs a numerical integration of some integrand function `f(p::Meshes.Point)` over the domain specified by `geometry` using the specified integration algorithm, e.g. `GaussKronrod()`.

Optionally, a fourth argument can be provided to specify the floating point precision level desired. This setting can be manipulated if your integrand function produces outputs with alternate floating point precision (e.g. `Float16`, `BigFloat`, etc) AND you'd prefer to avoid implicit type promotions.

```julia
lineintegral(f, geometry)
surfaceintegral(f, geometry)
volumeintegral(f, geometry)
```
Alias functions are provided for convenience. These are simply wrappers for `integral` that first validate that the provided `geometry` has the expected number of parametric/manifold dimensions. Like with `integral` in the examples above, the `algorithm` can also be specified as a third-argument.
- `lineintegral` for curve-like geometries or polytopes (e.g. `Segment`, `Ray`, `BezierCurve`, `Rope`, etc)
- `surfaceintegral` for surfaces (e.g. `Disk`, `Sphere`, `CylinderSurface`, etc)
- `volumeintegral` for (3D) volumes (e.g. `Ball`, `Cone`, `Torus`, etc)

# Demo

```julia
using Meshes
using MeshIntegrals
using Unitful

# Define a unit circle on the xy-plane
origin = Point(0,0,0)
= Vec(0,0,1)
xy_plane = Plane(origin,ẑ)
unit_circle_xy = Circle(xy_plane, 1.0)

# Approximate unit_circle_xy with a high-order Bezier curve
unit_circle_bz = BezierCurve(
[Point(cos(t), sin(t), 0.0) for t in range(0,2pi,length=361)]
# Define a path that approximates a sine-wave on the xy-plane
mypath = BezierCurve(
[Point(t*u"m", sin(t)*u"m", 0.0u"m") for t in range(-pi, pi, length=361)]
)

# A Real-valued function
f(x, y, z) = abs(x + y)
f(p) = f(to(p)...)
# Map f(::Point) -> f(x, y, z) in unitless coordinates
f(p::Meshes.Point) = f(ustrip(to(p))...)

integral(f, unit_circle_xy, GaussKronrod())
# 0.000170 seconds (5.00 k allocations: 213.531 KiB)
# ans == 5.656854249525293 m^2
# Integrand function in units of Ohms/meter
f(x, y, z) = (1 / sqrt(1 + cos(x)^2)) * u"Ω/m"

integral(f, unit_circle_bz, GaussKronrod())
# 0.017122 seconds (18.93 k allocations: 78.402 MiB)
# ans = 5.551055333711397 m^2
integral(f, mypath)
# -> Approximately 2*Pi Ω
```

0 comments on commit 8813827

Please sign in to comment.