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