Neko 1.99.1
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
speclib.f90
Go to the documentation of this file.
1! Copyright (c) 2008-2020, UCHICAGO ARGONNE, LLC.
2!
3! The UChicago Argonne, LLC as Operator of Argonne National
4! Laboratory holds copyright in the Software. The copyright holder
5! reserves all rights except those expressly granted to licensees,
6! and U.S. Government license rights.
7!
8! Redistribution and use in source and binary forms, with or without
9! modification, are permitted provided that the following conditions
10! are met:
11!
12! 1. Redistributions of source code must retain the above copyright
13! notice, this list of conditions and the disclaimer below.
14!
15! 2. Redistributions in binary form must reproduce the above copyright
16! notice, this list of conditions and the disclaimer (as noted below)
17! in the documentation and/or other materials provided with the
18! distribution.
19!
20! 3. Neither the name of ANL nor the names of its contributors
21! may be used to endorse or promote products derived from this software
22! without specific prior written permission.
23!
24! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25! "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26! LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27! FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
28! UCHICAGO ARGONNE, LLC, THE U.S. DEPARTMENT OF
29! ENERGY OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30! SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
31! TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32! DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33! THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34! (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35! OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36!
37! Additional BSD Notice
38! ---------------------
39! 1. This notice is required to be provided under our contract with
40! the U.S. Department of Energy (DOE). This work was produced at
41! Argonne National Laboratory under Contract
42! No. DE-AC02-06CH11357 with the DOE.
43!
44! 2. Neither the United States Government nor UCHICAGO ARGONNE,
45! LLC nor any of their employees, makes any warranty,
46! express or implied, or assumes any liability or responsibility for the
47! accuracy, completeness, or usefulness of any information, apparatus,
48! product, or process disclosed, or represents that its use would not
49! infringe privately-owned rights.
50!
51! 3. Also, reference herein to any specific commercial products, process,
52! or services by trade name, trademark, manufacturer or otherwise does
53! not necessarily constitute or imply its endorsement, recommendation,
54! or favoring by the United States Government or UCHICAGO ARGONNE LLC.
55! The views and opinions of authors expressed
56! herein do not necessarily state or reflect those of the United States
57! Government or UCHICAGO ARGONNE, LLC, and shall
58! not be used for advertising or product endorsement purposes.
59!
60!==============================================================================
61!
75!
76!------------------------------------------------------------------------------
77!
78! ABBRIVIATIONS:
79!
80! M - Set of mesh points
81! Z - Set of collocation/quadrature points
82! W - Set of quadrature weights
83! H - Lagrangian interpolant
84! D - Derivative operator
85! I - Interpolation operator
86! GL - Gauss Legendre
87! GLL - Gauss-Lobatto Legendre
88! GJ - Gauss Jacobi
89! GLJ - Gauss-Lobatto Jacobi
90!
91!
92! MAIN ROUTINES:
93!
94! Points and weights:
95!
96! ZWGL Compute Gauss Legendre points and weights
97! ZWGLL Compute Gauss-Lobatto Legendre points and weights
98! ZWGJ Compute Gauss Jacobi points and weights (general)
99! ZWGLJ Compute Gauss-Lobatto Jacobi points and weights (general)
100!
101! Lagrangian interpolants:
102!
103! HGL Compute Gauss Legendre Lagrangian interpolant
104! HGLL Compute Gauss-Lobatto Legendre Lagrangian interpolant
105! HGJ Compute Gauss Jacobi Lagrangian interpolant (general)
106! HGLJ Compute Gauss-Lobatto Jacobi Lagrangian interpolant (general)
107!
108! Derivative operators:
109!
110! DGLL Compute Gauss-Lobatto Legendre derivative matrix
111! DGLLGL Compute derivative matrix for a staggered mesh (GLL->GL)
112! DGJ Compute Gauss Jacobi derivative matrix (general)
113! DGLJ Compute Gauss-Lobatto Jacobi derivative matrix (general)
114! DGLJGJ Compute derivative matrix for a staggered mesh (GLJ->GJ) (general)
115!
116! Interpolation operators:
117!
118! IGLM Compute interpolation operator GL -> M
119! IGLLM Compute interpolation operator GLL -> M
120! IGJM Compute interpolation operator GJ -> M (general)
121! IGLJM Compute interpolation operator GLJ -> M (general)
122!
123! Other:
124!
125! PNLEG Compute Legendre polynomial of degree N
126! legendre_poly Compute Legendre polynomial of degree 0-N
127! PNDLEG Compute derivative of Legendre polynomial of degree N
128!
129! Comments:
130!
131! Note that many of the above routines exist in both single and
132! double precision. If the name of the single precision routine is
133! SUB, the double precision version is called SUBD. In most cases
134! all the "low-level" arithmetic is done in double precision, even
135! for the single precsion versions.
136!
137! Useful references:
138!
139! [1] Gabor Szego: Orthogonal Polynomials, American Mathematical Society,
140! Providence, Rhode Island, 1939.
141! [2] Abramowitz & Stegun: Handbook of Mathematical Functions,
142! Dover, New York, 1972.
143! [3] Canuto, Hussaini, Quarteroni & Zang: Spectral Methods in Fluid
144! Dynamics, Springer-Verlag, 1988.
145!
146!
147!==============================================================================
149 use num_types, only : rp, xp
150 use math, only: abscmp
151 use utils, only : neko_error
152 use, intrinsic :: iso_fortran_env, only : stderr => error_unit
153 implicit none
154
155contains
156
163 subroutine zwgl(Z, W, NP)
164 integer, intent(in) :: NP
165 real(kind=rp), intent(inout) :: z(np), w(np)
166 real(kind=rp) alpha, beta
167 alpha = 0.0_rp
168 beta = 0.0_rp
169 call zwgj(z, w, np, alpha, beta)
170 end subroutine zwgl
171
172
178 subroutine zwgll(Z, W, NP)
179 integer, intent(in) :: NP
180 real(kind=rp), intent(inout) :: z(np), w(np)
181 real(kind=rp) alpha, beta
182 alpha = 0.0_rp
183 beta = 0.0_rp
184 call zwglj(z, w, np, alpha, beta)
185 end subroutine zwgll
186
191 subroutine zwgj(Z, W, NP, ALPHA, BETA)
192 integer, intent(in) :: NP
193 real(kind=rp), intent(inout) :: z(np), w(np)
194 real(kind=rp), intent(in) :: alpha, beta
195
196 integer, parameter :: NMAX = 84
197 integer, parameter :: NZD = nmax
198
199 real(kind=xp) zd(nzd), wd(nzd), alphad, betad
200 integer :: I, NPMAX
201
202 npmax = nzd
203 if (np .gt. npmax) then
204 write (stderr, *) 'Too large polynomial degree in ZWGJ'
205 write (stderr, *) 'Maximum polynomial degree is', nmax
206 write (stderr, *) 'Here NP=', np
207 call neko_error
208 end if
209
210 alphad = real(alpha, kind=xp)
211 betad = real(beta, kind=xp)
212 call zwgjd(zd, wd, np, alphad, betad)
213 do i = 1, np
214 z(i) = real(zd(i), kind=rp)
215 w(i) = real(wd(i), kind=rp)
216 end do
217 end subroutine zwgj
218
223 subroutine zwgjd(Z, W, NP, ALPHA, BETA)
224 integer, intent(in) :: NP
225 real(kind=xp), intent(inout) :: z(np), w(np)
226 real(kind=xp), intent(in) :: alpha, beta
227
228 real(kind=xp) :: dn, apb
229 real(kind=xp) :: fac1, fac2, fac3, fnorm
230 real(kind=xp) :: rcoef, p, pd, pm1, pdm1, pm2, pdm2
231 real(kind=xp) :: dnp1, dnp2
232 integer :: N, NP1, NP2, I
233
234 n = np - 1
235 dn = real(n, kind=xp)
236
237 apb = alpha + beta
238
239 if (np .le. 0) then
240 write (stderr, *) 'ZWGJD: Minimum number of Gauss points is 1', np
241 call neko_error
242 else if ((alpha .le. -1.0_xp) .or. (beta .le. -1.0_xp)) then
243 call neko_error('ZWGJD: Alpha and Beta must be greater than -1')
244 end if
245
246 if (np .eq. 1) then
247 z(1) = (beta - alpha) / (apb + 2.0_xp)
248 w(1) = gammaf(alpha + 1.0_xp) * gammaf(beta + 1.0_xp) / &
249 gammaf(apb + 2.0_xp) * 2.0_xp**(apb + 1.0_xp)
250 return
251 end if
252
253 call jacg(z, np, alpha, beta)
254
255 np1 = n + 1
256 np2 = n + 2
257 dnp1 = real(np1, kind=xp)
258 dnp2 = real(np2, kind=xp)
259 fac1 = dnp1 + alpha + beta + 1.0_xp
260 fac2 = fac1 + dnp1
261 fac3 = fac2 + 1.0_xp
262 fnorm = pnormj(np1, alpha, beta)
263 rcoef = (fnorm*fac2*fac3) / (2.0_xp*fac1*dnp2)
264 do i = 1, np
265 call jacobf(p, pd, pm1, pdm1, pm2, pdm2, np2, alpha, beta, z(i))
266 w(i) = -rcoef/(p*pdm1)
267 end do
268 end subroutine zwgjd
269
274 subroutine zwglj(Z, W, NP, ALPHA, BETA)
275 integer, intent(in) :: NP
276 real(kind=rp), intent(inout) :: z(np), w(np)
277 real(kind=rp), intent(in) :: alpha, beta
278
279 integer, parameter :: NMAX = 84
280 integer, parameter :: NZD = nmax
281
282 real(kind=xp) zd(nzd), wd(nzd), alphad, betad
283 integer :: I, NPMAX
284
285 npmax = nzd
286 if (np .gt. npmax) then
287 write (stderr, *) 'Too large polynomial degree in ZWGLJ'
288 write (stderr, *) 'Maximum polynomial degree is', nmax
289 write (stderr, *) 'Here NP=', np
290 call neko_error
291 end if
292 alphad = real(alpha, kind=xp)
293 betad = real(beta, kind=xp)
294 call zwgljd(zd, wd, np, alphad, betad)
295 do i = 1, np
296 z(i) = real(zd(i), kind=rp)
297 w(i) = real(wd(i), kind=rp)
298 end do
299 end subroutine zwglj
300
301
306 subroutine zwgljd(Z, W, NP, ALPHA, BETA)
307
308 integer, intent(in) :: NP
309 real(kind=xp), intent(inout) :: z(np), w(np)
310 real(kind=xp), intent(in) :: alpha, beta
311
312 real(kind=xp) :: alpg, betg
313 real(kind=xp) :: p, pd, pm1, pdm1, pm2, pdm2
314 integer :: N, NM1, I
315
316 n = np - 1
317 nm1 = n - 1
318
319 if (np .le. 1) then
320 write (stderr, *) 'ZWGLJD: Minimum number of Gauss-Lobatto points is 2'
321 write (stderr, *) 'ZWGLJD: alpha, beta:', alpha, beta, np
322 call neko_error
323 else if ((alpha .le. -1.0_xp) .or. (beta .le. -1.0_xp)) then
324 call neko_error('ZWGLJD: Alpha and Beta must be greater than -1')
325 end if
326
327 if (nm1 .gt. 0) then
328 alpg = alpha + 1.0_xp
329 betg = beta + 1.0_xp
330 call zwgjd(z(2), w(2), nm1, alpg, betg)
331 end if
332
333 z(1) = -1.0_xp
334 z(np) = 1.0_xp
335 do i = 2, np - 1
336 w(i) = w(i) / (1.0_xp-z(i)**2)
337 end do
338 call jacobf(p, pd, pm1, pdm1, pm2, pdm2, n, alpha, beta, z(1))
339 w(1) = endw1(n, alpha, beta) / (2.0_xp*pd)
340 call jacobf(p, pd, pm1, pdm1, pm2, pdm2, n, alpha, beta, z(np))
341 w(np) = endw2(n, alpha, beta) / (2.0_xp*pd)
342
343 end subroutine zwgljd
344
346 real(kind=xp) function endw1(N, ALPHA, BETA)
347
348 real(kind=xp), intent(in) :: alpha, beta
349 integer, intent(in) :: n
350
351 real(kind=xp) :: apb
352 real(kind=xp) :: f1, f2, f3, fint1, fint2
353 real(kind=xp) :: a1, a2, a3, di, abn, abnn
354 integer :: i
355
356 if (n .eq. 0) then
357 endw1 = 0.0_xp
358 return
359 end if
360
361 apb = alpha + beta
362 f1 = gammaf(alpha + 2.0_xp)*gammaf(beta + 1.0_xp) / gammaf(apb + 3.0_xp)
363 f1 = f1*(apb + 2.0_xp)*2.0_xp**(apb + 2.0_xp)/2.0_xp
364 if (n .eq. 1) then
365 endw1 = f1
366 return
367 end if
368
369 fint1 = gammaf(alpha + 2.0_xp)*gammaf(beta + 1.0_xp) / gammaf(apb + 3.0_xp)
370 fint1 = fint1*2.0_xp**(apb + 2.0_xp)
371 fint2 = gammaf(alpha + 2.0_xp)*gammaf(beta + 2.0_xp) / gammaf(apb + 4.0_xp)
372 fint2 = fint2*2.0_xp**(apb + 3.0_xp)
373 f2 = (-2.0_xp*(beta + 2.0_xp)*fint1 + (apb + 4.0_xp)*fint2) * &
374 (apb + 3.0_xp) / 4.0_xp
375 if (n .eq. 2) then
376 endw1 = f2
377 return
378 end if
379
380 do i = 3, n
381 di = real(i - 1, kind=xp)
382 abn = alpha + beta + di
383 abnn = abn + di
384 a1 = -(2.0_xp*(di + alpha) * (di + beta)) / (abn*abnn*(abnn + 1.0_xp))
385 a2 = (2.0_xp*(alpha - beta)) / (abnn*(abnn + 2.0_xp))
386 a3 = (2.0_xp*(abn + 1.0_xp)) / ((abnn + 2.0_xp) * (abnn + 1.0_xp))
387 f3 = -(a2*f2 + a1*f1) / a3
388 f1 = f2
389 f2 = f3
390 end do
391 endw1 = f3
392 end function endw1
393
395 real(kind=xp) function endw2(N, ALPHA, BETA)
396
397 real(kind=xp), intent(in) :: alpha, beta
398 integer, intent(in) :: n
399
400 real(kind=xp) :: apb
401 real(kind=xp) :: f1, f2, f3, fint1, fint2
402 real(kind=xp) :: a1, a2, a3, di, abn, abnn
403 integer :: i
404
405
406 if (n .eq. 0) then
407 endw2 = 0.0_xp
408 return
409 end if
410
411 apb = alpha + beta
412 f1 = gammaf(alpha + 1.0_xp)*gammaf(beta + 2.0_xp) / gammaf(apb + 3.0_xp)
413 f1 = f1*(apb + 2.0_xp)*2.0_xp**(apb + 2.0_xp)/2.0_xp
414 if (n .eq. 1) then
415 endw2 = f1
416 return
417 end if
418
419 fint1 = gammaf(alpha + 1.0_xp)*gammaf(beta + 2.0_xp) / gammaf(apb + 3.0_xp)
420 fint1 = fint1*2.0_xp**(apb + 2.0_xp)
421 fint2 = gammaf(alpha + 2.0_xp)*gammaf(beta + 2.0_xp) / gammaf(apb + 4.0_xp)
422 fint2 = fint2*2.0_xp**(apb + 3.0_xp)
423 f2 = (2.0_xp*(alpha + 2.0_xp)*fint1 - (apb + 4.0_xp)*fint2) * &
424 (apb + 3.0_xp) / 4.0_xp
425 if (n .eq. 2) then
426 endw2 = f2
427 return
428 end if
429
430 do i = 3, n
431 di = ((i-1))
432 abn = alpha + beta + di
433 abnn = abn + di
434 a1 = -(2.0_xp*(di + alpha) * (di + beta)) / (abn*abnn*(abnn + 1.0_xp))
435 a2 = (2.0_xp*(alpha - beta)) / (abnn*(abnn + 2.0_xp))
436 a3 = (2.0_xp*(abn + 1.0_xp)) / ((abnn + 2.0_xp) * (abnn + 1.0_xp))
437 f3 = -(a2*f2 + a1*f1)/a3
438 f1 = f2
439 f2 = f3
440 end do
441 endw2 = f3
442 end function endw2
443
445 real(kind=xp) function gammaf(X)
446 real(kind=xp), intent(in) :: x
447 real(kind=xp), parameter :: pi = 4.0_xp*atan(1.0_xp)
448
449 gammaf = 1.0_xp
450 if (abscmp(x, -0.5_xp)) gammaf = -2.0_xp*sqrt(pi)
451 if (abscmp(x, 0.5_xp)) gammaf = sqrt(pi)
452 if (abscmp(x, 1.0_xp)) gammaf = 1.0_xp
453 if (abscmp(x, 2.0_xp)) gammaf = 1.0_xp
454 if (abscmp(x, 1.5_xp)) gammaf = sqrt(pi) / 2.0_xp
455 if (abscmp(x, 2.5_xp)) gammaf = 1.5_xp * sqrt(pi) / 2.0_xp
456 if (abscmp(x, 3.5_xp)) gammaf = 0.5_xp * (2.5_xp * (1.5_xp * sqrt(pi)))
457 if (abscmp(x, 3.0_xp)) gammaf = 2.0_xp
458 if (abscmp(x, 4.0_xp)) gammaf = 6.0_xp
459 if (abscmp(x, 5.0_xp)) gammaf = 24.0_xp
460 if (abscmp(x, 6.0_xp)) gammaf = 120.0_xp
461 end function gammaf
462
464 real(kind=xp) function pnormj(N, ALPHA, BETA)
465 real(kind=xp), intent(in) :: alpha, beta
466 integer, intent(in) :: n
467
468 real(kind=xp) :: dn, dindx
469 real(kind=xp) :: const, prod, frac
470 integer :: i
471
472 dn = real(n, kind=xp)
473 const = alpha + beta + 1.0_xp
474 if (n .le. 1) then
475 prod = gammaf(dn + alpha)*gammaf(dn + beta)
476 prod = prod / (gammaf(dn)*gammaf(dn + alpha + beta))
477 pnormj = prod * 2.0_xp**const / (2.0_xp*dn + const)
478 return
479 end if
480
481 prod = gammaf(alpha + 1.0_xp)*gammaf(beta + 1.0_xp)
482 prod = prod/(2.0_xp*(1.0_xp + const)*gammaf(const + 1.0_xp))
483 prod = prod*(1.0_xp + alpha) * (2.0_xp + alpha)
484 prod = prod*(1.0_xp + beta) * (2.0_xp + beta)
485 do i = 3, n
486 dindx = real(i, kind=xp)
487 frac = (dindx + alpha) * (dindx + beta) / (dindx*(dindx + alpha + beta))
488 prod = prod*frac
489 end do
490 pnormj = prod*2.0_xp**const / (2.0_xp*dn + const)
491 end function pnormj
492
499 subroutine jacg(XJAC, NP, ALPHA, BETA)
500 integer, intent(in) :: NP
501 real(kind=xp), intent(inout) :: xjac(np)
502 real(kind=xp), intent(in) :: alpha, beta
503
504 integer, parameter :: KSTOP = 10
505 real(kind=rp), parameter :: eps = 1.0e-12_rp
506 real(kind=xp), parameter :: pi = 4.0_xp*atan(1.0_xp)
507
508 real(kind=xp) :: dth, x, x1, x2, xlast, delx, xmin
509 real(kind=xp) :: p, pd, pm1, pdm1, pm2, pdm2
510 real(kind=xp) :: recsum, swap
511 integer :: I, J, K, N, JM, JMIN
512
513 n = np - 1
514 dth = pi / (2.0_xp*real(n, kind=xp) + 2.0_xp)
515 do j = 1, np
516 if (j .eq. 1) then
517 x = cos((2.0_xp*(real(j, kind=xp) - 1.0_xp) + 1.0_xp)*dth)
518 else
519 x1 = cos((2.0_xp*(real(j, kind=xp) - 1.0_xp) + 1.0_xp)*dth)
520 x2 = xlast
521 x = (x1 + x2) / 2.0_xp
522 end if
523
524 do k = 1, kstop
525 call jacobf(p, pd, pm1, pdm1, pm2, pdm2, np, alpha, beta, x)
526 recsum = 0.0_xp
527 jm = j - 1
528 do i = 1, jm
529 recsum = recsum + 1.0_xp / (x-xjac(np - i + 1))
530 end do
531 delx = -p / (pd - recsum*p)
532 x = x + delx
533 if (abs(delx) .lt. eps) exit
534 end do
535
536 xjac(np-j + 1) = x
537 xlast = x
538 end do
539
540 do i = 1, np
541 xmin = 2.
542 do j = i, np
543 if (xjac(j) .lt. xmin) then
544 xmin = xjac(j)
545 jmin = j
546 end if
547 end do
548 if (jmin .ne. i) then
549 swap = xjac(i)
550 xjac(i) = xjac(jmin)
551 xjac(jmin) = swap
552 end if
553 end do
554 end subroutine jacg
555
558 subroutine jacobf(POLY, PDER, POLYM1, PDERM1, POLYM2, PDERM2, N, ALP, BET, X)
559
560 real(kind=xp), intent(inout) :: poly, pder, polym1, pderm1, polym2, pderm2
561 real(kind=xp), intent(in) :: alp, bet, x
562 integer, intent(in) :: N
563
564 real(kind=xp) :: apb, polyl, pderl, polyn, pdern
565 real(kind=xp) :: psave, pdsave
566 real(kind=xp) :: a1, a2, a3, a4, b3
567 real(kind=xp) :: dk
568 integer :: K
569
570 apb = alp + bet
571 poly = 1.0_xp
572 pder = 0.0_xp
573 if (n .eq. 0) return
574
575 polyl = poly
576 pderl = pder
577 poly = (alp - bet + (apb + 2.0_xp)*x) / 2.0_xp
578 pder = (apb + 2.0_xp) / 2.0_xp
579 if (n .eq. 1) return
580
581 do k = 2, n
582 dk = real(k, kind=xp)
583 a1 = 2.0_xp*dk*(dk + apb) * (2.0_xp*dk + apb - 2.0_xp)
584 a2 = (2.0_xp*dk + apb - 1.0_xp) * (alp**2 - bet**2)
585 b3 = (2.0_xp*dk + apb - 2.0_xp)
586 a3 = b3*(b3 + 1.0_xp) * (b3 + 2.0_xp)
587 a4 = 2.0_xp*(dk + alp - 1.0_xp) * (dk + bet - 1.0_xp) * (2.0_xp*dk + apb)
588 polyn = ((a2 + a3*x)*poly - a4*polyl) / a1
589 pdern = ((a2 + a3*x)*pder - a4*pderl + a3*poly) / a1
590 psave = polyl
591 pdsave = pderl
592 polyl = poly
593 poly = polyn
594 pderl = pder
595 pder = pdern
596 end do
597 polym1 = polyl
598 pderm1 = pderl
599 polym2 = psave
600 pderm2 = pdsave
601 end subroutine jacobf
602
606 real(kind=xp) function hgj(II, Z, ZGJ, NP, ALPHA, BETA)
607 integer, intent(in) :: np, ii
608 real(kind=xp), intent(in) :: z, zgj(np), alpha, beta
609
610 integer, parameter :: nmax = 84
611 integer, parameter :: nzd = nmax
612
613 real(kind=xp) zd, zgjd(nzd)
614 integer :: i, npmax
615
616 npmax = nzd
617 if (np .gt. npmax) then
618 write (stderr, *) 'Too large polynomial degree in HGJ'
619 write (stderr, *) 'Maximum polynomial degree is', nmax
620 write (stderr, *) 'Here NP=', np
621 call neko_error
622 end if
623
624 zd = z
625 do i = 1, np
626 zgjd(i) = zgj(i)
627 end do
628 hgj = hgjd(ii, zd, zgjd, np, alpha, beta)
629 end function hgj
630
634 real(kind=xp) function hgjd(II, Z, ZGJ, NP, ALPHA, BETA)
635 integer, intent(in) :: np, ii
636 real(kind=xp), intent(in) :: z, zgj(np), alpha, beta
637
638 real(kind=xp) :: eps, zi, dz
639 real(kind=xp) :: pz, pdz, pzi, pdzi, pm1, pdm1, pm2, pdm2
640
641 eps = 1.0e-5_xp
642 zi = zgj(ii)
643 dz = z - zi
644 if (abs(dz) .lt. eps) then
645 hgjd = 1.0_xp
646 return
647 end if
648 call jacobf(pzi, pdzi, pm1, pdm1, pm2, pdm2, np, alpha, beta, zi)
649 call jacobf(pz, pdz, pm1, pdm1, pm2, pdm2, np, alpha, beta, z)
650 hgjd = pz / (pdzi*(z-zi))
651 end function hgjd
652
656 real(kind=xp) function hglj(II, Z, ZGLJ, NP, ALPHA, BETA)
657 integer, intent(in) :: np, ii
658 real(kind=xp), intent(in) :: z, zglj(np), alpha, beta
659
660 integer, parameter :: nmax = 84
661 integer, parameter :: nzd = nmax
662
663 real(kind=xp) zd, zgljd(nzd)
664 integer :: i, npmax
665
666 npmax = nzd
667 if (np .gt. npmax) then
668 write (stderr, *) 'Too large polynomial degree in HGLJ'
669 write (stderr, *) 'Maximum polynomial degree is', nmax
670 write (stderr, *) 'Here NP=', np
671 call neko_error
672 end if
673 zd = z
674 do i = 1, np
675 zgljd(i) = zglj(i)
676 end do
677 hglj = hgljd(ii, zd, zgljd, np, alpha, beta)
678 end function hglj
679
683 real(kind=xp) function hgljd(I, Z, ZGLJ, NP, ALPHA, BETA)
684 integer, intent(in) :: np, i
685 real(kind=xp), intent(in) :: z, zglj(np), alpha, beta
686
687 real(kind=xp) :: eps, zi, dz, dn
688 real(kind=xp) :: p, pd, pi, pdi, pm1, pdm1, pm2, pdm2
689 real(kind=xp) :: eigval, const
690 integer :: n
691
692 eps = 1.0e-5_xp
693 zi = zglj(i)
694 dz = z-zi
695 if (abs(dz) .lt. eps) then
696 hgljd = 1.0_xp
697 return
698 end if
699
700 n = np - 1
701 dn = real(n, kind=xp)
702 eigval = -dn*(dn + alpha + beta + 1.0_xp)
703 call jacobf(pi, pdi, pm1, pdm1, pm2, pdm2, n, alpha, beta, zi)
704 const = eigval*pi + alpha*(1.0_xp + zi)*pdi - beta*(1.0_xp - zi)*pdi
705 call jacobf(p, pd, pm1, pdm1, pm2, pdm2, n, alpha, beta, z)
706 hgljd = (1.0_xp - z**2)*pd / (const*(z - zi))
707 end function hgljd
708
714 subroutine dgj(D, DT, Z, NZ, NZD, ALPHA, BETA)
715 integer, intent(in) :: NZ, NZD
716 real(kind=xp), intent(inout) :: d(nzd, nzd), dt(nzd, nzd)
717 real(kind=xp), intent(in) :: z(nz), alpha, beta
718
719 integer, parameter :: NMAX = 84
720 integer, parameter :: NZDD = nmax
721
722 real(kind=xp) :: dd(nzdd, nzdd), dtd(nzdd, nzdd), zd(nzdd)
723 integer :: I, J
724
725 if (nz .le. 0) then
726 call neko_error('DGJ: Minimum number of Gauss points is 1')
727 else if (nz .gt. nmax) then
728 write (stderr, *) 'Too large polynomial degree in DGJ'
729 write (stderr, *) 'Maximum polynomial degree is', nmax
730 write (stderr, *) 'Here Nz=', nz
731 call neko_error
732 else if ((alpha .le. -1.0_xp) .or. (beta .le. -1.0_xp)) then
733 call neko_error('DGJ: Alpha and Beta must be greater than -1')
734 end if
735
736 do i = 1, nz
737 zd(i) = z(i)
738 end do
739 call dgjd(dd, dtd, zd, nz, nzdd, alpha, beta)
740 do i = 1, nz
741 do j = 1, nz
742 d(i, j) = dd(i, j)
743 dt(i, j) = dtd(i, j)
744 end do
745 end do
746 end subroutine dgj
747
753 subroutine dgjd(D, DT, Z, NZ, NZD, ALPHA, BETA)
754 integer, intent(in) :: NZ, NZD
755 real(kind=xp), intent(inout) :: d(nzd, nzd), dt(nzd, nzd)
756 real(kind=xp), intent(in) :: z(nz), alpha, beta
757
758 real(kind=xp) :: dn
759 real(kind=xp) :: pdi, pdj, pi, pj, pm1, pdm1, pm2, pdm2
760 integer :: I, J, N
761
762 n = nz - 1
763 dn = real(n, kind=xp)
764
765
766 if (nz .le. 1) then
767 call neko_error('DGJD: Minimum number of Gauss-Lobatto points is 2')
768 else if ((alpha .le. -1.0_xp) .or. (beta .le. -1.0_xp)) then
769 call neko_error('DGJD: Alpha and Beta must be greater than -1')
770 end if
771
772 do i = 1, nz
773 do j = 1, nz
774 call jacobf(pi, pdi, pm1, pdm1, pm2, pdm2, nz, alpha, beta, z(i))
775 call jacobf(pj, pdj, pm1, pdm1, pm2, pdm2, nz, alpha, beta, z(j))
776 if (i .ne. j) then
777 d(i, j) = pdi / (pdj*(z(i) - z(j)))
778 else
779 d(i, j) = ((alpha + beta + 2.0_xp)*z(i) + alpha - beta) / &
780 (2.0_xp*(1.0_xp - z(i)**2))
781 end if
782 dt(j, i) = d(i, j)
783 end do
784 end do
785 end subroutine dgjd
786
792 subroutine dglj(D, DT, Z, NZ, NZD, ALPHA, BETA)
793 integer, parameter :: NMAX = 84
794 integer, parameter :: NZDD = nmax
795 integer, intent(in) :: NZ, NZD
796 real(kind=xp), intent(inout) :: d(nzd, nzd), dt(nzd, nzd)
797 real(kind=xp), intent(in) :: z(nz), alpha, beta
798
799 real(kind=xp) :: dd(nzdd, nzdd), dtd(nzdd, nzdd), zd(nzdd)
800 integer :: I, J
801
802 if (nz .le. 1) then
803 call neko_error('DGLJ: Minimum number of Gauss-Lobatto points is 2')
804 else if (nz .gt. nmax) then
805 write (stderr, *) 'Too large polynomial degree in DGLJ'
806 write (stderr, *) 'Maximum polynomial degree is', nmax
807 write (stderr, *) 'Here NZ=', nz
808 call neko_error
809 else if ((alpha .le. -1.0_xp) .or. (beta .le. -1.0_xp)) then
810 call neko_error('DGLJ: Alpha and Beta must be greater than -1')
811 end if
812
813 do i = 1, nz
814 zd(i) = z(i)
815 end do
816 call dgljd(dd, dtd, zd, nz, nzdd, alpha, beta)
817 do i = 1, nz
818 do j = 1, nz
819 d(i, j) = dd(i, j)
820 dt(i, j) = dtd(i, j)
821 end do
822 end do
823 end subroutine dglj
824
825
831 subroutine dgljd(D, DT, Z, NZ, NZD, ALPHA, BETA)
832 integer, intent(in) :: NZ, NZD
833 real(kind=xp), intent(inout) :: d(nzd, nzd), dt(nzd, nzd)
834 real(kind=xp), intent(in) :: z(nz), alpha, beta
835
836 real(kind=xp) :: dn, eigval
837 real(kind=xp) :: pdi, pdj, pi, pj, pm1, pdm1, pm2, pdm2
838 real(kind=xp) :: ci, cj
839 integer :: I, J, N
840
841 n = nz - 1
842 dn = real(n, kind=xp)
843
844 eigval = -dn*(dn + alpha + beta + 1.0_xp)
845
846 if (nz .le. 1) then
847 call neko_error('DGLJD: Minimum number of Gauss-Lobatto points is 2')
848 else if ((alpha .le. -1.0_xp) .or. (beta .le. -1.0_xp)) then
849 call neko_error('DGLJD: Alpha and Beta must be greater than -1')
850 end if
851
852 do i = 1, nz
853 do j = 1, nz
854 call jacobf(pi, pdi, pm1, pdm1, pm2, pdm2, n, alpha, beta, z(i))
855 call jacobf(pj, pdj, pm1, pdm1, pm2, pdm2, n, alpha, beta, z(j))
856 ci = eigval*pi - (beta*(1.0_xp - z(i)) - alpha*(1.0_xp + z(i)))*pdi
857 cj = eigval*pj - (beta*(1.0_xp - z(j)) - alpha*(1.0_xp + z(j)))*pdj
858
859 ! Todo: This should have some elses in there
860 if (i .ne. j) then
861 d(i, j) = ci / (cj*(z(i) - z(j)))
862 else if (i .eq. 1) then
863 d(i, j) = (eigval + alpha) / (2.0_xp*(beta + 2.0_xp))
864 else if (i .eq. nz) then
865 d(i, j) = -(eigval + beta) / (2.0_xp*(alpha + 2.0_xp))
866 else
867 d(i, j) = (alpha*(1.0_xp + z(i)) - beta*(1.0_xp - z(i))) / &
868 (2.0_xp*(1.0_xp - z(i)**2))
869 end if
870 dt(j, i) = d(i, j)
871 end do
872 end do
873 end subroutine dgljd
874
879 subroutine dgll(D, DT, Z, NZ, NZD)
880
881 integer, intent(in) :: NZ, NZD
882 real(kind=rp), intent(inout) :: d(nzd, nzd), dt(nzd, nzd)
883 real(kind=rp), intent(in) :: z(nz)
884
885 integer, parameter :: NMAX = 84
886
887 real(kind=xp) :: d0, fn
888 integer :: I, J, N
889
890 n = nz - 1
891 if (nz .gt. nmax) then
892 write (stderr, *) 'Subroutine DGLL'
893 write (stderr, *) 'Maximum polynomial degree =', nmax
894 write (stderr, *) 'Polynomial degree =', nz
895 call neko_error
896 else if (nz .eq. 1) then
897 d(1, 1) = 0.0_rp
898 return
899 end if
900
901 fn = real(n, kind=xp)
902 d0 = fn*(fn + 1.0_xp)/4.0_xp
903 do i = 1, nz
904 do j = 1, nz
905 if (i .ne. j) then
906 d(i, j) = pnleg(real(z(i), xp), n)/ &
907 (pnleg(real(z(j), xp), n) * (z(i) - z(j)))
908 else if (i .eq. 1) then
909 d(i, j) = -d0
910 else if (i .eq. nz) then
911 d(i, j) = d0
912 else
913 d(i, j) = 0.0_rp
914 end if
915 dt(j, i) = d(i, j)
916 end do
917 end do
918 end subroutine dgll
919
922 real(kind=xp) function hgll(I, Z, ZGLL, NZ)
923 integer, intent(in) :: i, nz
924 real(kind=xp), intent(in) :: zgll(nz), z
925
926 real(kind=xp) :: eps, dz
927 real(kind=xp) :: alfan
928 integer :: n
929
930 eps = 1.0e-5_xp
931 dz = z - zgll(i)
932 if (abs(dz) .lt. eps) then
933 hgll = 1.0_xp
934 return
935 end if
936
937 n = nz - 1
938 alfan = real(n, kind=xp) * (real(n, kind=xp) + 1.0_xp)
939 hgll = -(1.0_xp - z*z)*pndleg(z, n) / (alfan*pnleg(zgll(i), n) * &
940 (z - zgll(i)))
941 end function hgll
942
945 real(kind=xp) function hgl (I, Z, ZGL, NZ)
946 integer, intent(in) :: i, nz
947 real(kind=xp), intent(in) :: zgl(nz), z
948 real(kind=xp) :: eps, dz
949
950 integer :: n
951
952 eps = 1.0e-5_xp
953 dz = z - zgl(i)
954 if (abs(dz) .lt. eps) then
955 hgl = 1.0_xp
956 return
957 end if
958
959 n = nz - 1
960 hgl = pnleg(z, nz) / (pndleg(zgl(i), nz) * (z - zgl(i)))
961 end function hgl
962
966 real(kind=xp) function pnleg(Z, N)
967
968!---------------------------------------------------------------------
969!
970! This next statement is to overcome the underflow bug in the i860.
971! It can be removed at a later date. 11 Aug 1990 pff.
972!
973
974 real(kind=xp), intent(in) :: z
975 integer, intent(in) :: n
976
977 real(kind=xp) :: p1, p2, p3, fk
978 integer :: k
979
980 p1 = 1.0_xp
981 if (n .eq. 0) then
982 pnleg = p1
983 return
984 end if
985
986 p2 = z
987 p3 = p2
988 do k = 1, n-1
989 fk = real(k, kind=xp)
990 p3 = ((2.0_xp*fk + 1.0_xp)*z*p2 - fk*p1) / (fk + 1.0_xp)
991 p1 = p2
992 p2 = p3
993 end do
994 pnleg = p3
995 end function pnleg
996
999 subroutine legendre_poly(L, x, N)
1000 integer, intent(in) :: N
1001 real(kind=rp), intent(inout) :: l(0:n)
1002 real(kind=rp), intent(in) :: x
1003
1004 real(kind=rp) :: dj
1005 integer :: j
1006
1007 l(0) = 1.0_rp
1008 if (n .eq. 0) return
1009 l(1) = x
1010
1011 do j = 1, n-1
1012 dj = real(j, kind=rp)
1013 l(j + 1) = ((2.0_rp*dj + 1.0_rp)*x*l(j) - dj*l(j-1)) / (dj + 1.0_rp)
1014 end do
1015 end subroutine legendre_poly
1016
1020 real(kind=xp) function pndleg(Z, N)
1021 real(kind=xp), intent(in) :: z
1022 integer, intent(in) :: n
1023
1024 real(kind=xp) :: p1, p2, p3, p1d, p2d, p3d, fk
1025 integer :: k
1026
1027 if (n .eq. 0) then
1028 pndleg = 0.0_xp
1029 return
1030 end if
1031
1032 p1 = 1.0_xp
1033 p2 = z
1034 p1d = 0.0_xp
1035 p2d = 1.0_xp
1036 p3d = 1.0_xp
1037 do k = 1, n-1
1038 fk = real(k, kind=xp)
1039 p3 = ((2.0_xp*fk + 1.0_xp)*z*p2 - fk*p1) / (fk + 1.0_xp)
1040 p3d = ((2.0_xp*fk + 1.0_xp)*p2 + (2.0_xp*fk + 1.0_xp)*z*p2d - fk*p1d) / &
1041 (fk + 1.0_xp)
1042 p1 = p2
1043 p2 = p3
1044 p1d = p2d
1045 p2d = p3d
1046 end do
1047 pndleg = p3d
1048 end function pndleg
1049
1057 subroutine dgllgl(D, DT, ZM1, ZM2, IM12, NZM1, NZM2, ND1, ND2)
1058 integer, intent(in) :: NZM1, NZM2, ND1, ND2
1059 real(kind=xp), intent(inout) :: d(nd2, nd1), dt(nd1, nd2)
1060 real(kind=xp), intent(in) :: zm1(nd1), zm2(nd2), im12(nd2, nd1)
1061
1062 real(kind=xp) eps, zp, zq
1063 integer :: IP, JQ, NM1
1064
1065 if (nzm1 .eq. 1) then
1066 d(1, 1) = 0.0_xp
1067 dt(1, 1) = 0.0_xp
1068 return
1069 end if
1070 eps = 1.0e-6_xp
1071 nm1 = nzm1 - 1
1072 do ip = 1, nzm2
1073 do jq = 1, nzm1
1074 zp = zm2(ip)
1075 zq = zm1(jq)
1076 if ((abs(zp) .lt. eps) .and. (abs(zq) .lt. eps)) then
1077 d(ip, jq) = 0.0_xp
1078 else
1079 d(ip, jq) = (pnleg(zp, nm1) / pnleg(zq, nm1) - im12(ip, jq)) / &
1080 (zp - zq)
1081 end if
1082 dt(jq, ip) = d(ip, jq)
1083 end do
1084 end do
1085 end subroutine dgllgl
1086
1095 subroutine dgljgj(D, DT, ZGL, ZG, IGLG, NPGL, NPG, ND1, ND2, ALPHA, BETA)
1096 integer, intent(in) :: NPGL, NPG, ND1, ND2
1097 real(kind=xp), intent(inout) :: d(nd2, nd1), dt(nd1, nd2)
1098 real(kind=xp), intent(in) :: zgl(nd1), zg(nd2), iglg(nd2, nd1), alpha, beta
1099
1100 integer, parameter :: NMAX = 84
1101 integer, parameter :: NDD = nmax
1102
1103 real(kind=xp) dd(ndd, ndd), dtd(ndd, ndd)
1104 real(kind=xp) zgd(ndd), zgld(ndd), iglgd(ndd, ndd)
1105 integer :: I, J
1106
1107 if (npgl .le. 1) then
1108 call neko_error('DGLJGJ: Minimum number of Gauss-Lobatto points is 2')
1109 else if (npgl .gt. nmax) then
1110 write(stderr, *) 'Polynomial degree too high in DGLJGJ'
1111 write(stderr, *) 'Maximum polynomial degree is', nmax
1112 write(stderr, *) 'Here NPGL=', npgl
1113 call neko_error
1114 else if ((alpha .le. -1.0_xp) .or. (beta .le. -1.0_xp)) then
1115 call neko_error('DGLJGJ: Alpha and Beta must be greater than -1')
1116 end if
1117
1118 do i = 1, npg
1119 zgd(i) = zg(i)
1120 do j = 1, npgl
1121 iglgd(i, j) = iglg(i, j)
1122 end do
1123 end do
1124 do i = 1, npgl
1125 zgld(i) = zgl(i)
1126 end do
1127 call dgljgjd(dd, dtd, zgld, zgd, iglgd, npgl, npg, ndd, ndd, alpha, beta)
1128 do i = 1, npg
1129 do j = 1, npgl
1130 d(i, j) = dd(i, j)
1131 dt(j, i) = dtd(j, i)
1132 end do
1133 end do
1134 end subroutine dgljgj
1135
1144 subroutine dgljgjd(D, DT, ZGL, ZG, IGLG, NPGL, NPG, ND1, ND2, ALPHA, BETA)
1145 integer, intent(in) :: NPGL, NPG, ND1, ND2
1146 real(kind=xp), intent(inout) :: d(nd2, nd1), dt(nd1, nd2)
1147 real(kind=xp), intent(in) :: zgl(nd1), zg(nd2), iglg(nd2, nd1), alpha, beta
1148
1149 real(kind=xp) :: eps, eigval, dn
1150 real(kind=xp) :: pdi, pdj, pi, pj, pm1, pdm1, pm2, pdm2
1151 real(kind=xp) :: dz, faci, facj, const
1152 integer :: I, J, NGL
1153
1154 if (npgl .le. 1) then
1155 call neko_error('DGLJGJD: Minimum number of Gauss-Lobatto points is 2')
1156 else if ((alpha .le. -1.0_xp) .or. (beta .le. -1.0_xp)) then
1157 call neko_error('DGLJGJD: Alpha and Beta must be greater than -1')
1158 end if
1159
1160 eps = 1.0e-6_xp
1161
1162 ngl = npgl-1
1163 dn = real(ngl, kind=xp)
1164 eigval = -dn*(dn + alpha + beta + 1.0_xp)
1165
1166 do i = 1, npg
1167 do j = 1, npgl
1168 dz = abs(zg(i)-zgl(j))
1169 if (dz .lt. eps) then
1170 d(i, j) = (alpha*(1.0_xp + zg(i)) - beta*(1.0_xp - zg(i))) / &
1171 (2.0_xp*(1.0_xp - zg(i)**2))
1172 else
1173 call jacobf(pi, pdi, pm1, pdm1, pm2, pdm2, ngl, alpha, beta, zg(i))
1174 call jacobf(pj, pdj, pm1, pdm1, pm2, pdm2, ngl, alpha, beta, zgl(j))
1175 faci = alpha*(1.0_xp + zg(i)) - beta*(1.0_xp - zg(i))
1176 facj = alpha*(1.0_xp + zgl(j)) - beta*(1.0_xp - zgl(j))
1177 const = eigval*pj + facj*pdj
1178 d(i, j) = ((eigval*pi + faci*pdi) * (zg(i) - zgl(j)) - &
1179 (1.0_xp - zg(i)**2)*pdi) / (const*(zg(i) - zgl(j))**2)
1180 end if
1181 dt(j, i) = d(i, j)
1182 end do
1183 end do
1184 end subroutine dgljgjd
1185
1191 subroutine iglm(I12, IT12, Z1, Z2, NZ1, NZ2, ND1, ND2)
1192 integer, intent(in) :: NZ1, NZ2, ND1, ND2
1193 real(kind=xp), intent(inout) :: i12(nd2, nd1), it12(nd1, nd2)
1194 real(kind=xp), intent(in) :: z1(nd1), z2(nd2)
1195 real(kind=xp) :: zi
1196 integer :: I, J
1197
1198 if (nz1 .eq. 1) then
1199 i12(1, 1) = 1.0_xp
1200 it12(1, 1) = 1.0_xp
1201 return
1202 end if
1203
1204 do i = 1, nz2
1205 zi = z2(i)
1206 do j = 1, nz1
1207 i12(i, j) = hgl(j, zi, z1, nz1)
1208 it12(j, i) = i12(i, j)
1209 end do
1210 end do
1211 end subroutine iglm
1212
1218 subroutine igllm(I12, IT12, Z1, Z2, NZ1, NZ2, ND1, ND2)
1219 integer, intent(in) :: NZ1, NZ2, ND1, ND2
1220 real(kind=xp), intent(inout) :: i12(nd2, nd1), it12(nd1, nd2)
1221 real(kind=xp), intent(in) :: z1(nd1), z2(nd2)
1222 real(kind=xp) :: zi
1223 integer :: I, J
1224
1225 if (nz1 .eq. 1) then
1226 i12(1, 1) = 1.0_xp
1227 it12(1, 1) = 1.0_xp
1228 return
1229 end if
1230
1231 do i = 1, nz2
1232 zi = z2(i)
1233 do j = 1, nz1
1234 i12(i, j) = hgll(j, zi, z1, nz1)
1235 it12(j, i) = i12(i, j)
1236 end do
1237 end do
1238 end subroutine igllm
1239
1246 subroutine igjm(I12, IT12, Z1, Z2, NZ1, NZ2, ND1, ND2, ALPHA, BETA)
1247 integer, intent(in) :: NZ1, NZ2, ND1, ND2
1248 real(kind=xp), intent(inout) :: i12(nd2, nd1), it12(nd1, nd2)
1249 real(kind=xp), intent(in) :: z1(nd1), z2(nd2), alpha, beta
1250 real(kind=xp) :: zi
1251 integer :: I, J
1252
1253 if (nz1 .eq. 1) then
1254 i12(1, 1) = 1.0_xp
1255 it12(1, 1) = 1.0_xp
1256 return
1257 end if
1258
1259 do i = 1, nz2
1260 zi = z2(i)
1261 do j = 1, nz1
1262 i12(i, j) = hgj(j, zi, z1, nz1, alpha, beta)
1263 it12(j, i) = i12(i, j)
1264 end do
1265 end do
1266 end subroutine igjm
1267
1274 subroutine igljm(I12, IT12, Z1, Z2, NZ1, NZ2, ND1, ND2, ALPHA, BETA)
1275 integer, intent(in) :: NZ1, NZ2, ND1, ND2
1276 real(kind=xp), intent(inout) :: i12(nd2, nd1), it12(nd1, nd2)
1277 real(kind=xp), intent(in) :: z1(nd1), z2(nd2), alpha, beta
1278 real(kind=xp) :: zi
1279 integer :: I, J
1280
1281 if (nz1 .eq. 1) then
1282 i12(1, 1) = 1.0_xp
1283 it12(1, 1) = 1.0_xp
1284 return
1285 end if
1286
1287 do i = 1, nz2
1288 zi = z2(i)
1289 do j = 1, nz1
1290 i12(i, j) = hglj(j, zi, z1, nz1, alpha, beta)
1291 it12(j, i) = i12(i, j)
1292 end do
1293 end do
1294 end subroutine igljm
1295end module speclib
double real
Definition math.f90:60
real(kind=rp), parameter, public pi
Definition math.f90:75
integer, parameter, public xp
Definition num_types.f90:14
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:12
LIBRARY ROUTINES FOR SPECTRAL METHODS.
Definition speclib.f90:148
subroutine dgj(d, dt, z, nz, nzd, alpha, beta)
Compute the derivative matrix D and its transpose DT associated with the Nth order Lagrangian interpo...
Definition speclib.f90:715
real(kind=xp) function pndleg(z, n)
Compute the derivative of the Nth order Legendre polynomial at Z. (Simpler than JACOBF) Based on the ...
Definition speclib.f90:1021
subroutine dgll(d, dt, z, nz, nzd)
Compute the derivative matrix D and its transpose DT associated with the Nth order Lagrangian interpo...
Definition speclib.f90:880
subroutine igjm(i12, it12, z1, z2, nz1, nz2, nd1, nd2, alpha, beta)
Compute the one-dimensional interpolation operator (matrix) I12 ands its transpose IT12 for interpola...
Definition speclib.f90:1247
real(kind=xp) function hgj(ii, z, zgj, np, alpha, beta)
Compute the value of the Lagrangian interpolant HGJ through the NP Gauss Jacobi points ZGJ at the poi...
Definition speclib.f90:607
subroutine dgllgl(d, dt, zm1, zm2, im12, nzm1, nzm2, nd1, nd2)
Compute the (one-dimensional) derivative matrix D and its transpose DT associated with taking the der...
Definition speclib.f90:1058
subroutine zwgll(z, w, np)
Generate NP Gauss-Lobatto Legendre points (Z) and weights (W) associated with Jacobi polynomial P(N)(...
Definition speclib.f90:179
real(kind=xp) function pnormj(n, alpha, beta)
Definition speclib.f90:465
subroutine dgjd(d, dt, z, nz, nzd, alpha, beta)
Compute the derivative matrix D and its transpose DT associated with the Nth order Lagrangian interpo...
Definition speclib.f90:754
real(kind=xp) function gammaf(x)
Definition speclib.f90:446
subroutine jacg(xjac, np, alpha, beta)
Compute NP Gauss points XJAC, which are the zeros of the Jacobi polynomial J(NP) with parameters ALPH...
Definition speclib.f90:500
subroutine zwgljd(z, w, np, alpha, beta)
Generate NP GAUSS LOBATTO JACOBI points (Z) and weights (W) associated with Jacobi polynomial P(N)(al...
Definition speclib.f90:307
real(kind=xp) function hglj(ii, z, zglj, np, alpha, beta)
Compute the value of the Lagrangian interpolant HGLJ through the NZ Gauss-Lobatto Jacobi points ZGLJ ...
Definition speclib.f90:657
real(kind=xp) function hgljd(i, z, zglj, np, alpha, beta)
Compute the value of the Lagrangian interpolant HGLJD through the NZ Gauss-Lobatto Jacobi points ZJAC...
Definition speclib.f90:684
subroutine zwglj(z, w, np, alpha, beta)
Generate NP GAUSS LOBATTO JACOBI points (Z) and weights (W) associated with Jacobi polynomial P(N)(al...
Definition speclib.f90:275
subroutine zwgj(z, w, np, alpha, beta)
Generate NP GAUSS JACOBI points (Z) and weights (W) associated with Jacobi polynomial P(N)(alpha>-1,...
Definition speclib.f90:192
subroutine iglm(i12, it12, z1, z2, nz1, nz2, nd1, nd2)
Compute the one-dimensional interpolation operator (matrix) I12 ands its transpose IT12 for interpola...
Definition speclib.f90:1192
subroutine jacobf(poly, pder, polym1, pderm1, polym2, pderm2, n, alp, bet, x)
Computes the Jacobi polynomial (POLY) and its derivative (PDER) of degree N at X.
Definition speclib.f90:559
subroutine zwgjd(z, w, np, alpha, beta)
Generate NP GAUSS JACOBI points (Z) and weights (W) associated with Jacobi polynomial P(N)(alpha>-1,...
Definition speclib.f90:224
subroutine dglj(d, dt, z, nz, nzd, alpha, beta)
Compute the derivative matrix D and its transpose DT associated with the Nth order Lagrangian interpo...
Definition speclib.f90:793
subroutine dgljgj(d, dt, zgl, zg, iglg, npgl, npg, nd1, nd2, alpha, beta)
Compute the (one-dimensional) derivative matrix D and its transpose DT associated with taking the der...
Definition speclib.f90:1096
real(kind=xp) function pnleg(z, n)
Compute the value of the Nth order Legendre polynomial at Z. (Simpler than JACOBF) Based on the recur...
Definition speclib.f90:967
real(kind=xp) function hgl(i, z, zgl, nz)
Compute the value of the Lagrangian interpolant HGL through the NZ Gauss Legendre points ZGL at the p...
Definition speclib.f90:946
subroutine dgljd(d, dt, z, nz, nzd, alpha, beta)
Compute the derivative matrix D and its transpose DT associated with the Nth order Lagrangian interpo...
Definition speclib.f90:832
subroutine legendre_poly(l, x, n)
Evaluate Legendre polynomials of degrees 0-N at point x and store in array L.
Definition speclib.f90:1000
real(kind=xp) function endw1(n, alpha, beta)
Definition speclib.f90:347
subroutine igllm(i12, it12, z1, z2, nz1, nz2, nd1, nd2)
Compute the one-dimensional interpolation operator (matrix) I12 ands its transpose IT12 for interpola...
Definition speclib.f90:1219
subroutine dgljgjd(d, dt, zgl, zg, iglg, npgl, npg, nd1, nd2, alpha, beta)
Compute the (one-dimensional) derivative matrix D and its transpose DT associated with taking the der...
Definition speclib.f90:1145
subroutine zwgl(z, w, np)
Generate NP Gauss Legendre points Z and weights W associated with Jacobi polynomial ....
Definition speclib.f90:164
real(kind=xp) function hgll(i, z, zgll, nz)
Compute the value of the Lagrangian interpolant L through the NZ Gauss-Lobatto Legendre points ZGLL a...
Definition speclib.f90:923
real(kind=xp) function hgjd(ii, z, zgj, np, alpha, beta)
Compute the value of the Lagrangian interpolant HGJD through the NZ Gauss-Lobatto Jacobi points ZGJ a...
Definition speclib.f90:635
real(kind=xp) function endw2(n, alpha, beta)
Definition speclib.f90:396
subroutine igljm(i12, it12, z1, z2, nz1, nz2, nd1, nd2, alpha, beta)
Compute the one-dimensional interpolation operator (matrix) I12 ands its transpose IT12 for interpola...
Definition speclib.f90:1275
Utilities.
Definition utils.f90:35