80 use,
intrinsic :: iso_c_binding
85 real(kind=
rp),
allocatable :: s(:,:,:,:)
86 real(kind=
rp),
allocatable :: d(:,:)
87 type(c_ptr) :: s_d = c_null_ptr
88 type(c_ptr) :: d_d = c_null_ptr
89 real(kind=
rp),
allocatable :: len_lr(:), len_ls(:), len_lt(:)
90 real(kind=
rp),
allocatable :: len_mr(:), len_ms(:), len_mt(:)
91 real(kind=
rp),
allocatable :: len_rr(:), len_rs(:), len_rt(:)
92 real(kind=
rp),
allocatable :: swplen(:,:,:,:)
93 type(c_ptr) :: swplen_d = c_null_ptr
96 type(
gs_t),
pointer :: gs_h => null()
97 type(
mesh_t),
pointer :: msh => null()
107 module procedure qp_sygv
114 class(
fdm_t),
intent(inout) :: this
115 type(
space_t),
target,
intent(inout) :: Xh
116 type(
dofmap_t),
target,
intent(in) :: dof
117 type(
gs_t),
target,
intent(inout) :: gs_h
119 real(kind=
rp),
dimension((Xh%lx)**2) :: ah, bh, ch, dh, zh
120 real(kind=
rp),
dimension((Xh%lx)**2) :: dph, jph, bgl, zglhat, dgl, jgl, wh
121 integer :: nl, n, nelv
127 allocate(this%s(nl*nl, 2, dof%msh%gdim, dof%msh%nelv))
128 allocate(this%d(nl**3, dof%msh%nelv))
129 allocate(this%swplen(xh%lx, xh%lx, xh%lx, dof%msh%nelv))
130 allocate(this%len_lr(nelv), this%len_ls(nelv), this%len_lt(nelv))
131 allocate(this%len_mr(nelv), this%len_ms(nelv), this%len_mt(nelv))
132 allocate(this%len_rr(nelv), this%len_rs(nelv), this%len_rt(nelv))
136 call rzero(this%swplen, xh%lxyz * dof%msh%nelv)
139 call device_map(this%s, this%s_d, nl*nl*2*dof%msh%gdim*dof%msh%nelv)
140 call device_map(this%d, this%d_d, nl**dof%msh%gdim*dof%msh%nelv)
141 call device_map(this%swplen, this%swplen_d, xh%lxyz*dof%msh%nelv)
144 call semhat(ah, bh, ch, dh, zh, dph, jph, bgl, zglhat, dgl, jgl, n, wh)
150 call swap_lengths(this, dof%x%x, dof%y%x, dof%z%x, dof%msh%nelv, dof%msh%gdim)
156 nl*nl*2*dof%msh%gdim*dof%msh%nelv,
host_to_device, sync = .false.)
165 type(
fdm_t),
intent(inout) :: this
166 integer,
intent(in) :: gdim, nelv
167 real(kind=
rp),
dimension(this%Xh%lxyz, nelv),
intent(in) :: x, y, z
168 integer :: j, k, e, n2, nz0, nzn, nx, lx1, n
170 associate(l => this%swplen, xh => this%Xh, &
171 llr => this%len_lr, lls => this%len_ls, llt => this%len_lt, &
172 lmr => this%len_mr, lms => this%len_ms, lmt => this%len_mt, &
173 lrr => this%len_rr, lrs => this%len_rs, lrt => this%len_rt)
179 if (gdim .eq. 3)
then
183 call plane_space(lmr, lms, lmt, 0, n2, xh%wx, x, y, z, &
184 nx, n2, nz0, nzn, nelv, gdim)
186 if (gdim .eq. 3)
then
190 l(1, k, j, e) = lmr(e)
191 l(n, k, j, e) = lmr(e)
192 l(k, 1, j, e) = lms(e)
193 l(k, n, j, e) = lms(e)
194 l(k, j, 1, e) = lmt(e)
195 l(k, j, n, e) = lmt(e)
202 call this%gs_h%op(l, this%dof%size(), gs_op_add)
206 call this%gs_h%op(l, this%dof%size(), gs_op_add)
210 llr(e) = l(1, 2, 2, e) - lmr(e)
211 lrr(e) = l(n, 2, 2, e) - lmr(e)
212 lls(e) = l(2, 1, 2, e) - lms(e)
213 lrs(e) = l(2, n, 2, e) - lms(e)
214 llt(e) = l(2, 2, 1, e) - lmt(e)
215 lrt(e) = l(2, 2, n, e) - lmt(e)
220 l(1, j, 1, e) = lmr(e)
221 l(n, j, 1, e) = lmr(e)
222 l(j, 1, 1, e) = lms(e)
223 l(j, n, 1, e) = lms(e)
230 call this%gs_h%op(l, this%dof%size(), gs_op_add)
234 call this%gs_h%op(l, this%dof%size(), gs_op_add)
238 llr(e) = l(1, 2, 1, e) - lmr(e)
239 lrr(e) = l(n, 2, 1, e) - lmr(e)
240 lls(e) = l(2, 1, 1, e) - lms(e)
241 lrs(e) = l(2, n, 1, e) - lms(e)
251 nx, nxn, nz0, nzn, nelv, gdim)
252 integer,
intent(in) :: nxn, nzn, i1, i2, nelv, gdim, nx, nz0
253 real(kind=rp),
intent(inout) :: lr(nelv), ls(nelv), lt(nelv)
254 real(kind=rp),
intent(inout) :: w(nx)
255 real(kind=rp),
intent(in) :: x(0:nxn, 0:nxn, nz0:nzn, nelv)
256 real(kind=rp),
intent(in) :: y(0:nxn, 0:nxn, nz0:nzn, nelv)
257 real(kind=rp),
intent(in) :: z(0:nxn, 0:nxn, nz0:nzn, nelv)
258 real(kind=rp) :: lr2, ls2, lt2, weight, wsum
259 integer :: ny, nz, j1, k1, j2, k2, i, j, k, ie
268 if (gdim .eq. 3)
then
274 lr2 = lr2 + weight /&
275 ( (x(i2, j, k, ie) - x(i1, j, k, ie))**2&
276 + (y(i2, j, k, ie) - y(i1, j, k, ie))**2&
277 + (z(i2, j, k, ie) - z(i1, j, k, ie))**2 )
282 lr(ie) = 1d0/sqrt(lr2)
288 ls2 = ls2 + weight / &
289 ( (x(i, j2, k, ie) - x(i, j1, k, ie))**2 &
290 + (y(i, j2, k, ie) - y(i, j1, k, ie))**2 &
291 + (z(i, j2, k, ie) - z(i, j1, k, ie))**2 )
296 ls(ie) = 1d0/sqrt(ls2)
302 lt2 = lt2 + weight / &
303 ( (x(i, j, k2, ie) - x(i, j, k1, ie))**2 &
304 + (y(i, j, k2, ie) - y(i, j, k1, ie))**2 &
305 + (z(i, j, k2, ie) - z(i, j, k1, ie))**2 )
310 lt(ie) = 1d0/sqrt(lt2)
316 lr2 = lr2 + weight / &
317 ( (x(i2, j, 1, ie) - x(i1, j, 1, ie))**2 &
318 + (y(i2, j, 1, ie) - y(i1, j, 1, ie))**2 )
322 lr(ie) = 1d0/sqrt(lr2)
327 ls2 = ls2 + weight / &
328 ( (x(i, j2, 1, ie) - x(i, j1, 1, ie))**2 &
329 + (y(i, j2, 1, ie) - y(i, j1, 1, ie))**2 )
333 ls(ie) = 1d0/sqrt(ls2)
341 integer,
intent(in) :: nl, n
342 type(
fdm_t),
intent(inout) :: this
343 real(kind=rp),
intent(inout) :: ah(n+1, n+1), bh(n+1)
344 real(kind=rp),
dimension(2*this%Xh%lx + 4) :: lr, ls, lt
346 integer :: ie, il, nr, ns, nt
347 integer :: lbr, rbr, lbs, rbs, lbt, rbt
348 real(kind=rp) :: eps, diag
350 associate(s => this%s, d => this%d, &
351 llr => this%len_lr, lls => this%len_ls, llt => this%len_lt, &
352 lmr => this%len_mr, lms => this%len_ms, lmt => this%len_mt, &
353 lrr => this%len_rr, lrs => this%len_rs, lrt => this%len_rt)
354 do ie = 1, this%dof%msh%nelv
355 lbr = this%dof%msh%facet_type(1, ie)
356 rbr = this%dof%msh%facet_type(2, ie)
357 lbs = this%dof%msh%facet_type(3, ie)
358 rbs = this%dof%msh%facet_type(4, ie)
359 lbt = this%dof%msh%facet_type(5, ie)
360 rbt = this%dof%msh%facet_type(6, ie)
366 llr(ie), lmr(ie), lrr(ie), ah, bh, n)
368 lls(ie), lms(ie), lrs(ie), ah, bh, n)
369 if (this%dof%msh%gdim .eq. 3)
then
371 llt(ie), lmt(ie), lrt(ie), ah, bh, n)
375 if (.not. this%dof%msh%gdim .eq. 3)
then
376 eps = 1d-5 * (vlmax(lr(2), nr - 2) + vlmax(ls(2), ns - 2))
380 if (diag .gt. eps)
then
381 d(il, ie) = 1.0_rp / diag
389 eps = 1d-5 * (vlmax(lr(2), nr - 2) + &
390 vlmax(ls(2), ns - 2) + vlmax(lt(2), nt - 2))
394 diag = lr(i) + ls(j) + lt(k)
395 if (diag .gt. eps)
then
396 d(il, ie) = 1.0_rp / diag
410 subroutine fdm_setup_fast1d(s, lam, nl, lbc, rbc, ll, lm, lr, ah, bh, n)
411 integer,
intent(in) :: nl, lbc, rbc, n
412 real(kind=rp),
intent(inout) :: s(nl, nl, 2), lam(nl), ll, lm, lr
413 real(kind=rp),
intent(inout) :: ah(0:n, 0:n), bh(0:n)
415 real(kind=rp) :: b(2*(n+3)**2)
423 if (lbc .gt. 0)
call row_zero(s, nl, nl, 1)
424 if (lbc .eq. 1)
call row_zero(s, nl, nl, 2)
425 if (rbc .gt. 0)
call row_zero(s, nl, nl, nl)
426 if (rbc .eq. 1)
call row_zero(s, nl, nl, nl-1)
428 call trsp(s(1, 1, 2), nl, s, nl)
436 integer,
intent(in) :: n, lx
437 real(kind=rp),
intent(inout) :: a(n, n), b(n, n), lam(n)
439 real(kind=rp) :: bw(4*(lx+2)**3)
443 call sygv(a, b, lam, n, lx, bw, lbw)
448 integer,
intent(in) :: n, lx, lbw
449 real(kind=sp),
intent(inout) :: a(n, n), b(n, n), lam(n)
450 real(kind=sp) :: bw(4*(lx+2)**3)
452 call ssygv(1,
'V',
'U', n, a, n, b, n, lam, bw, lbw, info)
456 integer,
intent(in) :: n, lx, lbw
457 real(kind=dp),
intent(inout) :: a(n, n), b(n, n), lam(n)
458 real(kind=dp) :: bw(4*(lx+2)**3)
460 call dsygv(1,
'V',
'U', n, a, n, b, n, lam, bw, lbw, info)
464 subroutine qp_sygv(a, b, lam, n, lx, bw, lbw)
465 integer,
intent(in) :: n, lx, lbw
466 real(kind=qp),
intent(inout) :: a(n, n), b(n, n), lam(n)
467 real(kind=dp) :: a2(n, n), b2(n, n), lam2(n)
468 real(kind=qp) :: bw(4*(lx+2)**3)
469 real(kind=dp) :: bw2(4*(lx+2)**3)
475 call dsygv(1,
'V',
'U', n, a2, n, b2, n, lam2, bw2, lbw, info)
479 if (pe_rank .eq. 0)
then
480 call neko_warning(
'Real precision choice not supported for fdm, ' // &
481 'treating it as double')
484 end subroutine qp_sygv
488 integer,
intent(in) ::lbc, rbc, n
489 real(kind=rp),
intent(inout) :: a(0:n+2, 0:n+2), ll, lm, lr
490 real(kind=rp),
intent(inout) :: ah(0:n, 0:n)
492 integer :: i, j, i0, i1
495 if (lbc .eq. 1) i0 = 1
497 if (rbc .eq. 1) i1 = n - 1
499 call rzero(a, (n+3) * (n+3))
507 a(i+1, j+1) = fac * ah(i, j)
513 a(0, 0) = fac * ah(n-1, n-1)
514 a(1, 0) = fac * ah(n, n-1)
515 a(0, 1) = fac * ah(n-1, n)
516 a(1, 1) = a(1, 1) + fac * ah(n, n)
523 a(n+1, n+1) = a(n+1, n+1) + fac * ah(0, 0)
524 a(n+2, n+1) = fac * ah(1, 0)
525 a(n+1, n+2) = fac * ah(0, 1)
526 a(n+2, n+2) = fac * ah(1, 1)
534 integer,
intent(in) :: lbc, rbc, n
535 real(kind=rp),
intent(inout) :: b(0:n+2, 0:n+2), ll, lm, lr
536 real(kind=rp),
intent(inout) :: bh(0:n)
541 if (lbc .eq. 1) i0 = 1
543 if (rbc .eq. 1) i1 = n - 1
545 call rzero(b, (n + 3) * (n + 3))
552 b(i+1, i+1) = fac * bh(i)
557 b(0, 0) = fac * bh(n-1)
558 b(1, 1) = b(1, 1) + fac * bh(n)
565 b(n+1, n+1) = b(n+1, n+1) + fac * bh(0)
566 b(n+2, n+2) = fac * bh(1)
574 class(
fdm_t),
intent(inout) :: this
576 if (
allocated(this%s))
then
577 if (neko_bcknd_device .eq. 1)
then
578 call device_unmap(this%s, this%s_d)
583 if (
allocated(this%d))
then
584 if (neko_bcknd_device .eq. 1)
then
585 call device_unmap(this%d, this%d_d)
590 if (
allocated(this%len_lr))
then
591 deallocate(this%len_lr)
594 if (
allocated(this%len_ls))
then
595 deallocate(this%len_ls)
598 if (
allocated(this%len_lt))
then
599 deallocate(this%len_lt)
602 if (
allocated(this%len_mr))
then
603 deallocate(this%len_mr)
606 if (
allocated(this%len_ms))
then
607 deallocate(this%len_ms)
610 if (
allocated(this%len_mt))
then
611 deallocate(this%len_mt)
614 if (
allocated(this%len_rr))
then
615 deallocate(this%len_rr)
618 if (
allocated(this%len_rs))
then
619 deallocate(this%len_rs)
622 if (
allocated(this%len_rt))
then
623 deallocate(this%len_rt)
626 if (
allocated(this%swplen))
then
627 if (neko_bcknd_device .eq. 1)
then
628 call device_unmap(this%swplen, this%swplen_d)
630 deallocate(this%swplen)
641 class(
fdm_t),
intent(inout) :: this
642 real(kind=rp),
dimension((this%Xh%lx + 2)**3, this%msh%nelv), &
643 intent(inout) :: e, r
644 type(c_ptr),
optional :: stream
647 if (
present(stream))
then
653 if (neko_bcknd_sx .eq. 1)
then
654 call fdm_do_fast_sx(e, r, this%s, this%d, &
655 this%Xh%lx+2, this%msh%gdim, this%msh%nelv)
656 else if (neko_bcknd_xsmm .eq. 1)
then
657 call fdm_do_fast_xsmm(e, r, this%s, this%d, &
658 this%Xh%lx+2, this%msh%gdim, this%msh%nelv)
659 else if (neko_bcknd_device .eq. 1)
then
660 call fdm_do_fast_device(e, r, this%s, this%d, &
661 this%Xh%lx+2, this%msh%gdim, this%msh%nelv, strm)
663 call fdm_do_fast_cpu(e, r, this%s, this%d, &
664 this%Xh%lx+2, this%msh%gdim, this%msh%nelv)
Map a Fortran array to a device (allocate and associate)
Copy data between host and device (or device and device)
Unmap a Fortran array from a device (deassociate and free)
integer, public pe_rank
MPI rank.
Device abstraction, common interface for various accelerators.
integer, parameter, public host_to_device
integer, parameter, public device_to_host
type(c_ptr), bind(C), public glb_cmd_queue
Global command queue.
Defines a mapping of the degrees of freedom.
Fast diagonalization methods from NEKTON.
subroutine, public semhat(a, b, c, d, z, dgll, jgll, bgl, zgl, dgl, jgl, n, w)
Generate matrices for single element, 1D operators: a = Laplacian b = diagonal mass matrix c = convec...
subroutine, public fdm_do_fast_cpu(e, r, s, d, nl, ldim, nelv)
subroutine, public fdm_do_fast_device(e, r, s, d, nl, ldim, nelv, stream)
Fast Diagonalization SX-Aurora backend.
subroutine, public fdm_do_fast_sx(e, r, s, d, nl, ldim, nelv)
Fast Diagonalization libxsmm backend.
subroutine fdm_do_fast_xsmm(e, r, s, d, nl, ldim, nelv)
Type for the Fast Diagonalization connected with the schwarz overlapping solves.
subroutine swap_lengths(this, x, y, z, nelv, gdim)
subroutine fdm_setup_fast(this, ah, bh, nl, n)
Setup the arrays s, d needed for the fast evaluation of the system.
subroutine fdm_init(this, xh, dof, gs_h)
subroutine fdm_compute(this, e, r, stream)
subroutine fdm_free(this)
subroutine dp_sygv(a, b, lam, n, lx, bw, lbw)
subroutine generalev(a, b, lam, n, lx)
Solve the generalized eigenvalue problem /$ A x = lam B x/$ A – symm. B – symm., pos....
subroutine fdm_setup_fast1d(s, lam, nl, lbc, rbc, ll, lm, lr, ah, bh, n)
subroutine fdm_setup_fast1d_b(b, lbc, rbc, ll, lm, lr, bh, n)
subroutine plane_space(lr, ls, lt, i1, i2, w, x, y, z, nx, nxn, nz0, nzn, nelv, gdim)
Here, spacing is based on harmonic mean. pff 2/10/07 We no longer base this on the finest grid,...
subroutine fdm_setup_fast1d_a(a, lbc, rbc, ll, lm, lr, ah, n)
subroutine sp_sygv(a, b, lam, n, lx, bw, lbw)
subroutine, public row_zero(a, m, n, e)
Sets row e to 0 in matrix a.
subroutine, public rzero(a, n)
Zero a real vector.
real(kind=rp) function, public vlmax(vec, n)
maximum value of a vector of length n
integer, parameter neko_bcknd_sx
integer, parameter neko_bcknd_device
integer, parameter neko_bcknd_xsmm
integer, parameter, public qp
integer, parameter, public dp
integer, parameter, public sp
integer, parameter, public rp
Global precision used in computations.
Defines a function space.
subroutine, public trsp(a, lda, b, ldb)
Transpose of a rectangular tensor .
subroutine, public neko_warning(warning_msg)
Reports a warning to standard output.
The function space for the SEM solution fields.