@@ -22,7 +22,7 @@ Conformal mapping of Gauss ellipses to sausage_transformations using a truncated
2222# Example:
2323```jldoctest
2424# sausage_transformation conformal map
25- g, gprime = LFAToolkit.sausage_transformation(9)
25+ g, gprime = LFAToolkit.sausage_transformation(9);
2626
2727# verify
2828@assert g.(LinRange(-1,1,5)) ≈ [-0.9999999999999999, -0.39765215163451934, 0.0, 0.39765215163451934, 0.9999999999999999]
@@ -35,12 +35,12 @@ function sausage_transformation(d)
3535 c = zeros (d + 1 )
3636 c[2 : 2 : end ] = [1 , cumprod (1 : 2 : d- 2 ) ./ cumprod (2 : 2 : d- 1 )... ] ./ (1 : 2 : d)
3737 c /= sum (c)
38- pg = Polynomial (c)
39- pgprime = derivative (pg )
38+ gp = Polynomial (c)
39+ gprimep = derivative (gp )
4040
41- # Lower from Polynomial to Function
42- g (x) = pg (x)
43- gprime (x) = pgprime (x)
41+ # lower from Polynomial to Function
42+ g (x) = gp (x)
43+ gprime (x) = gprimep (x)
4444 g, gprime
4545end
4646
@@ -58,7 +58,6 @@ The Kosloff and Tal-Ezer conformal map derived from the inverse sine function.
5858# Example:
5959```jldoctest
6060# kosloff_talezer_transformation conformal map
61- numberquadraturepoints = 5;
6261g, gprime = LFAToolkit.kosloff_talezer_transformation(0.95);
6362
6463# verify
@@ -102,11 +101,11 @@ function hale_trefethen_strip_transformation(ρ)
102101 d = 0.5 + 1 / (exp (τ * π) + 1 )
103102 π2 = π / 2
104103
105- # Unscaled functions of u
104+ # unscaled functions of u
106105 gu (u) = log (1 + exp (- τ * (π2 + u))) - log (1 + exp (- τ * (π2 - u))) + d * τ * u
107106 gprimeu (u) = 1 / (exp (τ * (π2 + u)) + 1 ) + 1 / (exp (τ * (π2 - u)) + 1 ) - d
108107
109- # Normalizing factor and scaled functions of s
108+ # normalizing factor and scaled functions of s
110109 C = 1 / gu (π / 2 )
111110 g (s) = C * gu (asin (s))
112111 gprime (s) = - τ * C / sqrt (1 - s^ 2 ) * gprimeu (asin (s))
@@ -128,14 +127,16 @@ Transformed quadrature by applying a smooth mapping = (g, gprime) from the origi
128127
129128# Example:
130129```jldoctest
130+ using FastGaussQuadrature;
131+
131132# generate transformed quadrature points, weights with choice of conformal map
132- points, weights = LFAToolkit.gaussquadrature (5)
133- mapping = sausage_transformation(9)
134- mpoints, mweights = transformquadrature(points, weights, mapping)
133+ points, weights = gausslegendre (5);
134+ mapping = sausage_transformation(9);
135+ mappedpoints, mappedweights = transformquadrature(points, weights, mapping);
135136
136137# verify:
137- wsum = sum(mweights );
138- @assert wsum ≈ 2.0
138+ weightsum = sum(mappedweights );
139+ @assert weightsum ≈ 2.0
139140
140141# output
141142
@@ -167,240 +168,6 @@ end
167168# utility functions for generating polynomial bases
168169# ------------------------------------------------------------------------------
169170
170- """
171- ```julia
172- gaussquadrature(q, mapping)
173- ```
174-
175- Construct a Gauss-Legendre quadrature with the option of applying conformal maps
176-
177- # Arguments:
178- - `q`: number of quadrature points
179- - `mapping`: choice of conformal map
180-
181- # Returns:
182- - Gauss-Legendre quadrature points and weights, with conformal mapping applied to the points, if provided
183-
184- # Example:
185- ```jldoctest
186- # generate Gauss-Legendre points and weights
187- quadraturepoints, quadratureweights = LFAToolkit.gaussquadrature(5);
188-
189- # verify
190- truepoints = [
191- -√(5 + 2*√(10/7))/3,
192- -√(5 - 2*√(10/7))/3,
193- 0.0,
194- √(5 - 2*√(10/7))/3,
195- √(5 + 2*√(10/7))/3
196- ];
197- @assert truepoints ≈ quadraturepoints
198-
199- trueweights = [
200- (322-13*√70)/900,
201- (322+13*√70)/900,
202- 128/225,
203- (322+13*√70)/900,
204- (322-13*√70)/900
205- ];
206- @assert trueweights ≈ quadratureweights
207-
208- # generate Gauss-Legendre points and weights
209- mapping = hale_trefethen_strip_transformation(1.4);
210- quadraturepoints, quadratureweights = LFAToolkit.gaussquadrature(5, mapping = mapping);
211-
212- # verify
213- @assert quadraturepoints ≈ [-0.7948688880827978, -0.3997698842865811, 0.0, 0.3997698842865811, 0.7948688880827978]
214- @assert quadratureweights ≈ [0.3807611340604039, 0.3992835637032222, 0.3999715882806566, 0.3992835637032222, 0.3807611340604039]
215-
216- # Accuracy test see Hale and Trefethen Fig 3.4
217- f(x) = exp(-40*x^2)
218- x, w = LFAToolkit.gaussquadrature(40);
219- ref = w' * f.(x);
220- x, w = LFAToolkit.gaussquadrature(20);
221- xm, wm = LFAToolkit.gaussquadrature(20, mapping=hale_trefethen_strip_transformation(1.4))
222-
223- # verify
224- @assert isapprox(w' * f.(x) - ref, -2.879622518375813e-5, rtol=1e-10)
225- @assert isapprox(wm' * f.(xm) - ref, -3.26498938996167e-10, rtol=1e-5)
226-
227- # output
228-
229- ```
230- """
231- function gaussquadrature (q:: Int ; mapping:: Union{Tuple{Function,Function},Nothing} = nothing )
232- quadraturepoints = zeros (Float64, q)
233- quadratureweights = zeros (Float64, q)
234-
235- if q < 1
236- throw (DomainError (q, " q must be greater than or equal to 1" )) # COV_EXCL_LINE
237- end
238-
239- # build qref1d, qweight1d
240- for i = 0 : floor (Int, q / 2 )
241- # guess
242- xi = cos (π * (2 * i + 1.0 ) / (2 * q))
243-
244- # Pn(xi)
245- p0 = 1.0
246- p1 = xi
247- p2 = 0.0
248- for j = 2 : q
249- p2 = ((2 * j - 1.0 ) * xi * p1 - (j - 1.0 ) * p0) / j
250- p0 = p1
251- p1 = p2
252- end
253-
254- # first Newton step
255- dp2 = (xi * p2 - p0) * q / (xi * xi - 1.0 )
256- xi = xi - p2 / dp2
257-
258- # Newton to convergence
259- iter = 0
260- maxiter = q^ 2 * 100
261- while iter < maxiter && abs (p2) > 1e-15
262- p0 = 1.0
263- p1 = xi
264- for j = 2 : q
265- p2 = ((2 * j - 1.0 ) * xi * p1 - (j - 1.0 ) * p0) / j
266- p0 = p1
267- p1 = p2
268- end
269- dp2 = (xi * p2 - p0) * q / (xi * xi - 1.0 )
270- xi = xi - p2 / dp2
271- iter += 1
272- end
273-
274- # save xi, wi
275- quadraturepoints[i+ 1 ] = - xi
276- quadraturepoints[q- i] = xi
277- wi = 2.0 / ((1.0 - xi * xi) * dp2 * dp2)
278- quadratureweights[i+ 1 ] = wi
279- quadratureweights[q- i] = wi
280- end
281- quadraturepoints[abs .(quadraturepoints).< 10 * eps ()] .= 0
282-
283- return transformquadrature (quadraturepoints, quadratureweights, mapping)
284- end
285-
286- """
287- ```julia
288- gausslobattoquadrature(q, weights, mapping)
289- ```
290-
291- Construct a Gauss-Legendre-Lobatto quadrature with the option of applying conformal maps
292-
293- # Arguments:
294- - `q`: number of Gauss-Legendre-Lobatto points
295- - `weights`: boolean flag indicating if quadrature weights are desired
296- - `mapping`: choice of conformal map
297-
298- # Returns:
299- - Gauss-Legendre-Lobatto quadrature points or points and weights, with conformal mapping applied to the points, if provided
300-
301- # Example:
302- ```jldoctest
303- # generate Gauss-Legendre-Lobatto points and weights
304- quadraturepoints, quadratureweights = LFAToolkit.gausslobattoquadrature(5, true);
305-
306- # verify
307- truepoints = [-1.0, -√(3/7), 0.0, √(3/7), 1.0];
308- @assert truepoints ≈ quadraturepoints
309-
310- # verify
311- trueweights = [1/10, 49/90, 32/45, 49/90, 1/10];
312- @assert trueweights ≈ quadratureweights
313-
314- # generate Gauss-Legendre-Lobatto points and weights
315- mapping = sausage_transformation(9);
316- quadraturepoints, quadratureweights = LFAToolkit.gausslobattoquadrature(5, true, mapping=mapping)
317-
318- # verify
319- @assert quadraturepoints ≈ [-0.9999999999999999, -0.5418159129215785, 0.0, 0.5418159129215785, 0.9999999999999999]
320- @assert quadratureweights ≈ [0.18690312494113656, 0.5445666710618016, 0.5400742149974571, 0.5445666710618016, 0.18690312494113656]
321-
322- # output
323-
324- ```
325- """
326- function gausslobattoquadrature (
327- q:: Int ,
328- weights:: Bool ;
329- mapping:: Union{Tuple{Function,Function},Nothing} = nothing ,
330- )
331- quadraturepoints = zeros (Float64, q)
332- quadratureweights = zeros (Float64, q)
333-
334- if q < 2
335- throw (DomainError (q, " q must be greater than or equal to 2" )) # COV_EXCL_LINE
336- end
337-
338- # endpoints
339- quadraturepoints[1 ] = - 1.0
340- quadraturepoints[q] = 1.0
341- if weights
342- wi = 2.0 / (q * (q - 1.0 ))
343- quadratureweights[1 ] = wi
344- quadratureweights[q] = wi
345- end
346-
347- # build qref1d, qweight1d
348- for i = 1 : floor (Int, (q - 1 ) / 2 )
349- # guess
350- xi = cos (π * i / (q - 1.0 ))
351-
352- # Pn(xi)
353- p0 = 1.0
354- p1 = xi
355- p2 = 0.0
356- for j = 2 : q- 1
357- p2 = ((2 * j - 1.0 ) * xi * p1 - (j - 1.0 ) * p0) / j
358- p0 = p1
359- p1 = p2
360- end
361-
362- # first Newton step
363- dp2 = (xi * p2 - p0) * q / (xi * xi - 1.0 )
364- d2p2 = (2 * xi * dp2 - q * (q - 1.0 ) * p2) / (1.0 - xi * xi)
365- xi = xi - dp2 / d2p2
366-
367- # Newton to convergence
368- iter = 0
369- maxiter = q^ 2 * 100
370- while iter < maxiter && abs (dp2) > 1e-15
371- p0 = 1.0
372- p1 = xi
373- for j = 2 : q- 1
374- p2 = ((2 * j - 1.0 ) * xi * p1 - (j - 1.0 ) * p0) / j
375- p0 = p1
376- p1 = p2
377- end
378- dp2 = (xi * p2 - p0) * q / (xi * xi - 1.0 )
379- d2p2 = (2 * xi * dp2 - q * (q - 1.0 ) * p2) / (1.0 - xi * xi)
380- xi = xi - dp2 / d2p2
381- iter += 1
382- end
383-
384- # save xi, wi
385- quadraturepoints[i+ 1 ] = - xi
386- quadraturepoints[q- i] = xi
387- if weights
388- wi = 2.0 / (q * (q - 1.0 ) * p2 * p2)
389- quadratureweights[i+ 1 ] = wi
390- quadratureweights[q- i] = wi
391- end
392- end
393- quadraturepoints[abs .(quadraturepoints).< 10 * eps ()] .= 0
394-
395-
396- # return
397- if weights
398- return transformquadrature (quadraturepoints, quadratureweights, mapping)
399- else
400- return transformquadrature (quadraturepoints, mapping)
401- end
402- end
403-
404171"""
405172```julia
406173buildinterpolationandgradient(
@@ -420,11 +187,13 @@ Build one dimensional interpolation and gradient matrices, from Fornberg 1998
420187
421188# Example:
422189```jldoctest
190+ using FastGaussQuadrature
191+
423192# get nodes, quadrature points, and weights
424193numbernodes = 3;
425194numberquadraturepoints = 4;
426- nodes = LFAToolkit.gausslobattoquadrature (numbernodes, false );
427- quadraturepoints, quadratureweights1d = LFAToolkit.gaussquadrature (numberquadraturepoints);
195+ nodes, = gausslobatto (numbernodes);
196+ quadraturepoints, quadratureweights1d = gausslegendre (numberquadraturepoints);
428197
429198# build interpolation, gradient matrices
430199interpolation, gradient = LFAToolkit.buildinterpolationandgradient(nodes, quadraturepoints);
@@ -584,14 +353,13 @@ function TensorH1LagrangeBasis(
584353 end
585354
586355 # get nodes, quadrature points, and weights
587- nodes1d = gausslobattoquadrature (numbernodes1d, false )
356+ nodes1d, = gausslobatto (numbernodes1d)
588357 quadraturepoints1d = []
589358 quadratureweights1d = []
590359 if collocatedquadrature
591- quadraturepoints1d, quadratureweights1d =
592- gausslobattoquadrature (numberquadraturepoints1d, true )
360+ quadraturepoints1d, quadratureweights1d = gausslobatto (numberquadraturepoints1d)
593361 else
594- quadraturepoints1d, quadratureweights1d = gaussquadrature (numberquadraturepoints1d)
362+ quadraturepoints1d, quadratureweights1d = gausslegendre (numberquadraturepoints1d)
595363 end
596364
597365 # build interpolation, gradient matrices
@@ -682,7 +450,7 @@ function TensorH1UniformBasis(
682450
683451 # get nodes, quadrature points, and weights
684452 nodes1d = [- 1.0 : (2.0 / (numbernodes1d- 1 )): 1.0 ... ]
685- quadraturepoints1d, quadratureweights1d = gaussquadrature (numberquadraturepoints1d)
453+ quadraturepoints1d, quadratureweights1d = gausslegendre (numberquadraturepoints1d)
686454
687455 # build interpolation, gradient matrices
688456 interpolation1d, gradient1d = buildinterpolationandgradient (nodes1d, quadraturepoints1d)
@@ -1103,7 +871,7 @@ function TensorH1LagrangeHProlongationBasis(
1103871 numberfineelements1d:: Int ,
1104872)
1105873 # generate nodes
1106- nodescoarse1d = gausslobattoquadrature (numbernodes1d, false )
874+ nodescoarse1d, = gausslobatto (numbernodes1d)
1107875 nodesfine1d = zeros ((numbernodes1d - 1 ) * numberfineelements1d + 1 )
1108876 for i = 1 : numberfineelements1d
1109877 nodesfine1d[(i- 1 )* numbernodes1d- i+ 2 : i* numbernodes1d- i+ 1 ] =
0 commit comments