Neko 1.99.6
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
183
184
185 contains
186 procedure, private, pass(this) :: init_empty => coef_init_empty
187 procedure, private, pass(this) :: init_all => coef_init_all
188 procedure, pass(this) :: free => coef_free
189 procedure, pass(this) :: get_normal => coef_get_normal
190 procedure, pass(this) :: get_area => coef_get_area
191 procedure, pass(this) :: generate_cyclic_bc => coef_generate_cyclic_bc
192 procedure, pass(this) :: recompute_metrics => coef_recompute_metrics
193 procedure, pass(this) :: enable_b_history => coef_enable_lagged_mass
194 procedure, pass(this) :: update_b_history => coef_update_lagged_mass
195 generic :: init => init_empty, init_all
196 end type coef_t
197
198contains
199
201 subroutine coef_init_empty(this, Xh, msh)
202 class(coef_t), intent(inout) :: this
203 type(space_t), intent(inout), target :: Xh
204 type(mesh_t), intent(inout), target :: msh
205 integer :: n
206 call this%free()
207 this%msh => msh
208 this%Xh => xh
209
210 allocate(this%drdx(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
211 allocate(this%dsdx(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
212 allocate(this%dtdx(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
213
214 allocate(this%drdy(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
215 allocate(this%dsdy(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
216 allocate(this%dtdy(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
217
218 allocate(this%drdz(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
219 allocate(this%dsdz(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
220 allocate(this%dtdz(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
221
222
223 !
224 ! Setup device memory (if present)
225 !
226
227 n = this%Xh%lx * this%Xh%ly * this%Xh%lz * this%msh%nelv
228 if (neko_bcknd_device .eq. 1) then
229
230 call device_map(this%drdx, this%drdx_d, n)
231 call device_map(this%drdy, this%drdy_d, n)
232 call device_map(this%drdz, this%drdz_d, n)
233
234 call device_map(this%dsdx, this%dsdx_d, n)
235 call device_map(this%dsdy, this%dsdy_d, n)
236 call device_map(this%dsdz, this%dsdz_d, n)
237
238 call device_map(this%dtdx, this%dtdx_d, n)
239 call device_map(this%dtdy, this%dtdy_d, n)
240 call device_map(this%dtdz, this%dtdz_d, n)
241
242 end if
243
244 end subroutine coef_init_empty
245
247 subroutine coef_init_all(this, gs_h)
248 class(coef_t), intent(inout), target :: this
249 type(gs_t), intent(inout), target :: gs_h
250 integer :: n, m, ncyc
251 call this%free()
252
253 this%msh => gs_h%dofmap%msh
254 this%Xh => gs_h%dofmap%Xh
255 this%dof => gs_h%dofmap
256 this%gs_h => gs_h
257
258 !
259 ! Allocate arrays for geometric data
260 !
262 allocate(this%G11(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
263 allocate(this%G22(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
264 allocate(this%G33(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
265 allocate(this%G12(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
266 allocate(this%G13(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
267 allocate(this%G23(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
268
269 allocate(this%dxdr(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
270 allocate(this%dxds(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
271 allocate(this%dxdt(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
272
273 allocate(this%dydr(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
274 allocate(this%dyds(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
275 allocate(this%dydt(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
276
277 allocate(this%dzdr(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
278 allocate(this%dzds(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
279 allocate(this%dzdt(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
280
281 allocate(this%drdx(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
282 allocate(this%dsdx(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
283 allocate(this%dtdx(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
284
285 allocate(this%drdy(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
286 allocate(this%dsdy(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
287 allocate(this%dtdy(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
288
289 allocate(this%drdz(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
290 allocate(this%dsdz(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
291 allocate(this%dtdz(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
292
293 allocate(this%jac(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
294 allocate(this%jacinv(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
295
296 allocate(this%area(this%Xh%lx, this%Xh%ly, 6, this%msh%nelv))
297 allocate(this%nx(this%Xh%lx, this%Xh%ly, 6, this%msh%nelv))
298 allocate(this%ny(this%Xh%lx, this%Xh%ly, 6, this%msh%nelv))
299 allocate(this%nz(this%Xh%lx, this%Xh%ly, 6, this%msh%nelv))
300
301 allocate(this%B(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
302 allocate(this%Binv(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
303
304 ! We do this so in a static simulation we don't allocate extra memory
305 this%Blag => this%B
306 this%Blaglag => this%B
307
308 allocate(this%h1(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
309 allocate(this%h2(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
310
311 allocate(this%mult(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
312
313
314 !
315 ! Setup device memory (if present)
316 !
317
318 n = this%Xh%lx * this%Xh%ly * this%Xh%lz * this%msh%nelv
319 if (neko_bcknd_device .eq. 1) then
320 call device_map(this%G11, this%G11_d, n)
321 call device_map(this%G22, this%G22_d, n)
322 call device_map(this%G33, this%G33_d, n)
323 call device_map(this%G12, this%G12_d, n)
324 call device_map(this%G13, this%G13_d, n)
325 call device_map(this%G23, this%G23_d, n)
326
327 call device_map(this%dxdr, this%dxdr_d, n)
328 call device_map(this%dydr, this%dydr_d, n)
329 call device_map(this%dzdr, this%dzdr_d, n)
330
331 call device_map(this%dxds, this%dxds_d, n)
332 call device_map(this%dyds, this%dyds_d, n)
333 call device_map(this%dzds, this%dzds_d, n)
334
335 call device_map(this%dxdt, this%dxdt_d, n)
336 call device_map(this%dydt, this%dydt_d, n)
337 call device_map(this%dzdt, this%dzdt_d, n)
338
339 call device_map(this%drdx, this%drdx_d, n)
340 call device_map(this%drdy, this%drdy_d, n)
341 call device_map(this%drdz, this%drdz_d, n)
342
343 call device_map(this%dsdx, this%dsdx_d, n)
344 call device_map(this%dsdy, this%dsdy_d, n)
345 call device_map(this%dsdz, this%dsdz_d, n)
346
347 call device_map(this%dtdx, this%dtdx_d, n)
348 call device_map(this%dtdy, this%dtdy_d, n)
349 call device_map(this%dtdz, this%dtdz_d, n)
350
351 call device_map(this%mult, this%mult_d, n)
352 call device_map(this%h1, this%h1_d, n)
353 call device_map(this%h2, this%h2_d, n)
354
355 call device_map(this%jac, this%jac_d, n)
356 call device_map(this%jacinv, this%jacinv_d, n)
357 call device_map(this%B, this%B_d, n)
358 call device_map(this%Binv, this%Binv_d, n)
359
360 this%Blag_d = this%B_d
361 this%Blaglag_d = this%B_d
362
363 m = this%Xh%lx * this%Xh%ly * 6 * this%msh%nelv
364
365 call device_map(this%area, this%area_d, m)
366 call device_map(this%nx, this%nx_d, m)
367 call device_map(this%ny, this%ny_d, m)
368 call device_map(this%nz, this%nz_d, m)
369
370 end if
371
372 call coef_generate_dxyzdrst(this)
373
374 call coef_generate_geo(this)
375
376 ! call coef_generate_geo_compressed(this)
377
379
380 call coef_generate_mass(this)
381
382 this%coef_metrics_initialized = .true.
383
384
385 ! This is a placeholder, just for now
386 ! We can probably find a prettier solution
387 if (neko_bcknd_device .eq. 1) then
388 call device_rone(this%h1_d, n)
389 call device_rone(this%h2_d, n)
390 call device_memcpy(this%h1, this%h1_d, n, &
391 device_to_host, sync = .false.)
392 call device_memcpy(this%h2, this%h2_d, n, &
393 device_to_host, sync = .false.)
394 else
395 call rone(this%h1,n)
396 call rone(this%h2,n)
397 end if
398
399 this%ifh2 = .false.
400
401 !
402 ! Set up multiplicity
403 !
404 if (neko_bcknd_device .eq. 1) then
405 call device_rone(this%mult_d, n)
406 else
407 call rone(this%mult, n)
408 end if
409
410 call gs_h%op(this%mult, n, gs_op_add)
411
412 if (neko_bcknd_device .eq. 1) then
413 call device_invcol1(this%mult_d, n)
414 call device_memcpy(this%mult, this%mult_d, n, &
415 device_to_host, sync = .true.)
416 else
417 call invcol1(this%mult, n)
418 end if
419
420 ncyc = this%msh%periodic%size * this%Xh%lx * this%Xh%lx
421 allocate(this%cyc_msk(0:ncyc))
422 this%cyc_msk(0) = ncyc + 1
423 if (ncyc .gt. 0) then
424 allocate(this%R11(ncyc))
425 allocate(this%R12(ncyc))
426
428 call rone(this%R11, ncyc)
429 call rzero(this%R12, ncyc)
430
431 if (neko_bcknd_device .eq. 1) then
432 call device_map(this%cyc_msk, this%cyc_msk_d, ncyc+1)
433 call device_map(this%R11, this%R11_d, ncyc)
434 call device_map(this%R12, this%R12_d, ncyc)
435
436 call device_memcpy(this%cyc_msk, this%cyc_msk_d, ncyc+1, &
437 host_to_device, sync = .false.)
438 call device_memcpy(this%R11, this%R11_d, ncyc, &
439 host_to_device, sync = .false.)
440 call device_memcpy(this%R12, this%R12_d, ncyc, &
441 host_to_device, sync = .false.)
442 end if
443
444 end if
445 end subroutine coef_init_all
446
448 subroutine coef_free(this)
449 class(coef_t), intent(inout), target :: this
450
451 if (allocated(this%G11)) then
452 if (neko_bcknd_device .eq. 1) call device_unmap(this%G11, this%G11_d)
453 deallocate(this%G11)
454 end if
455
456 if (allocated(this%G22)) then
457 if (neko_bcknd_device .eq. 1) call device_unmap(this%G22, this%G22_d)
458 deallocate(this%G22)
459 end if
460
461 if (allocated(this%G33)) then
462 if (neko_bcknd_device .eq. 1) call device_unmap(this%G33, this%G33_d)
463 deallocate(this%G33)
464 end if
465
466 if (allocated(this%G12)) then
467 if (neko_bcknd_device .eq. 1) call device_unmap(this%G12, this%G12_d)
468 deallocate(this%G12)
469 end if
470
471 if (allocated(this%G13)) then
472 if (neko_bcknd_device .eq. 1) call device_unmap(this%G13, this%G13_d)
473 deallocate(this%G13)
474 end if
475
476 if (allocated(this%G23)) then
477 if (neko_bcknd_device .eq. 1) call device_unmap(this%G23, this%G23_d)
478 deallocate(this%G23)
479 end if
480
481 if (allocated(this%G11_compressed)) then
482 deallocate(this%G11_compressed)
483 end if
484
485 if (allocated(this%compression_inds)) then
486 deallocate(this%compression_inds)
487 end if
488
489 if (allocated(this%G22_compressed)) then
490 deallocate(this%G22_compressed)
491 end if
492
493 if (allocated(this%G33_compressed)) then
494 deallocate(this%G33_compressed)
495 end if
496
497 if (allocated(this%G12_compressed)) then
498 deallocate(this%G12_compressed)
499 end if
500
501 if (allocated(this%G13_compressed)) then
502 deallocate(this%G13_compressed)
503 end if
504
505 if (allocated(this%G23_compressed)) then
506 deallocate(this%G23_compressed)
507 end if
508
509 if (allocated(this%mult)) then
510 if (neko_bcknd_device .eq. 1) call device_unmap(this%mult, this%mult_d)
511 deallocate(this%mult)
512 end if
513
514 if (associated(this%Blag) .and. &
515 .not. associated(this%Blag, this%B)) then
516 if (c_associated(this%Blag_d) .and. &
517 .not. c_associated(this%Blag_d, this%B_d)) then
518 call device_unmap(this%Blag, this%Blag_d)
519 end if
520 deallocate(this%Blag)
521 end if
522 nullify(this%Blag)
523
524 if (associated(this%Blaglag) .and. &
525 .not. associated(this%Blaglag, this%B)) then
526 if (c_associated(this%Blaglag_d) .and. &
527 .not. c_associated(this%Blaglag_d, this%B_d)) then
528 call device_unmap(this%Blaglag, this%Blaglag_d)
529 end if
530 deallocate(this%Blaglag)
531 end if
532 nullify(this%Blaglag)
533
534 if (c_associated(this%Blag_d) .and. &
535 .not. c_associated(this%Blag_d, this%B_d)) then
536 this%Blag_d = c_null_ptr
537 end if
538 this%Blag_d = c_null_ptr
539
540 if (c_associated(this%Blaglag_d) .and. &
541 .not. c_associated(this%Blaglag_d, this%B_d)) then
542 this%Blaglag_d = c_null_ptr
543 end if
544 this%Blaglag_d = c_null_ptr
545
546 if (allocated(this%B)) then
547 if (neko_bcknd_device .eq. 1) call device_unmap(this%B, this%B_d)
548 deallocate(this%B)
549 end if
550
551 if (allocated(this%Binv)) then
552 if (neko_bcknd_device .eq. 1) call device_unmap(this%Binv, this%Binv_d)
553 deallocate(this%Binv)
554 end if
555
556 if (allocated(this%dxdr)) then
557 if (neko_bcknd_device .eq. 1) call device_unmap(this%dxdr, this%dxdr_d)
558 deallocate(this%dxdr)
559 end if
560
561 if (allocated(this%dxds)) then
562 if (neko_bcknd_device .eq. 1) call device_unmap(this%dxds, this%dxds_d)
563 deallocate(this%dxds)
564 end if
565
566 if (allocated(this%dxdt)) then
567 if (neko_bcknd_device .eq. 1) call device_unmap(this%dxdt, this%dxdt_d)
568 deallocate(this%dxdt)
569 end if
570
571 if (allocated(this%dydr)) then
572 if (neko_bcknd_device .eq. 1) call device_unmap(this%dydr, this%dydr_d)
573 deallocate(this%dydr)
574 end if
575
576 if (allocated(this%dyds)) then
577 if (neko_bcknd_device .eq. 1) call device_unmap(this%dyds, this%dyds_d)
578 deallocate(this%dyds)
579 end if
580
581 if (allocated(this%dydt)) then
582 if (neko_bcknd_device .eq. 1) call device_unmap(this%dydt, this%dydt_d)
583 deallocate(this%dydt)
584 end if
585
586 if (allocated(this%dzdr)) then
587 if (neko_bcknd_device .eq. 1) call device_unmap(this%dzdr, this%dzdr_d)
588 deallocate(this%dzdr)
589 end if
590
591 if (allocated(this%dzds)) then
592 if (neko_bcknd_device .eq. 1) call device_unmap(this%dzds, this%dzds_d)
593 deallocate(this%dzds)
594 end if
595
596 if (allocated(this%dzdt)) then
597 if (neko_bcknd_device .eq. 1) call device_unmap(this%dzdt, this%dzdt_d)
598 deallocate(this%dzdt)
599 end if
600
601 if (allocated(this%drdx)) then
602 if (neko_bcknd_device .eq. 1) call device_unmap(this%drdx, this%drdx_d)
603 deallocate(this%drdx)
604 end if
605
606 if (allocated(this%dsdx)) then
607 if (neko_bcknd_device .eq. 1) call device_unmap(this%dsdx, this%dsdx_d)
608 deallocate(this%dsdx)
609 end if
610
611 if (allocated(this%dtdx)) then
612 if (neko_bcknd_device .eq. 1) call device_unmap(this%dtdx, this%dtdx_d)
613 deallocate(this%dtdx)
614 end if
615
616 if (allocated(this%drdy)) then
617 if (neko_bcknd_device .eq. 1) call device_unmap(this%drdy, this%drdy_d)
618 deallocate(this%drdy)
619 end if
620
621 if (allocated(this%dsdy)) then
622 if (neko_bcknd_device .eq. 1) call device_unmap(this%dsdy, this%dsdy_d)
623 deallocate(this%dsdy)
624 end if
625
626 if (allocated(this%dtdy)) then
627 if (neko_bcknd_device .eq. 1) call device_unmap(this%dtdy, this%dtdy_d)
628 deallocate(this%dtdy)
629 end if
630
631 if (allocated(this%drdz)) then
632 if (neko_bcknd_device .eq. 1) call device_unmap(this%drdz, this%drdz_d)
633 deallocate(this%drdz)
634 end if
635
636 if (allocated(this%dsdz)) then
637 if (neko_bcknd_device .eq. 1) call device_unmap(this%dsdz, this%dsdz_d)
638 deallocate(this%dsdz)
639 end if
640
641 if (allocated(this%dtdz)) then
642 if (neko_bcknd_device .eq. 1) call device_unmap(this%dtdz, this%dtdz_d)
643 deallocate(this%dtdz)
644 end if
645
646 if (allocated(this%jac)) then
647 if (neko_bcknd_device .eq. 1) call device_unmap(this%jac, this%jac_d)
648 deallocate(this%jac)
649 end if
650
651 if (allocated(this%jacinv)) then
652 if (neko_bcknd_device .eq. 1) then
653 call device_unmap(this%jacinv, this%jacinv_d)
654 end if
655 deallocate(this%jacinv)
656 end if
657
658 if (allocated(this%h1)) then
659 if (neko_bcknd_device .eq. 1) call device_unmap(this%h1, this%h1_d)
660 deallocate(this%h1)
661 end if
662
663 if (allocated(this%h2)) then
664 if (neko_bcknd_device .eq. 1) call device_unmap(this%h2, this%h2_d)
665 deallocate(this%h2)
666 end if
667
668 if (allocated(this%area)) then
669 if (neko_bcknd_device .eq. 1) call device_unmap(this%area, this%area_d)
670 deallocate(this%area)
671 end if
672
673 if (allocated(this%nx)) then
674 if (neko_bcknd_device .eq. 1) call device_unmap(this%nx, this%nx_d)
675 deallocate(this%nx)
676 end if
677
678 if (allocated(this%ny)) then
679 if (neko_bcknd_device .eq. 1) call device_unmap(this%ny, this%ny_d)
680 deallocate(this%ny)
681 end if
682
683 if (allocated(this%nz)) then
684 if (neko_bcknd_device .eq. 1) call device_unmap(this%nz, this%nz_d)
685 deallocate(this%nz)
686 end if
687
688 if (allocated(this%cyc_msk)) then
689 if (neko_bcknd_device .eq. 1) then
690 call device_unmap(this%cyc_msk, this%cyc_msk_d)
691 end if
692 deallocate(this%cyc_msk)
693 end if
694
695 if (allocated(this%R11)) then
696 if (neko_bcknd_device .eq. 1) call device_unmap(this%R11, this%R11_d)
697 deallocate(this%R11)
698 end if
699
700 if (allocated(this%R12)) then
701 if (neko_bcknd_device .eq. 1) call device_unmap(this%R12, this%R12_d)
702 deallocate(this%R12)
703 end if
704
705
706 nullify(this%msh)
707 nullify(this%Xh)
708 nullify(this%dof)
709 nullify(this%gs_h)
710
711 end subroutine coef_free
712
714 type(coef_t), intent(inout) :: c
715 integer :: e, i, lxy, lyz, ntot
716
717 lxy = c%Xh%lx*c%Xh%ly
718 lyz = c%Xh%ly*c%Xh%lz
719 ntot = c%dof%size()
720
721 associate(drdx => c%drdx, drdy => c%drdy, drdz => c%drdz, &
722 dsdx => c%dsdx, dsdy => c%dsdy, dsdz => c%dsdz, &
723 dtdx => c%dtdx, dtdy => c%dtdy, dtdz => c%dtdz, &
724 dxdr => c%dxdr, dydr => c%dydr, dzdr => c%dzdr, &
725 dxds => c%dxds, dyds => c%dyds, dzds => c%dzds, &
726 dxdt => c%dxdt, dydt => c%dydt, dzdt => c%dzdt, &
727 dx => c%Xh%dx, dy => c%Xh%dy, dz => c%Xh%dz, &
728 x => c%dof%x, y => c%dof%y, z => c%dof%z, &
729 lx => c%Xh%lx, ly => c%Xh%ly, lz => c%Xh%lz, &
730 dyt => c%Xh%dyt, dzt => c%Xh%dzt, &
731 jacinv => c%jacinv, jac => c%jac)
732
733 if (neko_bcknd_device .eq. 1) then
734
735 call device_coef_generate_dxydrst(c%drdx_d, c%drdy_d, c%drdz_d, &
736 c%dsdx_d, c%dsdy_d, c%dsdz_d, c%dtdx_d, c%dtdy_d, c%dtdz_d, &
737 c%dxdr_d, c%dydr_d, c%dzdr_d, c%dxds_d, c%dyds_d, c%dzds_d, &
738 c%dxdt_d, c%dydt_d, c%dzdt_d, c%Xh%dx_d, c%Xh%dy_d, c%Xh%dz_d, &
739 c%dof%x_d, c%dof%y_d, c%dof%z_d, c%jacinv_d, c%jac_d, &
740 c%Xh%lx, c%msh%nelv)
741
742 ! copy to host only at initialization.
743 if (.not. c%coef_metrics_initialized) then
744 call device_memcpy(dxdr, c%dxdr_d, ntot, device_to_host, &
745 sync = .false.)
746 call device_memcpy(dydr, c%dydr_d, ntot, device_to_host, &
747 sync = .false.)
748 call device_memcpy(dzdr, c%dzdr_d, ntot, device_to_host, &
749 sync = .false.)
750 call device_memcpy(dxds, c%dxds_d, ntot, device_to_host, &
751 sync = .false.)
752 call device_memcpy(dyds, c%dyds_d, ntot, device_to_host, &
753 sync = .false.)
754 call device_memcpy(dzds, c%dzds_d, ntot, device_to_host, &
755 sync = .false.)
756 call device_memcpy(dxdt, c%dxdt_d, ntot, device_to_host, &
757 sync = .false.)
758 call device_memcpy(dydt, c%dydt_d, ntot, device_to_host, &
759 sync = .false.)
760 call device_memcpy(dzdt, c%dzdt_d, ntot, device_to_host, &
761 sync = .false.)
762 call device_memcpy(drdx, c%drdx_d, ntot, device_to_host, &
763 sync = .false.)
764 call device_memcpy(drdy, c%drdy_d, ntot, device_to_host, &
765 sync = .false.)
766 call device_memcpy(drdz, c%drdz_d, ntot, device_to_host, &
767 sync = .false.)
768 call device_memcpy(dsdx, c%dsdx_d, ntot, device_to_host, &
769 sync = .false.)
770 call device_memcpy(dsdy, c%dsdy_d, ntot, device_to_host, &
771 sync = .false.)
772 call device_memcpy(dsdz, c%dsdz_d, ntot, device_to_host, &
773 sync = .false.)
774 call device_memcpy(dtdx, c%dtdx_d, ntot, device_to_host, &
775 sync = .false.)
776 call device_memcpy(dtdy, c%dtdy_d, ntot, device_to_host, &
777 sync = .false.)
778 call device_memcpy(dtdz, c%dtdz_d, ntot, device_to_host, &
779 sync = .false.)
780 call device_memcpy(jac, c%jac_d, ntot, device_to_host, &
781 sync = .false.)
782 call device_memcpy(jacinv, c%jacinv_d, ntot, device_to_host, &
783 sync = .true.)
784 end if
785
786 else
787 !$omp parallel do private(i)
788 do e = 1, c%msh%nelv
789 call mxm(dx, lx, x(1,1,1,e), lx, dxdr(1,1,1,e), lyz)
790 call mxm(dx, lx, y(1,1,1,e), lx, dydr(1,1,1,e), lyz)
791 call mxm(dx, lx, z(1,1,1,e), lx, dzdr(1,1,1,e), lyz)
792
793 do i = 1, lz
794 call mxm(x(1,1,i,e), lx, dyt, ly, dxds(1,1,i,e), ly)
795 call mxm(y(1,1,i,e), lx, dyt, ly, dyds(1,1,i,e), ly)
796 call mxm(z(1,1,i,e), lx, dyt, ly, dzds(1,1,i,e), ly)
797 end do
798
799 ! We actually take 2d into account, wow, need to do that for the rest.
800 if (c%msh%gdim .eq. 3) then
801 call mxm(x(1,1,1,e), lxy, dzt, lz, dxdt(1,1,1,e), lz)
802 call mxm(y(1,1,1,e), lxy, dzt, lz, dydt(1,1,1,e), lz)
803 call mxm(z(1,1,1,e), lxy, dzt, lz, dzdt(1,1,1,e), lz)
804 else
805 call rzero(dxdt(1,1,1,e), lxy)
806 call rzero(dydt(1,1,1,e), lxy)
807 call rone(dzdt(1,1,1,e), lxy)
808 end if
809 end do
810 !$omp end parallel do
811
812 if (c%msh%gdim .eq. 2) then
813 call rzero (jac, ntot)
814 call addcol3 (jac, dxdr, dyds, ntot)
815 call subcol3 (jac, dxds, dydr, ntot)
816 call copy (drdx, dyds, ntot)
817 call copy (drdy, dxds, ntot)
818 call chsign (drdy, ntot)
819 call copy (dsdx, dydr, ntot)
820 call chsign (dsdx, ntot)
821 call copy (dsdy, dxdr, ntot)
822 call rzero (drdz, ntot)
823 call rzero (dsdz, ntot)
824 call rone (dtdz, ntot)
825 else
826 !$omp parallel private(i)
827 !$omp do simd
828 do i = 1, ntot
829 c%jac(i, 1, 1, 1) = 0.0_rp
830 end do
831 !$omp end do simd
832 !$omp do simd
833 do i = 1, ntot
834 c%jac(i, 1, 1, 1) = c%jac(i, 1, 1, 1) + ( c%dxdr(i, 1, 1, 1) &
835 * c%dyds(i, 1, 1, 1) * c%dzdt(i, 1, 1, 1) )
836
837 c%jac(i, 1, 1, 1) = c%jac(i, 1, 1, 1) + ( c%dxdt(i, 1, 1, 1) &
838 * c%dydr(i, 1, 1, 1) * c%dzds(i, 1, 1, 1) )
839
840 c%jac(i, 1, 1, 1) = c%jac(i, 1, 1, 1) + ( c%dxds(i, 1, 1, 1) &
841 * c%dydt(i, 1, 1, 1) * c%dzdr(i, 1, 1, 1) )
842 end do
843 !$omp end do simd
844 !$omp do simd
845 do i = 1, ntot
846 c%jac(i, 1, 1, 1) = c%jac(i, 1, 1, 1) - ( c%dxdr(i, 1, 1, 1) &
847 * c%dydt(i, 1, 1, 1) * c%dzds(i, 1, 1, 1) )
848
849 c%jac(i, 1, 1, 1) = c%jac(i, 1, 1, 1) - ( c%dxds(i, 1, 1, 1) &
850 * c%dydr(i, 1, 1, 1) * c%dzdt(i, 1, 1, 1) )
851
852 c%jac(i, 1, 1, 1) = c%jac(i, 1, 1, 1) - ( c%dxdt(i, 1, 1, 1) &
853 * c%dyds(i, 1, 1, 1) * c%dzdr(i, 1, 1, 1) )
854 end do
855 !$omp end do simd
856 !$omp do simd
857 do i = 1, ntot
858 c%drdx(i, 1, 1, 1) = c%dyds(i, 1, 1, 1) * c%dzdt(i, 1, 1, 1) &
859 - c%dydt(i, 1, 1, 1) * c%dzds(i, 1, 1, 1)
860
861 c%drdy(i, 1, 1, 1) = c%dxdt(i, 1, 1, 1) * c%dzds(i, 1, 1, 1) &
862 - c%dxds(i, 1, 1, 1) * c%dzdt(i, 1, 1, 1)
863
864 c%drdz(i, 1, 1, 1) = c%dxds(i, 1, 1, 1) * c%dydt(i, 1, 1, 1) &
865 - c%dxdt(i, 1, 1, 1) * c%dyds(i, 1, 1, 1)
866 end do
867 !$omp end do simd
868 !$omp do simd
869 do i = 1, ntot
870 c%dsdx(i, 1, 1, 1) = c%dydt(i, 1, 1, 1) * c%dzdr(i, 1, 1, 1) &
871 - c%dydr(i, 1, 1, 1) * c%dzdt(i, 1, 1, 1)
872
873 c%dsdy(i, 1, 1, 1) = c%dxdr(i, 1, 1, 1) * c%dzdt(i, 1, 1, 1) &
874 - c%dxdt(i, 1, 1, 1) * c%dzdr(i, 1, 1, 1)
875
876 c%dsdz(i, 1, 1, 1) = c%dxdt(i, 1, 1, 1) * c%dydr(i, 1, 1, 1) &
877 - c%dxdr(i, 1, 1, 1) * c%dydt(i, 1, 1, 1)
878 end do
879 !$omp end do simd
880 !$omp do simd
881 do i = 1, ntot
882 c%dtdx(i, 1, 1, 1) = c%dydr(i, 1, 1, 1) * c%dzds(i, 1, 1, 1) &
883 - c%dyds(i, 1, 1, 1) * c%dzdr(i, 1, 1, 1)
884
885 c%dtdy(i, 1, 1, 1) = c%dxds(i, 1, 1, 1) * c%dzdr(i, 1, 1, 1) &
886 - c%dxdr(i, 1, 1, 1) * c%dzds(i, 1, 1, 1)
887
888 c%dtdz(i, 1, 1, 1) = c%dxdr(i, 1, 1, 1) * c%dyds(i, 1, 1, 1) &
889 - c%dxds(i, 1, 1, 1) * c%dydr(i, 1, 1, 1)
890 end do
891 !$omp end do simd
892 !$omp end parallel
893 end if
894 call invers2(jacinv, jac, ntot)
895 end if
896 end associate
897
898 end subroutine coef_generate_dxyzdrst
899
902 subroutine coef_generate_geo(c)
903 type(coef_t), intent(inout) :: c
904 integer :: e, i, lxyz, ntot
905
906 lxyz = c%Xh%lx * c%Xh%ly * c%Xh%lz
907 ntot = c%dof%size()
908
909 if (neko_bcknd_device .eq. 1) then
910
911 call device_coef_generate_geo(c%G11_d, c%G12_d, c%G13_d, &
912 c%G22_d, c%G23_d, c%G33_d, &
913 c%drdx_d, c%drdy_d, c%drdz_d, &
914 c%dsdx_d, c%dsdy_d, c%dsdz_d, &
915 c%dtdx_d, c%dtdy_d, c%dtdz_d, &
916 c%jacinv_d, c%Xh%w3_d, c%msh%nelv, &
917 c%Xh%lx, c%msh%gdim)
918
919 ! copy to host only at initialization.
920 if (.not. c%coef_metrics_initialized) then
921 call device_memcpy(c%G11, c%G11_d, ntot, device_to_host, &
922 sync = .false.)
923 call device_memcpy(c%G22, c%G22_d, ntot, device_to_host, &
924 sync = .false.)
925 call device_memcpy(c%G33, c%G33_d, ntot, device_to_host, &
926 sync = .false.)
927 call device_memcpy(c%G12, c%G12_d, ntot, device_to_host, &
928 sync = .false.)
929 call device_memcpy(c%G13, c%G13_d, ntot, device_to_host, &
930 sync = .false.)
931 call device_memcpy(c%G23, c%G23_d, ntot, device_to_host, &
932 sync = .true.)
933 end if
934
935 else
936 if (c%msh%gdim .eq. 2) then
937
938 do i = 1, ntot
939 c%G11(i, 1, 1, 1) = c%drdx(i, 1, 1, 1) * c%drdx(i, 1, 1, 1) &
940 + c%drdy(i, 1, 1, 1) * c%drdy(i, 1, 1, 1)
941
942 c%G22(i, 1, 1, 1) = c%dsdx(i, 1, 1, 1) * c%dsdx(i, 1, 1, 1) &
943 + c%dsdy(i, 1, 1, 1) * c%dsdy(i, 1, 1, 1)
944
945 c%G12(i, 1, 1, 1) = c%drdx(i, 1, 1, 1) * c%dsdx(i, 1, 1, 1) &
946 + c%drdy(i, 1, 1, 1) * c%dsdy(i, 1, 1, 1)
947 end do
948
949 do i = 1, ntot
950 c%G11(i, 1, 1, 1) = c%G11(i, 1, 1, 1) * c%jacinv(i, 1, 1, 1)
951 c%G22(i, 1, 1, 1) = c%G22(i, 1, 1, 1) * c%jacinv(i, 1, 1, 1)
952 c%G12(i, 1, 1, 1) = c%G12(i, 1, 1, 1) * c%jacinv(i, 1, 1, 1)
953 c%G33(i, 1, 1, 1) = 0.0_rp
954 c%G13(i, 1, 1, 1) = 0.0_rp
955 c%G23(i, 1, 1, 1) = 0.0_rp
956 end do
957
958 do concurrent(e = 1:c%msh%nelv)
959 do concurrent(i = 1:lxyz)
960 c%G11(i,1,1,e) = c%G11(i,1,1,e) * c%Xh%w3(i,1,1)
961 c%G22(i,1,1,e) = c%G22(i,1,1,e) * c%Xh%w3(i,1,1)
962 c%G12(i,1,1,e) = c%G12(i,1,1,e) * c%Xh%w3(i,1,1)
963 end do
964 end do
965
966 else
967 !$omp parallel private(i)
968 !$omp do
969 do i = 1, ntot
970 c%G11(i, 1, 1, 1) = c%drdx(i, 1, 1, 1) * c%drdx(i, 1, 1, 1) &
971 + c%drdy(i, 1, 1, 1) * c%drdy(i, 1, 1, 1) &
972 + c%drdz(i, 1, 1, 1) * c%drdz(i, 1, 1, 1)
973
974 c%G22(i, 1, 1, 1) = c%dsdx(i, 1, 1, 1) * c%dsdx(i, 1, 1, 1) &
975 + c%dsdy(i, 1, 1, 1) * c%dsdy(i, 1, 1, 1) &
976 + c%dsdz(i, 1, 1, 1) * c%dsdz(i, 1, 1, 1)
977
978 c%G33(i, 1, 1, 1) = c%dtdx(i, 1, 1, 1) * c%dtdx(i, 1, 1, 1) &
979 + c%dtdy(i, 1, 1, 1) * c%dtdy(i, 1, 1, 1) &
980 + c%dtdz(i, 1, 1, 1) * c%dtdz(i, 1, 1, 1)
981 end do
982 !$omp end do
983 !$omp do
984 do i = 1, ntot
985 c%G11(i, 1, 1, 1) = c%G11(i, 1, 1, 1) * c%jacinv(i, 1, 1, 1)
986 c%G22(i, 1, 1, 1) = c%G22(i, 1, 1, 1) * c%jacinv(i, 1, 1, 1)
987 c%G33(i, 1, 1, 1) = c%G33(i, 1, 1, 1) * c%jacinv(i, 1, 1, 1)
988 end do
989 !$omp end do
990 !$omp do
991 do i = 1, ntot
992 c%G12(i, 1, 1, 1) = c%drdx(i, 1, 1, 1) * c%dsdx(i, 1, 1, 1) &
993 + c%drdy(i, 1, 1, 1) * c%dsdy(i, 1, 1, 1) &
994 + c%drdz(i, 1, 1, 1) * c%dsdz(i, 1, 1, 1)
995
996 c%G13(i, 1, 1, 1) = c%drdx(i, 1, 1, 1) * c%dtdx(i, 1, 1, 1) &
997 + c%drdy(i, 1, 1, 1) * c%dtdy(i, 1, 1, 1) &
998 + c%drdz(i, 1, 1, 1) * c%dtdz(i, 1, 1, 1)
999
1000 c%G23(i, 1, 1, 1) = c%dsdx(i, 1, 1, 1) * c%dtdx(i, 1, 1, 1) &
1001 + c%dsdy(i, 1, 1, 1) * c%dtdy(i, 1, 1, 1) &
1002 + c%dsdz(i, 1, 1, 1) * c%dtdz(i, 1, 1, 1)
1003 end do
1004 !$omp end do
1005 !$omp do
1006 do i = 1, ntot
1007 c%G12(i, 1, 1, 1) = c%G12(i, 1, 1, 1) * c%jacinv(i, 1, 1, 1)
1008 c%G13(i, 1, 1, 1) = c%G13(i, 1, 1, 1) * c%jacinv(i, 1, 1, 1)
1009 c%G23(i, 1, 1, 1) = c%G23(i, 1, 1, 1) * c%jacinv(i, 1, 1, 1)
1010 end do
1011 !$omp end do
1012 !$omp do
1013 do e = 1, c%msh%nelv
1014 do concurrent(i = 1:lxyz)
1015 c%G11(i,1,1,e) = c%G11(i,1,1,e) * c%Xh%w3(i,1,1)
1016 c%G22(i,1,1,e) = c%G22(i,1,1,e) * c%Xh%w3(i,1,1)
1017 c%G12(i,1,1,e) = c%G12(i,1,1,e) * c%Xh%w3(i,1,1)
1018
1019 c%G33(i,1,1,e) = c%G33(i,1,1,e) * c%Xh%w3(i,1,1)
1020 c%G13(i,1,1,e) = c%G13(i,1,1,e) * c%Xh%w3(i,1,1)
1021 c%G23(i,1,1,e) = c%G23(i,1,1,e) * c%Xh%w3(i,1,1)
1022 end do
1023 end do
1024 !$omp end do
1025 !$omp end parallel
1026 end if
1027 end if
1028
1029 end subroutine coef_generate_geo
1030
1034 type(coef_t), intent(inout) :: c
1035 integer :: e, m, i, lxyz, m_max
1036 integer, allocatable :: c_inds_rev(:) ! reverse compression indices map
1037 real(kind=rp) :: ctol = 1.0e-7_rp
1038 real(kind=rp) :: diff = 0.0_rp
1039
1040 ! First step, allocate full-size lookup structure for entire mesh
1041 allocate(c%compression_inds(c%msh%nelv))
1042 allocate(c_inds_rev(c%msh%nelv))
1043
1044 ! Second step, loop over all elements, compute compression mapping
1045 ! First entry must be itself to get started
1046 m_max = 1
1047 c%compression_inds(1) = 1
1048 c_inds_rev = 0
1049 c_inds_rev(1) = 1
1050
1051 ! Loop over elements, but skip first
1052 lxyz = c%Xh%lx * c%Xh%ly * c%Xh%lz
1053 do e = 2, c%msh%nelv
1054 ! Loop over possible compression candidates
1055 do m = 1, m_max
1056 diff = 0.0_rp
1057 ! Loop over quadrature points
1058 do i = 1, lxyz
1059 ! diff += abs( \| G(i,:,:,e) - G(i,:,:,reverse(m)) \|_l1 )
1060 diff = diff + abs(c%G11(i,1,1,e) - c%G11(i,1,1,c_inds_rev(m))) &
1061 + 2.0*abs(c%G12(i,1,1,e) - c%G12(i,1,1,c_inds_rev(m))) &
1062 + 2.0*abs(c%G13(i,1,1,e) - c%G13(i,1,1,c_inds_rev(m))) &
1063 + abs(c%G22(i,1,1,e) - c%G22(i,1,1,c_inds_rev(m))) &
1064 + 2.0*abs(c%G23(i,1,1,e) - c%G23(i,1,1,c_inds_rev(m))) &
1065 + abs(c%G33(i,1,1,e) - c%G33(i,1,1,c_inds_rev(m)))
1066 end do
1067
1068 ! match is found; mapping(e) is redundant
1069 if ( diff .le. ctol ) then
1070 c%compression_inds(e) = m
1071 exit
1072 end if
1073 end do
1074
1075 ! never found a match
1076 if ( diff .gt. ctol ) then
1077 m_max = m_max + 1
1078 c%compression_inds(e) = m_max
1079 c_inds_rev(m_max) = e
1080 end if
1081 end do
1082
1083 write(*,*)
1084 write(*,*) '------Mapping Compression-----'
1085 write(*,*) 'Compressed from ', c%msh%nelv, ' to ', m_max
1086
1087 ! Third step, allocate and fill Gij_compressed objects
1088 allocate(c%G11_compressed(c%Xh%lx, c%Xh%ly, c%Xh%lz, m_max))
1089 allocate(c%G22_compressed(c%Xh%lx, c%Xh%ly, c%Xh%lz, m_max))
1090 allocate(c%G33_compressed(c%Xh%lx, c%Xh%ly, c%Xh%lz, m_max))
1091 allocate(c%G12_compressed(c%Xh%lx, c%Xh%ly, c%Xh%lz, m_max))
1092 allocate(c%G13_compressed(c%Xh%lx, c%Xh%ly, c%Xh%lz, m_max))
1093 allocate(c%G23_compressed(c%Xh%lx, c%Xh%ly, c%Xh%lz, m_max))
1094 do m = 1, m_max
1095 do i = 1, lxyz
1096 c%G11_compressed(i,1,1,m) = c%G11(i,1,1,c_inds_rev(m))
1097 c%G22_compressed(i,1,1,m) = c%G22(i,1,1,c_inds_rev(m))
1098 c%G33_compressed(i,1,1,m) = c%G33(i,1,1,c_inds_rev(m))
1099 c%G12_compressed(i,1,1,m) = c%G12(i,1,1,c_inds_rev(m))
1100 c%G13_compressed(i,1,1,m) = c%G13(i,1,1,c_inds_rev(m))
1101 c%G23_compressed(i,1,1,m) = c%G23(i,1,1,c_inds_rev(m))
1102 end do
1103 end do
1104
1105 deallocate(c_inds_rev)
1106
1107 end subroutine coef_generate_geo_compressed
1108
1112 type(coef_t), intent(inout) :: c
1113 integer :: e, i, lxyz, ntot
1114
1115 lxyz = c%Xh%lx * c%Xh%ly * c%Xh%lz
1116 ntot = c%dof%size()
1117
1118 if (neko_bcknd_device .eq. 1) then
1119 call device_coef_generate_mass(c%B_d, c%Binv_d, c%jac_d, c%Xh%w3_d, &
1120 lxyz, c%msh%nelv)
1121 ! copy to host only at initialization.
1122 if (.not. c%coef_metrics_initialized) then
1123 call device_memcpy(c%B, c%B_d, ntot, device_to_host, sync = .false.)
1124 end if
1125 else
1126 do concurrent(e = 1:c%msh%nelv)
1127 ! Here we need to handle things differently for axis symmetric elements
1128 do concurrent(i = 1:lxyz)
1129 c%B(i,1,1,e) = c%jac(i,1,1,e) * c%Xh%w3(i,1,1)
1130 c%Binv(i,1,1,e) = c%B(i,1,1,e)
1131 end do
1132 end do
1133 end if
1134
1135 call c%gs_h%op(c%Binv, ntot, gs_op_add)
1136
1137 if (neko_bcknd_device .eq. 1) then
1138 call device_invcol1(c%Binv_d, ntot)
1139 ! copy to host only at initialization.
1140 if (.not. c%coef_metrics_initialized) then
1141 call device_memcpy(c%Binv, c%Binv_d, ntot, &
1142 device_to_host, sync = .true.)
1143 end if
1144 else
1145 call invcol1(c%Binv, ntot)
1146 end if
1147
1149 if (neko_bcknd_device .eq. 1) then
1150 c%volume = device_glsum(c%B_d, ntot)
1151 else
1152 c%volume = glsum(c%B, ntot)
1153 end if
1154
1155 end subroutine coef_generate_mass
1156
1157 pure function coef_get_normal(this, i, j, k, e, facet) result(normal)
1158 class(coef_t), intent(in) :: this
1159 integer, intent(in) :: i, j, k, e, facet
1160 real(kind=rp) :: normal(3)
1161
1162 select case (facet)
1163 case (1, 2)
1164 normal(1) = this%nx(j, k, facet, e)
1165 normal(2) = this%ny(j, k, facet, e)
1166 normal(3) = this%nz(j, k, facet, e)
1167 case (3, 4)
1168 normal(1) = this%nx(i, k, facet, e)
1169 normal(2) = this%ny(i, k, facet, e)
1170 normal(3) = this%nz(i, k, facet, e)
1171 case (5, 6)
1172 normal(1) = this%nx(i, j, facet, e)
1173 normal(2) = this%ny(i, j, facet, e)
1174 normal(3) = this%nz(i, j, facet, e)
1175 end select
1176 end function coef_get_normal
1177
1178 pure function coef_get_area(this, i, j, k, e, facet) result(area)
1179 class(coef_t), intent(in) :: this
1180 integer, intent(in) :: i, j, k, e, facet
1181 real(kind=rp) :: area
1182
1183 select case (facet)
1184 case (1, 2)
1185 area = this%area(j, k, facet, e)
1186 case (3, 4)
1187 area = this%area(i, k, facet, e)
1188 case (5, 6)
1189 area = this%area(i, j, facet, e)
1190 end select
1191 end function coef_get_area
1192
1193
1196 type(coef_t), intent(inout) :: coef
1197 real(kind=rp), allocatable :: a(:,:,:,:)
1198 real(kind=rp), allocatable :: b(:,:,:,:)
1199 real(kind=rp), allocatable :: c(:,:,:,:)
1200 real(kind=rp), allocatable :: dot(:,:,:,:)
1201 integer :: n, m, e, i, j, k, lx
1202 real(kind=rp) :: weight, len
1203 n = coef%dof%size()
1204 lx = coef%Xh%lx
1205
1206 if (neko_bcknd_device .eq. 1) then
1207
1208 call device_coef_generate_area_and_normal( &
1209 coef%area_d, coef%nx_d, coef%ny_d, coef%nz_d, &
1210 coef%dxdr_d, coef%dydr_d, coef%dzdr_d, &
1211 coef%dxds_d, coef%dyds_d, coef%dzds_d, &
1212 coef%dxdt_d, coef%dydt_d, coef%dzdt_d, &
1213 coef%Xh%wx_d, coef%Xh%wy_d, coef%Xh%wz_d, &
1214 lx, coef%msh%nelv, neko_eps)
1215
1216 ! Here, we always copy back to host.
1217 m = size(coef%area)
1218 call device_memcpy(coef%area, coef%area_d, m, &
1219 device_to_host, sync = .false.)
1220 call device_memcpy(coef%nx, coef%nx_d, m, &
1221 device_to_host, sync = .false.)
1222 call device_memcpy(coef%ny, coef%ny_d, m, &
1223 device_to_host, sync = .false.)
1224 call device_memcpy(coef%nz, coef%nz_d, &
1225 m, device_to_host, sync = .true.)
1226
1227 else
1228
1229 allocate(a(coef%Xh%lx, coef%Xh%lx, coef%Xh%lx, coef%msh%nelv))
1230 allocate(b(coef%Xh%lx, coef%Xh%lx, coef%Xh%lx, coef%msh%nelv))
1231 allocate(c(coef%Xh%lx, coef%Xh%lx, coef%Xh%lx, coef%msh%nelv))
1232 allocate(dot(coef%Xh%lx, coef%Xh%lx, coef%Xh%lx, coef%msh%nelv))
1233
1234 !$omp parallel private (e, i, j, k, weight, len)
1235
1236 ! ds x dt
1237 !$omp do simd
1238 do i = 1, n
1239 a(i, 1, 1, 1) = coef%dyds(i, 1, 1, 1) * coef%dzdt(i, 1, 1, 1) &
1240 - coef%dzds(i, 1, 1, 1) * coef%dydt(i, 1, 1, 1)
1241
1242 b(i, 1, 1, 1) = coef%dzds(i, 1, 1, 1) * coef%dxdt(i, 1, 1, 1) &
1243 - coef%dxds(i, 1, 1, 1) * coef%dzdt(i, 1, 1, 1)
1244
1245 c(i, 1, 1, 1) = coef%dxds(i, 1, 1, 1) * coef%dydt(i, 1, 1, 1) &
1246 - coef%dyds(i, 1, 1, 1) * coef%dxdt(i, 1, 1, 1)
1247 end do
1248 !$omp end do simd
1249 !$omp do simd
1250 do i = 1, n
1251 dot(i, 1, 1, 1) = a(i, 1, 1, 1) * a(i, 1, 1, 1) &
1252 + b(i, 1, 1, 1) * b(i, 1, 1, 1) &
1253 + c(i, 1, 1, 1) * c(i, 1, 1, 1)
1254 end do
1255 !$omp end do simd
1256 !$omp do
1257 do e = 1, coef%msh%nelv
1258 do concurrent(k = 1:coef%Xh%lx)
1259 do concurrent(j = 1:coef%Xh%lx)
1260 weight = coef%Xh%wy(j) * coef%Xh%wz(k)
1261 coef%area(j, k, 2, e) = sqrt(dot(lx, j, k, e)) * weight
1262 coef%area(j, k, 1, e) = sqrt(dot(1, j, k, e)) * weight
1263 coef%nx(j,k, 1, e) = -a(1, j, k, e)
1264 coef%nx(j,k, 2, e) = a(lx, j, k, e)
1265 coef%ny(j,k, 1, e) = -b(1, j, k, e)
1266 coef%ny(j,k, 2, e) = b(lx, j, k, e)
1267 coef%nz(j,k, 1, e) = -c(1, j, k, e)
1268 coef%nz(j,k, 2, e) = c(lx, j, k, e)
1269 end do
1270 end do
1271 end do
1272 !$omp end do
1273
1274 ! dr x dt
1275 !$omp do simd
1276 do i = 1, n
1277 a(i, 1, 1, 1) = coef%dydr(i, 1, 1, 1) * coef%dzdt(i, 1, 1, 1) &
1278 - coef%dzdr(i, 1, 1, 1) * coef%dydt(i, 1, 1, 1)
1279
1280 b(i, 1, 1, 1) = coef%dzdr(i, 1, 1, 1) * coef%dxdt(i, 1, 1, 1) &
1281 - coef%dxdr(i, 1, 1, 1) * coef%dzdt(i, 1, 1, 1)
1282
1283 c(i, 1, 1, 1) = coef%dxdr(i, 1, 1, 1) * coef%dydt(i, 1, 1, 1) &
1284 - coef%dydr(i, 1, 1, 1) * coef%dxdt(i, 1, 1, 1)
1285 end do
1286 !$omp end do simd
1287 !$omp do simd
1288 do i = 1, n
1289 dot(i, 1, 1, 1) = a(i, 1, 1, 1) * a(i, 1, 1, 1) &
1290 + b(i, 1, 1, 1) * b(i, 1, 1, 1) &
1291 + c(i, 1, 1, 1) * c(i, 1, 1, 1)
1292 end do
1293 !$omp end do simd
1294 !$omp do
1295 do e = 1, coef%msh%nelv
1296 do concurrent(k = 1:coef%Xh%lx)
1297 do concurrent(j = 1:coef%Xh%lx)
1298 weight = coef%Xh%wx(j) * coef%Xh%wz(k)
1299 coef%area(j, k, 3, e) = sqrt(dot(j, 1, k, e)) * weight
1300 coef%area(j, k, 4, e) = sqrt(dot(j, lx, k, e)) * weight
1301 coef%nx(j,k, 3, e) = a(j, 1, k, e)
1302 coef%nx(j,k, 4, e) = -a(j, lx, k, e)
1303 coef%ny(j,k, 3, e) = b(j, 1, k, e)
1304 coef%ny(j,k, 4, e) = -b(j, lx, k, e)
1305 coef%nz(j,k, 3, e) = c(j, 1, k, e)
1306 coef%nz(j,k, 4, e) = -c(j, lx, k, e)
1307 end do
1308 end do
1309 end do
1310 !$omp end do
1311 ! dr x ds
1312 !$omp do simd
1313 do i = 1, n
1314 a(i, 1, 1, 1) = coef%dydr(i, 1, 1, 1) * coef%dzds(i, 1, 1, 1) &
1315 - coef%dzdr(i, 1, 1, 1) * coef%dyds(i, 1, 1, 1)
1316
1317 b(i, 1, 1, 1) = coef%dzdr(i, 1, 1, 1) * coef%dxds(i, 1, 1, 1) &
1318 - coef%dxdr(i, 1, 1, 1) * coef%dzds(i, 1, 1, 1)
1319
1320 c(i, 1, 1, 1) = coef%dxdr(i, 1, 1, 1) * coef%dyds(i, 1, 1, 1) &
1321 - coef%dydr(i, 1, 1, 1) * coef%dxds(i, 1, 1, 1)
1322 end do
1323 !$omp end do simd
1324 !$omp do simd
1325 do i = 1, n
1326 dot(i, 1, 1, 1) = a(i, 1, 1, 1) * a(i, 1, 1, 1) &
1327 + b(i, 1, 1, 1) * b(i, 1, 1, 1) &
1328 + c(i, 1, 1, 1) * c(i, 1, 1, 1)
1329 end do
1330 !$omp end do simd
1331 !$omp do
1332 do e = 1, coef%msh%nelv
1333 do concurrent(k = 1:coef%Xh%lx)
1334 do concurrent(j = 1:coef%Xh%lx)
1335 weight = coef%Xh%wx(j) * coef%Xh%wy(k)
1336 coef%area(j, k, 5, e) = sqrt(dot(j, k, 1, e)) * weight
1337 coef%area(j, k, 6, e) = sqrt(dot(j, k, lx, e)) * weight
1338 coef%nx(j,k, 5, e) = -a(j, k, 1, e)
1339 coef%nx(j,k, 6, e) = a(j, k, lx, e)
1340 coef%ny(j,k, 5, e) = -b(j, k, 1, e)
1341 coef%ny(j,k, 6, e) = b(j, k, lx, e)
1342 coef%nz(j,k, 5, e) = -c(j, k, 1, e)
1343 coef%nz(j,k, 6, e) = c(j, k, lx, e)
1344 end do
1345 end do
1346 end do
1347 !$omp end do
1348 ! Normalize
1349 !$omp do
1350 do j = 1, size(coef%nz)
1351 len = sqrt(coef%nx(j,1,1,1)**2 + &
1352 coef%ny(j,1,1,1)**2 + coef%nz(j,1,1,1)**2)
1353 if (len .gt. neko_eps) then
1354 coef%nx(j,1,1,1) = coef%nx(j,1,1,1) / len
1355 coef%ny(j,1,1,1) = coef%ny(j,1,1,1) / len
1356 coef%nz(j,1,1,1) = coef%nz(j,1,1,1) / len
1357 end if
1358 end do
1359 !$omp end do
1360 !$omp end parallel
1361
1362 deallocate(dot)
1363 deallocate(c)
1364 deallocate(b)
1365 deallocate(a)
1366
1367 end if
1368
1369 end subroutine coef_generate_area_and_normal
1370
1372 class(coef_t), intent(inout) :: this
1373 real(kind=rp) :: un(3), len, d
1374 integer :: lx, ly, lz, np, np_glb, ierr
1375 integer :: i, j, k, pf, pe, n, nc, ncyc
1376
1377 if (.not. this%cyclic) return
1378
1379 np = this%msh%periodic%size
1380 call mpi_allreduce(np, np_glb, 1, &
1381 mpi_integer, mpi_sum, neko_comm, ierr)
1382
1383 if (np_glb .eq. 0) then
1384 call neko_error("There are no periodic boundaries. " // &
1385 "Switch cyclic off in the case file.")
1386 end if
1387
1388 if (np .eq. 0) return
1389
1390 lx = this%Xh%lx
1391 ly = this%Xh%ly
1392 lz = this%Xh%lz
1393 ncyc = this%cyc_msk(0) - 1
1394 nc = 1
1395 do n = 1, np
1396 pf = this%msh%periodic%facet_el(n)%x(1)
1397 pe = this%msh%periodic%facet_el(n)%x(2)
1398 do k = 1, lz
1399 do j = 1, ly
1400 do i = 1, lx
1401 if (index_is_on_facet(i, j, k, lx, ly, lz, pf)) then
1402 un = this%get_normal(i, j, k, pe, pf)
1403 len = sqrt(un(1) * un(1) + un(2) * un(2))
1404 if (len .gt. neko_eps) then
1405 d = this%dof%y(i, j, k, pe) * un(1) &
1406 - this%dof%x(i, j, k, pe) * un(2)
1407
1408 this%cyc_msk(nc) = linear_index(i, j, k, pe, lx, ly, lz)
1409 this%R11(nc) = un(1) / len * sign(1.0_rp, d)
1410 this%R12(nc) = un(2) / len * sign(1.0_rp, d)
1411 nc = nc + 1
1412 else
1413 call neko_error("x and y components of surface " // &
1414 "normals are zero. Cyclic rotations must be " // &
1415 "around z-axis.")
1416 end if
1417 end if
1418 end do
1419 end do
1420 end do
1421 end do
1422
1423 if (nc - 1 /= ncyc) then
1424 call neko_error("The number of cyclic GLL points were " // &
1425 "not estimated correctly.")
1426 end if
1427
1428 if (neko_bcknd_device .eq. 1) then
1429 call device_memcpy(this%cyc_msk, this%cyc_msk_d, ncyc+1, &
1430 host_to_device, sync = .false.)
1431 call device_memcpy(this%R11, this%R11_d, ncyc, &
1432 host_to_device, sync = .false.)
1433 call device_memcpy(this%R12, this%R12_d, ncyc, &
1434 host_to_device, sync = .false.)
1435 end if
1436
1437 end subroutine coef_generate_cyclic_bc
1438
1439
1441 subroutine coef_recompute_metrics(this)
1442 class(coef_t), intent(inout) :: this
1443
1444 call coef_generate_dxyzdrst(this)
1445 call coef_generate_geo(this)
1447 call coef_generate_mass(this)
1448 if (this%cyclic) then
1449 call coef_generate_cyclic_bc(this)
1450 end if
1451 end subroutine coef_recompute_metrics
1452
1453
1457 class(coef_t), intent(inout), target :: this
1458 integer :: n
1459
1460 ! Return if already allocated distinctly
1461 if (.not. associated(this%Blag, this%B)) return
1462
1463 n = this%Xh%lx * this%Xh%ly * this%Xh%lz * this%msh%nelv
1464
1465
1466 nullify(this%Blag)
1467 nullify(this%Blaglag)
1468
1469 allocate(this%Blag(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
1470 allocate(this%Blaglag(this%Xh%lx, this%Xh%ly, this%Xh%lz, this%msh%nelv))
1471
1472 this%Blag = this%B
1473 this%Blaglag = this%B
1474
1475 if (neko_bcknd_device .eq. 1) then
1476
1477 this%Blag_d = c_null_ptr
1478 this%Blaglag_d = c_null_ptr
1479
1480 call device_map(this%Blag, this%Blag_d, n)
1481 call device_map(this%Blaglag, this%Blaglag_d, n)
1482
1483 call device_memcpy(this%Blag, this%Blag_d, n, &
1484 host_to_device, sync = .false.)
1485 call device_memcpy(this%Blaglag, this%Blaglag_d, n, &
1486 host_to_device, sync = .true.)
1487 end if
1488
1489 end subroutine coef_enable_lagged_mass
1490
1491
1494 class(coef_t), intent(inout), target :: this
1495 integer :: n
1496
1497 ! If this%Blag does not have separate memory, we don't need to update it.
1498 if (associated(this%Blag, this%B)) return
1499 n = this%Xh%lx * this%Xh%ly * this%Xh%lz * this%msh%nelv
1500 if (neko_bcknd_device .eq. 1) then
1501 call device_copy(this%Blaglag_d, this%Blag_d, n)
1502 call device_copy(this%Blag_d, this%B_d, n)
1503 else
1504 this%Blaglag = this%Blag
1505 this%Blag = this%B
1506 end if
1507
1508 end subroutine coef_update_lagged_mass
1509
1510end 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:903
subroutine coef_free(this)
Deallocate coefficients.
Definition coef.f90:449
subroutine coef_recompute_metrics(this)
Recompute and update geometric factors (ALE)
Definition coef.f90:1442
pure real(kind=rp) function coef_get_area(this, i, j, k, e, facet)
Definition coef.f90:1179
pure real(kind=rp) function, dimension(3) coef_get_normal(this, i, j, k, e, facet)
Definition coef.f90:1158
subroutine coef_update_lagged_mass(this)
Update history: Blaglag = Blag, Blag = B.
Definition coef.f90:1494
subroutine coef_generate_dxyzdrst(c)
Definition coef.f90:714
subroutine coef_generate_area_and_normal(coef)
Generate facet area and surface normals.
Definition coef.f90:1196
subroutine coef_init_empty(this, xh, msh)
Initialize empty coefs for a space and a mesh.
Definition coef.f90:202
subroutine coef_init_all(this, gs_h)
Initialize coefficients.
Definition coef.f90:248
subroutine coef_enable_lagged_mass(this)
Enable separate memory for lagged B matrices if needed. For eg. when mesh moves.
Definition coef.f90:1457
subroutine coef_generate_geo_compressed(c)
Compute processor-local compressed versions of mappings Gij.
Definition coef.f90:1034
subroutine coef_generate_cyclic_bc(this)
Definition coef.f90:1372
subroutine coef_generate_mass(c)
Generate mass matrix B for the given mesh and space.
Definition coef.f90:1112
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