Neko 1.99.3
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
opr_xsmm.F90
Go to the documentation of this file.
1! Copyright (c) 2008-2020, UCHICAGO ARGONNE, LLC.
2!
3! The UChicago Argonne, LLC as Operator of Argonne National
4! Laboratory holds copyright in the Software. The copyright holder
5! reserves all rights except those expressly granted to licensees,
6! and U.S. Government license rights.
7!
8! Redistribution and use in source and binary forms, with or without
9! modification, are permitted provided that the following conditions
10! are met:
11!
12! 1. Redistributions of source code must retain the above copyright
13! notice, this list of conditions and the disclaimer below.
14!
15! 2. Redistributions in binary form must reproduce the above copyright
16! notice, this list of conditions and the disclaimer (as noted below)
17! in the documentation and/or other materials provided with the
18! distribution.
19!
20! 3. Neither the name of ANL nor the names of its contributors
21! may be used to endorse or promote products derived from this software
22! without specific prior written permission.
23!
24! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25! "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26! LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27! FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
28! UCHICAGO ARGONNE, LLC, THE U.S. DEPARTMENT OF
29! ENERGY OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30! SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
31! TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32! DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33! THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34! (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35! OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36!
37! Additional BSD Notice
38! ---------------------
39! 1. This notice is required to be provided under our contract with
40! the U.S. Department of Energy (DOE). This work was produced at
41! Argonne National Laboratory under Contract
42! No. DE-AC02-06CH11357 with the DOE.
43!
44! 2. Neither the United States Government nor UCHICAGO ARGONNE,
45! LLC nor any of their employees, makes any warranty,
46! express or implied, or assumes any liability or responsibility for the
47! accuracy, completeness, or usefulness of any information, apparatus,
48! product, or process disclosed, or represents that its use would not
49! infringe privately-owned rights.
50!
51! 3. Also, reference herein to any specific commercial products, process,
52! or services by trade name, trademark, manufacturer or otherwise does
53! not necessarily constitute or imply its endorsement, recommendation,
54! or favoring by the United States Government or UCHICAGO ARGONNE LLC.
55! The views and opinions of authors expressed
56! herein do not necessarily state or reflect those of the United States
57! Government or UCHICAGO ARGONNE, LLC, and shall
58! not be used for advertising or product endorsement purposes.
59!
62 use num_types, only : rp
63 use mxm_wrapper, only : mxm
64 use space, only : space_t
65 use coefs, only : coef_t
66 use math, only : rzero, col2, col3, sub3, add2, addcol3, invcol2, copy
67 use mesh, only : mesh_t
69 use gather_scatter, only : gs_t, gs_op_add
70 use mathops, only : opcolv
71#ifdef HAVE_LIBXSMM
72 use libxsmm, only: libxsmm_mmcall => libxsmm_dmmcall_abc, &
73 libxsmm_dmmfunction, libxsmm_dispatch, &
74 libxsmm_prefetch_auto
75#endif
76 implicit none
77 private
78
81
82#ifdef HAVE_LIBXSMM
83 type(libxsmm_dmmfunction), private :: lgrad_xmm1
84 type(libxsmm_dmmfunction), private :: lgrad_xmm2
85 type(libxsmm_dmmfunction), private :: lgrad_xmm3
86#endif
87
88contains
89
90 subroutine opr_xsmm_dudxyz(du, u, dr, ds, dt, coef)
91 type(coef_t), intent(in), target :: coef
92 real(kind=rp), dimension(coef%Xh%lx, coef%Xh%ly, coef%Xh%lz, & coef%msh%nelv), intent(inout) :: du
93 real(kind=rp), dimension(coef%Xh%lx, coef%Xh%ly, coef%Xh%lz, & coef%msh%nelv), intent(in) :: u, dr, ds, dt
94#ifdef HAVE_LIBXSMM
95 real(kind=rp) :: drst(coef%Xh%lx, coef%Xh%ly, coef%Xh%lz)
96 type(space_t), pointer :: xh
97 type(mesh_t), pointer :: msh
98 integer :: e, k, lxy, lyz, lxyz
99 type(libxsmm_dmmfunction), save :: dudxyz_xmm1
100 type(libxsmm_dmmfunction), save :: dudxyz_xmm2
101 type(libxsmm_dmmfunction), save :: dudxyz_xmm3
102 logical, save :: dudxyz_xsmm_init = .false.
103
104 xh => coef%Xh
105 msh => coef%msh
106 lxy = xh%lx*xh%ly
107 lyz = xh%ly*xh%lz
108 lxyz = xh%lx*xh%ly*xh%lz
109
110 if (.not. dudxyz_xsmm_init) then
111 call libxsmm_dispatch(dudxyz_xmm1, xh%lx, xh%ly*xh%lz, xh%lx, &
112 alpha = 1d0, beta = 0d0, prefetch = libxsmm_prefetch_auto)
113 call libxsmm_dispatch(dudxyz_xmm2, xh%lx, xh%ly, xh%ly, &
114 alpha = 1d0, beta = 0d0, prefetch = libxsmm_prefetch_auto)
115 call libxsmm_dispatch(dudxyz_xmm3, xh%lx*xh%ly, xh%lz, xh%lz, &
116 alpha = 1d0, beta = 0d0, prefetch = libxsmm_prefetch_auto)
117 dudxyz_xsmm_init = .true.
118 end if
119
120 do e = 1, msh%nelv
121 if (msh%gdim .eq. 2) then
122 call mxm(xh%dx, xh%lx, u(1,1,1,e), xh%lx, du(1,1,1,e), lyz)
123 call col2(du(1,1,1,e), dr(1,1,1,e), lxyz)
124 call mxm(u(1,1,1,e), xh%lx, xh%dyt, xh%ly, drst, xh%ly)
125 call addcol3(du(1,1,1,e), drst, ds(1,1,1,e), lxyz)
126 else
127 call libxsmm_mmcall(dudxyz_xmm1, xh%dx, u(1,1,1,e), du(1,1,1,e))
128 call col2(du(1,1,1,e), dr(1,1,1,e), lxyz)
129 do k = 1, xh%lz
130 call libxsmm_mmcall(dudxyz_xmm2, u(1,1,k,e), xh%dyt, drst(1,1,k))
131 end do
132 call addcol3(du(1,1,1,e), drst, ds(1,1,1,e), lxyz)
133 call libxsmm_mmcall(dudxyz_xmm3, u(1,1,1,e), xh%dzt, drst)
134 call addcol3(du(1,1,1,e), drst, dt(1,1,1,e), lxyz)
135 end if
136 end do
137 call col2(du, coef%jacinv, coef%dof%n_dofs)
138
139#endif
140 end subroutine opr_xsmm_dudxyz
141
142 subroutine opr_xsmm_opgrad(ux, uy, uz, u, coef)
143 type(coef_t), intent(in) :: coef
144 real(kind=rp), dimension(coef%Xh%lxyz, coef%msh%nelv), intent(inout) :: ux
145 real(kind=rp), dimension(coef%Xh%lxyz, coef%msh%nelv), intent(inout) :: uy
146 real(kind=rp), dimension(coef%Xh%lxyz, coef%msh%nelv), intent(inout) :: uz
147 real(kind=rp), dimension(coef%Xh%lxyz, coef%msh%nelv), intent(in) :: u
148#ifdef HAVE_LIBXSMM
149 real(kind=rp) :: ur(coef%Xh%lxyz)
150 real(kind=rp) :: us(coef%Xh%lxyz)
151 real(kind=rp) :: ut(coef%Xh%lxyz)
152 logical, save :: lgrad_xsmm_init = .false.
153 integer, save :: init_size = 0
154 integer :: e, i, n
155 n = coef%Xh%lx - 1
156
157
158 if ((.not. lgrad_xsmm_init) .or. &
159 (init_size .gt. 0 .and. init_size .ne. n)) then
160 call libxsmm_dispatch(lgrad_xmm1, (n+1), (n+1)**2, (n+1), &
161 alpha = 1d0, beta = 0d0, prefetch = libxsmm_prefetch_auto)
162 call libxsmm_dispatch(lgrad_xmm2, (n+1), (n+1), (n+1), &
163 alpha = 1d0, beta = 0d0, prefetch = libxsmm_prefetch_auto)
164 call libxsmm_dispatch(lgrad_xmm3, (n+1)**2, (n+1), (n+1), &
165 alpha = 1d0, beta = 0d0, prefetch = libxsmm_prefetch_auto)
166 lgrad_xsmm_init = .true.
167 init_size = n
168 end if
169
170 do e = 1, coef%msh%nelv
171 if (coef%msh%gdim .eq. 3) then
172 call local_grad3_xsmm(ur, us, ut, u(1,e), n, coef%Xh%dx, coef%Xh%dxt)
173 do i = 1, coef%Xh%lxyz
174 ux(i,e) = coef%Xh%w3(i,1,1) * (ur(i) * coef%drdx(i,1,1,e) &
175 + us(i) * coef%dsdx(i,1,1,e) &
176 + ut(i) * coef%dtdx(i,1,1,e) )
177 uy(i,e) = coef%Xh%w3(i,1,1) * (ur(i) * coef%drdy(i,1,1,e) &
178 + us(i) * coef%dsdy(i,1,1,e) &
179 + ut(i) * coef%dtdy(i,1,1,e) )
180 uz(i,e) = coef%Xh%w3(i,1,1) * (ur(i) * coef%drdz(i,1,1,e) &
181 + us(i) * coef%dsdz(i,1,1,e) &
182 + ut(i) * coef%dtdz(i,1,1,e) )
183 end do
184 else
185
186 call local_grad2(ur, us, u(1,e), n, coef%Xh%dx, coef%Xh%dyt)
187
188 do i = 1, coef%Xh%lxyz
189 ux(i,e) = coef%Xh%w3(i,1,1) * (ur(i) * coef%drdx(i,1,1,e) &
190 + us(i) * coef%dsdx(i,1,1,e) )
191 uy(i,e) = coef%Xh%w3(i,1,1) * (ur(i) * coef%drdy(i,1,1,e) &
192 + us(i) * coef%dsdy(i,1,1,e) )
193 end do
194 end if
195 end do
196#endif
197 end subroutine opr_xsmm_opgrad
198
199 subroutine local_grad3_xsmm(ur, us, ut, u, n, D, Dt)
200 integer, intent(in) :: n
201 real(kind=rp), intent(inout) :: ur(0:n, 0:n, 0:n)
202 real(kind=rp), intent(inout) :: us(0:n, 0:n, 0:n)
203 real(kind=rp), intent(inout) :: ut(0:n, 0:n, 0:n)
204 real(kind=rp), intent(in) :: u(0:n, 0:n, 0:n)
205 real(kind=rp), intent(in) :: d(0:n, 0:n)
206 real(kind=rp), intent(in) :: dt(0:n, 0:n)
207#ifdef HAVE_LIBXSMM
208 integer :: m1, m2, k
209
210 m1 = n + 1
211 m2 = m1*m1
212
213 call libxsmm_mmcall(lgrad_xmm1, d, u, ur)
214 do k = 0, n
215 call libxsmm_mmcall(lgrad_xmm2, u(0,0,k), dt, us(0,0,k))
216 end do
217 call libxsmm_mmcall(lgrad_xmm3, u, dt, ut)
218#endif
219
220 end subroutine local_grad3_xsmm
221
222 subroutine local_grad2(ur, us, u, n, D, Dt)
223 integer, intent(in) :: n
224 real(kind=rp), intent(inout) :: ur(0:n, 0:n)
225 real(kind=rp), intent(inout) :: us(0:n, 0:n)
226 real(kind=rp), intent(in) :: u(0:n, 0:n)
227 real(kind=rp), intent(in) :: d(0:n, 0:n)
228 real(kind=rp), intent(in) :: dt(0:n, 0:n)
229 integer :: m1
230
231 m1 = n + 1
232
233 call mxm(d, m1, u, m1, ur, m1)
234 call mxm(u, m1, dt, m1, us, m1)
235
236 end subroutine local_grad2
237
238 subroutine opr_xsmm_cdtp(dtx, x, dr, ds, dt, coef)
239 type(coef_t), intent(in) :: coef
240 real(kind=rp), dimension(coef%Xh%lxyz, coef%msh%nelv), intent(inout) :: dtx
241 real(kind=rp), dimension(coef%Xh%lxyz, coef%msh%nelv), intent(inout) :: x
242 real(kind=rp), dimension(coef%Xh%lxyz, coef%msh%nelv), intent(in) :: dr
243 real(kind=rp), dimension(coef%Xh%lxyz, coef%msh%nelv), intent(in) :: ds
244 real(kind=rp), dimension(coef%Xh%lxyz, coef%msh%nelv), intent(in) :: dt
245#ifdef HAVE_LIBXSMM
246 real(kind=rp) :: wx(coef%Xh%lxyz)
247 real(kind=rp) :: ta1(coef%Xh%lxyz)
248 real(kind=rp) :: ta2(coef%Xh%lxyz)
249 real(kind=rp) :: ta3(coef%Xh%lxyz)
250 integer :: e, i1, i2, n1, n2, iz
251 type(space_t), pointer :: xh
252
253 type(libxsmm_dmmfunction), save :: cdtp_xmm1
254 type(libxsmm_dmmfunction), save :: cdtp_xmm2
255 type(libxsmm_dmmfunction), save :: cdtp_xmm3
256 logical, save :: cdtp_xsmm_init = .false.
257
258 xh => coef%Xh
259 n1 = xh%lx*xh%ly
260 n2 = xh%lx*xh%ly
261
262 if (.not. cdtp_xsmm_init) then
263 call libxsmm_dispatch(cdtp_xmm1, xh%lx, xh%ly*xh%lz, xh%lx, &
264 alpha = 1d0, beta = 0d0, prefetch = libxsmm_prefetch_auto)
265 call libxsmm_dispatch(cdtp_xmm2, xh%lx, xh%ly, xh%ly, &
266 alpha = 1d0, beta = 0d0, prefetch = libxsmm_prefetch_auto)
267 call libxsmm_dispatch(cdtp_xmm3, xh%lx*xh%ly, xh%lz, xh%lz, &
268 alpha = 1d0, beta = 0d0, prefetch = libxsmm_prefetch_auto)
269 cdtp_xsmm_init = .true.
270 end if
271
272 do e = 1, coef%msh%nelv
273 call col3(wx, coef%B(1,1,1,e), x(1,e), xh%lxyz)
274 call invcol2(wx, coef%jac(1,1,1,e), xh%lxyz)
275 call col3(ta1, wx, dr(1,e), xh%lxyz)
276 call libxsmm_mmcall(cdtp_xmm1, xh%dxt, ta1, dtx(1,e))
277 call col3 (ta1, wx, ds(1,e), xh%lxyz)
278 i1 = 1
279 i2 = 1
280 do iz = 1, xh%lz
281 call libxsmm_mmcall(cdtp_xmm2, ta1(i2), xh%dy, ta2(i1))
282 i1 = i1 + n1
283 i2 = i2 + n2
284 end do
285 call add2(dtx(1,e), ta2, xh%lxyz)
286 call col3(ta1, wx, dt(1,e), xh%lxyz)
287 call libxsmm_mmcall(cdtp_xmm3, ta1, xh%dz, ta2)
288 call add2 (dtx(1,e), ta2, xh%lxyz)
289 end do
290#endif
291 end subroutine opr_xsmm_cdtp
292
293 subroutine opr_xsmm_conv1(du, u, vx, vy, vz, Xh, coef, nelv, gdim)
294 type(space_t), intent(in) :: xh
295 type(coef_t), intent(in) :: coef
296 integer, intent(in) :: nelv, gdim
297 real(kind=rp), intent(inout) :: du(xh%lxyz, nelv)
298 real(kind=rp), intent(in), dimension(Xh%lx, Xh%ly, Xh%lz, nelv) :: u
299 real(kind=rp), intent(in), dimension(Xh%lx, Xh%ly, Xh%lz, nelv) :: vx
300 real(kind=rp), intent(in), dimension(Xh%lx, Xh%ly, Xh%lz, nelv) :: vy
301 real(kind=rp), intent(in), dimension(Xh%lx, Xh%ly, Xh%lz, nelv) :: vz
302#ifdef HAVE_LIBXSMM
303 ! Store the inverse jacobian to speed this operation up
304 real(kind=rp), dimension(Xh%lx, Xh%ly, Xh%lz) :: dudr, duds, dudt
305 integer :: ie, iz, i
306
307 type(libxsmm_dmmfunction), save :: conv1_xmm1
308 type(libxsmm_dmmfunction), save :: conv1_xmm2
309 type(libxsmm_dmmfunction), save :: conv1_xmm3
310 logical, save :: conv1_xsmm_init = .false.
311
312 if (.not. conv1_xsmm_init) then
313 call libxsmm_dispatch(conv1_xmm1, xh%lx, xh%ly*xh%lx, xh%lx, &
314 alpha = 1d0, beta = 0d0, prefetch = libxsmm_prefetch_auto)
315 call libxsmm_dispatch(conv1_xmm2, xh%lx, xh%ly, xh%ly, &
316 alpha = 1d0, beta = 0d0, prefetch = libxsmm_prefetch_auto)
317 call libxsmm_dispatch(conv1_xmm3, xh%lx*xh%ly, xh%lz, xh%lz, &
318 alpha = 1d0, beta = 0d0, prefetch = libxsmm_prefetch_auto)
319 conv1_xsmm_init = .true.
320 end if
321
322 ! Compute vel.grad(u)
323 do ie = 1, nelv
324 if (gdim .eq. 3) then
325 call libxsmm_mmcall(conv1_xmm1, xh%dx, u(1,1,1, ie), dudr)
326 do iz = 1, xh%lz
327 call libxsmm_mmcall(conv1_xmm2, u(1,1, iz, ie), xh%dyt,&
328 duds(1,1, iz))
329 end do
330 call libxsmm_mmcall(conv1_xmm3, u(1,1,1, ie), xh%dzt, dudt)
331 do i = 1, xh%lxyz
332 du(i, ie) = coef%jacinv(i,1,1, ie) * ( &
333 vx(i,1,1, ie) * ( &
334 coef%drdx(i,1,1, ie) * dudr(i,1,1) &
335 + coef%dsdx(i,1,1, ie) * duds(i,1,1) &
336 + coef%dtdx(i,1,1, ie) * dudt(i,1,1)) &
337 + vy(i,1,1, ie) * ( &
338 coef%drdy(i,1,1, ie) * dudr(i,1,1) &
339 + coef%dsdy(i,1,1, ie) * duds(i,1,1) &
340 + coef%dtdy(i,1,1, ie) * dudt(i,1,1)) &
341 + vz(i,1,1, ie) * ( &
342 coef%drdz(i,1,1, ie) * dudr(i,1,1) &
343 + coef%dsdz(i,1,1, ie) * duds(i,1,1) &
344 + coef%dtdz(i,1,1, ie) * dudt(i,1,1)))
345 end do
346 else
347 ! 2D
348 call mxm(xh%dx, xh%lx, u(1,1,1, ie), xh%lx, dudr, xh%lyz)
349 call mxm(u(1,1,1, ie), xh%lx, xh%dyt, xh%ly, duds, xh%ly)
350 do i = 1, xh%lxyz
351 du(i, ie) = coef%jacinv(i,1,1, ie) * ( &
352 vx(i,1,1, ie) * ( &
353 coef%drdx(i,1,1, ie) * dudr(i,1,1) &
354 + coef%dsdx(i,1,1, ie) * duds(i,1,1)) &
355 + vy(i,1,1, ie) * ( &
356 coef%drdy(i,1,1, ie) * dudr(i,1,1) &
357 + coef%dsdy(i,1,1, ie) * duds(i,1,1)))
358 end do
359 end if
360 end do
361
362#endif
363
364 end subroutine opr_xsmm_conv1
365
366 subroutine opr_xsmm_convect_scalar(du, u, cr, cs, ct, Xh_GLL, Xh_GL, &
367 coef_GLL, coef_GL, GLL_to_GL)
368 type(space_t), intent(in) :: xh_gl
369 type(space_t), intent(in) :: xh_gll
370 type(coef_t), intent(in) :: coef_gll
371 type(coef_t), intent(in) :: coef_gl
372 type(interpolator_t), intent(inout) :: gll_to_gl
373 real(kind=rp), intent(inout) :: du(xh_gll%lx, xh_gll%ly, xh_gll%lz, &
374 coef_gl%msh%nelv)
375 real(kind=rp), intent(inout) :: u(xh_gl%lxyz, coef_gl%msh%nelv)
376 real(kind=rp), intent(inout) :: cr(xh_gl%lxyz, coef_gl%msh%nelv)
377 real(kind=rp), intent(inout) :: cs(xh_gl%lxyz, coef_gl%msh%nelv)
378 real(kind=rp), intent(inout) :: ct(xh_gl%lxyz, coef_gl%msh%nelv)
379 real(kind=rp) :: ur(xh_gl%lxyz)
380 real(kind=rp) :: us(xh_gl%lxyz)
381 real(kind=rp) :: ut(xh_gl%lxyz)
382 real(kind=rp) :: ud(xh_gl%lxyz, coef_gl%msh%nelv)
383 logical, save :: lgrad_xsmm_init = .false.
384 integer, save :: init_size = 0
385 integer :: e, i, n, n_gll
386 n = coef_gl%Xh%lx - 1
387 n_gll = coef_gll%msh%nelv * xh_gll%lxyz
388
389#ifdef HAVE_LIBXSMM
390 if ((.not. lgrad_xsmm_init) .or. &
391 (init_size .gt. 0 .and. init_size .ne. n)) then
392 call libxsmm_dispatch(lgrad_xmm1, (n+1), (n+1)**2, (n+1), &
393 alpha = 1d0, beta = 0d0, prefetch = libxsmm_prefetch_auto)
394 call libxsmm_dispatch(lgrad_xmm2, (n+1), (n+1), (n+1), &
395 alpha = 1d0, beta = 0d0, prefetch = libxsmm_prefetch_auto)
396 call libxsmm_dispatch(lgrad_xmm3, (n+1)**2, (n+1), (n+1), &
397 alpha = 1d0, beta = 0d0, prefetch = libxsmm_prefetch_auto)
398 lgrad_xsmm_init = .true.
399 init_size = n
400 end if
401
402 do e = 1, coef_gll%msh%nelv
403 call local_grad3_xsmm(ur, us, ut, u(1,e), n, xh_gl%dx, xh_gl%dxt)
404 do i = 1, xh_gl%lxyz
405 ud(i,e) = cr(i,e) * ur(i) + cs(i,e) * us(i) + ct(i,e) * ut(i)
406 end do
407 end do
408#endif
409 call gll_to_gl%map(du, ud, coef_gl%msh%nelv, xh_gll)
410 call coef_gll%gs_h%op(du, n_gll, gs_op_add)
411 call col2(du, coef_gll%Binv, n_gll)
412 end subroutine opr_xsmm_convect_scalar
413
414 subroutine opr_xsmm_curl(w1, w2, w3, u1, u2, u3, work1, work2, c_Xh)
415 type(coef_t), intent(in) :: c_xh
416 real(kind=rp), intent(inout), &
417 dimension(c_Xh%Xh%lx, c_Xh%Xh%ly, c_Xh%Xh%lz, c_Xh%msh%nelv) :: w1
418 real(kind=rp), intent(inout), &
419 dimension(c_Xh%Xh%lx, c_Xh%Xh%ly, c_Xh%Xh%lz, c_Xh%msh%nelv) :: w2
420 real(kind=rp), intent(inout), &
421 dimension(c_Xh%Xh%lx, c_Xh%Xh%ly, c_Xh%Xh%lz, c_Xh%msh%nelv) :: w3
422 real(kind=rp), intent(in), &
423 dimension(c_Xh%Xh%lx, c_Xh%Xh%ly, c_Xh%Xh%lz, c_Xh%msh%nelv) :: u1
424 real(kind=rp), intent(in), &
425 dimension(c_Xh%Xh%lx, c_Xh%Xh%ly, c_Xh%Xh%lz, c_Xh%msh%nelv) :: u2
426 real(kind=rp), intent(in), &
427 dimension(c_Xh%Xh%lx, c_Xh%Xh%ly, c_Xh%Xh%lz, c_Xh%msh%nelv) :: u3
428 real(kind=rp), intent(inout), &
429 dimension(c_Xh%Xh%lx, c_Xh%Xh%ly, c_Xh%Xh%lz, c_Xh%msh%nelv) :: work1
430 real(kind=rp), intent(inout), &
431 dimension(c_Xh%Xh%lx, c_Xh%Xh%ly, c_Xh%Xh%lz, c_Xh%msh%nelv) :: work2
432 integer :: gdim, n
433
434 n = c_xh%dof%size()
435 gdim = c_xh%msh%gdim
436
437 ! this%work1=dw/dy ; this%work2=dv/dz
438 call opr_xsmm_dudxyz(work1, u3, c_xh%drdy, c_xh%dsdy, c_xh%dtdy, c_xh)
439 if (gdim .eq. 3) then
440 call opr_xsmm_dudxyz(work2, u2, c_xh%drdz, c_xh%dsdz, &
441 c_xh%dtdz, c_xh)
442 call sub3(w1, work1, work2, n)
443 else
444 call copy(w1, work1, n)
445 end if
446 ! this%work1=du/dz ; this%work2=dw/dx
447 if (gdim .eq. 3) then
448 call opr_xsmm_dudxyz(work1, u1, c_xh%drdz, c_xh%dsdz, &
449 c_xh%dtdz, c_xh)
450 call opr_xsmm_dudxyz(work2, u3, c_xh%drdx, c_xh%dsdx, &
451 c_xh%dtdx, c_xh)
452 call sub3(w2, work1, work2, n)
453 else
454 call rzero (work1, n)
455 call opr_xsmm_dudxyz(work2, u3, c_xh%drdx, c_xh%dsdx, &
456 c_xh%dtdx, c_xh)
457 call sub3(w2, work1, work2, n)
458 end if
459 ! this%work1=dv/dx ; this%work2=du/dy
460 call opr_xsmm_dudxyz(work1, u2, c_xh%drdx, c_xh%dsdx, c_xh%dtdx, c_xh)
461 call opr_xsmm_dudxyz(work2, u1, c_xh%drdy, c_xh%dsdy, c_xh%dtdy, c_xh)
462 call sub3(w3, work1, work2, n)
463 !! BC dependent, Needs to change if cyclic
464
465 call opcolv(w1, w2, w3, c_xh%B, gdim, n)
466 call c_xh%gs_h%op(w1, n, gs_op_add)
467 call c_xh%gs_h%op(w2, n, gs_op_add)
468 call c_xh%gs_h%op(w3, n, gs_op_add)
469 call opcolv(w1, w2, w3, c_xh%Binv, gdim, n)
470
471 end subroutine opr_xsmm_curl
472
473 subroutine opr_xsmm_set_convect_rst(cr, cs, ct, cx, cy, cz, Xh, coef)
474 type(space_t), intent(inout) :: xh
475 type(coef_t), intent(inout) :: coef
476 real(kind=rp), dimension(Xh%lxyz, coef%msh%nelv), &
477 intent(inout) :: cr, cs, ct
478 real(kind=rp), dimension(Xh%lxyz, coef%msh%nelv), &
479 intent(in) :: cx, cy, cz
480 integer :: e, i, t, nxyz
481
482 associate(drdx => coef%drdx, drdy => coef%drdy, drdz => coef%drdz, &
483 dsdx => coef%dsdx, dsdy => coef%dsdy, dsdz => coef%dsdz, &
484 dtdx => coef%dtdx, dtdy => coef%dtdy, dtdz => coef%dtdz, &
485 nelv => coef%msh%nelv, lx => xh%lx, w3 => xh%w3)
486 nxyz = lx * lx * lx
487 do e = 1, nelv
488 do i = 1, nxyz
489 cr(i,e) = w3(i,1,1) * (cx(i,e) * drdx(i,1,1,e) &
490 + cy(i,e) * drdy(i,1,1,e) &
491 + cz(i,e) * drdz(i,1,1,e))
492 cs(i,e) = w3(i,1,1) * (cx(i,e) * dsdx(i,1,1,e) &
493 + cy(i,e) * dsdy(i,1,1,e) &
494 + cz(i,e) * dsdz(i,1,1,e))
495 ct(i,e) = w3(i,1,1) * (cx(i,e) * dtdx(i,1,1,e) &
496 + cy(i,e) * dtdy(i,1,1,e) &
497 + cz(i,e) * dtdz(i,1,1,e))
498 end do
499 end do
500 end associate
501
502 end subroutine opr_xsmm_set_convect_rst
503
504end module opr_xsmm
505
Coefficients.
Definition coef.f90:34
Gather-scatter.
Routines to interpolate between different spaces.
Definition math.f90:60
subroutine, public invcol2(a, b, n)
Vector division .
Definition math.f90:1028
subroutine, public sub3(a, b, c, n)
Vector subtraction .
Definition math.f90:961
subroutine, public add2(a, b, n)
Vector addition .
Definition math.f90:898
subroutine, public addcol3(a, b, c, n)
Returns .
Definition math.f90:1162
subroutine, public col2(a, b, n)
Vector multiplication .
Definition math.f90:1044
subroutine, public copy(a, b, n)
Copy a vector .
Definition math.f90:289
subroutine, public col3(a, b, c, n)
Vector multiplication with 3 vectors .
Definition math.f90:1059
subroutine, public rzero(a, n)
Zero a real vector.
Definition math.f90:233
Collection of vector field operations operating on and . Note that in general the indices and ....
Definition mathops.f90:65
subroutine, public opcolv(a1, a2, a3, c, gdim, n)
Definition mathops.f90:101
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.
integer, parameter, public i2
Definition num_types.f90:5
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:12
Operators libxsmm backend.
Definition opr_xsmm.F90:61
subroutine local_grad3_xsmm(ur, us, ut, u, n, d, dt)
Definition opr_xsmm.F90:202
subroutine, public opr_xsmm_convect_scalar(du, u, cr, cs, ct, xh_gll, xh_gl, coef_gll, coef_gl, gll_to_gl)
Definition opr_xsmm.F90:370
subroutine, public opr_xsmm_conv1(du, u, vx, vy, vz, xh, coef, nelv, gdim)
Definition opr_xsmm.F90:296
subroutine, public opr_xsmm_cdtp(dtx, x, dr, ds, dt, coef)
Definition opr_xsmm.F90:241
subroutine, public opr_xsmm_curl(w1, w2, w3, u1, u2, u3, work1, work2, c_xh)
Definition opr_xsmm.F90:417
subroutine, public opr_xsmm_dudxyz(du, u, dr, ds, dt, coef)
Definition opr_xsmm.F90:91
subroutine, public opr_xsmm_opgrad(ux, uy, uz, u, coef)
Definition opr_xsmm.F90:145
subroutine, public opr_xsmm_set_convect_rst(cr, cs, ct, cx, cy, cz, xh, coef)
Definition opr_xsmm.F90:476
subroutine local_grad2(ur, us, u, n, d, dt)
Definition opr_xsmm.F90:225
Defines a function space.
Definition space.f90:34
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Definition coef.f90:63
Interpolation between two space::space_t.
The function space for the SEM solution fields.
Definition space.f90:63