@@ -34,93 +34,22 @@ steep performance cost, especially for curves with a large number of control poi
3434function integral (
3535 f,
3636 curve:: Meshes.BezierCurve ,
37- rule:: GaussLegendre ;
38- diff_method:: DM = _default_method (curve),
39- FP:: Type{T} = Float64,
40- alg:: Meshes.BezierEvalMethod = Meshes. Horner ()
41- ) where {DM <: DifferentiationMethod , T <: AbstractFloat }
42- # Compute Gauss-Legendre nodes/weights for x in interval [-1,1]
43- xs, ws = _gausslegendre (FP, rule. n)
44-
45- # Change of variables: x [-1,1] ↦ t [0,1]
46- t (x) = (1 // 2 ) * x + (1 // 2 )
47- point (x) = curve (t (x), alg)
48- integrand (x) = f (point (x)) * differential (curve, (t (x),), diff_method)
49-
50- # Integrate f along curve and apply domain-correction for [-1,1] ↦ [0, length]
51- return (1 // 2 ) * sum (w .* integrand (x) for (w, x) in zip (ws, xs))
52- end
53-
54- function integral (
55- f,
56- curve:: Meshes.BezierCurve ,
57- rule:: GaussKronrod ;
58- diff_method:: DM = _default_method (curve),
59- FP:: Type{T} = Float64,
60- alg:: Meshes.BezierEvalMethod = Meshes. Horner ()
61- ) where {DM <: DifferentiationMethod , T <: AbstractFloat }
62- point (t) = curve (t, alg)
63- integrand (t) = f (point (t)) * differential (curve, (t,), diff_method)
64- return QuadGK. quadgk (integrand, zero (FP), one (FP); rule. kwargs... )[1 ]
65- end
66-
67- function integral (
68- f,
69- curve:: Meshes.BezierCurve ,
70- rule:: HAdaptiveCubature ;
71- diff_method:: DM = _default_method (curve),
72- FP:: Type{T} = Float64,
73- alg:: Meshes.BezierEvalMethod = Meshes. Horner ()
74- ) where {DM <: DifferentiationMethod , T <: AbstractFloat }
75- point (t) = curve (t, alg)
76- integrand (ts) = f (point (only (ts))) * differential (curve, ts, diff_method)
77-
78- # HCubature doesn't support functions that output Unitful Quantity types
79- # Establish the units that are output by f
80- testpoint_parametriccoord = zeros (FP, 1 )
81- integrandunits = Unitful. unit .(integrand (testpoint_parametriccoord))
82- # Create a wrapper that returns only the value component in those units
83- uintegrand (ts) = Unitful. ustrip .(integrandunits, integrand (ts))
84- # Integrate only the unitless values
85- value = HCubature. hcubature (uintegrand, _zeros (FP, 1 ), _ones (FP, 1 ); rule. kwargs... )[1 ]
86-
87- # Reapply units
88- return value .* integrandunits
37+ rule:: IntegrationRule ;
38+ alg:: Meshes.BezierEvalMethod = Meshes. Horner (),
39+ kwargs...
40+ )
41+ # Generate a _ParametricGeometry whose parametric function auto-applies the alg kwarg
42+ paramfunction (t) = _parametric (curve, t, alg)
43+ param_curve = _ParametricGeometry (paramfunction, Meshes. paramdim (curve))
44+
45+ # Integrate the _ParametricGeometry using the standard methods
46+ return _integral (f, param_curve, rule; kwargs... )
8947end
9048
9149# ###############################################################################
92- # jacobian
50+ # Parametric
9351# ###############################################################################
9452
95- function jacobian (
96- bz:: Meshes.BezierCurve ,
97- ts:: V ,
98- diff_method:: Analytical
99- ) where {V <: Union{AbstractVector, Tuple} }
100- t = only (ts)
101- # Parameter t restricted to domain [0,1] by definition
102- if t < 0 || t > 1
103- throw (DomainError (t, " b(t) is not defined for t outside [0, 1]." ))
104- end
105-
106- # Aliases
107- P = bz. controls
108- N = Meshes. degree (bz)
109-
110- # Ensure that this implementation is tractible: limited by ability to calculate
111- # binomial(N, N/2) without overflow. It's possible to extend this range by
112- # converting N to a BigInt, but this results in always returning BigFloat's.
113- N <= 1028 || error (" This algorithm overflows for curves with ⪆1000 control points." )
114-
115- # Generator for Bernstein polynomial functions
116- B (i, n) = t -> binomial (Int128 (n), i) * t^ i * (1 - t)^ (n - i)
117-
118- # Derivative = N Σ_{i=0}^{N-1} sigma(i)
119- # P indices adjusted for Julia 1-based array indexing
120- sigma (i) = B (i, N - 1 )(t) .* (P[(i + 1 ) + 1 ] - P[(i) + 1 ])
121- derivative = N .* sum (sigma, 0 : (N - 1 ))
122-
123- return (derivative,)
53+ function _parametric (curve:: Meshes.BezierCurve , t, alg:: Meshes.BezierEvalMethod )
54+ return curve (t, alg)
12455end
125-
126- _has_analytical (:: Type{T} ) where {T <: Meshes.BezierCurve } = true
0 commit comments