Neko 1.99.7
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
coef.f90
Go to the documentation of this file.
1! Copyright (c) 2020-2026, The Neko Authors
2! All rights reserved.
3!
4! Redistribution and use in source and binary forms, with or without
5! modification, are permitted provided that the following conditions
6! are met:
7!
8! * Redistributions of source code must retain the above copyright
9! notice, this list of conditions and the following disclaimer.
10!
11! * Redistributions in binary form must reproduce the above
12! copyright notice, this list of conditions and the following
13! disclaimer in the documentation and/or other materials provided
14! with the distribution.
15!
16! * Neither the name of the authors nor the names of its
17! contributors may be used to endorse or promote products derived
18! from this software without specific prior written permission.
19!
20! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21! "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22! LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23! FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24! COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25! INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26! BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27! LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29! LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30! ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31! POSSIBILITY OF SUCH DAMAGE.
32!
34module coefs
35 use gather_scatter, only : gs_t
36 use gs_ops, only : gs_op_add
38 use num_types, only : rp
39 use dofmap, only : dofmap_t
40 use space, only : space_t
41 use math, only : rone, invcol1, addcol3, subcol3, copy, &
43 use mesh, only : mesh_t
49 use mxm_wrapper, only : mxm
54 use comm, only : neko_comm
56 use mpi_f08, only : mpi_allreduce, mpi_integer, mpi_sum
57 use, intrinsic :: iso_c_binding
58 implicit none
59 private
60
63 type, public :: coef_t
65 real(kind=rp), allocatable :: g11(:,:,:,:)
67 real(kind=rp), allocatable :: g22(:,:,:,:)
69 real(kind=rp), allocatable :: g33(:,:,:,:)
71 real(kind=rp), allocatable :: g12(:,:,:,:)
73 real(kind=rp), allocatable :: g13(:,:,:,:)
75 real(kind=rp), allocatable :: g23(:,:,:,:)
76
78 real(kind=rp), allocatable :: g11_compressed(:,:,:,:)
80 real(kind=rp), allocatable :: g22_compressed(:,:,:,:)
82 real(kind=rp), allocatable :: g33_compressed(:,:,:,:)
84 real(kind=rp), allocatable :: g12_compressed(:,:,:,:)
86 real(kind=rp), allocatable :: g13_compressed(:,:,:,:)
88 real(kind=rp), allocatable :: g23_compressed(:,:,:,:)
90 integer, allocatable :: compression_inds(:)
91
92 real(kind=rp), allocatable :: mult(:,:,:,:)
97 real(kind=rp), allocatable :: dxdr(:,:,:,:), dydr(:,:,:,:), dzdr(:,:,:,:)
98 real(kind=rp), allocatable :: dxds(:,:,:,:), dyds(:,:,:,:), dzds(:,:,:,:)
99 real(kind=rp), allocatable :: dxdt(:,:,:,:), dydt(:,:,:,:), dzdt(:,:,:,:)
103 real(kind=rp), allocatable :: drdx(:,:,:,:), drdy(:,:,:,:), drdz(:,:,:,:)
104 real(kind=rp), allocatable :: dsdx(:,:,:,:), dsdy(:,:,:,:), dsdz(:,:,:,:)
105 real(kind=rp), allocatable :: dtdx(:,:,:,:), dtdy(:,:,:,:), dtdz(:,:,:,:)
106
107 real(kind=rp), allocatable :: h1(:,:,:,:)
108 real(kind=rp), allocatable :: h2(:,:,:,:)
109 logical :: ifh2
110
111 real(kind=rp), allocatable :: jac(:,:,:,:)
112 real(kind=rp), allocatable :: jacinv(:,:,:,:)
113 real(kind=rp), allocatable :: b(:,:,:,:)
114 real(kind=rp), allocatable :: binv(:,:,:,:)
115 real(kind=rp), pointer :: blag(:,:,:,:) => null()
116 real(kind=rp), pointer :: blaglag(:,:,:,:) => null()
117 real(kind=rp), allocatable :: area(:,:,:,:)
118 real(kind=rp), allocatable :: nx(:,:,:,:)
119 real(kind=rp), allocatable :: ny(:,:,:,:)
120 real(kind=rp), allocatable :: nz(:,:,:,:)
121 logical :: cyclic = .false.
122 integer, allocatable :: cyc_msk(:)
123 real(kind=rp), allocatable :: r11(:)
124 real(kind=rp), allocatable :: r12(:)
125
126 !! True if geometric metrics have been initialized
127 logical, private :: coef_metrics_initialized = .false.
128
130
131 real(kind=rp) :: volume
132
133 type(space_t), pointer :: xh => null()
134 type(mesh_t), pointer :: msh => null()
135 type(dofmap_t), pointer :: dof => null()
136 type(gs_t), pointer :: gs_h=> null()
137
138 !
139 ! Device pointers (if present)
140 !
141
142 type(c_ptr) :: g11_d = c_null_ptr
143 type(c_ptr) :: g22_d = c_null_ptr
144 type(c_ptr) :: g33_d = c_null_ptr
145 type(c_ptr) :: g12_d = c_null_ptr
146 type(c_ptr) :: g13_d = c_null_ptr
147 type(c_ptr) :: g23_d = c_null_ptr
148 type(c_ptr) :: dxdr_d = c_null_ptr
149 type(c_ptr) :: dydr_d = c_null_ptr
150 type(c_ptr) :: dzdr_d = c_null_ptr
151 type(c_ptr) :: dxds_d = c_null_ptr
152 type(c_ptr) :: dyds_d = c_null_ptr
153 type(c_ptr) :: dzds_d = c_null_ptr
154 type(c_ptr) :: dxdt_d = c_null_ptr
155 type(c_ptr) :: dydt_d = c_null_ptr
156 type(c_ptr) :: dzdt_d = c_null_ptr
157 type(c_ptr) :: drdx_d = c_null_ptr
158 type(c_ptr) :: drdy_d = c_null_ptr
159 type(c_ptr) :: drdz_d = c_null_ptr
160 type(c_ptr) :: dsdx_d = c_null_ptr
161 type(c_ptr) :: dsdy_d = c_null_ptr
162 type(c_ptr) :: dsdz_d = c_null_ptr
163 type(c_ptr) :: dtdx_d = c_null_ptr
164 type(c_ptr) :: dtdy_d = c_null_ptr
165 type(c_ptr) :: dtdz_d = c_null_ptr
166 type(c_ptr) :: mult_d = c_null_ptr
167 type(c_ptr) :: h1_d = c_null_ptr
168 type(c_ptr) :: h2_d = c_null_ptr
169 type(c_ptr) :: jac_d = c_null_ptr
170 type(c_ptr) :: jacinv_d = c_null_ptr
171 type(c_ptr) :: b_d = c_null_ptr
172 type(c_ptr) :: blag_d = c_null_ptr
173 type(c_ptr) :: blaglag_d = c_null_ptr
174 type(c_ptr) :: binv_d = c_null_ptr
175 type(c_ptr) :: area_d = c_null_ptr
176 type(c_ptr) :: nx_d = c_null_ptr
177 type(c_ptr) :: ny_d = c_null_ptr
178 type(c_ptr) :: nz_d = c_null_ptr
179 type(c_ptr) :: cyc_msk_d = c_null_ptr
180 type(c_ptr) :: r11_d = c_null_ptr
181 type(c_ptr) :: r12_d = c_null_ptr
182
184 integer :: metrics_version = 0
185
186 contains
187 procedure, private, pass(this) :: init_empty => coef_init_empty
188 procedure, private, pass(this) :: init_all => coef_init_all
189 procedure, pass(this) :: free => coef_free
190 procedure, pass(this) :: get_normal => coef_get_normal
191 procedure, pass(this) :: get_area => coef_get_area
192 procedure, pass(this) :: generate_cyclic_bc => coef_generate_cyclic_bc
193 procedure, pass(this) :: recompute_metrics => coef_recompute_metrics
194 procedure, pass(this) :: enable_b_history => coef_enable_lagged_mass
195 procedure, pass(this) :: update_b_history => coef_update_lagged_mass
196 generic :: init => init_empty, init_all
197 end type coef_t
198
199contains
200
202 subroutine coef_init_empty(this, Xh, msh)
203 class(coef_t), intent(inout) :: this
204 type(space_t), intent(inout), target :: Xh
205 type(mesh_t), intent(inout), target :: msh
206 integer :: n
207 call this%free()
208 this%msh => msh
209 this%Xh => xh
210
211 allocate(this%drdx(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
212 allocate(this%dsdx(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
213 allocate(this%dtdx(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
214
215 allocate(this%drdy(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
216 allocate(this%dsdy(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
217 allocate(this%dtdy(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
218
219 allocate(this%drdz(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
220 allocate(this%dsdz(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
221 allocate(this%dtdz(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
222
223
224 !
225 ! Setup device memory (if present)
226 !
227
228 n = this%Xh%lx * this%Xh%ly * this%Xh%lz * this%msh%nelv
229 if (neko_bcknd_device .eq. 1) then
230
231 call device_map(this%drdx, this%drdx_d, n)
232 call device_map(this%drdy, this%drdy_d, n)
233 call device_map(this%drdz, this%drdz_d, n)
234
235 call device_map(this%dsdx, this%dsdx_d, n)
236 call device_map(this%dsdy, this%dsdy_d, n)
237 call device_map(this%dsdz, this%dsdz_d, n)
238
239 call device_map(this%dtdx, this%dtdx_d, n)
240 call device_map(this%dtdy, this%dtdy_d, n)
241 call device_map(this%dtdz, this%dtdz_d, n)
242
243 end if
244
245 end subroutine coef_init_empty
246
248 subroutine coef_init_all(this, gs_h)
249 class(coef_t), intent(inout), target :: this
250 type(gs_t), intent(inout), target :: gs_h
251 integer :: n, m, ncyc
252 call this%free()
253
254 this%msh => gs_h%dofmap%msh
255 this%Xh => gs_h%dofmap%Xh
256 this%dof => gs_h%dofmap
257 this%gs_h => gs_h
258
259 !
260 ! Allocate arrays for geometric data
261 !
263 allocate(this%G11(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
264 allocate(this%G22(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
265 allocate(this%G33(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
266 allocate(this%G12(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
267 allocate(this%G13(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
268 allocate(this%G23(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
269
270 allocate(this%dxdr(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
271 allocate(this%dxds(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
272 allocate(this%dxdt(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
273
274 allocate(this%dydr(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
275 allocate(this%dyds(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
276 allocate(this%dydt(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
277
278 allocate(this%dzdr(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
279 allocate(this%dzds(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
280 allocate(this%dzdt(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
281
282 allocate(this%drdx(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
283 allocate(this%dsdx(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
284 allocate(this%dtdx(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
285
286 allocate(this%drdy(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
287 allocate(this%dsdy(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
288 allocate(this%dtdy(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
289
290 allocate(this%drdz(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
291 allocate(this%dsdz(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
292 allocate(this%dtdz(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
293
294 allocate(this%jac(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
295 allocate(this%jacinv(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
296
297 allocate(this%area(this%Xh%lx, this%Xh%ly, 6, this%msh%nelv))
298 allocate(this%nx(this%Xh%lx, this%Xh%ly, 6, this%msh%nelv))
299 allocate(this%ny(this%Xh%lx, this%Xh%ly, 6, this%msh%nelv))
300 allocate(this%nz(this%Xh%lx, this%Xh%ly, 6, this%msh%nelv))
301
302 allocate(this%B(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
303 allocate(this%Binv(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
304
305 ! We do this so in a static simulation we don't allocate extra memory
306 this%Blag => this%B
307 this%Blaglag => this%B
308
309 allocate(this%h1(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
310 allocate(this%h2(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
311
312 allocate(this%mult(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
313
314
315 !
316 ! Setup device memory (if present)
317 !
318
319 n = this%Xh%lx * this%Xh%ly * this%Xh%lz * this%msh%nelv
320 if (neko_bcknd_device .eq. 1) then
321 call device_map(this%G11, this%G11_d, n)
322 call device_map(this%G22, this%G22_d, n)
323 call device_map(this%G33, this%G33_d, n)
324 call device_map(this%G12, this%G12_d, n)
325 call device_map(this%G13, this%G13_d, n)
326 call device_map(this%G23, this%G23_d, n)
327
328 call device_map(this%dxdr, this%dxdr_d, n)
329 call device_map(this%dydr, this%dydr_d, n)
330 call device_map(this%dzdr, this%dzdr_d, n)
331
332 call device_map(this%dxds, this%dxds_d, n)
333 call device_map(this%dyds, this%dyds_d, n)
334 call device_map(this%dzds, this%dzds_d, n)
335
336 call device_map(this%dxdt, this%dxdt_d, n)
337 call device_map(this%dydt, this%dydt_d, n)
338 call device_map(this%dzdt, this%dzdt_d, n)
339
340 call device_map(this%drdx, this%drdx_d, n)
341 call device_map(this%drdy, this%drdy_d, n)
342 call device_map(this%drdz, this%drdz_d, n)
343
344 call device_map(this%dsdx, this%dsdx_d, n)
345 call device_map(this%dsdy, this%dsdy_d, n)
346 call device_map(this%dsdz, this%dsdz_d, n)
347
348 call device_map(this%dtdx, this%dtdx_d, n)
349 call device_map(this%dtdy, this%dtdy_d, n)
350 call device_map(this%dtdz, this%dtdz_d, n)
351
352 call device_map(this%mult, this%mult_d, n)
353 call device_map(this%h1, this%h1_d, n)
354 call device_map(this%h2, this%h2_d, n)
355
356 call device_map(this%jac, this%jac_d, n)
357 call device_map(this%jacinv, this%jacinv_d, n)
358 call device_map(this%B, this%B_d, n)
359 call device_map(this%Binv, this%Binv_d, n)
360
361 this%Blag_d = this%B_d
362 this%Blaglag_d = this%B_d
363
364 m = this%Xh%lx * this%Xh%ly * 6 * this%msh%nelv
365
366 call device_map(this%area, this%area_d, m)
367 call device_map(this%nx, this%nx_d, m)
368 call device_map(this%ny, this%ny_d, m)
369 call device_map(this%nz, this%nz_d, m)
370
371 end if
372
373 call coef_generate_dxyzdrst(this)
374
375 call coef_generate_geo(this)
376
377 ! call coef_generate_geo_compressed(this)
378
380
381 call coef_generate_mass(this)
382
383 this%coef_metrics_initialized = .true.
384
385
386 ! This is a placeholder, just for now
387 ! We can probably find a prettier solution
388 if (neko_bcknd_device .eq. 1) then
389 call device_rone(this%h1_d, n)
390 call device_rone(this%h2_d, n)
391 call device_memcpy(this%h1, this%h1_d, n, &
392 device_to_host, sync = .false.)
393 call device_memcpy(this%h2, this%h2_d, n, &
394 device_to_host, sync = .false.)
395 else
396 call rone(this%h1,n)
397 call rone(this%h2,n)
398 end if
399
400 this%ifh2 = .false.
401
402 !
403 ! Set up multiplicity
404 !
405 if (neko_bcknd_device .eq. 1) then
406 call device_rone(this%mult_d, n)
407 else
408 call rone(this%mult, n)
409 end if
410
411 call gs_h%op(this%mult, n, gs_op_add)
412
413 if (neko_bcknd_device .eq. 1) then
414 call device_invcol1(this%mult_d, n)
415 call device_memcpy(this%mult, this%mult_d, n, &
416 device_to_host, sync = .true.)
417 else
418 call invcol1(this%mult, n)
419 end if
420
421 ncyc = this%msh%periodic%size * this%Xh%lx * this%Xh%lx
422 allocate(this%cyc_msk(0:ncyc))
423 this%cyc_msk(0) = ncyc + 1
424 if (ncyc .gt. 0) then
425 allocate(this%R11(ncyc))
426 allocate(this%R12(ncyc))
427
429 call rone(this%R11, ncyc)
430 call rzero(this%R12, ncyc)
431
432 if (neko_bcknd_device .eq. 1) then
433 call device_map(this%cyc_msk, this%cyc_msk_d, ncyc+1)
434 call device_map(this%R11, this%R11_d, ncyc)
435 call device_map(this%R12, this%R12_d, ncyc)
436
437 call device_memcpy(this%cyc_msk, this%cyc_msk_d, ncyc+1, &
438 host_to_device, sync = .false.)
439 call device_memcpy(this%R11, this%R11_d, ncyc, &
440 host_to_device, sync = .false.)
441 call device_memcpy(this%R12, this%R12_d, ncyc, &
442 host_to_device, sync = .false.)
443 end if
444
445 end if
446 end subroutine coef_init_all
447
449 subroutine coef_free(this)
450 class(coef_t), intent(inout), target :: this
451
452 if (allocated(this%G11)) then
453 if (neko_bcknd_device .eq. 1) call device_unmap(this%G11, this%G11_d)
454 deallocate(this%G11)
455 end if
456
457 if (allocated(this%G22)) then
458 if (neko_bcknd_device .eq. 1) call device_unmap(this%G22, this%G22_d)
459 deallocate(this%G22)
460 end if
461
462 if (allocated(this%G33)) then
463 if (neko_bcknd_device .eq. 1) call device_unmap(this%G33, this%G33_d)
464 deallocate(this%G33)
465 end if
466
467 if (allocated(this%G12)) then
468 if (neko_bcknd_device .eq. 1) call device_unmap(this%G12, this%G12_d)
469 deallocate(this%G12)
470 end if
471
472 if (allocated(this%G13)) then
473 if (neko_bcknd_device .eq. 1) call device_unmap(this%G13, this%G13_d)
474 deallocate(this%G13)
475 end if
476
477 if (allocated(this%G23)) then
478 if (neko_bcknd_device .eq. 1) call device_unmap(this%G23, this%G23_d)
479 deallocate(this%G23)
480 end if
481
482 if (allocated(this%G11_compressed)) then
483 deallocate(this%G11_compressed)
484 end if
485
486 if (allocated(this%compression_inds)) then
487 deallocate(this%compression_inds)
488 end if
489
490 if (allocated(this%G22_compressed)) then
491 deallocate(this%G22_compressed)
492 end if
493
494 if (allocated(this%G33_compressed)) then
495 deallocate(this%G33_compressed)
496 end if
497
498 if (allocated(this%G12_compressed)) then
499 deallocate(this%G12_compressed)
500 end if
501
502 if (allocated(this%G13_compressed)) then
503 deallocate(this%G13_compressed)
504 end if
505
506 if (allocated(this%G23_compressed)) then
507 deallocate(this%G23_compressed)
508 end if
509
510 if (allocated(this%mult)) then
511 if (neko_bcknd_device .eq. 1) call device_unmap(this%mult, this%mult_d)
512 deallocate(this%mult)
513 end if
514
515 if (associated(this%Blag) .and. &
516 .not. associated(this%Blag, this%B)) then
517 if (c_associated(this%Blag_d) .and. &
518 .not. c_associated(this%Blag_d, this%B_d)) then
519 call device_unmap(this%Blag, this%Blag_d)
520 end if
521 deallocate(this%Blag)
522 end if
523 nullify(this%Blag)
524
525 if (associated(this%Blaglag) .and. &
526 .not. associated(this%Blaglag, this%B)) then
527 if (c_associated(this%Blaglag_d) .and. &
528 .not. c_associated(this%Blaglag_d, this%B_d)) then
529 call device_unmap(this%Blaglag, this%Blaglag_d)
530 end if
531 deallocate(this%Blaglag)
532 end if
533 nullify(this%Blaglag)
534
535 if (c_associated(this%Blag_d) .and. &
536 .not. c_associated(this%Blag_d, this%B_d)) then
537 this%Blag_d = c_null_ptr
538 end if
539 this%Blag_d = c_null_ptr
540
541 if (c_associated(this%Blaglag_d) .and. &
542 .not. c_associated(this%Blaglag_d, this%B_d)) then
543 this%Blaglag_d = c_null_ptr
544 end if
545 this%Blaglag_d = c_null_ptr
546
547 if (allocated(this%B)) then
548 if (neko_bcknd_device .eq. 1) call device_unmap(this%B, this%B_d)
549 deallocate(this%B)
550 end if
551
552 if (allocated(this%Binv)) then
553 if (neko_bcknd_device .eq. 1) call device_unmap(this%Binv, this%Binv_d)
554 deallocate(this%Binv)
555 end if
556
557 if (allocated(this%dxdr)) then
558 if (neko_bcknd_device .eq. 1) call device_unmap(this%dxdr, this%dxdr_d)
559 deallocate(this%dxdr)
560 end if
561
562 if (allocated(this%dxds)) then
563 if (neko_bcknd_device .eq. 1) call device_unmap(this%dxds, this%dxds_d)
564 deallocate(this%dxds)
565 end if
566
567 if (allocated(this%dxdt)) then
568 if (neko_bcknd_device .eq. 1) call device_unmap(this%dxdt, this%dxdt_d)
569 deallocate(this%dxdt)
570 end if
571
572 if (allocated(this%dydr)) then
573 if (neko_bcknd_device .eq. 1) call device_unmap(this%dydr, this%dydr_d)
574 deallocate(this%dydr)
575 end if
576
577 if (allocated(this%dyds)) then
578 if (neko_bcknd_device .eq. 1) call device_unmap(this%dyds, this%dyds_d)
579 deallocate(this%dyds)
580 end if
581
582 if (allocated(this%dydt)) then
583 if (neko_bcknd_device .eq. 1) call device_unmap(this%dydt, this%dydt_d)
584 deallocate(this%dydt)
585 end if
586
587 if (allocated(this%dzdr)) then
588 if (neko_bcknd_device .eq. 1) call device_unmap(this%dzdr, this%dzdr_d)
589 deallocate(this%dzdr)
590 end if
591
592 if (allocated(this%dzds)) then
593 if (neko_bcknd_device .eq. 1) call device_unmap(this%dzds, this%dzds_d)
594 deallocate(this%dzds)
595 end if
596
597 if (allocated(this%dzdt)) then
598 if (neko_bcknd_device .eq. 1) call device_unmap(this%dzdt, this%dzdt_d)
599 deallocate(this%dzdt)
600 end if
601
602 if (allocated(this%drdx)) then
603 if (neko_bcknd_device .eq. 1) call device_unmap(this%drdx, this%drdx_d)
604 deallocate(this%drdx)
605 end if
606
607 if (allocated(this%dsdx)) then
608 if (neko_bcknd_device .eq. 1) call device_unmap(this%dsdx, this%dsdx_d)
609 deallocate(this%dsdx)
610 end if
611
612 if (allocated(this%dtdx)) then
613 if (neko_bcknd_device .eq. 1) call device_unmap(this%dtdx, this%dtdx_d)
614 deallocate(this%dtdx)
615 end if
616
617 if (allocated(this%drdy)) then
618 if (neko_bcknd_device .eq. 1) call device_unmap(this%drdy, this%drdy_d)
619 deallocate(this%drdy)
620 end if
621
622 if (allocated(this%dsdy)) then
623 if (neko_bcknd_device .eq. 1) call device_unmap(this%dsdy, this%dsdy_d)
624 deallocate(this%dsdy)
625 end if
626
627 if (allocated(this%dtdy)) then
628 if (neko_bcknd_device .eq. 1) call device_unmap(this%dtdy, this%dtdy_d)
629 deallocate(this%dtdy)
630 end if
631
632 if (allocated(this%drdz)) then
633 if (neko_bcknd_device .eq. 1) call device_unmap(this%drdz, this%drdz_d)
634 deallocate(this%drdz)
635 end if
636
637 if (allocated(this%dsdz)) then
638 if (neko_bcknd_device .eq. 1) call device_unmap(this%dsdz, this%dsdz_d)
639 deallocate(this%dsdz)
640 end if
641
642 if (allocated(this%dtdz)) then
643 if (neko_bcknd_device .eq. 1) call device_unmap(this%dtdz, this%dtdz_d)
644 deallocate(this%dtdz)
645 end if
646
647 if (allocated(this%jac)) then
648 if (neko_bcknd_device .eq. 1) call device_unmap(this%jac, this%jac_d)
649 deallocate(this%jac)
650 end if
651
652 if (allocated(this%jacinv)) then
653 if (neko_bcknd_device .eq. 1) then
654 call device_unmap(this%jacinv, this%jacinv_d)
655 end if
656 deallocate(this%jacinv)
657 end if
658
659 if (allocated(this%h1)) then
660 if (neko_bcknd_device .eq. 1) call device_unmap(this%h1, this%h1_d)
661 deallocate(this%h1)
662 end if
663
664 if (allocated(this%h2)) then
665 if (neko_bcknd_device .eq. 1) call device_unmap(this%h2, this%h2_d)
666 deallocate(this%h2)
667 end if
668
669 if (allocated(this%area)) then
670 if (neko_bcknd_device .eq. 1) call device_unmap(this%area, this%area_d)
671 deallocate(this%area)
672 end if
673
674 if (allocated(this%nx)) then
675 if (neko_bcknd_device .eq. 1) call device_unmap(this%nx, this%nx_d)
676 deallocate(this%nx)
677 end if
678
679 if (allocated(this%ny)) then
680 if (neko_bcknd_device .eq. 1) call device_unmap(this%ny, this%ny_d)
681 deallocate(this%ny)
682 end if
683
684 if (allocated(this%nz)) then
685 if (neko_bcknd_device .eq. 1) call device_unmap(this%nz, this%nz_d)
686 deallocate(this%nz)
687 end if
688
689 if (allocated(this%cyc_msk)) then
690 if (neko_bcknd_device .eq. 1) then
691 call device_unmap(this%cyc_msk, this%cyc_msk_d)
692 end if
693 deallocate(this%cyc_msk)
694 end if
695
696 if (allocated(this%R11)) then
697 if (neko_bcknd_device .eq. 1) call device_unmap(this%R11, this%R11_d)
698 deallocate(this%R11)
699 end if
700
701 if (allocated(this%R12)) then
702 if (neko_bcknd_device .eq. 1) call device_unmap(this%R12, this%R12_d)
703 deallocate(this%R12)
704 end if
705
706
707 nullify(this%msh)
708 nullify(this%Xh)
709 nullify(this%dof)
710 nullify(this%gs_h)
711
712 end subroutine coef_free
713
715 type(coef_t), intent(inout) :: c
716 integer :: e, i, lxy, lyz, ntot
717
718 lxy = c%Xh%lx*c%Xh%ly
719 lyz = c%Xh%ly*c%Xh%lz
720 ntot = c%dof%size()
721
722 associate(drdx => c%drdx, drdy => c%drdy, drdz => c%drdz, &
723 dsdx => c%dsdx, dsdy => c%dsdy, dsdz => c%dsdz, &
724 dtdx => c%dtdx, dtdy => c%dtdy, dtdz => c%dtdz, &
725 dxdr => c%dxdr, dydr => c%dydr, dzdr => c%dzdr, &
726 dxds => c%dxds, dyds => c%dyds, dzds => c%dzds, &
727 dxdt => c%dxdt, dydt => c%dydt, dzdt => c%dzdt, &
728 dx => c%Xh%dx, dy => c%Xh%dy, dz => c%Xh%dz, &
729 x => c%dof%x, y => c%dof%y, z => c%dof%z, &
730 lx => c%Xh%lx, ly => c%Xh%ly, lz => c%Xh%lz, &
731 dyt => c%Xh%dyt, dzt => c%Xh%dzt, &
732 jacinv => c%jacinv, jac => c%jac)
733
734 if (neko_bcknd_device .eq. 1) then
735
736 call device_coef_generate_dxydrst(c%drdx_d, c%drdy_d, c%drdz_d, &
737 c%dsdx_d, c%dsdy_d, c%dsdz_d, c%dtdx_d, c%dtdy_d, c%dtdz_d, &
738 c%dxdr_d, c%dydr_d, c%dzdr_d, c%dxds_d, c%dyds_d, c%dzds_d, &
739 c%dxdt_d, c%dydt_d, c%dzdt_d, c%Xh%dx_d, c%Xh%dy_d, c%Xh%dz_d, &
740 c%dof%x_d, c%dof%y_d, c%dof%z_d, c%jacinv_d, c%jac_d, &
741 c%Xh%lx, c%msh%nelv)
742
743 ! copy to host only at initialization.
744 if (.not. c%coef_metrics_initialized) then
745 call device_memcpy(dxdr, c%dxdr_d, ntot, device_to_host, &
746 sync = .false.)
747 call device_memcpy(dydr, c%dydr_d, ntot, device_to_host, &
748 sync = .false.)
749 call device_memcpy(dzdr, c%dzdr_d, ntot, device_to_host, &
750 sync = .false.)
751 call device_memcpy(dxds, c%dxds_d, ntot, device_to_host, &
752 sync = .false.)
753 call device_memcpy(dyds, c%dyds_d, ntot, device_to_host, &
754 sync = .false.)
755 call device_memcpy(dzds, c%dzds_d, ntot, device_to_host, &
756 sync = .false.)
757 call device_memcpy(dxdt, c%dxdt_d, ntot, device_to_host, &
758 sync = .false.)
759 call device_memcpy(dydt, c%dydt_d, ntot, device_to_host, &
760 sync = .false.)
761 call device_memcpy(dzdt, c%dzdt_d, ntot, device_to_host, &
762 sync = .false.)
763 call device_memcpy(drdx, c%drdx_d, ntot, device_to_host, &
764 sync = .false.)
765 call device_memcpy(drdy, c%drdy_d, ntot, device_to_host, &
766 sync = .false.)
767 call device_memcpy(drdz, c%drdz_d, ntot, device_to_host, &
768 sync = .false.)
769 call device_memcpy(dsdx, c%dsdx_d, ntot, device_to_host, &
770 sync = .false.)
771 call device_memcpy(dsdy, c%dsdy_d, ntot, device_to_host, &
772 sync = .false.)
773 call device_memcpy(dsdz, c%dsdz_d, ntot, device_to_host, &
774 sync = .false.)
775 call device_memcpy(dtdx, c%dtdx_d, ntot, device_to_host, &
776 sync = .false.)
777 call device_memcpy(dtdy, c%dtdy_d, ntot, device_to_host, &
778 sync = .false.)
779 call device_memcpy(dtdz, c%dtdz_d, ntot, device_to_host, &
780 sync = .false.)
781 call device_memcpy(jac, c%jac_d, ntot, device_to_host, &
782 sync = .false.)
783 call device_memcpy(jacinv, c%jacinv_d, ntot, device_to_host, &
784 sync = .true.)
785 end if
786
787 else
788 !$omp parallel do private(i)
789 do e = 1, c%msh%nelv
790 call mxm(dx, lx, x(1,1,1,e), lx, dxdr(1,1,1,e), lyz)
791 call mxm(dx, lx, y(1,1,1,e), lx, dydr(1,1,1,e), lyz)
792 call mxm(dx, lx, z(1,1,1,e), lx, dzdr(1,1,1,e), lyz)
793
794 do i = 1, lz
795 call mxm(x(1,1,i,e), lx, dyt, ly, dxds(1,1,i,e), ly)
796 call mxm(y(1,1,i,e), lx, dyt, ly, dyds(1,1,i,e), ly)
797 call mxm(z(1,1,i,e), lx, dyt, ly, dzds(1,1,i,e), ly)
798 end do
799
800 ! We actually take 2d into account, wow, need to do that for the rest.
801 if (c%msh%gdim .eq. 3) then
802 call mxm(x(1,1,1,e), lxy, dzt, lz, dxdt(1,1,1,e), lz)
803 call mxm(y(1,1,1,e), lxy, dzt, lz, dydt(1,1,1,e), lz)
804 call mxm(z(1,1,1,e), lxy, dzt, lz, dzdt(1,1,1,e), lz)
805 else
806 call rzero(dxdt(1,1,1,e), lxy)
807 call rzero(dydt(1,1,1,e), lxy)
808 call rone(dzdt(1,1,1,e), lxy)
809 end if
810 end do
811 !$omp end parallel do
812
813 if (c%msh%gdim .eq. 2) then
814 call rzero (jac, ntot)
815 call addcol3 (jac, dxdr, dyds, ntot)
816 call subcol3 (jac, dxds, dydr, ntot)
817 call copy (drdx, dyds, ntot)
818 call copy (drdy, dxds, ntot)
819 call chsign (drdy, ntot)
820 call copy (dsdx, dydr, ntot)
821 call chsign (dsdx, ntot)
822 call copy (dsdy, dxdr, ntot)
823 call rzero (drdz, ntot)
824 call rzero (dsdz, ntot)
825 call rone (dtdz, ntot)
826 else
827 !$omp parallel private(i)
828 !$omp do simd
829 do i = 1, ntot
830 c%jac(i, 1, 1, 1) = 0.0_rp
831 end do
832 !$omp end do simd
833 !$omp do simd
834 do i = 1, ntot
835 c%jac(i, 1, 1, 1) = c%jac(i, 1, 1, 1) + ( c%dxdr(i, 1, 1, 1) &
836 * c%dyds(i, 1, 1, 1) * c%dzdt(i, 1, 1, 1) )
837
838 c%jac(i, 1, 1, 1) = c%jac(i, 1, 1, 1) + ( c%dxdt(i, 1, 1, 1) &
839 * c%dydr(i, 1, 1, 1) * c%dzds(i, 1, 1, 1) )
840
841 c%jac(i, 1, 1, 1) = c%jac(i, 1, 1, 1) + ( c%dxds(i, 1, 1, 1) &
842 * c%dydt(i, 1, 1, 1) * c%dzdr(i, 1, 1, 1) )
843 end do
844 !$omp end do simd
845 !$omp do simd
846 do i = 1, ntot
847 c%jac(i, 1, 1, 1) = c%jac(i, 1, 1, 1) - ( c%dxdr(i, 1, 1, 1) &
848 * c%dydt(i, 1, 1, 1) * c%dzds(i, 1, 1, 1) )
849
850 c%jac(i, 1, 1, 1) = c%jac(i, 1, 1, 1) - ( c%dxds(i, 1, 1, 1) &
851 * c%dydr(i, 1, 1, 1) * c%dzdt(i, 1, 1, 1) )
852
853 c%jac(i, 1, 1, 1) = c%jac(i, 1, 1, 1) - ( c%dxdt(i, 1, 1, 1) &
854 * c%dyds(i, 1, 1, 1) * c%dzdr(i, 1, 1, 1) )
855 end do
856 !$omp end do simd
857 !$omp do simd
858 do i = 1, ntot
859 c%drdx(i, 1, 1, 1) = c%dyds(i, 1, 1, 1) * c%dzdt(i, 1, 1, 1) &
860 - c%dydt(i, 1, 1, 1) * c%dzds(i, 1, 1, 1)
861
862 c%drdy(i, 1, 1, 1) = c%dxdt(i, 1, 1, 1) * c%dzds(i, 1, 1, 1) &
863 - c%dxds(i, 1, 1, 1) * c%dzdt(i, 1, 1, 1)
864
865 c%drdz(i, 1, 1, 1) = c%dxds(i, 1, 1, 1) * c%dydt(i, 1, 1, 1) &
866 - c%dxdt(i, 1, 1, 1) * c%dyds(i, 1, 1, 1)
867 end do
868 !$omp end do simd
869 !$omp do simd
870 do i = 1, ntot
871 c%dsdx(i, 1, 1, 1) = c%dydt(i, 1, 1, 1) * c%dzdr(i, 1, 1, 1) &
872 - c%dydr(i, 1, 1, 1) * c%dzdt(i, 1, 1, 1)
873
874 c%dsdy(i, 1, 1, 1) = c%dxdr(i, 1, 1, 1) * c%dzdt(i, 1, 1, 1) &
875 - c%dxdt(i, 1, 1, 1) * c%dzdr(i, 1, 1, 1)
876
877 c%dsdz(i, 1, 1, 1) = c%dxdt(i, 1, 1, 1) * c%dydr(i, 1, 1, 1) &
878 - c%dxdr(i, 1, 1, 1) * c%dydt(i, 1, 1, 1)
879 end do
880 !$omp end do simd
881 !$omp do simd
882 do i = 1, ntot
883 c%dtdx(i, 1, 1, 1) = c%dydr(i, 1, 1, 1) * c%dzds(i, 1, 1, 1) &
884 - c%dyds(i, 1, 1, 1) * c%dzdr(i, 1, 1, 1)
885
886 c%dtdy(i, 1, 1, 1) = c%dxds(i, 1, 1, 1) * c%dzdr(i, 1, 1, 1) &
887 - c%dxdr(i, 1, 1, 1) * c%dzds(i, 1, 1, 1)
888
889 c%dtdz(i, 1, 1, 1) = c%dxdr(i, 1, 1, 1) * c%dyds(i, 1, 1, 1) &
890 - c%dxds(i, 1, 1, 1) * c%dydr(i, 1, 1, 1)
891 end do
892 !$omp end do simd
893 !$omp end parallel
894 end if
895 call invers2(jacinv, jac, ntot)
896 end if
897 end associate
898
899 end subroutine coef_generate_dxyzdrst
900
903 subroutine coef_generate_geo(c)
904 type(coef_t), intent(inout) :: c
905 integer :: e, i, lxyz, ntot
906
907 lxyz = c%Xh%lx * c%Xh%ly * c%Xh%lz
908 ntot = c%dof%size()
909
910 if (neko_bcknd_device .eq. 1) then
911
912 call device_coef_generate_geo(c%G11_d, c%G12_d, c%G13_d, &
913 c%G22_d, c%G23_d, c%G33_d, &
914 c%drdx_d, c%drdy_d, c%drdz_d, &
915 c%dsdx_d, c%dsdy_d, c%dsdz_d, &
916 c%dtdx_d, c%dtdy_d, c%dtdz_d, &
917 c%jacinv_d, c%Xh%w3_d, c%msh%nelv, &
918 c%Xh%lx, c%msh%gdim)
919
920 ! copy to host only at initialization.
921 if (.not. c%coef_metrics_initialized) then
922 call device_memcpy(c%G11, c%G11_d, ntot, device_to_host, &
923 sync = .false.)
924 call device_memcpy(c%G22, c%G22_d, ntot, device_to_host, &
925 sync = .false.)
926 call device_memcpy(c%G33, c%G33_d, ntot, device_to_host, &
927 sync = .false.)
928 call device_memcpy(c%G12, c%G12_d, ntot, device_to_host, &
929 sync = .false.)
930 call device_memcpy(c%G13, c%G13_d, ntot, device_to_host, &
931 sync = .false.)
932 call device_memcpy(c%G23, c%G23_d, ntot, device_to_host, &
933 sync = .true.)
934 end if
935
936 else
937 if (c%msh%gdim .eq. 2) then
938
939 do i = 1, ntot
940 c%G11(i, 1, 1, 1) = c%drdx(i, 1, 1, 1) * c%drdx(i, 1, 1, 1) &
941 + c%drdy(i, 1, 1, 1) * c%drdy(i, 1, 1, 1)
942
943 c%G22(i, 1, 1, 1) = c%dsdx(i, 1, 1, 1) * c%dsdx(i, 1, 1, 1) &
944 + c%dsdy(i, 1, 1, 1) * c%dsdy(i, 1, 1, 1)
945
946 c%G12(i, 1, 1, 1) = c%drdx(i, 1, 1, 1) * c%dsdx(i, 1, 1, 1) &
947 + c%drdy(i, 1, 1, 1) * c%dsdy(i, 1, 1, 1)
948 end do
949
950 do i = 1, ntot
951 c%G11(i, 1, 1, 1) = c%G11(i, 1, 1, 1) * c%jacinv(i, 1, 1, 1)
952 c%G22(i, 1, 1, 1) = c%G22(i, 1, 1, 1) * c%jacinv(i, 1, 1, 1)
953 c%G12(i, 1, 1, 1) = c%G12(i, 1, 1, 1) * c%jacinv(i, 1, 1, 1)
954 c%G33(i, 1, 1, 1) = 0.0_rp
955 c%G13(i, 1, 1, 1) = 0.0_rp
956 c%G23(i, 1, 1, 1) = 0.0_rp
957 end do
958
959 do concurrent(e = 1:c%msh%nelv)
960 do concurrent(i = 1:lxyz)
961 c%G11(i,1,1,e) = c%G11(i,1,1,e) * c%Xh%w3(i,1,1)
962 c%G22(i,1,1,e) = c%G22(i,1,1,e) * c%Xh%w3(i,1,1)
963 c%G12(i,1,1,e) = c%G12(i,1,1,e) * c%Xh%w3(i,1,1)
964 end do
965 end do
966
967 else
968 !$omp parallel private(i)
969 !$omp do
970 do i = 1, ntot
971 c%G11(i, 1, 1, 1) = c%drdx(i, 1, 1, 1) * c%drdx(i, 1, 1, 1) &
972 + c%drdy(i, 1, 1, 1) * c%drdy(i, 1, 1, 1) &
973 + c%drdz(i, 1, 1, 1) * c%drdz(i, 1, 1, 1)
974
975 c%G22(i, 1, 1, 1) = c%dsdx(i, 1, 1, 1) * c%dsdx(i, 1, 1, 1) &
976 + c%dsdy(i, 1, 1, 1) * c%dsdy(i, 1, 1, 1) &
977 + c%dsdz(i, 1, 1, 1) * c%dsdz(i, 1, 1, 1)
978
979 c%G33(i, 1, 1, 1) = c%dtdx(i, 1, 1, 1) * c%dtdx(i, 1, 1, 1) &
980 + c%dtdy(i, 1, 1, 1) * c%dtdy(i, 1, 1, 1) &
981 + c%dtdz(i, 1, 1, 1) * c%dtdz(i, 1, 1, 1)
982 end do
983 !$omp end do
984 !$omp do
985 do i = 1, ntot
986 c%G11(i, 1, 1, 1) = c%G11(i, 1, 1, 1) * c%jacinv(i, 1, 1, 1)
987 c%G22(i, 1, 1, 1) = c%G22(i, 1, 1, 1) * c%jacinv(i, 1, 1, 1)
988 c%G33(i, 1, 1, 1) = c%G33(i, 1, 1, 1) * c%jacinv(i, 1, 1, 1)
989 end do
990 !$omp end do
991 !$omp do
992 do i = 1, ntot
993 c%G12(i, 1, 1, 1) = c%drdx(i, 1, 1, 1) * c%dsdx(i, 1, 1, 1) &
994 + c%drdy(i, 1, 1, 1) * c%dsdy(i, 1, 1, 1) &
995 + c%drdz(i, 1, 1, 1) * c%dsdz(i, 1, 1, 1)
996
997 c%G13(i, 1, 1, 1) = c%drdx(i, 1, 1, 1) * c%dtdx(i, 1, 1, 1) &
998 + c%drdy(i, 1, 1, 1) * c%dtdy(i, 1, 1, 1) &
999 + c%drdz(i, 1, 1, 1) * c%dtdz(i, 1, 1, 1)
1000
1001 c%G23(i, 1, 1, 1) = c%dsdx(i, 1, 1, 1) * c%dtdx(i, 1, 1, 1) &
1002 + c%dsdy(i, 1, 1, 1) * c%dtdy(i, 1, 1, 1) &
1003 + c%dsdz(i, 1, 1, 1) * c%dtdz(i, 1, 1, 1)
1004 end do
1005 !$omp end do
1006 !$omp do
1007 do i = 1, ntot
1008 c%G12(i, 1, 1, 1) = c%G12(i, 1, 1, 1) * c%jacinv(i, 1, 1, 1)
1009 c%G13(i, 1, 1, 1) = c%G13(i, 1, 1, 1) * c%jacinv(i, 1, 1, 1)
1010 c%G23(i, 1, 1, 1) = c%G23(i, 1, 1, 1) * c%jacinv(i, 1, 1, 1)
1011 end do
1012 !$omp end do
1013 !$omp do
1014 do e = 1, c%msh%nelv
1015 do concurrent(i = 1:lxyz)
1016 c%G11(i,1,1,e) = c%G11(i,1,1,e) * c%Xh%w3(i,1,1)
1017 c%G22(i,1,1,e) = c%G22(i,1,1,e) * c%Xh%w3(i,1,1)
1018 c%G12(i,1,1,e) = c%G12(i,1,1,e) * c%Xh%w3(i,1,1)
1019
1020 c%G33(i,1,1,e) = c%G33(i,1,1,e) * c%Xh%w3(i,1,1)
1021 c%G13(i,1,1,e) = c%G13(i,1,1,e) * c%Xh%w3(i,1,1)
1022 c%G23(i,1,1,e) = c%G23(i,1,1,e) * c%Xh%w3(i,1,1)
1023 end do
1024 end do
1025 !$omp end do
1026 !$omp end parallel
1027 end if
1028 end if
1029
1030 end subroutine coef_generate_geo
1031
1035 type(coef_t), intent(inout) :: c
1036 integer :: e, m, i, lxyz, m_max
1037 integer, allocatable :: c_inds_rev(:) ! reverse compression indices map
1038 real(kind=rp) :: ctol = 1.0e-7_rp
1039 real(kind=rp) :: diff = 0.0_rp
1040
1041 ! First step, allocate full-size lookup structure for entire mesh
1042 allocate(c%compression_inds(c%msh%nelv))
1043 allocate(c_inds_rev(c%msh%nelv))
1044
1045 ! Second step, loop over all elements, compute compression mapping
1046 ! First entry must be itself to get started
1047 m_max = 1
1048 c%compression_inds(1) = 1
1049 c_inds_rev = 0
1050 c_inds_rev(1) = 1
1051
1052 ! Loop over elements, but skip first
1053 lxyz = c%Xh%lx * c%Xh%ly * c%Xh%lz
1054 do e = 2, c%msh%nelv
1055 ! Loop over possible compression candidates
1056 do m = 1, m_max
1057 diff = 0.0_rp
1058 ! Loop over quadrature points
1059 do i = 1, lxyz
1060 ! diff += abs( \| G(i,:,:,e) - G(i,:,:,reverse(m)) \|_l1 )
1061 diff = diff + abs(c%G11(i,1,1,e) - c%G11(i,1,1,c_inds_rev(m))) &
1062 + 2.0*abs(c%G12(i,1,1,e) - c%G12(i,1,1,c_inds_rev(m))) &
1063 + 2.0*abs(c%G13(i,1,1,e) - c%G13(i,1,1,c_inds_rev(m))) &
1064 + abs(c%G22(i,1,1,e) - c%G22(i,1,1,c_inds_rev(m))) &
1065 + 2.0*abs(c%G23(i,1,1,e) - c%G23(i,1,1,c_inds_rev(m))) &
1066 + abs(c%G33(i,1,1,e) - c%G33(i,1,1,c_inds_rev(m)))
1067 end do
1068
1069 ! match is found; mapping(e) is redundant
1070 if ( diff .le. ctol ) then
1071 c%compression_inds(e) = m
1072 exit
1073 end if
1074 end do
1075
1076 ! never found a match
1077 if ( diff .gt. ctol ) then
1078 m_max = m_max + 1
1079 c%compression_inds(e) = m_max
1080 c_inds_rev(m_max) = e
1081 end if
1082 end do
1083
1084 write(*,*)
1085 write(*,*) '------Mapping Compression-----'
1086 write(*,*) 'Compressed from ', c%msh%nelv, ' to ', m_max
1087
1088 ! Third step, allocate and fill Gij_compressed objects
1089 allocate(c%G11_compressed(c%Xh%lx, c%Xh%ly, c%Xh%lz, m_max))
1090 allocate(c%G22_compressed(c%Xh%lx, c%Xh%ly, c%Xh%lz, m_max))
1091 allocate(c%G33_compressed(c%Xh%lx, c%Xh%ly, c%Xh%lz, m_max))
1092 allocate(c%G12_compressed(c%Xh%lx, c%Xh%ly, c%Xh%lz, m_max))
1093 allocate(c%G13_compressed(c%Xh%lx, c%Xh%ly, c%Xh%lz, m_max))
1094 allocate(c%G23_compressed(c%Xh%lx, c%Xh%ly, c%Xh%lz, m_max))
1095 do m = 1, m_max
1096 do i = 1, lxyz
1097 c%G11_compressed(i,1,1,m) = c%G11(i,1,1,c_inds_rev(m))
1098 c%G22_compressed(i,1,1,m) = c%G22(i,1,1,c_inds_rev(m))
1099 c%G33_compressed(i,1,1,m) = c%G33(i,1,1,c_inds_rev(m))
1100 c%G12_compressed(i,1,1,m) = c%G12(i,1,1,c_inds_rev(m))
1101 c%G13_compressed(i,1,1,m) = c%G13(i,1,1,c_inds_rev(m))
1102 c%G23_compressed(i,1,1,m) = c%G23(i,1,1,c_inds_rev(m))
1103 end do
1104 end do
1105
1106 deallocate(c_inds_rev)
1107
1108 end subroutine coef_generate_geo_compressed
1109
1113 type(coef_t), intent(inout) :: c
1114 integer :: e, i, lxyz, ntot
1115
1116 lxyz = c%Xh%lx * c%Xh%ly * c%Xh%lz
1117 ntot = c%dof%size()
1118
1119 if (neko_bcknd_device .eq. 1) then
1120 call device_coef_generate_mass(c%B_d, c%Binv_d, c%jac_d, c%Xh%w3_d, &
1121 lxyz, c%msh%nelv)
1122 ! copy to host only at initialization.
1123 if (.not. c%coef_metrics_initialized) then
1124 call device_memcpy(c%B, c%B_d, ntot, device_to_host, sync = .false.)
1125 end if
1126 else
1127 do concurrent(e = 1:c%msh%nelv)
1128 ! Here we need to handle things differently for axis symmetric elements
1129 do concurrent(i = 1:lxyz)
1130 c%B(i,1,1,e) = c%jac(i,1,1,e) * c%Xh%w3(i,1,1)
1131 c%Binv(i,1,1,e) = c%B(i,1,1,e)
1132 end do
1133 end do
1134 end if
1135
1136 call c%gs_h%op(c%Binv, ntot, gs_op_add)
1137
1138 if (neko_bcknd_device .eq. 1) then
1139 call device_invcol1(c%Binv_d, ntot)
1140 ! copy to host only at initialization.
1141 if (.not. c%coef_metrics_initialized) then
1142 call device_memcpy(c%Binv, c%Binv_d, ntot, &
1143 device_to_host, sync = .true.)
1144 end if
1145 else
1146 call invcol1(c%Binv, ntot)
1147 end if
1148
1150 if (neko_bcknd_device .eq. 1) then
1151 c%volume = device_glsum(c%B_d, ntot)
1152 else
1153 c%volume = glsum(c%B, ntot)
1154 end if
1155
1156 end subroutine coef_generate_mass
1157
1158 pure function coef_get_normal(this, i, j, k, e, facet) result(normal)
1159 class(coef_t), intent(in) :: this
1160 integer, intent(in) :: i, j, k, e, facet
1161 real(kind=rp) :: normal(3)
1162
1163 select case (facet)
1164 case (1, 2)
1165 normal(1) = this%nx(j, k, facet, e)
1166 normal(2) = this%ny(j, k, facet, e)
1167 normal(3) = this%nz(j, k, facet, e)
1168 case (3, 4)
1169 normal(1) = this%nx(i, k, facet, e)
1170 normal(2) = this%ny(i, k, facet, e)
1171 normal(3) = this%nz(i, k, facet, e)
1172 case (5, 6)
1173 normal(1) = this%nx(i, j, facet, e)
1174 normal(2) = this%ny(i, j, facet, e)
1175 normal(3) = this%nz(i, j, facet, e)
1176 end select
1177 end function coef_get_normal
1178
1179 pure function coef_get_area(this, i, j, k, e, facet) result(area)
1180 class(coef_t), intent(in) :: this
1181 integer, intent(in) :: i, j, k, e, facet
1182 real(kind=rp) :: area
1183
1184 select case (facet)
1185 case (1, 2)
1186 area = this%area(j, k, facet, e)
1187 case (3, 4)
1188 area = this%area(i, k, facet, e)
1189 case (5, 6)
1190 area = this%area(i, j, facet, e)
1191 end select
1192 end function coef_get_area
1193
1194
1197 type(coef_t), intent(inout) :: coef
1198 real(kind=rp), allocatable :: a(:,:,:,:)
1199 real(kind=rp), allocatable :: b(:,:,:,:)
1200 real(kind=rp), allocatable :: c(:,:,:,:)
1201 real(kind=rp), allocatable :: dot(:,:,:,:)
1202 integer :: n, m, e, i, j, k, lx
1203 real(kind=rp) :: weight, len
1204 n = coef%dof%size()
1205 lx = coef%Xh%lx
1206
1207 if (neko_bcknd_device .eq. 1) then
1208
1209 call device_coef_generate_area_and_normal( &
1210 coef%area_d, coef%nx_d, coef%ny_d, coef%nz_d, &
1211 coef%dxdr_d, coef%dydr_d, coef%dzdr_d, &
1212 coef%dxds_d, coef%dyds_d, coef%dzds_d, &
1213 coef%dxdt_d, coef%dydt_d, coef%dzdt_d, &
1214 coef%Xh%wx_d, coef%Xh%wy_d, coef%Xh%wz_d, &
1215 lx, coef%msh%nelv, neko_eps)
1216
1217 ! Here, we always copy back to host.
1218 m = size(coef%area)
1219 call device_memcpy(coef%area, coef%area_d, m, &
1220 device_to_host, sync = .false.)
1221 call device_memcpy(coef%nx, coef%nx_d, m, &
1222 device_to_host, sync = .false.)
1223 call device_memcpy(coef%ny, coef%ny_d, m, &
1224 device_to_host, sync = .false.)
1225 call device_memcpy(coef%nz, coef%nz_d, &
1226 m, device_to_host, sync = .true.)
1227
1228 else
1229
1230 allocate(a(coef%Xh%lx, coef%Xh%lx, coef%Xh%lx, coef%msh%nelv))
1231 allocate(b(coef%Xh%lx, coef%Xh%lx, coef%Xh%lx, coef%msh%nelv))
1232 allocate(c(coef%Xh%lx, coef%Xh%lx, coef%Xh%lx, coef%msh%nelv))
1233 allocate(dot(coef%Xh%lx, coef%Xh%lx, coef%Xh%lx, coef%msh%nelv))
1234
1235 !$omp parallel private (e, i, j, k, weight, len)
1236
1237 ! ds x dt
1238 !$omp do simd
1239 do i = 1, n
1240 a(i, 1, 1, 1) = coef%dyds(i, 1, 1, 1) * coef%dzdt(i, 1, 1, 1) &
1241 - coef%dzds(i, 1, 1, 1) * coef%dydt(i, 1, 1, 1)
1242
1243 b(i, 1, 1, 1) = coef%dzds(i, 1, 1, 1) * coef%dxdt(i, 1, 1, 1) &
1244 - coef%dxds(i, 1, 1, 1) * coef%dzdt(i, 1, 1, 1)
1245
1246 c(i, 1, 1, 1) = coef%dxds(i, 1, 1, 1) * coef%dydt(i, 1, 1, 1) &
1247 - coef%dyds(i, 1, 1, 1) * coef%dxdt(i, 1, 1, 1)
1248 end do
1249 !$omp end do simd
1250 !$omp do simd
1251 do i = 1, n
1252 dot(i, 1, 1, 1) = a(i, 1, 1, 1) * a(i, 1, 1, 1) &
1253 + b(i, 1, 1, 1) * b(i, 1, 1, 1) &
1254 + c(i, 1, 1, 1) * c(i, 1, 1, 1)
1255 end do
1256 !$omp end do simd
1257 !$omp do
1258 do e = 1, coef%msh%nelv
1259 do concurrent(k = 1:coef%Xh%lx)
1260 do concurrent(j = 1:coef%Xh%lx)
1261 weight = coef%Xh%wy(j) * coef%Xh%wz(k)
1262 coef%area(j, k, 2, e) = sqrt(dot(lx, j, k, e)) * weight
1263 coef%area(j, k, 1, e) = sqrt(dot(1, j, k, e)) * weight
1264 coef%nx(j,k, 1, e) = -a(1, j, k, e)
1265 coef%nx(j,k, 2, e) = a(lx, j, k, e)
1266 coef%ny(j,k, 1, e) = -b(1, j, k, e)
1267 coef%ny(j,k, 2, e) = b(lx, j, k, e)
1268 coef%nz(j,k, 1, e) = -c(1, j, k, e)
1269 coef%nz(j,k, 2, e) = c(lx, j, k, e)
1270 end do
1271 end do
1272 end do
1273 !$omp end do
1274
1275 ! dr x dt
1276 !$omp do simd
1277 do i = 1, n
1278 a(i, 1, 1, 1) = coef%dydr(i, 1, 1, 1) * coef%dzdt(i, 1, 1, 1) &
1279 - coef%dzdr(i, 1, 1, 1) * coef%dydt(i, 1, 1, 1)
1280
1281 b(i, 1, 1, 1) = coef%dzdr(i, 1, 1, 1) * coef%dxdt(i, 1, 1, 1) &
1282 - coef%dxdr(i, 1, 1, 1) * coef%dzdt(i, 1, 1, 1)
1283
1284 c(i, 1, 1, 1) = coef%dxdr(i, 1, 1, 1) * coef%dydt(i, 1, 1, 1) &
1285 - coef%dydr(i, 1, 1, 1) * coef%dxdt(i, 1, 1, 1)
1286 end do
1287 !$omp end do simd
1288 !$omp do simd
1289 do i = 1, n
1290 dot(i, 1, 1, 1) = a(i, 1, 1, 1) * a(i, 1, 1, 1) &
1291 + b(i, 1, 1, 1) * b(i, 1, 1, 1) &
1292 + c(i, 1, 1, 1) * c(i, 1, 1, 1)
1293 end do
1294 !$omp end do simd
1295 !$omp do
1296 do e = 1, coef%msh%nelv
1297 do concurrent(k = 1:coef%Xh%lx)
1298 do concurrent(j = 1:coef%Xh%lx)
1299 weight = coef%Xh%wx(j) * coef%Xh%wz(k)
1300 coef%area(j, k, 3, e) = sqrt(dot(j, 1, k, e)) * weight
1301 coef%area(j, k, 4, e) = sqrt(dot(j, lx, k, e)) * weight
1302 coef%nx(j,k, 3, e) = a(j, 1, k, e)
1303 coef%nx(j,k, 4, e) = -a(j, lx, k, e)
1304 coef%ny(j,k, 3, e) = b(j, 1, k, e)
1305 coef%ny(j,k, 4, e) = -b(j, lx, k, e)
1306 coef%nz(j,k, 3, e) = c(j, 1, k, e)
1307 coef%nz(j,k, 4, e) = -c(j, lx, k, e)
1308 end do
1309 end do
1310 end do
1311 !$omp end do
1312 ! dr x ds
1313 !$omp do simd
1314 do i = 1, n
1315 a(i, 1, 1, 1) = coef%dydr(i, 1, 1, 1) * coef%dzds(i, 1, 1, 1) &
1316 - coef%dzdr(i, 1, 1, 1) * coef%dyds(i, 1, 1, 1)
1317
1318 b(i, 1, 1, 1) = coef%dzdr(i, 1, 1, 1) * coef%dxds(i, 1, 1, 1) &
1319 - coef%dxdr(i, 1, 1, 1) * coef%dzds(i, 1, 1, 1)
1320
1321 c(i, 1, 1, 1) = coef%dxdr(i, 1, 1, 1) * coef%dyds(i, 1, 1, 1) &
1322 - coef%dydr(i, 1, 1, 1) * coef%dxds(i, 1, 1, 1)
1323 end do
1324 !$omp end do simd
1325 !$omp do simd
1326 do i = 1, n
1327 dot(i, 1, 1, 1) = a(i, 1, 1, 1) * a(i, 1, 1, 1) &
1328 + b(i, 1, 1, 1) * b(i, 1, 1, 1) &
1329 + c(i, 1, 1, 1) * c(i, 1, 1, 1)
1330 end do
1331 !$omp end do simd
1332 !$omp do
1333 do e = 1, coef%msh%nelv
1334 do concurrent(k = 1:coef%Xh%lx)
1335 do concurrent(j = 1:coef%Xh%lx)
1336 weight = coef%Xh%wx(j) * coef%Xh%wy(k)
1337 coef%area(j, k, 5, e) = sqrt(dot(j, k, 1, e)) * weight
1338 coef%area(j, k, 6, e) = sqrt(dot(j, k, lx, e)) * weight
1339 coef%nx(j,k, 5, e) = -a(j, k, 1, e)
1340 coef%nx(j,k, 6, e) = a(j, k, lx, e)
1341 coef%ny(j,k, 5, e) = -b(j, k, 1, e)
1342 coef%ny(j,k, 6, e) = b(j, k, lx, e)
1343 coef%nz(j,k, 5, e) = -c(j, k, 1, e)
1344 coef%nz(j,k, 6, e) = c(j, k, lx, e)
1345 end do
1346 end do
1347 end do
1348 !$omp end do
1349 ! Normalize
1350 !$omp do
1351 do j = 1, size(coef%nz)
1352 len = sqrt(coef%nx(j,1,1,1)**2 + &
1353 coef%ny(j,1,1,1)**2 + coef%nz(j,1,1,1)**2)
1354 if (len .gt. neko_eps) then
1355 coef%nx(j,1,1,1) = coef%nx(j,1,1,1) / len
1356 coef%ny(j,1,1,1) = coef%ny(j,1,1,1) / len
1357 coef%nz(j,1,1,1) = coef%nz(j,1,1,1) / len
1358 end if
1359 end do
1360 !$omp end do
1361 !$omp end parallel
1362
1363 deallocate(dot)
1364 deallocate(c)
1365 deallocate(b)
1366 deallocate(a)
1367
1368 end if
1369
1370 end subroutine coef_generate_area_and_normal
1371
1373 class(coef_t), intent(inout) :: this
1374 real(kind=rp) :: un(3), len, d
1375 integer :: lx, ly, lz, np, np_glb, ierr
1376 integer :: i, j, k, pf, pe, n, nc, ncyc
1377
1378 if (.not. this%cyclic) return
1379
1380 np = this%msh%periodic%size
1381 call mpi_allreduce(np, np_glb, 1, &
1382 mpi_integer, mpi_sum, neko_comm, ierr)
1383
1384 if (np_glb .eq. 0) then
1385 call neko_error("There are no periodic boundaries. " // &
1386 "Switch cyclic off in the case file.")
1387 end if
1388
1389 if (np .eq. 0) return
1390
1391 lx = this%Xh%lx
1392 ly = this%Xh%ly
1393 lz = this%Xh%lz
1394 ncyc = this%cyc_msk(0) - 1
1395 nc = 1
1396 do n = 1, np
1397 pf = this%msh%periodic%facet_el(n)%x(1)
1398 pe = this%msh%periodic%facet_el(n)%x(2)
1399 do k = 1, lz
1400 do j = 1, ly
1401 do i = 1, lx
1402 if (index_is_on_facet(i, j, k, lx, ly, lz, pf)) then
1403 un = this%get_normal(i, j, k, pe, pf)
1404 len = sqrt(un(1) * un(1) + un(2) * un(2))
1405 if (len .gt. neko_eps) then
1406 d = this%dof%y(i, j, k, pe) * un(1) &
1407 - this%dof%x(i, j, k, pe) * un(2)
1408
1409 this%cyc_msk(nc) = linear_index(i, j, k, pe, lx, ly, lz)
1410 this%R11(nc) = un(1) / len * sign(1.0_rp, d)
1411 this%R12(nc) = un(2) / len * sign(1.0_rp, d)
1412 nc = nc + 1
1413 else
1414 call neko_error("x and y components of surface " // &
1415 "normals are zero. Cyclic rotations must be " // &
1416 "around z-axis.")
1417 end if
1418 end if
1419 end do
1420 end do
1421 end do
1422 end do
1423
1424 if (nc - 1 /= ncyc) then
1425 call neko_error("The number of cyclic GLL points were " // &
1426 "not estimated correctly.")
1427 end if
1428
1429 if (neko_bcknd_device .eq. 1) then
1430 call device_memcpy(this%cyc_msk, this%cyc_msk_d, ncyc+1, &
1431 host_to_device, sync = .false.)
1432 call device_memcpy(this%R11, this%R11_d, ncyc, &
1433 host_to_device, sync = .false.)
1434 call device_memcpy(this%R12, this%R12_d, ncyc, &
1435 host_to_device, sync = .false.)
1436 end if
1437
1438 end subroutine coef_generate_cyclic_bc
1439
1440
1442 subroutine coef_recompute_metrics(this)
1443 class(coef_t), intent(inout) :: this
1444
1445 call coef_generate_dxyzdrst(this)
1446 call coef_generate_geo(this)
1448 call coef_generate_mass(this)
1449 if (this%cyclic) then
1450 call coef_generate_cyclic_bc(this)
1451 end if
1452 this%metrics_version = this%metrics_version + 1
1453 end subroutine coef_recompute_metrics
1454
1455
1459 class(coef_t), intent(inout), target :: this
1460 integer :: n
1461
1462 ! Return if already allocated distinctly
1463 if (.not. associated(this%Blag, this%B)) return
1464
1465 n = this%Xh%lx * this%Xh%ly * this%Xh%lz * this%msh%nelv
1466
1467
1468 nullify(this%Blag)
1469 nullify(this%Blaglag)
1470
1471 allocate(this%Blag(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
1472 allocate(this%Blaglag(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
1473
1474 this%Blag = this%B
1475 this%Blaglag = this%B
1476
1477 if (neko_bcknd_device .eq. 1) then
1478
1479 this%Blag_d = c_null_ptr
1480 this%Blaglag_d = c_null_ptr
1481
1482 call device_map(this%Blag, this%Blag_d, n)
1483 call device_map(this%Blaglag, this%Blaglag_d, n)
1484
1485 call device_memcpy(this%Blag, this%Blag_d, n, &
1486 host_to_device, sync = .false.)
1487 call device_memcpy(this%Blaglag, this%Blaglag_d, n, &
1488 host_to_device, sync = .true.)
1489 end if
1490
1491 end subroutine coef_enable_lagged_mass
1492
1493
1496 class(coef_t), intent(inout), target :: this
1497 integer :: n
1498
1499 ! If this%Blag does not have separate memory, we don't need to update it.
1500 if (associated(this%Blag, this%B)) return
1501 n = this%Xh%lx * this%Xh%ly * this%Xh%lz * this%msh%nelv
1502 if (neko_bcknd_device .eq. 1) then
1503 call device_copy(this%Blaglag_d, this%Blag_d, n)
1504 call device_copy(this%Blag_d, this%B_d, n)
1505 else
1506 this%Blaglag = this%Blag
1507 this%Blag = this%B
1508 end if
1509
1510 end subroutine coef_update_lagged_mass
1511
1512end module coefs
Map a Fortran array to a device (allocate and associate)
Definition device.F90:83
Copy data between host and device (or device and device)
Definition device.F90:72
Unmap a Fortran array from a device (deassociate and free)
Definition device.F90:89
Coefficients.
Definition coef.f90:34
subroutine coef_generate_geo(c)
Generate geometric data for the given mesh.
Definition coef.f90:904
subroutine coef_free(this)
Deallocate coefficients.
Definition coef.f90:450
subroutine coef_recompute_metrics(this)
Recompute and update geometric factors (ALE)
Definition coef.f90:1443
pure real(kind=rp) function coef_get_area(this, i, j, k, e, facet)
Definition coef.f90:1180
pure real(kind=rp) function, dimension(3) coef_get_normal(this, i, j, k, e, facet)
Definition coef.f90:1159
subroutine coef_update_lagged_mass(this)
Update history: Blaglag = Blag, Blag = B.
Definition coef.f90:1496
subroutine coef_generate_dxyzdrst(c)
Definition coef.f90:715
subroutine coef_generate_area_and_normal(coef)
Generate facet area and surface normals.
Definition coef.f90:1197
subroutine coef_init_empty(this, xh, msh)
Initialize empty coefs for a space and a mesh.
Definition coef.f90:203
subroutine coef_init_all(this, gs_h)
Initialize coefficients.
Definition coef.f90:249
subroutine coef_enable_lagged_mass(this)
Enable separate memory for lagged B matrices if needed. For eg. when mesh moves.
Definition coef.f90:1459
subroutine coef_generate_geo_compressed(c)
Compute processor-local compressed versions of mappings Gij.
Definition coef.f90:1035
subroutine coef_generate_cyclic_bc(this)
Definition coef.f90:1373
subroutine coef_generate_mass(c)
Generate mass matrix B for the given mesh and space.
Definition coef.f90:1113
Definition comm.F90:1
type(mpi_comm), public neko_comm
MPI communicator.
Definition comm.F90:46
subroutine, public device_coef_generate_area_and_normal(area_d, nx_d, ny_d, nz_d, dxdr_d, dydr_d, dzdr_d, dxds_d, dyds_d, dzds_d, dxdt_d, dydt_d, dzdt_d, wx_d, wy_d, wz_d, lx, nel, eps)
subroutine, public device_coef_generate_dxydrst(drdx_d, drdy_d, drdz_d, dsdx_d, dsdy_d, dsdz_d, dtdx_d, dtdy_d, dtdz_d, dxdr_d, dydr_d, dzdr_d, dxds_d, dyds_d, dzds_d, dxdt_d, dydt_d, dzdt_d, dx_d, dy_d, dz_d, x_d, y_d, z_d, jacinv_d, jac_d, lx, nel)
subroutine, public device_coef_generate_mass(b, binv, jac, w3, lxyz, nel)
subroutine, public device_coef_generate_geo(g11_d, g12_d, g13_d, g22_d, g23_d, g33_d, drdx_d, drdy_d, drdz_d, dsdx_d, dsdy_d, dsdz_d, dtdx_d, dtdy_d, dtdz_d, jacinv_d, w3_d, nel, lx, gdim)
real(kind=rp) function, public device_glsum(a_d, n, strm)
Sum a vector of length n.
subroutine, public device_invcol1(a_d, n, strm)
Invert a vector .
subroutine, public device_rone(a_d, n, strm)
Set all elements to one.
subroutine, public device_copy(a_d, b_d, n, strm)
Copy a vector .
Device abstraction, common interface for various accelerators.
Definition device.F90:34
integer, parameter, public host_to_device
Definition device.F90:48
integer, parameter, public device_to_host
Definition device.F90:48
Defines a mapping of the degrees of freedom.
Definition dofmap.f90:35
Gather-scatter.
Defines Gather-scatter operations.
Definition gs_ops.f90:34
integer, parameter, public gs_op_add
Definition gs_ops.f90:36
Definition math.f90:60
subroutine, public invers2(a, b, n)
Compute inverted vector .
Definition math.f90:800
subroutine, public subcol3(a, b, c, n)
Returns .
Definition math.f90:1077
subroutine, public rone(a, n)
Set all elements to one.
Definition math.f90:277
real(kind=rp) function, public glsum(a, n)
Sum a vector of length n.
Definition math.f90:629
subroutine, public addcol3(a, b, c, n)
Returns .
Definition math.f90:1164
subroutine, public invcol1(a, n)
Invert a vector .
Definition math.f90:771
subroutine, public chsign(a, n)
Change sign of vector .
Definition math.f90:726
subroutine, public copy(a, b, n)
Copy a vector .
Definition math.f90:291
real(kind=rp), parameter, public neko_eps
Machine epsilon .
Definition math.f90:70
subroutine, public rzero(a, n)
Zero a real vector.
Definition math.f90:235
Defines a mesh.
Definition mesh.f90:34
Wrapper for all matrix-matrix product implementations.
subroutine, public mxm(a, n1, b, n2, c, n3)
Compute matrix-matrix product for contiguously packed matrices A,B, and C.
Build configurations.
integer, parameter neko_bcknd_device
integer, parameter neko_bcknd_opencl
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:12
Defines a function space.
Definition space.f90:34
Utilities.
Definition utils.f90:35
pure logical function, public index_is_on_facet(i, j, k, lx, ly, lz, facet)
Definition utils.f90:314
pure integer function, public linear_index(i, j, k, l, lx, ly, lz)
Compute the address of a (i,j,k,l) array with sizes (1:lx, 1:ly, 1:lz, :)
Definition utils.f90:289
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Definition coef.f90:63
Gather-scatter kernel.
The function space for the SEM solution fields.
Definition space.f90:64