ADflow  v1.0
ADflow is a finite volume RANS solver tailored for gradient-based aerodynamic design optimization.
adjointExtra_b.f90
Go to the documentation of this file.
1 ! generated by tapenade (inria, ecuador team)
2 ! tapenade 3.16 (develop) - 22 aug 2023 15:51
3 !
5  implicit none
6 
7 contains
8 ! differentiation of volume_block in reverse (adjoint) mode (with options noisize i4 dr8 r8):
9 ! gradient of useful results: *x *vol
10 ! with respect to varying inputs: *x *vol
11 ! rw status of diff variables: *x:incr *vol:in-out
12 ! plus diff mem management of: x:in vol:in
13  subroutine volume_block_b()
14 ! this is copy of metric.f90. it was necessary to copy this file
15 ! since there is debugging stuff in the original that is not
16 ! necessary for ad.
17  use constants
18  use blockpointers
19  use cgnsgrid
20  use communication
22  implicit none
23 !
24 ! local parameter.
25 !
26  real(kind=realtype), parameter :: thresvolume=1.e-2_realtype
27  real(kind=realtype), parameter :: halocellratio=1e-10_realtype
28 !
29 ! local variables.
30 !
31  integer(kind=inttype) :: i, j, k, n, m, l, ii
32  integer(kind=inttype) :: mm
33  real(kind=realtype) :: fact, mult
34  real(kind=realtype) :: xp, yp, zp, vp1, vp2, vp3, vp4, vp5, vp6
35  real(kind=realtype) :: xpd, ypd, zpd, vp1d, vp2d, vp3d, vp4d, vp5d, &
36 & vp6d
37  real(kind=realtype) :: xxp, yyp, zzp
38  real(kind=realtype), dimension(3) :: v1, v2
39  intrinsic abs
40  real(kind=realtype) :: tempd
41  real(kind=realtype) :: tmp
42  real(kind=realtype) :: tmpd
43  real(kind=realtype) :: tmp0
44  real(kind=realtype) :: tmpd0
45  real(kind=realtype) :: tmp1
46  real(kind=realtype) :: tmpd1
47  integer :: branch
48 ! compute the volumes. the hexahedron is split into 6 pyramids
49 ! whose volumes are computed. the volume is positive for a
50 ! right handed block.
51 ! initialize the volumes to zero. the reasons is that the second
52 ! level halo's must be initialized to zero and for convenience
53 ! all the volumes are set to zero.
54  vol = zero
55  do k=1,ke
56  call pushinteger4(n)
57  n = k - 1
58  do j=1,je
59  call pushinteger4(m)
60  m = j - 1
61  do i=1,ie
62  l = i - 1
63 ! compute the coordinates of the center of gravity.
64  call pushreal8(xp)
65  xp = eighth*(x(i, j, k, 1)+x(i, m, k, 1)+x(i, m, n, 1)+x(i, j&
66 & , n, 1)+x(l, j, k, 1)+x(l, m, k, 1)+x(l, m, n, 1)+x(l, j, n&
67 & , 1))
68  call pushreal8(yp)
69  yp = eighth*(x(i, j, k, 2)+x(i, m, k, 2)+x(i, m, n, 2)+x(i, j&
70 & , n, 2)+x(l, j, k, 2)+x(l, m, k, 2)+x(l, m, n, 2)+x(l, j, n&
71 & , 2))
72  call pushreal8(zp)
73  zp = eighth*(x(i, j, k, 3)+x(i, m, k, 3)+x(i, m, n, 3)+x(i, j&
74 & , n, 3)+x(l, j, k, 3)+x(l, m, k, 3)+x(l, m, n, 3)+x(l, j, n&
75 & , 3))
76 ! compute the volumes of the 6 sub pyramids. the
77 ! arguments of volpym must be such that for a (regular)
78 ! right handed hexahedron all volumes are positive.
79  call volpym(x(i, j, k, 1), x(i, j, k, 2), x(i, j, k, 3), x(i, &
80 & j, n, 1), x(i, j, n, 2), x(i, j, n, 3), x(i, m, n, 1), x&
81 & (i, m, n, 2), x(i, m, n, 3), x(i, m, k, 1), x(i, m, k, 2&
82 & ), x(i, m, k, 3), vp1)
83  call volpym(x(l, j, k, 1), x(l, j, k, 2), x(l, j, k, 3), x(l, &
84 & m, k, 1), x(l, m, k, 2), x(l, m, k, 3), x(l, m, n, 1), x&
85 & (l, m, n, 2), x(l, m, n, 3), x(l, j, n, 1), x(l, j, n, 2&
86 & ), x(l, j, n, 3), vp2)
87  call volpym(x(i, j, k, 1), x(i, j, k, 2), x(i, j, k, 3), x(l, &
88 & j, k, 1), x(l, j, k, 2), x(l, j, k, 3), x(l, j, n, 1), x&
89 & (l, j, n, 2), x(l, j, n, 3), x(i, j, n, 1), x(i, j, n, 2&
90 & ), x(i, j, n, 3), vp3)
91  call volpym(x(i, m, k, 1), x(i, m, k, 2), x(i, m, k, 3), x(i, &
92 & m, n, 1), x(i, m, n, 2), x(i, m, n, 3), x(l, m, n, 1), x&
93 & (l, m, n, 2), x(l, m, n, 3), x(l, m, k, 1), x(l, m, k, 2&
94 & ), x(l, m, k, 3), vp4)
95  call volpym(x(i, j, k, 1), x(i, j, k, 2), x(i, j, k, 3), x(i, &
96 & m, k, 1), x(i, m, k, 2), x(i, m, k, 3), x(l, m, k, 1), x&
97 & (l, m, k, 2), x(l, m, k, 3), x(l, j, k, 1), x(l, j, k, 2&
98 & ), x(l, j, k, 3), vp5)
99  call volpym(x(i, j, n, 1), x(i, j, n, 2), x(i, j, n, 3), x(l, &
100 & j, n, 1), x(l, j, n, 2), x(l, j, n, 3), x(l, m, n, 1), x&
101 & (l, m, n, 2), x(l, m, n, 3), x(i, m, n, 1), x(i, m, n, 2&
102 & ), x(i, m, n, 3), vp6)
103 ! set the volume to 1/6 of the sum of the volumes of the
104 ! pyramid. remember that volpym computes 6 times the
105 ! volume.
106  vol(i, j, k) = sixth*(vp1+vp2+vp3+vp4+vp5+vp6)
107  if (vol(i, j, k) .ge. 0.) then
108  call pushcontrol1b(0)
109  vol(i, j, k) = vol(i, j, k)
110  else
111  vol(i, j, k) = -vol(i, j, k)
112  call pushcontrol1b(1)
113  end if
114  end do
115  end do
116  end do
117 ! some additional safety stuff for halo volumes.
118  do k=2,kl
119  do j=2,jl
120  if (vol(1, j, k)/vol(2, j, k) .lt. halocellratio) then
121  vol(1, j, k) = vol(2, j, k)
122  call pushcontrol1b(0)
123  else
124  call pushcontrol1b(1)
125  end if
126  if (vol(ie, j, k)/vol(il, j, k) .lt. halocellratio) then
127  tmp = vol(il, j, k)
128  vol(ie, j, k) = tmp
129  call pushcontrol1b(1)
130  else
131  call pushcontrol1b(0)
132  end if
133  end do
134  end do
135  do k=2,kl
136  do i=1,ie
137  if (vol(i, 1, k)/vol(i, 2, k) .lt. halocellratio) then
138  vol(i, 1, k) = vol(i, 2, k)
139  call pushcontrol1b(0)
140  else
141  call pushcontrol1b(1)
142  end if
143  if (vol(i, je, k)/vol(i, jl, k) .lt. halocellratio) then
144  tmp0 = vol(i, jl, k)
145  vol(i, je, k) = tmp0
146  call pushcontrol1b(1)
147  else
148  call pushcontrol1b(0)
149  end if
150  end do
151  end do
152  do j=1,je
153  do i=1,ie
154  if (vol(i, j, 1)/vol(i, j, 2) .lt. halocellratio) then
155  vol(i, j, 1) = vol(i, j, 2)
156  call pushcontrol1b(0)
157  else
158  call pushcontrol1b(1)
159  end if
160  if (vol(i, j, ke)/vol(i, j, kl) .lt. halocellratio) then
161  tmp1 = vol(i, j, kl)
162  vol(i, j, ke) = tmp1
163  call pushcontrol1b(1)
164  else
165  call pushcontrol1b(0)
166  end if
167  end do
168  end do
169  do j=je,1,-1
170  do i=ie,1,-1
171  call popcontrol1b(branch)
172  if (branch .ne. 0) then
173  tmpd1 = vold(i, j, ke)
174  vold(i, j, ke) = 0.0_8
175  vold(i, j, kl) = vold(i, j, kl) + tmpd1
176  end if
177  call popcontrol1b(branch)
178  if (branch .eq. 0) then
179  vold(i, j, 2) = vold(i, j, 2) + vold(i, j, 1)
180  vold(i, j, 1) = 0.0_8
181  end if
182  end do
183  end do
184  do k=kl,2,-1
185  do i=ie,1,-1
186  call popcontrol1b(branch)
187  if (branch .ne. 0) then
188  tmpd0 = vold(i, je, k)
189  vold(i, je, k) = 0.0_8
190  vold(i, jl, k) = vold(i, jl, k) + tmpd0
191  end if
192  call popcontrol1b(branch)
193  if (branch .eq. 0) then
194  vold(i, 2, k) = vold(i, 2, k) + vold(i, 1, k)
195  vold(i, 1, k) = 0.0_8
196  end if
197  end do
198  end do
199  do k=kl,2,-1
200  do j=jl,2,-1
201  call popcontrol1b(branch)
202  if (branch .ne. 0) then
203  tmpd = vold(ie, j, k)
204  vold(ie, j, k) = 0.0_8
205  vold(il, j, k) = vold(il, j, k) + tmpd
206  end if
207  call popcontrol1b(branch)
208  if (branch .eq. 0) then
209  vold(2, j, k) = vold(2, j, k) + vold(1, j, k)
210  vold(1, j, k) = 0.0_8
211  end if
212  end do
213  end do
214  vp1d = 0.0_8
215  vp2d = 0.0_8
216  vp3d = 0.0_8
217  vp4d = 0.0_8
218  vp5d = 0.0_8
219  vp6d = 0.0_8
220  do k=ke,1,-1
221  do j=je,1,-1
222  do i=ie,1,-1
223  call popcontrol1b(branch)
224  if (branch .ne. 0) vold(i, j, k) = -vold(i, j, k)
225  tempd = sixth*vold(i, j, k)
226  vold(i, j, k) = 0.0_8
227  vp1d = vp1d + tempd
228  vp2d = vp2d + tempd
229  vp3d = vp3d + tempd
230  vp4d = vp4d + tempd
231  vp5d = vp5d + tempd
232  vp6d = vp6d + tempd
233  l = i - 1
234  zpd = 0.0_8
235  ypd = 0.0_8
236  xpd = 0.0_8
237  call volpym_b(x(i, j, n, 1), xd(i, j, n, 1), x(i, j, n, 2), xd&
238 & (i, j, n, 2), x(i, j, n, 3), xd(i, j, n, 3), x(l, j, n&
239 & , 1), xd(l, j, n, 1), x(l, j, n, 2), xd(l, j, n, 2), x&
240 & (l, j, n, 3), xd(l, j, n, 3), x(l, m, n, 1), xd(l, m, &
241 & n, 1), x(l, m, n, 2), xd(l, m, n, 2), x(l, m, n, 3), &
242 & xd(l, m, n, 3), x(i, m, n, 1), xd(i, m, n, 1), x(i, m&
243 & , n, 2), xd(i, m, n, 2), x(i, m, n, 3), xd(i, m, n, 3)&
244 & , vp6, vp6d)
245  vp6d = 0.0_8
246  call volpym_b(x(i, j, k, 1), xd(i, j, k, 1), x(i, j, k, 2), xd&
247 & (i, j, k, 2), x(i, j, k, 3), xd(i, j, k, 3), x(i, m, k&
248 & , 1), xd(i, m, k, 1), x(i, m, k, 2), xd(i, m, k, 2), x&
249 & (i, m, k, 3), xd(i, m, k, 3), x(l, m, k, 1), xd(l, m, &
250 & k, 1), x(l, m, k, 2), xd(l, m, k, 2), x(l, m, k, 3), &
251 & xd(l, m, k, 3), x(l, j, k, 1), xd(l, j, k, 1), x(l, j&
252 & , k, 2), xd(l, j, k, 2), x(l, j, k, 3), xd(l, j, k, 3)&
253 & , vp5, vp5d)
254  vp5d = 0.0_8
255  call volpym_b(x(i, m, k, 1), xd(i, m, k, 1), x(i, m, k, 2), xd&
256 & (i, m, k, 2), x(i, m, k, 3), xd(i, m, k, 3), x(i, m, n&
257 & , 1), xd(i, m, n, 1), x(i, m, n, 2), xd(i, m, n, 2), x&
258 & (i, m, n, 3), xd(i, m, n, 3), x(l, m, n, 1), xd(l, m, &
259 & n, 1), x(l, m, n, 2), xd(l, m, n, 2), x(l, m, n, 3), &
260 & xd(l, m, n, 3), x(l, m, k, 1), xd(l, m, k, 1), x(l, m&
261 & , k, 2), xd(l, m, k, 2), x(l, m, k, 3), xd(l, m, k, 3)&
262 & , vp4, vp4d)
263  vp4d = 0.0_8
264  call volpym_b(x(i, j, k, 1), xd(i, j, k, 1), x(i, j, k, 2), xd&
265 & (i, j, k, 2), x(i, j, k, 3), xd(i, j, k, 3), x(l, j, k&
266 & , 1), xd(l, j, k, 1), x(l, j, k, 2), xd(l, j, k, 2), x&
267 & (l, j, k, 3), xd(l, j, k, 3), x(l, j, n, 1), xd(l, j, &
268 & n, 1), x(l, j, n, 2), xd(l, j, n, 2), x(l, j, n, 3), &
269 & xd(l, j, n, 3), x(i, j, n, 1), xd(i, j, n, 1), x(i, j&
270 & , n, 2), xd(i, j, n, 2), x(i, j, n, 3), xd(i, j, n, 3)&
271 & , vp3, vp3d)
272  vp3d = 0.0_8
273  call volpym_b(x(l, j, k, 1), xd(l, j, k, 1), x(l, j, k, 2), xd&
274 & (l, j, k, 2), x(l, j, k, 3), xd(l, j, k, 3), x(l, m, k&
275 & , 1), xd(l, m, k, 1), x(l, m, k, 2), xd(l, m, k, 2), x&
276 & (l, m, k, 3), xd(l, m, k, 3), x(l, m, n, 1), xd(l, m, &
277 & n, 1), x(l, m, n, 2), xd(l, m, n, 2), x(l, m, n, 3), &
278 & xd(l, m, n, 3), x(l, j, n, 1), xd(l, j, n, 1), x(l, j&
279 & , n, 2), xd(l, j, n, 2), x(l, j, n, 3), xd(l, j, n, 3)&
280 & , vp2, vp2d)
281  vp2d = 0.0_8
282  call volpym_b(x(i, j, k, 1), xd(i, j, k, 1), x(i, j, k, 2), xd&
283 & (i, j, k, 2), x(i, j, k, 3), xd(i, j, k, 3), x(i, j, n&
284 & , 1), xd(i, j, n, 1), x(i, j, n, 2), xd(i, j, n, 2), x&
285 & (i, j, n, 3), xd(i, j, n, 3), x(i, m, n, 1), xd(i, m, &
286 & n, 1), x(i, m, n, 2), xd(i, m, n, 2), x(i, m, n, 3), &
287 & xd(i, m, n, 3), x(i, m, k, 1), xd(i, m, k, 1), x(i, m&
288 & , k, 2), xd(i, m, k, 2), x(i, m, k, 3), xd(i, m, k, 3)&
289 & , vp1, vp1d)
290  vp1d = 0.0_8
291  call popreal8(zp)
292  tempd = eighth*zpd
293  xd(i, j, k, 3) = xd(i, j, k, 3) + tempd
294  xd(i, m, k, 3) = xd(i, m, k, 3) + tempd
295  xd(i, m, n, 3) = xd(i, m, n, 3) + tempd
296  xd(i, j, n, 3) = xd(i, j, n, 3) + tempd
297  xd(l, j, k, 3) = xd(l, j, k, 3) + tempd
298  xd(l, m, k, 3) = xd(l, m, k, 3) + tempd
299  xd(l, m, n, 3) = xd(l, m, n, 3) + tempd
300  xd(l, j, n, 3) = xd(l, j, n, 3) + tempd
301  call popreal8(yp)
302  tempd = eighth*ypd
303  xd(i, j, k, 2) = xd(i, j, k, 2) + tempd
304  xd(i, m, k, 2) = xd(i, m, k, 2) + tempd
305  xd(i, m, n, 2) = xd(i, m, n, 2) + tempd
306  xd(i, j, n, 2) = xd(i, j, n, 2) + tempd
307  xd(l, j, k, 2) = xd(l, j, k, 2) + tempd
308  xd(l, m, k, 2) = xd(l, m, k, 2) + tempd
309  xd(l, m, n, 2) = xd(l, m, n, 2) + tempd
310  xd(l, j, n, 2) = xd(l, j, n, 2) + tempd
311  call popreal8(xp)
312  tempd = eighth*xpd
313  xd(i, j, k, 1) = xd(i, j, k, 1) + tempd
314  xd(i, m, k, 1) = xd(i, m, k, 1) + tempd
315  xd(i, m, n, 1) = xd(i, m, n, 1) + tempd
316  xd(i, j, n, 1) = xd(i, j, n, 1) + tempd
317  xd(l, j, k, 1) = xd(l, j, k, 1) + tempd
318  xd(l, m, k, 1) = xd(l, m, k, 1) + tempd
319  xd(l, m, n, 1) = xd(l, m, n, 1) + tempd
320  xd(l, j, n, 1) = xd(l, j, n, 1) + tempd
321  end do
322  call popinteger4(m)
323  end do
324  call popinteger4(n)
325  end do
326  vold = 0.0_8
327 
328  contains
329 ! differentiation of volpym in reverse (adjoint) mode (with options noisize i4 dr8 r8):
330 ! gradient of useful results: xp yp zp xa xb xc xd ya yb
331 ! yc yd za zb zc zd volume
332 ! with respect to varying inputs: xp yp zp xa xb xc xd ya yb
333 ! yc yd za zb zc zd
334  subroutine volpym_b(xa, xad, ya, yad, za, zad, xb, xbd, yb, ybd, zb&
335 & , zbd, xc, xcd, yc, ycd, zc, zcd, xd, xdd, yd, ydd, zd, zdd, &
336 & volume, volumed)
337 !
338 ! volpym computes 6 times the volume of a pyramid. node p,
339 ! whose coordinates are set in the subroutine metric itself,
340 ! is the top node and a-b-c-d is the quadrilateral surface.
341 ! it is assumed that the cross product vca * vdb points in
342 ! the direction of the top node. here vca is the diagonal
343 ! running from node c to node a and vdb the diagonal from
344 ! node d to node b.
345 !
346  use precision
347  implicit none
348 !
349 ! function type.
350 !
351  real(kind=realtype) :: volume
352  real(kind=realtype) :: volumed
353 !
354 ! function arguments.
355 !
356  real(kind=realtype), intent(in) :: xa, ya, za, xb, yb, zb
357  real(kind=realtype) :: xad, yad, zad, xbd, ybd, zbd
358  real(kind=realtype), intent(in) :: xc, yc, zc, xd, yd, zd
359  real(kind=realtype) :: xcd, ycd, zcd, xdd, ydd, zdd
360  real(kind=realtype) :: tempd
361  real(kind=realtype) :: tempd0
362  real(kind=realtype) :: tempd1
363  real(kind=realtype) :: tempd2
364  real(kind=realtype) :: tempd3
365  real(kind=realtype) :: tempd4
366  real(kind=realtype) :: tempd5
367  real(kind=realtype) :: tempd6
368  real(kind=realtype) :: tempd7
369  tempd = ((ya-yc)*(zb-zd)-(za-zc)*(yb-yd))*volumed
370  tempd1 = (xp-fourth*(xa+xb+xc+xd))*volumed
371  tempd2 = ((za-zc)*(xb-xd)-(xa-xc)*(zb-zd))*volumed
372  tempd4 = (yp-fourth*(ya+yb+yc+yd))*volumed
373  tempd5 = ((xa-xc)*(yb-yd)-(ya-yc)*(xb-xd))*volumed
374  tempd7 = (zp-fourth*(za+zb+zc+zd))*volumed
375  zpd = zpd + tempd5
376  tempd6 = -(fourth*tempd5)
377  zad = zad + tempd6 + (xb-xd)*tempd4 - (yb-yd)*tempd1
378  zbd = zbd + tempd6 + (ya-yc)*tempd1 - (xa-xc)*tempd4
379  zcd = zcd + tempd6 + (yb-yd)*tempd1 - (xb-xd)*tempd4
380  zdd = zdd + tempd6 + (xa-xc)*tempd4 - (ya-yc)*tempd1
381  ypd = ypd + tempd2
382  tempd3 = -(fourth*tempd2)
383  ybd = ybd + (xa-xc)*tempd7 + tempd3 - (za-zc)*tempd1
384  ydd = ydd + tempd3 - (xa-xc)*tempd7 + (za-zc)*tempd1
385  yad = yad + tempd3 - (xb-xd)*tempd7 + (zb-zd)*tempd1
386  ycd = ycd + (xb-xd)*tempd7 + tempd3 - (zb-zd)*tempd1
387  xpd = xpd + tempd
388  tempd0 = -(fourth*tempd)
389  xad = xad + (yb-yd)*tempd7 + tempd0 - (zb-zd)*tempd4
390  xcd = xcd + (zb-zd)*tempd4 - (yb-yd)*tempd7 + tempd0
391  xbd = xbd + (za-zc)*tempd4 - (ya-yc)*tempd7 + tempd0
392  xdd = xdd + (ya-yc)*tempd7 + tempd0 - (za-zc)*tempd4
393  end subroutine volpym_b
394 
395  subroutine volpym(xa, ya, za, xb, yb, zb, xc, yc, zc, xd, yd, zd, &
396 & volume)
397 !
398 ! volpym computes 6 times the volume of a pyramid. node p,
399 ! whose coordinates are set in the subroutine metric itself,
400 ! is the top node and a-b-c-d is the quadrilateral surface.
401 ! it is assumed that the cross product vca * vdb points in
402 ! the direction of the top node. here vca is the diagonal
403 ! running from node c to node a and vdb the diagonal from
404 ! node d to node b.
405 !
406  use precision
407  implicit none
408 !
409 ! function type.
410 !
411  real(kind=realtype) :: volume
412 !
413 ! function arguments.
414 !
415  real(kind=realtype), intent(in) :: xa, ya, za, xb, yb, zb
416  real(kind=realtype), intent(in) :: xc, yc, zc, xd, yd, zd
417  volume = (xp-fourth*(xa+xb+xc+xd))*((ya-yc)*(zb-zd)-(za-zc)*(yb-yd&
418 & )) + (yp-fourth*(ya+yb+yc+yd))*((za-zc)*(xb-xd)-(xa-xc)*(zb-zd))&
419 & + (zp-fourth*(za+zb+zc+zd))*((xa-xc)*(yb-yd)-(ya-yc)*(xb-xd))
420  end subroutine volpym
421 
422  end subroutine volume_block_b
423 
424  subroutine volume_block()
425 ! this is copy of metric.f90. it was necessary to copy this file
426 ! since there is debugging stuff in the original that is not
427 ! necessary for ad.
428  use constants
429  use blockpointers
430  use cgnsgrid
431  use communication
433  implicit none
434 !
435 ! local parameter.
436 !
437  real(kind=realtype), parameter :: thresvolume=1.e-2_realtype
438  real(kind=realtype), parameter :: halocellratio=1e-10_realtype
439 !
440 ! local variables.
441 !
442  integer(kind=inttype) :: i, j, k, n, m, l, ii
443  integer(kind=inttype) :: mm
444  real(kind=realtype) :: fact, mult
445  real(kind=realtype) :: xp, yp, zp, vp1, vp2, vp3, vp4, vp5, vp6
446  real(kind=realtype) :: xxp, yyp, zzp
447  real(kind=realtype), dimension(3) :: v1, v2
448  intrinsic abs
449 ! compute the volumes. the hexahedron is split into 6 pyramids
450 ! whose volumes are computed. the volume is positive for a
451 ! right handed block.
452 ! initialize the volumes to zero. the reasons is that the second
453 ! level halo's must be initialized to zero and for convenience
454 ! all the volumes are set to zero.
455  vol = zero
456  do k=1,ke
457  n = k - 1
458  do j=1,je
459  m = j - 1
460  do i=1,ie
461  l = i - 1
462 ! compute the coordinates of the center of gravity.
463  xp = eighth*(x(i, j, k, 1)+x(i, m, k, 1)+x(i, m, n, 1)+x(i, j&
464 & , n, 1)+x(l, j, k, 1)+x(l, m, k, 1)+x(l, m, n, 1)+x(l, j, n&
465 & , 1))
466  yp = eighth*(x(i, j, k, 2)+x(i, m, k, 2)+x(i, m, n, 2)+x(i, j&
467 & , n, 2)+x(l, j, k, 2)+x(l, m, k, 2)+x(l, m, n, 2)+x(l, j, n&
468 & , 2))
469  zp = eighth*(x(i, j, k, 3)+x(i, m, k, 3)+x(i, m, n, 3)+x(i, j&
470 & , n, 3)+x(l, j, k, 3)+x(l, m, k, 3)+x(l, m, n, 3)+x(l, j, n&
471 & , 3))
472 ! compute the volumes of the 6 sub pyramids. the
473 ! arguments of volpym must be such that for a (regular)
474 ! right handed hexahedron all volumes are positive.
475  call volpym(x(i, j, k, 1), x(i, j, k, 2), x(i, j, k, 3), x(i, &
476 & j, n, 1), x(i, j, n, 2), x(i, j, n, 3), x(i, m, n, 1), x&
477 & (i, m, n, 2), x(i, m, n, 3), x(i, m, k, 1), x(i, m, k, 2&
478 & ), x(i, m, k, 3), vp1)
479  call volpym(x(l, j, k, 1), x(l, j, k, 2), x(l, j, k, 3), x(l, &
480 & m, k, 1), x(l, m, k, 2), x(l, m, k, 3), x(l, m, n, 1), x&
481 & (l, m, n, 2), x(l, m, n, 3), x(l, j, n, 1), x(l, j, n, 2&
482 & ), x(l, j, n, 3), vp2)
483  call volpym(x(i, j, k, 1), x(i, j, k, 2), x(i, j, k, 3), x(l, &
484 & j, k, 1), x(l, j, k, 2), x(l, j, k, 3), x(l, j, n, 1), x&
485 & (l, j, n, 2), x(l, j, n, 3), x(i, j, n, 1), x(i, j, n, 2&
486 & ), x(i, j, n, 3), vp3)
487  call volpym(x(i, m, k, 1), x(i, m, k, 2), x(i, m, k, 3), x(i, &
488 & m, n, 1), x(i, m, n, 2), x(i, m, n, 3), x(l, m, n, 1), x&
489 & (l, m, n, 2), x(l, m, n, 3), x(l, m, k, 1), x(l, m, k, 2&
490 & ), x(l, m, k, 3), vp4)
491  call volpym(x(i, j, k, 1), x(i, j, k, 2), x(i, j, k, 3), x(i, &
492 & m, k, 1), x(i, m, k, 2), x(i, m, k, 3), x(l, m, k, 1), x&
493 & (l, m, k, 2), x(l, m, k, 3), x(l, j, k, 1), x(l, j, k, 2&
494 & ), x(l, j, k, 3), vp5)
495  call volpym(x(i, j, n, 1), x(i, j, n, 2), x(i, j, n, 3), x(l, &
496 & j, n, 1), x(l, j, n, 2), x(l, j, n, 3), x(l, m, n, 1), x&
497 & (l, m, n, 2), x(l, m, n, 3), x(i, m, n, 1), x(i, m, n, 2&
498 & ), x(i, m, n, 3), vp6)
499 ! set the volume to 1/6 of the sum of the volumes of the
500 ! pyramid. remember that volpym computes 6 times the
501 ! volume.
502  vol(i, j, k) = sixth*(vp1+vp2+vp3+vp4+vp5+vp6)
503  if (vol(i, j, k) .ge. 0.) then
504  vol(i, j, k) = vol(i, j, k)
505  else
506  vol(i, j, k) = -vol(i, j, k)
507  end if
508  end do
509  end do
510  end do
511 ! some additional safety stuff for halo volumes.
512  do k=2,kl
513  do j=2,jl
514  if (vol(1, j, k)/vol(2, j, k) .lt. halocellratio) vol(1, j, k)&
515 & = vol(2, j, k)
516  if (vol(ie, j, k)/vol(il, j, k) .lt. halocellratio) vol(ie, j, k&
517 & ) = vol(il, j, k)
518  end do
519  end do
520  do k=2,kl
521  do i=1,ie
522  if (vol(i, 1, k)/vol(i, 2, k) .lt. halocellratio) vol(i, 1, k)&
523 & = vol(i, 2, k)
524  if (vol(i, je, k)/vol(i, jl, k) .lt. halocellratio) vol(i, je, k&
525 & ) = vol(i, jl, k)
526  end do
527  end do
528  do j=1,je
529  do i=1,ie
530  if (vol(i, j, 1)/vol(i, j, 2) .lt. halocellratio) vol(i, j, 1)&
531 & = vol(i, j, 2)
532  if (vol(i, j, ke)/vol(i, j, kl) .lt. halocellratio) vol(i, j, ke&
533 & ) = vol(i, j, kl)
534  end do
535  end do
536 
537  contains
538  subroutine volpym(xa, ya, za, xb, yb, zb, xc, yc, zc, xd, yd, zd, &
539 & volume)
540 !
541 ! volpym computes 6 times the volume of a pyramid. node p,
542 ! whose coordinates are set in the subroutine metric itself,
543 ! is the top node and a-b-c-d is the quadrilateral surface.
544 ! it is assumed that the cross product vca * vdb points in
545 ! the direction of the top node. here vca is the diagonal
546 ! running from node c to node a and vdb the diagonal from
547 ! node d to node b.
548 !
549  use precision
550  implicit none
551 !
552 ! function type.
553 !
554  real(kind=realtype) :: volume
555 !
556 ! function arguments.
557 !
558  real(kind=realtype), intent(in) :: xa, ya, za, xb, yb, zb
559  real(kind=realtype), intent(in) :: xc, yc, zc, xd, yd, zd
560  volume = (xp-fourth*(xa+xb+xc+xd))*((ya-yc)*(zb-zd)-(za-zc)*(yb-yd&
561 & )) + (yp-fourth*(ya+yb+yc+yd))*((za-zc)*(xb-xd)-(xa-xc)*(zb-zd))&
562 & + (zp-fourth*(za+zb+zc+zd))*((xa-xc)*(yb-yd)-(ya-yc)*(xb-xd))
563  end subroutine volpym
564 
565  end subroutine volume_block
566 
567 ! differentiation of metric_block in reverse (adjoint) mode (with options noisize i4 dr8 r8):
568 ! gradient of useful results: *x *si *sj *sk
569 ! with respect to varying inputs: *x *si *sj *sk
570 ! rw status of diff variables: *x:incr *si:in-out *sj:in-out
571 ! *sk:in-out
572 ! plus diff mem management of: x:in si:in sj:in sk:in
573  subroutine metric_block_b()
574  use constants
575  use blockpointers
576  implicit none
577 ! local variables.
578  integer(kind=inttype) :: i, j, k, n, m, l, ii
579  real(kind=realtype) :: fact
580  real(kind=realtype) :: xxp, yyp, zzp
581  real(kind=realtype), dimension(3) :: v1, v2
582  real(kind=realtype), dimension(3) :: v1d, v2d
583  intrinsic mod
584  real(kind=realtype) :: tempd
585 ! set the factor in the surface normals computation. for a
586 ! left handed block this factor is negative, such that the
587 ! normals still point in the direction of increasing index.
588 ! the formulae used later on assume a right handed block
589 ! and fact is used to correct this for a left handed block,
590 ! as well as the scaling factor of 0.5
591  if (righthanded) then
592  fact = half
593  else
594  fact = -half
595  end if
596  call pushreal8array(v1, 3)
597  call pushreal8array(v2, 3)
598 !$fwd-of ii-loop
599 !
600 ! computation of the face normals in i-, j- and k-direction.
601 ! formula's are valid for a right handed block; for a left
602 ! handed block the correct orientation is obtained via fact.
603 ! the normals point in the direction of increasing index.
604 ! the absolute value of fact is 0.5, because the cross
605 ! product of the two diagonals is twice the normal vector.
606 ! note that also the normals of the first level halo cells
607 ! are computed. these are needed for the viscous fluxes.
608 !
609 ! projected areas of cell faces in the i direction.
610  do ii=0,ke*je*(ie+1)-1
611 ! 0:ie
612  i = mod(ii, ie + 1) + 0
613 !1:je
614  j = mod(ii/(ie+1), je) + 1
615 !1:ke
616  k = ii/((ie+1)*je) + 1
617  n = k - 1
618  m = j - 1
619 ! determine the two diagonal vectors of the face.
620  v1(1) = x(i, j, n, 1) - x(i, m, k, 1)
621  v1(2) = x(i, j, n, 2) - x(i, m, k, 2)
622  v1(3) = x(i, j, n, 3) - x(i, m, k, 3)
623  v2(1) = x(i, j, k, 1) - x(i, m, n, 1)
624  v2(2) = x(i, j, k, 2) - x(i, m, n, 2)
625  v2(3) = x(i, j, k, 3) - x(i, m, n, 3)
626 ! the face normal, which is the cross product of the two
627 ! diagonal vectors times fact; remember that fact is
628 ! either -0.5 or 0.5.
629  si(i, j, k, 1) = fact*(v1(2)*v2(3)-v1(3)*v2(2))
630  si(i, j, k, 2) = fact*(v1(3)*v2(1)-v1(1)*v2(3))
631  si(i, j, k, 3) = fact*(v1(1)*v2(2)-v1(2)*v2(1))
632  end do
633  call pushreal8array(v1, 3)
634  call pushreal8array(v2, 3)
635 !$fwd-of ii-loop
636 ! projected areas of cell faces in the j direction
637  do ii=0,ke*(je+1)*ie-1
638 ! 1:ie
639  i = mod(ii, ie) + 1
640 !0:je
641  j = mod(ii/ie, je + 1) + 0
642 !1:ke
643  k = ii/(ie*(je+1)) + 1
644  n = k - 1
645  l = i - 1
646 ! determine the two diagonal vectors of the face.
647  v1(1) = x(i, j, n, 1) - x(l, j, k, 1)
648  v1(2) = x(i, j, n, 2) - x(l, j, k, 2)
649  v1(3) = x(i, j, n, 3) - x(l, j, k, 3)
650  v2(1) = x(l, j, n, 1) - x(i, j, k, 1)
651  v2(2) = x(l, j, n, 2) - x(i, j, k, 2)
652  v2(3) = x(l, j, n, 3) - x(i, j, k, 3)
653 ! the face normal, which is the cross product of the two
654 ! diagonal vectors times fact; remember that fact is
655 ! either -0.5 or 0.5.
656  sj(i, j, k, 1) = fact*(v1(2)*v2(3)-v1(3)*v2(2))
657  sj(i, j, k, 2) = fact*(v1(3)*v2(1)-v1(1)*v2(3))
658  sj(i, j, k, 3) = fact*(v1(1)*v2(2)-v1(2)*v2(1))
659  end do
660  v1d = 0.0_8
661  v2d = 0.0_8
662 !$bwd-of ii-loop
663  do ii=0,(ke+1)*je*ie-1
664 ! 1:ie
665  i = mod(ii, ie) + 1
666 !1:je
667  j = mod(ii/ie, je) + 1
668 !0:ke
669  k = ii/(ie*je) + 0
670  m = j - 1
671  l = i - 1
672 ! determine the two diagonal vectors of the face.
673  v1(1) = x(i, j, k, 1) - x(l, m, k, 1)
674  v1(2) = x(i, j, k, 2) - x(l, m, k, 2)
675  v1(3) = x(i, j, k, 3) - x(l, m, k, 3)
676  v2(1) = x(l, j, k, 1) - x(i, m, k, 1)
677  v2(2) = x(l, j, k, 2) - x(i, m, k, 2)
678  v2(3) = x(l, j, k, 3) - x(i, m, k, 3)
679 ! the face normal, which is the cross product of the two
680 ! diagonal vectors times fact; remember that fact is
681 ! either -0.5 or 0.5.
682  tempd = fact*skd(i, j, k, 3)
683  skd(i, j, k, 3) = 0.0_8
684  v1d(1) = v1d(1) + v2(2)*tempd
685  v2d(2) = v2d(2) + v1(1)*tempd
686  v1d(2) = v1d(2) - v2(1)*tempd
687  v2d(1) = v2d(1) - v1(2)*tempd
688  tempd = fact*skd(i, j, k, 2)
689  skd(i, j, k, 2) = 0.0_8
690  v1d(3) = v1d(3) + v2(1)*tempd
691  v2d(1) = v2d(1) + v1(3)*tempd
692  v1d(1) = v1d(1) - v2(3)*tempd
693  v2d(3) = v2d(3) - v1(1)*tempd
694  tempd = fact*skd(i, j, k, 1)
695  skd(i, j, k, 1) = 0.0_8
696  v1d(2) = v1d(2) + v2(3)*tempd
697  v2d(3) = v2d(3) + v1(2)*tempd
698  v1d(3) = v1d(3) - v2(2)*tempd
699  v2d(2) = v2d(2) - v1(3)*tempd
700  xd(l, j, k, 3) = xd(l, j, k, 3) + v2d(3)
701  xd(i, m, k, 3) = xd(i, m, k, 3) - v2d(3)
702  v2d(3) = 0.0_8
703  xd(l, j, k, 2) = xd(l, j, k, 2) + v2d(2)
704  xd(i, m, k, 2) = xd(i, m, k, 2) - v2d(2)
705  v2d(2) = 0.0_8
706  xd(l, j, k, 1) = xd(l, j, k, 1) + v2d(1)
707  xd(i, m, k, 1) = xd(i, m, k, 1) - v2d(1)
708  v2d(1) = 0.0_8
709  xd(i, j, k, 3) = xd(i, j, k, 3) + v1d(3)
710  xd(l, m, k, 3) = xd(l, m, k, 3) - v1d(3)
711  v1d(3) = 0.0_8
712  xd(i, j, k, 2) = xd(i, j, k, 2) + v1d(2)
713  xd(l, m, k, 2) = xd(l, m, k, 2) - v1d(2)
714  v1d(2) = 0.0_8
715  xd(i, j, k, 1) = xd(i, j, k, 1) + v1d(1)
716  xd(l, m, k, 1) = xd(l, m, k, 1) - v1d(1)
717  v1d(1) = 0.0_8
718  end do
719  call popreal8array(v2, 3)
720  call popreal8array(v1, 3)
721 !$bwd-of ii-loop
722  do ii=0,ke*(je+1)*ie-1
723 ! 1:ie
724  i = mod(ii, ie) + 1
725 !0:je
726  j = mod(ii/ie, je + 1) + 0
727 !1:ke
728  k = ii/(ie*(je+1)) + 1
729  n = k - 1
730  l = i - 1
731 ! determine the two diagonal vectors of the face.
732  v1(1) = x(i, j, n, 1) - x(l, j, k, 1)
733  v1(2) = x(i, j, n, 2) - x(l, j, k, 2)
734  v1(3) = x(i, j, n, 3) - x(l, j, k, 3)
735  v2(1) = x(l, j, n, 1) - x(i, j, k, 1)
736  v2(2) = x(l, j, n, 2) - x(i, j, k, 2)
737  v2(3) = x(l, j, n, 3) - x(i, j, k, 3)
738 ! the face normal, which is the cross product of the two
739 ! diagonal vectors times fact; remember that fact is
740 ! either -0.5 or 0.5.
741  tempd = fact*sjd(i, j, k, 3)
742  sjd(i, j, k, 3) = 0.0_8
743  v1d(1) = v1d(1) + v2(2)*tempd
744  v2d(2) = v2d(2) + v1(1)*tempd
745  v1d(2) = v1d(2) - v2(1)*tempd
746  v2d(1) = v2d(1) - v1(2)*tempd
747  tempd = fact*sjd(i, j, k, 2)
748  sjd(i, j, k, 2) = 0.0_8
749  v1d(3) = v1d(3) + v2(1)*tempd
750  v2d(1) = v2d(1) + v1(3)*tempd
751  v1d(1) = v1d(1) - v2(3)*tempd
752  v2d(3) = v2d(3) - v1(1)*tempd
753  tempd = fact*sjd(i, j, k, 1)
754  sjd(i, j, k, 1) = 0.0_8
755  v1d(2) = v1d(2) + v2(3)*tempd
756  v2d(3) = v2d(3) + v1(2)*tempd
757  v1d(3) = v1d(3) - v2(2)*tempd
758  v2d(2) = v2d(2) - v1(3)*tempd
759  xd(l, j, n, 3) = xd(l, j, n, 3) + v2d(3)
760  xd(i, j, k, 3) = xd(i, j, k, 3) - v2d(3)
761  v2d(3) = 0.0_8
762  xd(l, j, n, 2) = xd(l, j, n, 2) + v2d(2)
763  xd(i, j, k, 2) = xd(i, j, k, 2) - v2d(2)
764  v2d(2) = 0.0_8
765  xd(l, j, n, 1) = xd(l, j, n, 1) + v2d(1)
766  xd(i, j, k, 1) = xd(i, j, k, 1) - v2d(1)
767  v2d(1) = 0.0_8
768  xd(i, j, n, 3) = xd(i, j, n, 3) + v1d(3)
769  xd(l, j, k, 3) = xd(l, j, k, 3) - v1d(3)
770  v1d(3) = 0.0_8
771  xd(i, j, n, 2) = xd(i, j, n, 2) + v1d(2)
772  xd(l, j, k, 2) = xd(l, j, k, 2) - v1d(2)
773  v1d(2) = 0.0_8
774  xd(i, j, n, 1) = xd(i, j, n, 1) + v1d(1)
775  xd(l, j, k, 1) = xd(l, j, k, 1) - v1d(1)
776  v1d(1) = 0.0_8
777  end do
778  call popreal8array(v2, 3)
779  call popreal8array(v1, 3)
780 !$bwd-of ii-loop
781  do ii=0,ke*je*(ie+1)-1
782 ! 0:ie
783  i = mod(ii, ie + 1) + 0
784 !1:je
785  j = mod(ii/(ie+1), je) + 1
786 !1:ke
787  k = ii/((ie+1)*je) + 1
788  n = k - 1
789  m = j - 1
790 ! determine the two diagonal vectors of the face.
791  v1(1) = x(i, j, n, 1) - x(i, m, k, 1)
792  v1(2) = x(i, j, n, 2) - x(i, m, k, 2)
793  v1(3) = x(i, j, n, 3) - x(i, m, k, 3)
794  v2(1) = x(i, j, k, 1) - x(i, m, n, 1)
795  v2(2) = x(i, j, k, 2) - x(i, m, n, 2)
796  v2(3) = x(i, j, k, 3) - x(i, m, n, 3)
797 ! the face normal, which is the cross product of the two
798 ! diagonal vectors times fact; remember that fact is
799 ! either -0.5 or 0.5.
800  tempd = fact*sid(i, j, k, 3)
801  sid(i, j, k, 3) = 0.0_8
802  v1d(1) = v1d(1) + v2(2)*tempd
803  v2d(2) = v2d(2) + v1(1)*tempd
804  v1d(2) = v1d(2) - v2(1)*tempd
805  v2d(1) = v2d(1) - v1(2)*tempd
806  tempd = fact*sid(i, j, k, 2)
807  sid(i, j, k, 2) = 0.0_8
808  v1d(3) = v1d(3) + v2(1)*tempd
809  v2d(1) = v2d(1) + v1(3)*tempd
810  v1d(1) = v1d(1) - v2(3)*tempd
811  v2d(3) = v2d(3) - v1(1)*tempd
812  tempd = fact*sid(i, j, k, 1)
813  sid(i, j, k, 1) = 0.0_8
814  v1d(2) = v1d(2) + v2(3)*tempd
815  v2d(3) = v2d(3) + v1(2)*tempd
816  v1d(3) = v1d(3) - v2(2)*tempd
817  v2d(2) = v2d(2) - v1(3)*tempd
818  xd(i, j, k, 3) = xd(i, j, k, 3) + v2d(3)
819  xd(i, m, n, 3) = xd(i, m, n, 3) - v2d(3)
820  v2d(3) = 0.0_8
821  xd(i, j, k, 2) = xd(i, j, k, 2) + v2d(2)
822  xd(i, m, n, 2) = xd(i, m, n, 2) - v2d(2)
823  v2d(2) = 0.0_8
824  xd(i, j, k, 1) = xd(i, j, k, 1) + v2d(1)
825  xd(i, m, n, 1) = xd(i, m, n, 1) - v2d(1)
826  v2d(1) = 0.0_8
827  xd(i, j, n, 3) = xd(i, j, n, 3) + v1d(3)
828  xd(i, m, k, 3) = xd(i, m, k, 3) - v1d(3)
829  v1d(3) = 0.0_8
830  xd(i, j, n, 2) = xd(i, j, n, 2) + v1d(2)
831  xd(i, m, k, 2) = xd(i, m, k, 2) - v1d(2)
832  v1d(2) = 0.0_8
833  xd(i, j, n, 1) = xd(i, j, n, 1) + v1d(1)
834  xd(i, m, k, 1) = xd(i, m, k, 1) - v1d(1)
835  v1d(1) = 0.0_8
836  end do
837  end subroutine metric_block_b
838 
839  subroutine metric_block()
840  use constants
841  use blockpointers
842  implicit none
843 ! local variables.
844  integer(kind=inttype) :: i, j, k, n, m, l, ii
845  real(kind=realtype) :: fact
846  real(kind=realtype) :: xxp, yyp, zzp
847  real(kind=realtype), dimension(3) :: v1, v2
848  intrinsic mod
849 ! set the factor in the surface normals computation. for a
850 ! left handed block this factor is negative, such that the
851 ! normals still point in the direction of increasing index.
852 ! the formulae used later on assume a right handed block
853 ! and fact is used to correct this for a left handed block,
854 ! as well as the scaling factor of 0.5
855  if (righthanded) then
856  fact = half
857  else
858  fact = -half
859  end if
860 !$ad ii-loop
861 !
862 ! computation of the face normals in i-, j- and k-direction.
863 ! formula's are valid for a right handed block; for a left
864 ! handed block the correct orientation is obtained via fact.
865 ! the normals point in the direction of increasing index.
866 ! the absolute value of fact is 0.5, because the cross
867 ! product of the two diagonals is twice the normal vector.
868 ! note that also the normals of the first level halo cells
869 ! are computed. these are needed for the viscous fluxes.
870 !
871 ! projected areas of cell faces in the i direction.
872  do ii=0,ke*je*(ie+1)-1
873 ! 0:ie
874  i = mod(ii, ie + 1) + 0
875 !1:je
876  j = mod(ii/(ie+1), je) + 1
877 !1:ke
878  k = ii/((ie+1)*je) + 1
879  n = k - 1
880  m = j - 1
881 ! determine the two diagonal vectors of the face.
882  v1(1) = x(i, j, n, 1) - x(i, m, k, 1)
883  v1(2) = x(i, j, n, 2) - x(i, m, k, 2)
884  v1(3) = x(i, j, n, 3) - x(i, m, k, 3)
885  v2(1) = x(i, j, k, 1) - x(i, m, n, 1)
886  v2(2) = x(i, j, k, 2) - x(i, m, n, 2)
887  v2(3) = x(i, j, k, 3) - x(i, m, n, 3)
888 ! the face normal, which is the cross product of the two
889 ! diagonal vectors times fact; remember that fact is
890 ! either -0.5 or 0.5.
891  si(i, j, k, 1) = fact*(v1(2)*v2(3)-v1(3)*v2(2))
892  si(i, j, k, 2) = fact*(v1(3)*v2(1)-v1(1)*v2(3))
893  si(i, j, k, 3) = fact*(v1(1)*v2(2)-v1(2)*v2(1))
894  end do
895 !$ad ii-loop
896 ! projected areas of cell faces in the j direction
897  do ii=0,ke*(je+1)*ie-1
898 ! 1:ie
899  i = mod(ii, ie) + 1
900 !0:je
901  j = mod(ii/ie, je + 1) + 0
902 !1:ke
903  k = ii/(ie*(je+1)) + 1
904  n = k - 1
905  l = i - 1
906 ! determine the two diagonal vectors of the face.
907  v1(1) = x(i, j, n, 1) - x(l, j, k, 1)
908  v1(2) = x(i, j, n, 2) - x(l, j, k, 2)
909  v1(3) = x(i, j, n, 3) - x(l, j, k, 3)
910  v2(1) = x(l, j, n, 1) - x(i, j, k, 1)
911  v2(2) = x(l, j, n, 2) - x(i, j, k, 2)
912  v2(3) = x(l, j, n, 3) - x(i, j, k, 3)
913 ! the face normal, which is the cross product of the two
914 ! diagonal vectors times fact; remember that fact is
915 ! either -0.5 or 0.5.
916  sj(i, j, k, 1) = fact*(v1(2)*v2(3)-v1(3)*v2(2))
917  sj(i, j, k, 2) = fact*(v1(3)*v2(1)-v1(1)*v2(3))
918  sj(i, j, k, 3) = fact*(v1(1)*v2(2)-v1(2)*v2(1))
919  end do
920 !$ad ii-loop
921 ! projected areas of cell faces in the k direction.
922  do ii=0,(ke+1)*je*ie-1
923 ! 1:ie
924  i = mod(ii, ie) + 1
925 !1:je
926  j = mod(ii/ie, je) + 1
927 !0:ke
928  k = ii/(ie*je) + 0
929  m = j - 1
930  l = i - 1
931 ! determine the two diagonal vectors of the face.
932  v1(1) = x(i, j, k, 1) - x(l, m, k, 1)
933  v1(2) = x(i, j, k, 2) - x(l, m, k, 2)
934  v1(3) = x(i, j, k, 3) - x(l, m, k, 3)
935  v2(1) = x(l, j, k, 1) - x(i, m, k, 1)
936  v2(2) = x(l, j, k, 2) - x(i, m, k, 2)
937  v2(3) = x(l, j, k, 3) - x(i, m, k, 3)
938 ! the face normal, which is the cross product of the two
939 ! diagonal vectors times fact; remember that fact is
940 ! either -0.5 or 0.5.
941  sk(i, j, k, 1) = fact*(v1(2)*v2(3)-v1(3)*v2(2))
942  sk(i, j, k, 2) = fact*(v1(3)*v2(1)-v1(1)*v2(3))
943  sk(i, j, k, 3) = fact*(v1(1)*v2(2)-v1(2)*v2(1))
944  end do
945  end subroutine metric_block
946 
947 ! differentiation of boundarynormals in reverse (adjoint) mode (with options noisize i4 dr8 r8):
948 ! gradient of useful results: *si *sj *sk *(*bcdata.norm)
949 ! with respect to varying inputs: *si *sj *sk *(*bcdata.norm)
950 ! rw status of diff variables: *si:incr *sj:incr *sk:incr *(*bcdata.norm):in-out
951 ! plus diff mem management of: si:in sj:in sk:in bcdata:in *bcdata.norm:in
952  subroutine boundarynormals_b()
953 ! the unit normals on the boundary faces. these always point
954 ! out of the domain, so a multiplication by -1 is needed for
955 ! the imin, jmin and kmin boundaries.
956 !
957  use constants
958  use blockpointers
959  use cgnsgrid
960  use communication
962  implicit none
963 ! local variables.
964  integer(kind=inttype) :: i, j, ii
965  integer(kind=inttype) :: mm
966  real(kind=realtype) :: fact, mult
967  real(kind=realtype) :: factd
968  real(kind=realtype) :: xxp, yyp, zzp
969  real(kind=realtype) :: xxpd, yypd, zzpd
970  intrinsic mod
971  intrinsic sqrt
972  real(kind=realtype) :: tempd
973  integer :: branch
974  zzpd = 0.0_8
975  yypd = 0.0_8
976  xxpd = 0.0_8
977 !$bwd-of ii-loop
978  do mm=1,nbocos
979 !$bwd-of ii-loop
980  do ii=0,(bcdata(mm)%jcend-bcdata(mm)%jcbeg+1)*(bcdata(mm)%icend-&
981 & bcdata(mm)%icbeg+1)-1
982  i = mod(ii, bcdata(mm)%icend - bcdata(mm)%icbeg + 1) + bcdata(mm&
983 & )%icbeg
984  j = ii/(bcdata(mm)%icend-bcdata(mm)%icbeg+1) + bcdata(mm)%jcbeg
985  select case (bcfaceid(mm))
986  case (imin)
987  mult = -one
988  xxp = si(1, i, j, 1)
989  yyp = si(1, i, j, 2)
990  zzp = si(1, i, j, 3)
991  call pushcontrol3b(1)
992  case (imax)
993  mult = one
994  xxp = si(il, i, j, 1)
995  yyp = si(il, i, j, 2)
996  zzp = si(il, i, j, 3)
997  call pushcontrol3b(2)
998  case (jmin)
999  mult = -one
1000  xxp = sj(i, 1, j, 1)
1001  yyp = sj(i, 1, j, 2)
1002  zzp = sj(i, 1, j, 3)
1003  call pushcontrol3b(3)
1004  case (jmax)
1005  mult = one
1006  xxp = sj(i, jl, j, 1)
1007  yyp = sj(i, jl, j, 2)
1008  zzp = sj(i, jl, j, 3)
1009  call pushcontrol3b(4)
1010  case (kmin)
1011  mult = -one
1012  xxp = sk(i, j, 1, 1)
1013  yyp = sk(i, j, 1, 2)
1014  zzp = sk(i, j, 1, 3)
1015  call pushcontrol3b(5)
1016  case (kmax)
1017  mult = one
1018  xxp = sk(i, j, kl, 1)
1019  yyp = sk(i, j, kl, 2)
1020  zzp = sk(i, j, kl, 3)
1021  call pushcontrol3b(6)
1022  case default
1023  call pushcontrol3b(0)
1024  end select
1025 ! compute the inverse of the length of the normal vector
1026 ! and possibly correct for inward pointing.
1027  fact = sqrt(xxp*xxp + yyp*yyp + zzp*zzp)
1028  if (fact .gt. zero) then
1029  call pushreal8(fact)
1030  fact = mult/fact
1031  call pushcontrol1b(0)
1032  else
1033  call pushcontrol1b(1)
1034  end if
1035  factd = zzp*bcdatad(mm)%norm(i, j, 3)
1036  zzpd = zzpd + fact*bcdatad(mm)%norm(i, j, 3)
1037  bcdatad(mm)%norm(i, j, 3) = 0.0_8
1038  factd = factd + yyp*bcdatad(mm)%norm(i, j, 2)
1039  yypd = yypd + fact*bcdatad(mm)%norm(i, j, 2)
1040  bcdatad(mm)%norm(i, j, 2) = 0.0_8
1041  factd = factd + xxp*bcdatad(mm)%norm(i, j, 1)
1042  xxpd = xxpd + fact*bcdatad(mm)%norm(i, j, 1)
1043  bcdatad(mm)%norm(i, j, 1) = 0.0_8
1044  call popcontrol1b(branch)
1045  if (branch .eq. 0) then
1046  call popreal8(fact)
1047  factd = -(mult*factd/fact**2)
1048  end if
1049  if (xxp**2 + yyp**2 + zzp**2 .eq. 0.0_8) then
1050  tempd = 0.0_8
1051  else
1052  tempd = factd/(2.0*sqrt(xxp**2+yyp**2+zzp**2))
1053  end if
1054  xxpd = xxpd + 2*xxp*tempd
1055  yypd = yypd + 2*yyp*tempd
1056  zzpd = zzpd + 2*zzp*tempd
1057  call popcontrol3b(branch)
1058  if (branch .lt. 3) then
1059  if (branch .ne. 0) then
1060  if (branch .eq. 1) then
1061  sid(1, i, j, 3) = sid(1, i, j, 3) + zzpd
1062  sid(1, i, j, 2) = sid(1, i, j, 2) + yypd
1063  sid(1, i, j, 1) = sid(1, i, j, 1) + xxpd
1064  zzpd = 0.0_8
1065  yypd = 0.0_8
1066  xxpd = 0.0_8
1067  else
1068  sid(il, i, j, 3) = sid(il, i, j, 3) + zzpd
1069  sid(il, i, j, 2) = sid(il, i, j, 2) + yypd
1070  sid(il, i, j, 1) = sid(il, i, j, 1) + xxpd
1071  zzpd = 0.0_8
1072  yypd = 0.0_8
1073  xxpd = 0.0_8
1074  end if
1075  end if
1076  else if (branch .lt. 5) then
1077  if (branch .eq. 3) then
1078  sjd(i, 1, j, 3) = sjd(i, 1, j, 3) + zzpd
1079  sjd(i, 1, j, 2) = sjd(i, 1, j, 2) + yypd
1080  sjd(i, 1, j, 1) = sjd(i, 1, j, 1) + xxpd
1081  zzpd = 0.0_8
1082  yypd = 0.0_8
1083  xxpd = 0.0_8
1084  else
1085  sjd(i, jl, j, 3) = sjd(i, jl, j, 3) + zzpd
1086  sjd(i, jl, j, 2) = sjd(i, jl, j, 2) + yypd
1087  sjd(i, jl, j, 1) = sjd(i, jl, j, 1) + xxpd
1088  zzpd = 0.0_8
1089  yypd = 0.0_8
1090  xxpd = 0.0_8
1091  end if
1092  else if (branch .eq. 5) then
1093  skd(i, j, 1, 3) = skd(i, j, 1, 3) + zzpd
1094  skd(i, j, 1, 2) = skd(i, j, 1, 2) + yypd
1095  skd(i, j, 1, 1) = skd(i, j, 1, 1) + xxpd
1096  zzpd = 0.0_8
1097  yypd = 0.0_8
1098  xxpd = 0.0_8
1099  else
1100  skd(i, j, kl, 3) = skd(i, j, kl, 3) + zzpd
1101  skd(i, j, kl, 2) = skd(i, j, kl, 2) + yypd
1102  skd(i, j, kl, 1) = skd(i, j, kl, 1) + xxpd
1103  zzpd = 0.0_8
1104  yypd = 0.0_8
1105  xxpd = 0.0_8
1106  end if
1107  end do
1108  end do
1109  end subroutine boundarynormals_b
1110 
1111  subroutine boundarynormals()
1112 ! the unit normals on the boundary faces. these always point
1113 ! out of the domain, so a multiplication by -1 is needed for
1114 ! the imin, jmin and kmin boundaries.
1115 !
1116  use constants
1117  use blockpointers
1118  use cgnsgrid
1119  use communication
1120  use inputtimespectral
1121  implicit none
1122 ! local variables.
1123  integer(kind=inttype) :: i, j, ii
1124  integer(kind=inttype) :: mm
1125  real(kind=realtype) :: fact, mult
1126  real(kind=realtype) :: xxp, yyp, zzp
1127  intrinsic mod
1128  intrinsic sqrt
1129 !$ad ii-loop
1130 !loop over the boundary subfaces of this block.
1131 bocoloop:do mm=1,nbocos
1132 !$ad ii-loop
1133 ! loop over the boundary faces of the subface.
1134  do ii=0,(bcdata(mm)%jcend-bcdata(mm)%jcbeg+1)*(bcdata(mm)%icend-&
1135 & bcdata(mm)%icbeg+1)-1
1136  i = mod(ii, bcdata(mm)%icend - bcdata(mm)%icbeg + 1) + bcdata(mm&
1137 & )%icbeg
1138  j = ii/(bcdata(mm)%icend-bcdata(mm)%icbeg+1) + bcdata(mm)%jcbeg
1139  select case (bcfaceid(mm))
1140  case (imin)
1141  mult = -one
1142  xxp = si(1, i, j, 1)
1143  yyp = si(1, i, j, 2)
1144  zzp = si(1, i, j, 3)
1145  case (imax)
1146  mult = one
1147  xxp = si(il, i, j, 1)
1148  yyp = si(il, i, j, 2)
1149  zzp = si(il, i, j, 3)
1150  case (jmin)
1151  mult = -one
1152  xxp = sj(i, 1, j, 1)
1153  yyp = sj(i, 1, j, 2)
1154  zzp = sj(i, 1, j, 3)
1155  case (jmax)
1156  mult = one
1157  xxp = sj(i, jl, j, 1)
1158  yyp = sj(i, jl, j, 2)
1159  zzp = sj(i, jl, j, 3)
1160  case (kmin)
1161  mult = -one
1162  xxp = sk(i, j, 1, 1)
1163  yyp = sk(i, j, 1, 2)
1164  zzp = sk(i, j, 1, 3)
1165  case (kmax)
1166  mult = one
1167  xxp = sk(i, j, kl, 1)
1168  yyp = sk(i, j, kl, 2)
1169  zzp = sk(i, j, kl, 3)
1170  end select
1171 ! compute the inverse of the length of the normal vector
1172 ! and possibly correct for inward pointing.
1173  fact = sqrt(xxp*xxp + yyp*yyp + zzp*zzp)
1174  if (fact .gt. zero) fact = mult/fact
1175 ! compute the unit normal.
1176  bcdata(mm)%norm(i, j, 1) = fact*xxp
1177  bcdata(mm)%norm(i, j, 2) = fact*yyp
1178  bcdata(mm)%norm(i, j, 3) = fact*zzp
1179  end do
1180  end do bocoloop
1181  end subroutine boundarynormals
1182 
1183 ! differentiation of xhalo_block in reverse (adjoint) mode (with options noisize i4 dr8 r8):
1184 ! gradient of useful results: *x
1185 ! with respect to varying inputs: *x
1186 ! rw status of diff variables: *x:in-out
1187 ! plus diff mem management of: x:in
1188  subroutine xhalo_block_b()
1189 !
1190 ! xhalo determines the coordinates of the nodal halo's.
1191 ! first it sets all halo coordinates by simple extrapolation,
1192 ! then the symmetry planes are treated (also the unit normal of
1193 ! symmetry planes are determined) and finally an exchange is
1194 ! made for the internal halo's.
1195 !
1196  use constants
1197  use blockpointers
1198  use communication
1199  use inputtimespectral
1200  implicit none
1201 !
1202 ! local variables.
1203 !
1204  integer(kind=inttype) :: mm, i, j, k
1205  integer(kind=inttype) :: ibeg, iend, jbeg, jend, iimax, jjmax
1206  logical :: err
1207  real(kind=realtype) :: length, dot
1208  real(kind=realtype) :: dotd
1209  real(kind=realtype), dimension(3) :: v1, v2, norm
1210  real(kind=realtype), dimension(3) :: v1d
1211  intrinsic sqrt
1212  real(kind=realtype) :: tmp
1213  real(kind=realtype) :: tmpd
1214  real(kind=realtype) :: tmp0
1215  real(kind=realtype) :: tmpd0
1216  real(kind=realtype) :: tmp1
1217  real(kind=realtype) :: tmpd1
1218  real(kind=realtype) :: tmp2
1219  real(kind=realtype) :: tmpd2
1220  real(kind=realtype) :: tmp3
1221  real(kind=realtype) :: tmpd3
1222  real(kind=realtype) :: tmp4
1223  real(kind=realtype) :: tmpd4
1224  real(kind=realtype) :: tmp5
1225  real(kind=realtype) :: tmpd5
1226  real(kind=realtype) :: tmp6
1227  real(kind=realtype) :: tmpd6
1228  real(kind=realtype) :: tmp7
1229  real(kind=realtype) :: tmpd7
1230  real(kind=realtype) :: tempd
1231  real(kind=realtype) :: tmp8
1232  real(kind=realtype) :: tmpd8
1233  real(kind=realtype) :: tmp9
1234  real(kind=realtype) :: tmpd9
1235  real(kind=realtype) :: tmp10
1236  real(kind=realtype) :: tmpd10
1237  real(kind=realtype) :: tmp11
1238  real(kind=realtype) :: tmpd11
1239  real(kind=realtype) :: tmp12
1240  real(kind=realtype) :: tmpd12
1241  real(kind=realtype) :: tmp13
1242  real(kind=realtype) :: tmpd13
1243  real(kind=realtype) :: tmp14
1244  real(kind=realtype) :: tmpd14
1245  real(kind=realtype) :: tmp15
1246  real(kind=realtype) :: tmpd15
1247  real(kind=realtype) :: tmp16
1248  real(kind=realtype) :: tmpd16
1249  integer :: ad_from
1250  integer :: ad_to
1251  integer :: ad_from0
1252  integer :: ad_to0
1253  integer :: ad_from1
1254  integer :: ad_to1
1255  integer :: ad_from2
1256  integer :: ad_to2
1257  integer :: ad_from3
1258  integer :: ad_to3
1259  integer :: ad_from4
1260  integer :: ad_to4
1261  integer :: ad_from5
1262  integer :: ad_to5
1263  integer :: ad_from6
1264  integer :: ad_to6
1265  integer :: ad_from7
1266  integer :: ad_to7
1267  integer :: ad_from8
1268  integer :: ad_to8
1269  integer :: ad_from9
1270  integer :: ad_to9
1271  integer :: ad_from10
1272  integer :: ad_to10
1273  integer :: branch
1274 !
1275 ! mirror the halo coordinates adjacent to the symmetry
1276 ! planes
1277 !
1278 ! loop over boundary subfaces.
1279 loopbocos:do mm=1,nbocos
1280 ! the actual correction of the coordinates only takes
1281 ! place for symmetry planes.
1282  if (bctype(mm) .eq. symm) then
1283 ! set some variables, depending on the block face on
1284 ! which the subface is located.
1285  call pushreal8(norm(1))
1286  norm(1) = bcdata(mm)%symnorm(1)
1287  call pushreal8(norm(2))
1288  norm(2) = bcdata(mm)%symnorm(2)
1289  call pushreal8(norm(3))
1290  norm(3) = bcdata(mm)%symnorm(3)
1291  length = sqrt(norm(1)**2 + norm(2)**2 + norm(3)**2)
1292 ! compute the unit normal of the subface.
1293  call pushreal8(norm(1))
1294  norm(1) = norm(1)/length
1295  call pushreal8(norm(2))
1296  norm(2) = norm(2)/length
1297  call pushreal8(norm(3))
1298  norm(3) = norm(3)/length
1299 ! see xhalo_block for comments for below:
1300  if (length .gt. eps) then
1301  select case (bcfaceid(mm))
1302  case (imin)
1303  ibeg = jnbeg(mm)
1304  iend = jnend(mm)
1305  iimax = jl
1306  jbeg = knbeg(mm)
1307  jend = knend(mm)
1308  jjmax = kl
1309  if (ibeg .eq. 1) ibeg = 0
1310  if (iend .eq. iimax) iend = iimax + 1
1311  if (jbeg .eq. 1) jbeg = 0
1312  if (jend .eq. jjmax) jend = jjmax + 1
1313  ad_from0 = jbeg
1314  do j=ad_from0,jend
1315  ad_from = ibeg
1316  i = iend + 1
1317  call pushinteger4(i - 1)
1318  call pushinteger4(ad_from)
1319  end do
1320  call pushinteger4(j - 1)
1321  call pushinteger4(ad_from0)
1322  call pushcontrol4b(7)
1323  case (imax)
1324  ibeg = jnbeg(mm)
1325  iend = jnend(mm)
1326  iimax = jl
1327  jbeg = knbeg(mm)
1328  jend = knend(mm)
1329  jjmax = kl
1330  if (ibeg .eq. 1) ibeg = 0
1331  if (iend .eq. iimax) iend = iimax + 1
1332  if (jbeg .eq. 1) jbeg = 0
1333  if (jend .eq. jjmax) jend = jjmax + 1
1334  ad_from2 = jbeg
1335  do j=ad_from2,jend
1336  ad_from1 = ibeg
1337  i = iend + 1
1338  call pushinteger4(i - 1)
1339  call pushinteger4(ad_from1)
1340  end do
1341  call pushinteger4(j - 1)
1342  call pushinteger4(ad_from2)
1343  call pushcontrol4b(6)
1344  case (jmin)
1345  ibeg = inbeg(mm)
1346  iend = inend(mm)
1347  iimax = il
1348  jbeg = knbeg(mm)
1349  jend = knend(mm)
1350  jjmax = kl
1351  if (ibeg .eq. 1) ibeg = 0
1352  if (iend .eq. iimax) iend = iimax + 1
1353  if (jbeg .eq. 1) jbeg = 0
1354  if (jend .eq. jjmax) jend = jjmax + 1
1355  ad_from4 = jbeg
1356  do j=ad_from4,jend
1357  ad_from3 = ibeg
1358  i = iend + 1
1359  call pushinteger4(i - 1)
1360  call pushinteger4(ad_from3)
1361  end do
1362  call pushinteger4(j - 1)
1363  call pushinteger4(ad_from4)
1364  call pushcontrol4b(5)
1365  case (jmax)
1366  ibeg = inbeg(mm)
1367  iend = inend(mm)
1368  iimax = il
1369  jbeg = knbeg(mm)
1370  jend = knend(mm)
1371  jjmax = kl
1372  if (ibeg .eq. 1) ibeg = 0
1373  if (iend .eq. iimax) iend = iimax + 1
1374  if (jbeg .eq. 1) jbeg = 0
1375  if (jend .eq. jjmax) jend = jjmax + 1
1376  ad_from6 = jbeg
1377  do j=ad_from6,jend
1378  ad_from5 = ibeg
1379  i = iend + 1
1380  call pushinteger4(i - 1)
1381  call pushinteger4(ad_from5)
1382  end do
1383  call pushinteger4(j - 1)
1384  call pushinteger4(ad_from6)
1385  call pushcontrol4b(4)
1386  case (kmin)
1387  ibeg = inbeg(mm)
1388  iend = inend(mm)
1389  iimax = il
1390  jbeg = jnbeg(mm)
1391  jend = jnend(mm)
1392  jjmax = jl
1393  if (ibeg .eq. 1) ibeg = 0
1394  if (iend .eq. iimax) iend = iimax + 1
1395  if (jbeg .eq. 1) jbeg = 0
1396  if (jend .eq. jjmax) jend = jjmax + 1
1397  ad_from8 = jbeg
1398  do j=ad_from8,jend
1399  ad_from7 = ibeg
1400  i = iend + 1
1401  call pushinteger4(i - 1)
1402  call pushinteger4(ad_from7)
1403  end do
1404  call pushinteger4(j - 1)
1405  call pushinteger4(ad_from8)
1406  call pushcontrol4b(3)
1407  case (kmax)
1408  ibeg = inbeg(mm)
1409  iend = inend(mm)
1410  iimax = il
1411  jbeg = jnbeg(mm)
1412  jend = jnend(mm)
1413  jjmax = jl
1414  if (ibeg .eq. 1) ibeg = 0
1415  if (iend .eq. iimax) iend = iimax + 1
1416  if (jbeg .eq. 1) jbeg = 0
1417  if (jend .eq. jjmax) jend = jjmax + 1
1418  ad_from10 = jbeg
1419  do j=ad_from10,jend
1420  ad_from9 = ibeg
1421  i = iend + 1
1422  call pushinteger4(i - 1)
1423  call pushinteger4(ad_from9)
1424  end do
1425  call pushinteger4(j - 1)
1426  call pushinteger4(ad_from10)
1427  call pushcontrol4b(2)
1428  case default
1429  call pushcontrol4b(8)
1430  end select
1431  else
1432  call pushcontrol4b(1)
1433  end if
1434  else
1435  call pushcontrol4b(0)
1436  end if
1437  end do loopbocos
1438  v1d = 0.0_8
1439  do 100 mm=nbocos,1,-1
1440  call popcontrol4b(branch)
1441  if (branch .lt. 4) then
1442  if (branch .lt. 2) then
1443  if (branch .eq. 0) goto 100
1444  else if (branch .eq. 2) then
1445  call popinteger4(ad_from10)
1446  call popinteger4(ad_to10)
1447  do j=ad_to10,ad_from10,-1
1448  call popinteger4(ad_from9)
1449  call popinteger4(ad_to9)
1450  do i=ad_to9,ad_from9,-1
1451  tmpd16 = xd(i, j, ke, 3)
1452  xd(i, j, ke, 3) = 0.0_8
1453  xd(i, j, nz, 3) = xd(i, j, nz, 3) + tmpd16
1454  tmpd15 = xd(i, j, ke, 2)
1455  xd(i, j, ke, 2) = 0.0_8
1456  xd(i, j, nz, 2) = xd(i, j, nz, 2) + tmpd15
1457  tmpd14 = xd(i, j, ke, 1)
1458  dotd = norm(3)*tmpd16 + norm(2)*tmpd15 + norm(1)*tmpd14
1459  xd(i, j, ke, 1) = 0.0_8
1460  xd(i, j, nz, 1) = xd(i, j, nz, 1) + tmpd14
1461  tempd = two*dotd
1462  v1d(1) = v1d(1) + norm(1)*tempd
1463  v1d(2) = v1d(2) + norm(2)*tempd
1464  v1d(3) = v1d(3) + norm(3)*tempd
1465  xd(i, j, kl, 3) = xd(i, j, kl, 3) + v1d(3)
1466  xd(i, j, nz, 3) = xd(i, j, nz, 3) - v1d(3)
1467  v1d(3) = 0.0_8
1468  xd(i, j, kl, 2) = xd(i, j, kl, 2) + v1d(2)
1469  xd(i, j, nz, 2) = xd(i, j, nz, 2) - v1d(2)
1470  v1d(2) = 0.0_8
1471  xd(i, j, kl, 1) = xd(i, j, kl, 1) + v1d(1)
1472  xd(i, j, nz, 1) = xd(i, j, nz, 1) - v1d(1)
1473  v1d(1) = 0.0_8
1474  end do
1475  end do
1476  else
1477  call popinteger4(ad_from8)
1478  call popinteger4(ad_to8)
1479  do j=ad_to8,ad_from8,-1
1480  call popinteger4(ad_from7)
1481  call popinteger4(ad_to7)
1482  do i=ad_to7,ad_from7,-1
1483  xd(i, j, 2, 3) = xd(i, j, 2, 3) + xd(i, j, 0, 3)
1484  dotd = norm(3)*xd(i, j, 0, 3)
1485  xd(i, j, 0, 3) = 0.0_8
1486  xd(i, j, 2, 2) = xd(i, j, 2, 2) + xd(i, j, 0, 2)
1487  dotd = dotd + norm(2)*xd(i, j, 0, 2)
1488  xd(i, j, 0, 2) = 0.0_8
1489  xd(i, j, 2, 1) = xd(i, j, 2, 1) + xd(i, j, 0, 1)
1490  dotd = dotd + norm(1)*xd(i, j, 0, 1)
1491  xd(i, j, 0, 1) = 0.0_8
1492  tempd = two*dotd
1493  v1d(1) = v1d(1) + norm(1)*tempd
1494  v1d(2) = v1d(2) + norm(2)*tempd
1495  v1d(3) = v1d(3) + norm(3)*tempd
1496  xd(i, j, 1, 3) = xd(i, j, 1, 3) + v1d(3)
1497  xd(i, j, 2, 3) = xd(i, j, 2, 3) - v1d(3)
1498  v1d(3) = 0.0_8
1499  xd(i, j, 1, 2) = xd(i, j, 1, 2) + v1d(2)
1500  xd(i, j, 2, 2) = xd(i, j, 2, 2) - v1d(2)
1501  v1d(2) = 0.0_8
1502  xd(i, j, 1, 1) = xd(i, j, 1, 1) + v1d(1)
1503  xd(i, j, 2, 1) = xd(i, j, 2, 1) - v1d(1)
1504  v1d(1) = 0.0_8
1505  end do
1506  end do
1507  end if
1508  else if (branch .lt. 6) then
1509  if (branch .eq. 4) then
1510  call popinteger4(ad_from6)
1511  call popinteger4(ad_to6)
1512  do j=ad_to6,ad_from6,-1
1513  call popinteger4(ad_from5)
1514  call popinteger4(ad_to5)
1515  do i=ad_to5,ad_from5,-1
1516  tmpd13 = xd(i, je, j, 3)
1517  xd(i, je, j, 3) = 0.0_8
1518  xd(i, ny, j, 3) = xd(i, ny, j, 3) + tmpd13
1519  tmpd12 = xd(i, je, j, 2)
1520  xd(i, je, j, 2) = 0.0_8
1521  xd(i, ny, j, 2) = xd(i, ny, j, 2) + tmpd12
1522  tmpd11 = xd(i, je, j, 1)
1523  dotd = norm(3)*tmpd13 + norm(2)*tmpd12 + norm(1)*tmpd11
1524  xd(i, je, j, 1) = 0.0_8
1525  xd(i, ny, j, 1) = xd(i, ny, j, 1) + tmpd11
1526  tempd = two*dotd
1527  v1d(1) = v1d(1) + norm(1)*tempd
1528  v1d(2) = v1d(2) + norm(2)*tempd
1529  v1d(3) = v1d(3) + norm(3)*tempd
1530  xd(i, jl, j, 3) = xd(i, jl, j, 3) + v1d(3)
1531  xd(i, ny, j, 3) = xd(i, ny, j, 3) - v1d(3)
1532  v1d(3) = 0.0_8
1533  xd(i, jl, j, 2) = xd(i, jl, j, 2) + v1d(2)
1534  xd(i, ny, j, 2) = xd(i, ny, j, 2) - v1d(2)
1535  v1d(2) = 0.0_8
1536  xd(i, jl, j, 1) = xd(i, jl, j, 1) + v1d(1)
1537  xd(i, ny, j, 1) = xd(i, ny, j, 1) - v1d(1)
1538  v1d(1) = 0.0_8
1539  end do
1540  end do
1541  else
1542  call popinteger4(ad_from4)
1543  call popinteger4(ad_to4)
1544  do j=ad_to4,ad_from4,-1
1545  call popinteger4(ad_from3)
1546  call popinteger4(ad_to3)
1547  do i=ad_to3,ad_from3,-1
1548  xd(i, 2, j, 3) = xd(i, 2, j, 3) + xd(i, 0, j, 3)
1549  dotd = norm(3)*xd(i, 0, j, 3)
1550  xd(i, 0, j, 3) = 0.0_8
1551  xd(i, 2, j, 2) = xd(i, 2, j, 2) + xd(i, 0, j, 2)
1552  dotd = dotd + norm(2)*xd(i, 0, j, 2)
1553  xd(i, 0, j, 2) = 0.0_8
1554  xd(i, 2, j, 1) = xd(i, 2, j, 1) + xd(i, 0, j, 1)
1555  dotd = dotd + norm(1)*xd(i, 0, j, 1)
1556  xd(i, 0, j, 1) = 0.0_8
1557  tempd = two*dotd
1558  v1d(1) = v1d(1) + norm(1)*tempd
1559  v1d(2) = v1d(2) + norm(2)*tempd
1560  v1d(3) = v1d(3) + norm(3)*tempd
1561  xd(i, 1, j, 3) = xd(i, 1, j, 3) + v1d(3)
1562  xd(i, 2, j, 3) = xd(i, 2, j, 3) - v1d(3)
1563  v1d(3) = 0.0_8
1564  xd(i, 1, j, 2) = xd(i, 1, j, 2) + v1d(2)
1565  xd(i, 2, j, 2) = xd(i, 2, j, 2) - v1d(2)
1566  v1d(2) = 0.0_8
1567  xd(i, 1, j, 1) = xd(i, 1, j, 1) + v1d(1)
1568  xd(i, 2, j, 1) = xd(i, 2, j, 1) - v1d(1)
1569  v1d(1) = 0.0_8
1570  end do
1571  end do
1572  end if
1573  else if (branch .eq. 6) then
1574  call popinteger4(ad_from2)
1575  call popinteger4(ad_to2)
1576  do j=ad_to2,ad_from2,-1
1577  call popinteger4(ad_from1)
1578  call popinteger4(ad_to1)
1579  do i=ad_to1,ad_from1,-1
1580  tmpd10 = xd(ie, i, j, 3)
1581  xd(ie, i, j, 3) = 0.0_8
1582  xd(nx, i, j, 3) = xd(nx, i, j, 3) + tmpd10
1583  tmpd9 = xd(ie, i, j, 2)
1584  xd(ie, i, j, 2) = 0.0_8
1585  xd(nx, i, j, 2) = xd(nx, i, j, 2) + tmpd9
1586  tmpd8 = xd(ie, i, j, 1)
1587  dotd = norm(3)*tmpd10 + norm(2)*tmpd9 + norm(1)*tmpd8
1588  xd(ie, i, j, 1) = 0.0_8
1589  xd(nx, i, j, 1) = xd(nx, i, j, 1) + tmpd8
1590  tempd = two*dotd
1591  v1d(1) = v1d(1) + norm(1)*tempd
1592  v1d(2) = v1d(2) + norm(2)*tempd
1593  v1d(3) = v1d(3) + norm(3)*tempd
1594  xd(il, i, j, 3) = xd(il, i, j, 3) + v1d(3)
1595  xd(nx, i, j, 3) = xd(nx, i, j, 3) - v1d(3)
1596  v1d(3) = 0.0_8
1597  xd(il, i, j, 2) = xd(il, i, j, 2) + v1d(2)
1598  xd(nx, i, j, 2) = xd(nx, i, j, 2) - v1d(2)
1599  v1d(2) = 0.0_8
1600  xd(il, i, j, 1) = xd(il, i, j, 1) + v1d(1)
1601  xd(nx, i, j, 1) = xd(nx, i, j, 1) - v1d(1)
1602  v1d(1) = 0.0_8
1603  end do
1604  end do
1605  else if (branch .eq. 7) then
1606  call popinteger4(ad_from0)
1607  call popinteger4(ad_to0)
1608  do j=ad_to0,ad_from0,-1
1609  call popinteger4(ad_from)
1610  call popinteger4(ad_to)
1611  do i=ad_to,ad_from,-1
1612  xd(2, i, j, 3) = xd(2, i, j, 3) + xd(0, i, j, 3)
1613  dotd = norm(3)*xd(0, i, j, 3)
1614  xd(0, i, j, 3) = 0.0_8
1615  xd(2, i, j, 2) = xd(2, i, j, 2) + xd(0, i, j, 2)
1616  dotd = dotd + norm(2)*xd(0, i, j, 2)
1617  xd(0, i, j, 2) = 0.0_8
1618  xd(2, i, j, 1) = xd(2, i, j, 1) + xd(0, i, j, 1)
1619  dotd = dotd + norm(1)*xd(0, i, j, 1)
1620  xd(0, i, j, 1) = 0.0_8
1621  tempd = two*dotd
1622  v1d(1) = v1d(1) + norm(1)*tempd
1623  v1d(2) = v1d(2) + norm(2)*tempd
1624  v1d(3) = v1d(3) + norm(3)*tempd
1625  xd(1, i, j, 3) = xd(1, i, j, 3) + v1d(3)
1626  xd(2, i, j, 3) = xd(2, i, j, 3) - v1d(3)
1627  v1d(3) = 0.0_8
1628  xd(1, i, j, 2) = xd(1, i, j, 2) + v1d(2)
1629  xd(2, i, j, 2) = xd(2, i, j, 2) - v1d(2)
1630  v1d(2) = 0.0_8
1631  xd(1, i, j, 1) = xd(1, i, j, 1) + v1d(1)
1632  xd(2, i, j, 1) = xd(2, i, j, 1) - v1d(1)
1633  v1d(1) = 0.0_8
1634  end do
1635  end do
1636  end if
1637  call popreal8(norm(3))
1638  call popreal8(norm(2))
1639  call popreal8(norm(1))
1640  call popreal8(norm(3))
1641  call popreal8(norm(2))
1642  call popreal8(norm(1))
1643  100 continue
1644  do j=je,0,-1
1645  do i=ie,0,-1
1646  tmpd7 = xd(i, j, ke, 3)
1647  xd(i, j, ke, 3) = 0.0_8
1648  xd(i, j, kl, 3) = xd(i, j, kl, 3) + two*tmpd7
1649  xd(i, j, nz, 3) = xd(i, j, nz, 3) - tmpd7
1650  tmpd6 = xd(i, j, ke, 2)
1651  xd(i, j, ke, 2) = 0.0_8
1652  xd(i, j, kl, 2) = xd(i, j, kl, 2) + two*tmpd6
1653  xd(i, j, nz, 2) = xd(i, j, nz, 2) - tmpd6
1654  tmpd5 = xd(i, j, ke, 1)
1655  xd(i, j, ke, 1) = 0.0_8
1656  xd(i, j, kl, 1) = xd(i, j, kl, 1) + two*tmpd5
1657  xd(i, j, nz, 1) = xd(i, j, nz, 1) - tmpd5
1658  xd(i, j, 1, 3) = xd(i, j, 1, 3) + two*xd(i, j, 0, 3)
1659  xd(i, j, 2, 3) = xd(i, j, 2, 3) - xd(i, j, 0, 3)
1660  xd(i, j, 0, 3) = 0.0_8
1661  xd(i, j, 1, 2) = xd(i, j, 1, 2) + two*xd(i, j, 0, 2)
1662  xd(i, j, 2, 2) = xd(i, j, 2, 2) - xd(i, j, 0, 2)
1663  xd(i, j, 0, 2) = 0.0_8
1664  xd(i, j, 1, 1) = xd(i, j, 1, 1) + two*xd(i, j, 0, 1)
1665  xd(i, j, 2, 1) = xd(i, j, 2, 1) - xd(i, j, 0, 1)
1666  xd(i, j, 0, 1) = 0.0_8
1667  end do
1668  end do
1669  do k=kl,1,-1
1670  do i=ie,0,-1
1671  tmpd4 = xd(i, je, k, 3)
1672  xd(i, je, k, 3) = 0.0_8
1673  xd(i, jl, k, 3) = xd(i, jl, k, 3) + two*tmpd4
1674  xd(i, ny, k, 3) = xd(i, ny, k, 3) - tmpd4
1675  tmpd3 = xd(i, je, k, 2)
1676  xd(i, je, k, 2) = 0.0_8
1677  xd(i, jl, k, 2) = xd(i, jl, k, 2) + two*tmpd3
1678  xd(i, ny, k, 2) = xd(i, ny, k, 2) - tmpd3
1679  tmpd2 = xd(i, je, k, 1)
1680  xd(i, je, k, 1) = 0.0_8
1681  xd(i, jl, k, 1) = xd(i, jl, k, 1) + two*tmpd2
1682  xd(i, ny, k, 1) = xd(i, ny, k, 1) - tmpd2
1683  xd(i, 1, k, 3) = xd(i, 1, k, 3) + two*xd(i, 0, k, 3)
1684  xd(i, 2, k, 3) = xd(i, 2, k, 3) - xd(i, 0, k, 3)
1685  xd(i, 0, k, 3) = 0.0_8
1686  xd(i, 1, k, 2) = xd(i, 1, k, 2) + two*xd(i, 0, k, 2)
1687  xd(i, 2, k, 2) = xd(i, 2, k, 2) - xd(i, 0, k, 2)
1688  xd(i, 0, k, 2) = 0.0_8
1689  xd(i, 1, k, 1) = xd(i, 1, k, 1) + two*xd(i, 0, k, 1)
1690  xd(i, 2, k, 1) = xd(i, 2, k, 1) - xd(i, 0, k, 1)
1691  xd(i, 0, k, 1) = 0.0_8
1692  end do
1693  end do
1694  do k=kl,1,-1
1695  do j=jl,1,-1
1696  tmpd1 = xd(ie, j, k, 3)
1697  xd(ie, j, k, 3) = 0.0_8
1698  xd(il, j, k, 3) = xd(il, j, k, 3) + two*tmpd1
1699  xd(nx, j, k, 3) = xd(nx, j, k, 3) - tmpd1
1700  tmpd0 = xd(ie, j, k, 2)
1701  xd(ie, j, k, 2) = 0.0_8
1702  xd(il, j, k, 2) = xd(il, j, k, 2) + two*tmpd0
1703  xd(nx, j, k, 2) = xd(nx, j, k, 2) - tmpd0
1704  tmpd = xd(ie, j, k, 1)
1705  xd(ie, j, k, 1) = 0.0_8
1706  xd(il, j, k, 1) = xd(il, j, k, 1) + two*tmpd
1707  xd(nx, j, k, 1) = xd(nx, j, k, 1) - tmpd
1708  xd(1, j, k, 3) = xd(1, j, k, 3) + two*xd(0, j, k, 3)
1709  xd(2, j, k, 3) = xd(2, j, k, 3) - xd(0, j, k, 3)
1710  xd(0, j, k, 3) = 0.0_8
1711  xd(1, j, k, 2) = xd(1, j, k, 2) + two*xd(0, j, k, 2)
1712  xd(2, j, k, 2) = xd(2, j, k, 2) - xd(0, j, k, 2)
1713  xd(0, j, k, 2) = 0.0_8
1714  xd(1, j, k, 1) = xd(1, j, k, 1) + two*xd(0, j, k, 1)
1715  xd(2, j, k, 1) = xd(2, j, k, 1) - xd(0, j, k, 1)
1716  xd(0, j, k, 1) = 0.0_8
1717  end do
1718  end do
1719  end subroutine xhalo_block_b
1720 
1721  subroutine xhalo_block()
1722 !
1723 ! xhalo determines the coordinates of the nodal halo's.
1724 ! first it sets all halo coordinates by simple extrapolation,
1725 ! then the symmetry planes are treated (also the unit normal of
1726 ! symmetry planes are determined) and finally an exchange is
1727 ! made for the internal halo's.
1728 !
1729  use constants
1730  use blockpointers
1731  use communication
1732  use inputtimespectral
1733  implicit none
1734 !
1735 ! local variables.
1736 !
1737  integer(kind=inttype) :: mm, i, j, k
1738  integer(kind=inttype) :: ibeg, iend, jbeg, jend, iimax, jjmax
1739  logical :: err
1740  real(kind=realtype) :: length, dot
1741  real(kind=realtype), dimension(3) :: v1, v2, norm
1742  intrinsic sqrt
1743 ! extrapolation in i-direction.
1744  do k=1,kl
1745  do j=1,jl
1746  x(0, j, k, 1) = two*x(1, j, k, 1) - x(2, j, k, 1)
1747  x(0, j, k, 2) = two*x(1, j, k, 2) - x(2, j, k, 2)
1748  x(0, j, k, 3) = two*x(1, j, k, 3) - x(2, j, k, 3)
1749  x(ie, j, k, 1) = two*x(il, j, k, 1) - x(nx, j, k, 1)
1750  x(ie, j, k, 2) = two*x(il, j, k, 2) - x(nx, j, k, 2)
1751  x(ie, j, k, 3) = two*x(il, j, k, 3) - x(nx, j, k, 3)
1752  end do
1753  end do
1754 ! extrapolation in j-direction.
1755  do k=1,kl
1756  do i=0,ie
1757  x(i, 0, k, 1) = two*x(i, 1, k, 1) - x(i, 2, k, 1)
1758  x(i, 0, k, 2) = two*x(i, 1, k, 2) - x(i, 2, k, 2)
1759  x(i, 0, k, 3) = two*x(i, 1, k, 3) - x(i, 2, k, 3)
1760  x(i, je, k, 1) = two*x(i, jl, k, 1) - x(i, ny, k, 1)
1761  x(i, je, k, 2) = two*x(i, jl, k, 2) - x(i, ny, k, 2)
1762  x(i, je, k, 3) = two*x(i, jl, k, 3) - x(i, ny, k, 3)
1763  end do
1764  end do
1765 ! extrapolation in k-direction.
1766  do j=0,je
1767  do i=0,ie
1768  x(i, j, 0, 1) = two*x(i, j, 1, 1) - x(i, j, 2, 1)
1769  x(i, j, 0, 2) = two*x(i, j, 1, 2) - x(i, j, 2, 2)
1770  x(i, j, 0, 3) = two*x(i, j, 1, 3) - x(i, j, 2, 3)
1771  x(i, j, ke, 1) = two*x(i, j, kl, 1) - x(i, j, nz, 1)
1772  x(i, j, ke, 2) = two*x(i, j, kl, 2) - x(i, j, nz, 2)
1773  x(i, j, ke, 3) = two*x(i, j, kl, 3) - x(i, j, nz, 3)
1774  end do
1775  end do
1776 !
1777 ! mirror the halo coordinates adjacent to the symmetry
1778 ! planes
1779 !
1780 ! loop over boundary subfaces.
1781 loopbocos:do mm=1,nbocos
1782 ! the actual correction of the coordinates only takes
1783 ! place for symmetry planes.
1784  if (bctype(mm) .eq. symm) then
1785 ! set some variables, depending on the block face on
1786 ! which the subface is located.
1787  norm(1) = bcdata(mm)%symnorm(1)
1788  norm(2) = bcdata(mm)%symnorm(2)
1789  norm(3) = bcdata(mm)%symnorm(3)
1790  length = sqrt(norm(1)**2 + norm(2)**2 + norm(3)**2)
1791 ! compute the unit normal of the subface.
1792  norm(1) = norm(1)/length
1793  norm(2) = norm(2)/length
1794  norm(3) = norm(3)/length
1795 ! see xhalo_block for comments for below:
1796  if (length .gt. eps) then
1797  select case (bcfaceid(mm))
1798  case (imin)
1799  ibeg = jnbeg(mm)
1800  iend = jnend(mm)
1801  iimax = jl
1802  jbeg = knbeg(mm)
1803  jend = knend(mm)
1804  jjmax = kl
1805  if (ibeg .eq. 1) ibeg = 0
1806  if (iend .eq. iimax) iend = iimax + 1
1807  if (jbeg .eq. 1) jbeg = 0
1808  if (jend .eq. jjmax) jend = jjmax + 1
1809  do j=jbeg,jend
1810  do i=ibeg,iend
1811  v1(1) = x(1, i, j, 1) - x(2, i, j, 1)
1812  v1(2) = x(1, i, j, 2) - x(2, i, j, 2)
1813  v1(3) = x(1, i, j, 3) - x(2, i, j, 3)
1814  dot = two*(v1(1)*norm(1)+v1(2)*norm(2)+v1(3)*norm(3))
1815  x(0, i, j, 1) = x(2, i, j, 1) + dot*norm(1)
1816  x(0, i, j, 2) = x(2, i, j, 2) + dot*norm(2)
1817  x(0, i, j, 3) = x(2, i, j, 3) + dot*norm(3)
1818  end do
1819  end do
1820  case (imax)
1821  ibeg = jnbeg(mm)
1822  iend = jnend(mm)
1823  iimax = jl
1824  jbeg = knbeg(mm)
1825  jend = knend(mm)
1826  jjmax = kl
1827  if (ibeg .eq. 1) ibeg = 0
1828  if (iend .eq. iimax) iend = iimax + 1
1829  if (jbeg .eq. 1) jbeg = 0
1830  if (jend .eq. jjmax) jend = jjmax + 1
1831  do j=jbeg,jend
1832  do i=ibeg,iend
1833  v1(1) = x(il, i, j, 1) - x(nx, i, j, 1)
1834  v1(2) = x(il, i, j, 2) - x(nx, i, j, 2)
1835  v1(3) = x(il, i, j, 3) - x(nx, i, j, 3)
1836  dot = two*(v1(1)*norm(1)+v1(2)*norm(2)+v1(3)*norm(3))
1837  x(ie, i, j, 1) = x(nx, i, j, 1) + dot*norm(1)
1838  x(ie, i, j, 2) = x(nx, i, j, 2) + dot*norm(2)
1839  x(ie, i, j, 3) = x(nx, i, j, 3) + dot*norm(3)
1840  end do
1841  end do
1842  case (jmin)
1843  ibeg = inbeg(mm)
1844  iend = inend(mm)
1845  iimax = il
1846  jbeg = knbeg(mm)
1847  jend = knend(mm)
1848  jjmax = kl
1849  if (ibeg .eq. 1) ibeg = 0
1850  if (iend .eq. iimax) iend = iimax + 1
1851  if (jbeg .eq. 1) jbeg = 0
1852  if (jend .eq. jjmax) jend = jjmax + 1
1853  do j=jbeg,jend
1854  do i=ibeg,iend
1855  v1(1) = x(i, 1, j, 1) - x(i, 2, j, 1)
1856  v1(2) = x(i, 1, j, 2) - x(i, 2, j, 2)
1857  v1(3) = x(i, 1, j, 3) - x(i, 2, j, 3)
1858  dot = two*(v1(1)*norm(1)+v1(2)*norm(2)+v1(3)*norm(3))
1859  x(i, 0, j, 1) = x(i, 2, j, 1) + dot*norm(1)
1860  x(i, 0, j, 2) = x(i, 2, j, 2) + dot*norm(2)
1861  x(i, 0, j, 3) = x(i, 2, j, 3) + dot*norm(3)
1862  end do
1863  end do
1864  case (jmax)
1865  ibeg = inbeg(mm)
1866  iend = inend(mm)
1867  iimax = il
1868  jbeg = knbeg(mm)
1869  jend = knend(mm)
1870  jjmax = kl
1871  if (ibeg .eq. 1) ibeg = 0
1872  if (iend .eq. iimax) iend = iimax + 1
1873  if (jbeg .eq. 1) jbeg = 0
1874  if (jend .eq. jjmax) jend = jjmax + 1
1875  do j=jbeg,jend
1876  do i=ibeg,iend
1877  v1(1) = x(i, jl, j, 1) - x(i, ny, j, 1)
1878  v1(2) = x(i, jl, j, 2) - x(i, ny, j, 2)
1879  v1(3) = x(i, jl, j, 3) - x(i, ny, j, 3)
1880  dot = two*(v1(1)*norm(1)+v1(2)*norm(2)+v1(3)*norm(3))
1881  x(i, je, j, 1) = x(i, ny, j, 1) + dot*norm(1)
1882  x(i, je, j, 2) = x(i, ny, j, 2) + dot*norm(2)
1883  x(i, je, j, 3) = x(i, ny, j, 3) + dot*norm(3)
1884  end do
1885  end do
1886  case (kmin)
1887  ibeg = inbeg(mm)
1888  iend = inend(mm)
1889  iimax = il
1890  jbeg = jnbeg(mm)
1891  jend = jnend(mm)
1892  jjmax = jl
1893  if (ibeg .eq. 1) ibeg = 0
1894  if (iend .eq. iimax) iend = iimax + 1
1895  if (jbeg .eq. 1) jbeg = 0
1896  if (jend .eq. jjmax) jend = jjmax + 1
1897  do j=jbeg,jend
1898  do i=ibeg,iend
1899  v1(1) = x(i, j, 1, 1) - x(i, j, 2, 1)
1900  v1(2) = x(i, j, 1, 2) - x(i, j, 2, 2)
1901  v1(3) = x(i, j, 1, 3) - x(i, j, 2, 3)
1902  dot = two*(v1(1)*norm(1)+v1(2)*norm(2)+v1(3)*norm(3))
1903  x(i, j, 0, 1) = x(i, j, 2, 1) + dot*norm(1)
1904  x(i, j, 0, 2) = x(i, j, 2, 2) + dot*norm(2)
1905  x(i, j, 0, 3) = x(i, j, 2, 3) + dot*norm(3)
1906  end do
1907  end do
1908  case (kmax)
1909  ibeg = inbeg(mm)
1910  iend = inend(mm)
1911  iimax = il
1912  jbeg = jnbeg(mm)
1913  jend = jnend(mm)
1914  jjmax = jl
1915  if (ibeg .eq. 1) ibeg = 0
1916  if (iend .eq. iimax) iend = iimax + 1
1917  if (jbeg .eq. 1) jbeg = 0
1918  if (jend .eq. jjmax) jend = jjmax + 1
1919  do j=jbeg,jend
1920  do i=ibeg,iend
1921  v1(1) = x(i, j, kl, 1) - x(i, j, nz, 1)
1922  v1(2) = x(i, j, kl, 2) - x(i, j, nz, 2)
1923  v1(3) = x(i, j, kl, 3) - x(i, j, nz, 3)
1924  dot = two*(v1(1)*norm(1)+v1(2)*norm(2)+v1(3)*norm(3))
1925  x(i, j, ke, 1) = x(i, j, nz, 1) + dot*norm(1)
1926  x(i, j, ke, 2) = x(i, j, nz, 2) + dot*norm(2)
1927  x(i, j, ke, 3) = x(i, j, nz, 3) + dot*norm(3)
1928  end do
1929  end do
1930  end select
1931  end if
1932  end if
1933  end do loopbocos
1934  end subroutine xhalo_block
1935 
1936 ! differentiation of resscale in reverse (adjoint) mode (with options noisize i4 dr8 r8):
1937 ! gradient of useful results: *dw
1938 ! with respect to varying inputs: *dw
1939 ! rw status of diff variables: *dw:in-out
1940 ! plus diff mem management of: dw:in
1941  subroutine resscale_b()
1942  use constants
1943  use blockpointers, only : il, jl, kl, nx, ny, nz, volref, dw, dwd
1944  use flowvarrefstate, only : nwf, nt1, nt2
1945  use inputiteration, only : turbresscale
1946  implicit none
1947 ! local variables
1948  integer(kind=inttype) :: i, j, k, ii, nturb
1949  real(kind=realtype) :: ovol
1950  intrinsic mod
1951 ! divide through by the reference volume
1952  nturb = nt2 - nt1 + 1
1953 !$bwd-of ii-loop
1954  do ii=0,nx*ny*nz-1
1955  i = mod(ii, nx) + 2
1956  j = mod(ii/nx, ny) + 2
1957  k = ii/(nx*ny) + 2
1958  ovol = one/volref(i, j, k)
1959  dwd(i, j, k, nt1:nt2) = ovol*turbresscale(1:nturb)*dwd(i, j, k, &
1960 & nt1:nt2)
1961  dwd(i, j, k, 1:nwf) = ovol*dwd(i, j, k, 1:nwf)
1962  end do
1963  end subroutine resscale_b
1964 
1965  subroutine resscale()
1966  use constants
1967  use blockpointers, only : il, jl, kl, nx, ny, nz, volref, dw
1968  use flowvarrefstate, only : nwf, nt1, nt2
1969  use inputiteration, only : turbresscale
1970  implicit none
1971 ! local variables
1972  integer(kind=inttype) :: i, j, k, ii, nturb
1973  real(kind=realtype) :: ovol
1974  intrinsic mod
1975 ! divide through by the reference volume
1976  nturb = nt2 - nt1 + 1
1977 !$ad ii-loop
1978  do ii=0,nx*ny*nz-1
1979  i = mod(ii, nx) + 2
1980  j = mod(ii/nx, ny) + 2
1981  k = ii/(nx*ny) + 2
1982  ovol = one/volref(i, j, k)
1983  dw(i, j, k, 1:nwf) = dw(i, j, k, 1:nwf)*ovol
1984  dw(i, j, k, nt1:nt2) = dw(i, j, k, nt1:nt2)*ovol*turbresscale(1:&
1985 & nturb)
1986  end do
1987  end subroutine resscale
1988 
1989 ! differentiation of sumdwandfw in reverse (adjoint) mode (with options noisize i4 dr8 r8):
1990 ! gradient of useful results: *dw
1991 ! with respect to varying inputs: *dw *fw
1992 ! rw status of diff variables: *dw:in-out *fw:out
1993 ! plus diff mem management of: dw:in fw:in
1994  subroutine sumdwandfw_b()
1995  use constants
1996  use blockpointers, only : il, jl, kl, dw, dwd, fw, fwd, iblank
1997  use flowvarrefstate, only : nwf
1998  implicit none
1999 ! local variables
2000  integer(kind=inttype) :: i, j, k, l
2001  intrinsic real
2002  intrinsic max
2003  real(realtype) :: x1
2004  real(realtype) :: max1
2005  integer :: branch
2006  do l=1,nwf
2007  do k=2,kl
2008  do j=2,jl
2009  do i=2,il
2010  x1 = real(iblank(i, j, k), realtype)
2011  if (x1 .lt. zero) then
2012  call pushreal8(max1)
2013  max1 = zero
2014  call pushcontrol1b(0)
2015  else
2016  call pushreal8(max1)
2017  max1 = x1
2018  call pushcontrol1b(1)
2019  end if
2020  end do
2021  end do
2022  end do
2023  end do
2024  if (associated(fwd)) fwd = 0.0_8
2025  do l=nwf,1,-1
2026  do k=kl,2,-1
2027  do j=jl,2,-1
2028  do i=il,2,-1
2029  fwd(i, j, k, l) = fwd(i, j, k, l) + max1*dwd(i, j, k, l)
2030  dwd(i, j, k, l) = max1*dwd(i, j, k, l)
2031  call popcontrol1b(branch)
2032  if (branch .eq. 0) then
2033  call popreal8(max1)
2034  else
2035  call popreal8(max1)
2036  end if
2037  end do
2038  end do
2039  end do
2040  end do
2041  end subroutine sumdwandfw_b
2042 
2043  subroutine sumdwandfw()
2044  use constants
2045  use blockpointers, only : il, jl, kl, dw, fw, iblank
2046  use flowvarrefstate, only : nwf
2047  implicit none
2048 ! local variables
2049  integer(kind=inttype) :: i, j, k, l
2050  intrinsic real
2051  intrinsic max
2052  real(realtype) :: x1
2053  real(realtype) :: max1
2054  do l=1,nwf
2055  do k=2,kl
2056  do j=2,jl
2057  do i=2,il
2058  x1 = real(iblank(i, j, k), realtype)
2059  if (x1 .lt. zero) then
2060  max1 = zero
2061  else
2062  max1 = x1
2063  end if
2064  dw(i, j, k, l) = (dw(i, j, k, l)+fw(i, j, k, l))*max1
2065  end do
2066  end do
2067  end do
2068  end do
2069  end subroutine sumdwandfw
2070 
2071 end module adjointextra_b
2072 
subroutine volpym(xa, ya, za, xb, yb, zb, xc, yc, zc, xd, yd, zd, volume)
subroutine volpym_b(xa, xad, ya, yad, za, zad, xb, xbd, yb, ybd, zb, zbd, xc, xcd, yc, ycd, zc, zcd, xd, xdd, yd, ydd, zd, zdd, volume, volumed)
subroutine resscale_b()
subroutine boundarynormals_b()
subroutine xhalo_block()
subroutine metric_block_b()
subroutine xhalo_block_b()
subroutine volume_block()
subroutine sumdwandfw_b()
subroutine metric_block()
subroutine sumdwandfw()
subroutine volume_block_b()
subroutine resscale()
subroutine boundarynormals()
Definition: BCData.F90:1
real(kind=realtype), dimension(:, :, :, :), pointer fwd
integer(kind=inttype) jl
integer(kind=inttype), dimension(:), pointer knend
integer(kind=inttype), dimension(:), pointer inend
real(kind=realtype), dimension(:, :, :, :), pointer sjd
integer(kind=inttype), dimension(:), pointer knbeg
real(kind=realtype), dimension(:, :, :), pointer vold
logical righthanded
integer(kind=inttype), dimension(:), pointer jnbeg
integer(kind=inttype) nx
integer(kind=inttype) ny
integer(kind=inttype) ie
type(bcdatatype), dimension(:), pointer bcdatad
integer(kind=inttype), dimension(:, :, :), pointer iblank
real(kind=realtype), dimension(:, :, :, :), pointer skd
integer(kind=inttype), dimension(:), pointer bcfaceid
real(kind=realtype), dimension(:, :, :, :), pointer si
real(kind=realtype), dimension(:, :, :, :), pointer sid
integer(kind=inttype) nbocos
real(kind=realtype), dimension(:, :, :), pointer volref
real(kind=realtype), dimension(:, :, :, :), pointer sj
integer(kind=inttype), dimension(:), pointer jnend
integer(kind=inttype), dimension(:), pointer bctype
real(kind=realtype), dimension(:, :, :, :), pointer dw
real(kind=realtype), dimension(:, :, :, :), pointer sk
real(kind=realtype), dimension(:, :, :), pointer vol
real(kind=realtype), dimension(:, :, :, :), pointer xd
real(kind=realtype), dimension(:, :, :, :), pointer fw
integer(kind=inttype) nz
integer(kind=inttype) je
integer(kind=inttype) ke
real(kind=realtype), dimension(:, :, :, :), pointer x
integer(kind=inttype), dimension(:), pointer inbeg
real(kind=realtype), dimension(:, :, :, :), pointer dwd
integer(kind=inttype) kl
integer(kind=inttype) il
real(kind=realtype), parameter zero
Definition: constants.F90:71
integer(kind=inttype), parameter imax
Definition: constants.F90:293
integer(kind=inttype), parameter kmin
Definition: constants.F90:296
integer(kind=inttype), parameter jmax
Definition: constants.F90:295
real(kind=realtype), parameter eps
Definition: constants.F90:23
real(kind=realtype), parameter eighth
Definition: constants.F90:84
integer(kind=inttype), parameter symm
Definition: constants.F90:258
real(kind=realtype), parameter one
Definition: constants.F90:72
real(kind=realtype), parameter half
Definition: constants.F90:80
integer(kind=inttype), parameter imin
Definition: constants.F90:292
real(kind=realtype), parameter two
Definition: constants.F90:73
real(kind=realtype), parameter fourth
Definition: constants.F90:82
integer(kind=inttype), parameter kmax
Definition: constants.F90:297
integer(kind=inttype), parameter jmin
Definition: constants.F90:294
real(kind=realtype), parameter sixth
Definition: constants.F90:83
integer(kind=inttype) nt1
integer(kind=inttype) nwf
integer(kind=inttype) nt2
real(kind=realtype), dimension(4) turbresscale
Definition: inputParam.F90:293
integer, parameter realtype
Definition: precision.F90:112