-
Notifications
You must be signed in to change notification settings - Fork 94
Add integral and localintegral #1327
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
Changes from 31 commits
d2e040a
fcb384f
f1dd042
9bd228c
55c1649
98bdd41
8f3c1cf
fcb05d3
ecbcf48
e5795f0
da77b44
c5dd5ed
623861b
d5754f8
9252b6e
f9fd569
a6d59f1
00c6e9e
4a612cf
55fe6d9
07c68ae
98e17fe
0b09024
29e4507
e903f57
8e08a41
433bf24
f014999
36c42d5
f46c538
5692ebd
b52f395
7bd93a7
ffb13cc
2a0089a
b56976e
408c516
0b982e4
5685d5e
c6f2fa1
32de14c
9daa5dd
947f967
dd4082d
bcf0275
d316707
afff1a5
f0acc81
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| # ------------------------------------------------------------------ | ||
| # Licensed under the MIT License. See LICENSE in the project root. | ||
| # ------------------------------------------------------------------ | ||
|
|
||
| """ | ||
| integral(fun, geom; n=3) | ||
|
|
||
| Calculate the integral over the `geom`etry of the `fun`ction that maps | ||
| [`Point`](@ref)s to values in a linear space. | ||
|
|
||
| integral(fun, dom; n=3) | ||
|
|
||
| Alternatively, calculate the integral over the `dom`ain (e.g., mesh) by | ||
| summing the integrals for each constituent geometry. | ||
|
|
||
| Polynomials of degree up to `2n-1` are integrated exactly. | ||
|
|
||
| See also [`localintegral`](@ref). | ||
| """ | ||
| integral(fun, geom::Geometry; n=3) = localintegral(fun ∘ geom, geom; n) | ||
|
|
||
| # cylinder surface is the union of lateral surface and top/bottom disks | ||
| integral(fun, cylsurf::CylinderSurface; n=3) = | ||
| localintegral(fun ∘ cylsurf, cylsurf; n) + integral(fun, top(cylsurf); n) + integral(fun, bottom(cylsurf); n) | ||
|
|
||
| # cone surface is the union of lateral surface and base disk | ||
| integral(fun, conesurf::ConeSurface; n=3) = | ||
| localintegral(fun ∘ conesurf, conesurf; n) + integral(fun, base(conesurf); n) | ||
|
|
||
| # frustum surface is the union of lateral surface and top/bottom disks | ||
| integral(fun, frustumsurf::FrustumSurface; n=3) = | ||
| localintegral(fun ∘ frustumsurf, frustumsurf; n) + | ||
| integral(fun, top(frustumsurf); n) + | ||
| integral(fun, bottom(frustumsurf); n) | ||
|
|
||
| integral(fun, dom::Domain; n=3) = sum(integral(fun, geom; n) for geom in dom) | ||
|
|
||
| """ | ||
| localintegral(fun, geom; n=3) | ||
|
|
||
| Calculate the integral over the `geom`etry of the `fun`ction that maps | ||
| parametric coordinates `uvw` to values in a linear space. | ||
|
|
||
| Polynomials of degree up to `2n-1` are integrated exactly. | ||
|
|
||
| See also [`integral`](@ref). | ||
| """ | ||
| localintegral(fun, geom::Geometry; n=3) = _uvwintegral(fun, geom, n) | ||
|
|
||
| # -------------- | ||
| # SPECIAL CASES | ||
| # -------------- | ||
|
|
||
| # ray is parametrized over [0, ∞] interval | ||
| localintegral(fun, ray::Ray; n=3) = _uvwintegral(fun, ray, n, trans=t -> t / (1 - t)) | ||
|
|
||
| # line is parametrized over [-∞, ∞] interval | ||
| localintegral(fun, line::Line; n=3) = _uvwintegral(fun, line, n, trans=t -> log(t) - log(1 - t)) | ||
|
|
||
| # plane is parametrized over [-∞, ∞] interval | ||
| localintegral(fun, plane::Plane; n=3) = _uvwintegral(fun, plane, n, trans=t -> log(t) - log(1 - t)) | ||
juliohm marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| # triangle is parametrized with barycentric coordinates | ||
| # TODO: | ||
|
|
||
| # specialize quadrangle for performance | ||
| localintegral(fun, quad::Quadrangle; n=3) = _uvwintegral(fun, quad, n) | ||
|
||
|
|
||
| # tetrahedron is parametrized with barycentric coordinates | ||
| # TODO: | ||
|
|
||
| # ----------------- | ||
| # HELPER FUNCTIONS | ||
| # ----------------- | ||
|
|
||
| function _uvwintegral(fun, geom, n; trans=identity) | ||
| # parametric dimension and number type | ||
| N = paramdim(geom) | ||
| T = numtype(lentype(geom)) | ||
|
|
||
| # Gauss-Legendre quadrature points and weights | ||
| ts, ws = gausslegendre(n) | ||
| tgrid = Iterators.product(ntuple(_ -> T.(ts), N)...) | ||
| wgrid = Iterators.product(ntuple(_ -> T.(ws), N)...) | ||
|
|
||
| # map quadrature points in [-1, 1] to parametric coordinates in [0, 1], | ||
| # and then map parametric coordinates in [0, 1] to uvw parametrization | ||
| g = trans ∘ (t -> (t + 1) / 2) | ||
juliohm marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| # compute integral with change of variable and differential element | ||
| Σwᵢfᵢ = sum(zip(tgrid, wgrid)) do (t, w) | ||
| uvw = ntuple(i -> g(t[i]), N) | ||
| prod(w) * fun(uvw...) * differential(geom, uvw) | ||
| end | ||
|
|
||
| # adjust for change of variable | ||
| Σwᵢfᵢ / 2^N | ||
| end | ||
Uh oh!
There was an error while loading. Please reload this page.