ADflow  v1.0
ADflow is a finite volume RANS solver tailored for gradient-based aerodynamic design optimization.
solverUtils.F90
Go to the documentation of this file.
1 module solverutils
2 contains
3 #ifndef USE_TAPENADE
4  subroutine timestep(onlyRadii)
5  !
6  ! Shell function to call timeStep_block on all blocks
7  !
8  use constants
9  use blockpointers, only: ndom
11  use iteration, only: currentlevel
12  use utils, only: setpointers
13  implicit none
14  !
15  ! Subroutine argument.
16  !
17  logical, intent(in) :: onlyRadii
18  !
19  ! Local variables.
20  !
21  integer(kind=intType) :: sps, nn
22 
23  ! Loop over the number of spectral solutions.
24 
25  spectralloop: do sps = 1, ntimeintervalsspectral
26 
27  ! Loop over the number of blocks.
28 
29  domains: do nn = 1, ndom
30 
31  ! Set the pointers for this block.
32 
33  call setpointers(nn, currentlevel, sps)
34 
35  call timestep_block(onlyradii)
36 
37  end do domains
38 
39  end do spectralloop
40 
41  end subroutine timestep
42 #endif
43  subroutine timestep_block(onlyRadii)
44  !
45  ! timeStep computes the time step, or more precisely the time
46  ! step divided by the volume per unit CFL, in the owned cells.
47  ! However, for the artificial dissipation schemes, the spectral
48  ! radIi in the halo's are needed. Therefore the loop is taken
49  ! over the the first level of halo cells. The spectral radIi are
50  ! stored and possibly modified for high aspect ratio cells.
51  !
52  use constants
53  use blockpointers, only: ie, je, ke, il, jl, kl, w, p, rlv, rev, &
60  use inputphysics, only: equationmode
62  use section, only: sections
64  use utils, only: terminate
65  implicit none
66  !
67  ! Subroutine argument.
68  !
69  logical, intent(in) :: onlyRadii
70  !
71  ! Local parameters.
72  !
73  real(kind=realtype), parameter :: b = 2.0_realtype
74  !
75  ! Local variables.
76  !
77  integer(kind=intType) :: i, j, k, ii
78 
79  real(kind=realtype) :: plim, rlim, clim2
80  real(kind=realtype) :: uux, uuy, uuz, cc2, qsi, qsj, qsk, sx, sy, sz, rmu
81  real(kind=realtype) :: ri, rj, rk, rij, rjk, rki
82  real(kind=realtype) :: vsi, vsj, vsk, rfl, dpi, dpj, dpk
83  real(kind=realtype) :: sface, tmp
84 
85  logical :: radiiNeeded, doScaling
86 
87  ! Determine whether or not the spectral radii are needed for the
88  ! flux computation.
89 
90  radiineeded = radiineededcoarse
91  if (currentlevel <= groundlevel) radiineeded = radiineededfine
92 
93  ! Return immediately if only the spectral radii must be computed
94  ! and these are not needed for the flux computation.
95 
96  if (onlyradii .and. (.not. radiineeded)) return
97 
98  ! Set the value of plim. To be fully consistent this must have
99  ! the dimension of a pressure. Therefore a fraction of pInfCorr
100  ! is used. Idem for rlim; compute clim2 as well.
101 
102  plim = 0.001_realtype * pinfcorr
103  rlim = 0.001_realtype * rhoinf
104  clim2 = 0.000001_realtype * gammainf * pinfcorr / rhoinf
105 
106  doscaling = (dirscaling .and. currentlevel <= groundlevel)
107 
108  ! Initialize sFace to zero. This value will be used if the
109  ! block is not moving.
110 
111  sface = zero
112  !
113  ! Inviscid contribution, depending on the preconditioner.
114  ! Compute the cell centered values of the spectral radii.
115  !
116  select case (precond)
117 
118  case (noprecond)
119 
120  ! No preconditioner. Simply the standard spectral radius.
121  ! Loop over the cells, including the first level halo.
122 
123 #ifdef TAPENADE_REVERSE
124  !$AD II-LOOP
125  do ii = 0, ie * je * ke - 1
126  i = mod(ii, ie) + 1
127  j = mod(ii / ie, je) + 1
128  k = ii / (ie * je) + 1
129 #else
130  do k = 1, ke
131  do j = 1, je
132  do i = 1, ie
133 #endif
134  ! Compute the velocities and speed of sound squared.
135 
136  uux = w(i, j, k, ivx)
137  uuy = w(i, j, k, ivy)
138  uuz = w(i, j, k, ivz)
139  cc2 = gamma(i, j, k) * p(i, j, k) / w(i, j, k, irho)
140  cc2 = max(cc2, clim2)
141 
142  ! Set the dot product of the grid velocity and the
143  ! normal in i-direction for a moving face. To avoid
144  ! a number of multiplications by 0.5 simply the sum
145  ! is taken.
146 
147  if (addgridvelocities) &
148  sface = sfacei(i - 1, j, k) + sfacei(i, j, k)
149 
150  ! Spectral radius in i-direction.
151 
152  sx = si(i - 1, j, k, 1) + si(i, j, k, 1)
153  sy = si(i - 1, j, k, 2) + si(i, j, k, 2)
154  sz = si(i - 1, j, k, 3) + si(i, j, k, 3)
155 
156  qsi = uux * sx + uuy * sy + uuz * sz - sface
157 
158  ri = half * (abs(qsi) &
159  + acousticscalefactor * sqrt(cc2 * (sx**2 + sy**2 + sz**2)))
160 
161  ! The grid velocity in j-direction.
162 
163  if (addgridvelocities) &
164  sface = sfacej(i, j - 1, k) + sfacej(i, j, k)
165 
166  ! Spectral radius in j-direction.
167 
168  sx = sj(i, j - 1, k, 1) + sj(i, j, k, 1)
169  sy = sj(i, j - 1, k, 2) + sj(i, j, k, 2)
170  sz = sj(i, j - 1, k, 3) + sj(i, j, k, 3)
171 
172  qsj = uux * sx + uuy * sy + uuz * sz - sface
173 
174  rj = half * (abs(qsj) &
175  + acousticscalefactor * sqrt(cc2 * (sx**2 + sy**2 + sz**2)))
176 
177  ! The grid velocity in k-direction.
178 
179  if (addgridvelocities) &
180  sface = sfacek(i, j, k - 1) + sfacek(i, j, k)
181 
182  ! Spectral radius in k-direction.
183 
184  sx = sk(i, j, k - 1, 1) + sk(i, j, k, 1)
185  sy = sk(i, j, k - 1, 2) + sk(i, j, k, 2)
186  sz = sk(i, j, k - 1, 3) + sk(i, j, k, 3)
187 
188  qsk = uux * sx + uuy * sy + uuz * sz - sface
189 
190  rk = half * (abs(qsk) &
191  + acousticscalefactor * sqrt(cc2 * (sx**2 + sy**2 + sz**2)))
192 
193  ! Compute the inviscid contribution to the time step.
194 
195  if (.not. onlyradii) dtl(i, j, k) = ri + rj + rk
196 
197  !
198  ! Adapt the spectral radii if directional scaling must be
199  ! applied.
200  !
201  if (doscaling) then
202 
203  ! Avoid division by zero by clipping radi, radJ and
204  ! radK.
205 
206  ri = max(ri, eps)
207  rj = max(rj, eps)
208  rk = max(rk, eps)
209 
210  ! Compute the scaling in the three coordinate
211  ! directions.
212 
213  rij = (ri / rj)**adis
214  rjk = (rj / rk)**adis
215  rki = (rk / ri)**adis
216 
217  ! Create the scaled versions of the aspect ratios.
218  ! Note that the multiplication is done with radi, radJ
219  ! and radK, such that the influence of the clipping
220  ! is negligible.
221 
222  radi(i, j, k) = ri * (one + one / rij + rki)
223  radj(i, j, k) = rj * (one + one / rjk + rij)
224  radk(i, j, k) = rk * (one + one / rki + rjk)
225  else
226  radi(i, j, k) = ri
227  radj(i, j, k) = rj
228  radk(i, j, k) = rk
229  end if
230 #ifdef TAPENADE_REVERSE
231  end do
232 #else
233  end do
234  end do
235  end do
236 #endif
237 
238  case (turkel)
239  call terminate("timeStep", "Turkel preconditioner not implemented yet")
240 
241  case (choimerkle)
242  call terminate("timeStep", &
243  "choi merkle preconditioner not implemented yet")
244  end select
245 
246  ! The rest of this file can be skipped if only the spectral
247  ! radii need to be computed.
248  testradiionly: if (.not. onlyradii) then
249 
250  ! The viscous contribution, if needed.
251 
252  viscousterm: if (viscous) then
253 
254  ! Loop over the owned cell centers.
255 
256  do k = 2, kl
257  do j = 2, jl
258  do i = 2, il
259 
260  ! Compute the effective viscosity coefficient. The
261  ! factor 0.5 is a combination of two things. In the
262  ! standard central discretization of a second
263  ! derivative there is a factor 2 multiplying the
264  ! central node. However in the code below not the
265  ! average but the sum of the left and the right face
266  ! is taken and squared. This leads to a factor 4.
267  ! Combining both effects leads to 0.5. Furthermore,
268  ! it is divided by the volume and density to obtain
269  ! the correct dimensions and multiplied by the
270  ! non-dimensional factor factVis.
271 
272  rmu = rlv(i, j, k)
273  if (eddymodel) rmu = rmu + rev(i, j, k)
274  rmu = half * rmu / (w(i, j, k, irho) * vol(i, j, k))
275 
276  ! Add the viscous contribution in i-direction to the
277  ! (inverse) of the time step.
278 
279  sx = si(i, j, k, 1) + si(i - 1, j, k, 1)
280  sy = si(i, j, k, 2) + si(i - 1, j, k, 2)
281  sz = si(i, j, k, 3) + si(i - 1, j, k, 3)
282 
283  vsi = rmu * (sx * sx + sy * sy + sz * sz)
284  dtl(i, j, k) = dtl(i, j, k) + vsi
285 
286  ! Add the viscous contribution in j-direction to the
287  ! (inverse) of the time step.
288 
289  sx = sj(i, j, k, 1) + sj(i, j - 1, k, 1)
290  sy = sj(i, j, k, 2) + sj(i, j - 1, k, 2)
291  sz = sj(i, j, k, 3) + sj(i, j - 1, k, 3)
292 
293  vsj = rmu * (sx * sx + sy * sy + sz * sz)
294  dtl(i, j, k) = dtl(i, j, k) + vsj
295 
296  ! Add the viscous contribution in k-direction to the
297  ! (inverse) of the time step.
298 
299  sx = sk(i, j, k, 1) + sk(i, j, k - 1, 1)
300  sy = sk(i, j, k, 2) + sk(i, j, k - 1, 2)
301  sz = sk(i, j, k, 3) + sk(i, j, k - 1, 3)
302 
303  vsk = rmu * (sx * sx + sy * sy + sz * sz)
304  dtl(i, j, k) = dtl(i, j, k) + vsk
305 
306  end do
307  end do
308  end do
309 
310  end if viscousterm
311 
312  ! For the spectral mode an additional term term must be
313  ! taken into account, which corresponds to the contribution
314  ! of the highest frequency.
315 
316  if (equationmode == timespectral) then
317 
318  tmp = ntimeintervalsspectral * pi * timeref &
319  / sections(sectionid)%timePeriod
320 
321  ! Loop over the owned cell centers and add the term.
322 
323  do k = 2, kl
324  do j = 2, jl
325  do i = 2, il
326  dtl(i, j, k) = dtl(i, j, k) + tmp * vol(i, j, k)
327  end do
328  end do
329  end do
330 
331  end if
332 
333  ! Currently the inverse of dt/vol is stored in dtl. Invert
334  ! this value such that the time step per unit cfl number is
335  ! stored and correct in cases of high gradients.
336 
337  do k = 2, kl
338  do j = 2, jl
339  do i = 2, il
340  dpi = abs(p(i + 1, j, k) - two * p(i, j, k) + p(i - 1, j, k)) &
341  / (p(i + 1, j, k) + two * p(i, j, k) + p(i - 1, j, k) + plim)
342  dpj = abs(p(i, j + 1, k) - two * p(i, j, k) + p(i, j - 1, k)) &
343  / (p(i, j + 1, k) + two * p(i, j, k) + p(i, j - 1, k) + plim)
344  dpk = abs(p(i, j, k + 1) - two * p(i, j, k) + p(i, j, k - 1)) &
345  / (p(i, j, k + 1) + two * p(i, j, k) + p(i, j, k - 1) + plim)
346  rfl = one / (one + b * (dpi + dpj + dpk))
347 
348  dtl(i, j, k) = rfl / dtl(i, j, k)
349  end do
350  end do
351  end do
352 
353  end if testradiionly
354 
355  end subroutine timestep_block
356 
357 #ifndef USE_TAPENADE
358  subroutine gridvelocitiesfinelevel(useOldCoor, t, sps)
359  !
360  ! Shell function to call gridVelocitiesFineLevel on all blocks
361  !
362  use blockpointers
363  use constants
365  use iteration
366  use utils, only: setpointers
367  implicit none
368  !
369  ! Subroutine arguments.
370  !
371  integer(kind=intType), intent(in) :: sps
372  logical, intent(in) :: useOldCoor
373  real(kind=realtype), dimension(*), intent(in) :: t !
374  ! Local variables.
375  !
376  integer(kind=intType) :: nn
377 
378  ! Loop over the number of blocks.
379 
380  domains: do nn = 1, ndom
381 
382  ! Set the pointers for this block.
383 
384  call setpointers(nn, groundlevel, sps)
385  if (.NOT. usetsinterpolatedgridvelocity) then
386  call gridvelocitiesfinelevel_block(useoldcoor, t, sps, nn)
387  else
389  end if
390 
391  end do domains
392 
393  end subroutine gridvelocitiesfinelevel
394 #endif
395 #ifndef USE_TAPENADE
397 
398  use precision
399  use constants
400  use blockpointers
402  use flowvarrefstate, only: gammainf, pinf, rhoinf
404 
405  integer(kind=intType), intent(in) :: nn, sps
406  integer :: i, j, k, mm, ii, ie_l, je_l, ke_l
407  real(kind=realtype) :: x_vc, y_vc, z_vc
408  real(kind=realtype) :: x_fc, y_fc, z_fc
409  real(kind=realtype) :: ainf
410  real(kind=realtype) :: velxfreestream, velyfreestream, velzfreestream
411 
412  ! get the grid free stream velocity
413  ainf = sqrt(gammainf * pinf / rhoinf)
414  velxfreestream = (ainf * machgrid) * (-veldirfreestream(1))
415  velyfreestream = (ainf * machgrid) * (-veldirfreestream(2))
416  velzfreestream = (ainf * machgrid) * (-veldirfreestream(3))
417 
418  ! Grid velocities of the cell centers, including the
419  ! 1st level halo cells.
420 
421  ! Initialize with free stream velocity
422  ie_l = flowdoms(nn, 1, sps)%ie
423  je_l = flowdoms(nn, 1, sps)%je
424  ke_l = flowdoms(nn, 1, sps)%ke
425 
426  do k = 1, ke_l
427  do j = 1, je_l
428  do i = 1, ie_l
429 
430  s(i, j, k, 1) = velxfreestream
431  s(i, j, k, 2) = velyfreestream
432  s(i, j, k, 3) = velzfreestream
433 
434  end do
435  end do
436  end do
437 
438  ! The velocity contributed from mesh deformation
439  do mm = 1, ntimeintervalsspectral
440 
441  ie_l = flowdoms(nn, 1, mm)%ie
442  je_l = flowdoms(nn, 1, mm)%je
443  ke_l = flowdoms(nn, 1, mm)%ke
444 
445  do k = 1, ke_l
446  do j = 1, je_l
447  do i = 1, ie_l
448 
449  x_vc = eighth * (flowdoms(nn, 1, mm)%x(i - 1, j - 1, k - 1, 1) + &
450  flowdoms(nn, 1, mm)%x(i, j - 1, k - 1, 1) &
451  + flowdoms(nn, 1, mm)%x(i - 1, j, k - 1, 1) + &
452  flowdoms(nn, 1, mm)%x(i, j, k - 1, 1) &
453  + flowdoms(nn, 1, mm)%x(i - 1, j - 1, k, 1) + &
454  flowdoms(nn, 1, mm)%x(i, j - 1, k, 1) &
455  + flowdoms(nn, 1, mm)%x(i - 1, j, k, 1) + &
456  flowdoms(nn, 1, mm)%x(i, j, k, 1))
457 
458  y_vc = eighth * (flowdoms(nn, 1, mm)%x(i - 1, j - 1, k - 1, 2) + &
459  flowdoms(nn, 1, mm)%x(i, j - 1, k - 1, 2) &
460  + flowdoms(nn, 1, mm)%x(i - 1, j, k - 1, 2) + &
461  flowdoms(nn, 1, mm)%x(i, j, k - 1, 2) &
462  + flowdoms(nn, 1, mm)%x(i - 1, j - 1, k, 2) + &
463  flowdoms(nn, 1, mm)%x(i, j - 1, k, 2) &
464  + flowdoms(nn, 1, mm)%x(i - 1, j, k, 2) + &
465  flowdoms(nn, 1, mm)%x(i, j, k, 2))
466 
467  z_vc = eighth * (flowdoms(nn, 1, mm)%x(i - 1, j - 1, k - 1, 3) + &
468  flowdoms(nn, 1, mm)%x(i, j - 1, k - 1, 3) &
469  + flowdoms(nn, 1, mm)%x(i - 1, j, k - 1, 3) + &
470  flowdoms(nn, 1, mm)%x(i, j, k - 1, 3) &
471  + flowdoms(nn, 1, mm)%x(i - 1, j - 1, k, 3) + &
472  flowdoms(nn, 1, mm)%x(i, j - 1, k, 3) &
473  + flowdoms(nn, 1, mm)%x(i - 1, j, k, 3) + &
474  flowdoms(nn, 1, mm)%x(i, j, k, 3))
475 
476  s(i, j, k, 1) = s(i, j, k, 1) + dscalar(1, sps, mm) * x_vc
477  s(i, j, k, 2) = s(i, j, k, 2) + dscalar(1, sps, mm) * y_vc
478  s(i, j, k, 3) = s(i, j, k, 3) + dscalar(1, sps, mm) * z_vc
479 
480  end do
481  end do
482  end do
483 
484  end do
485 
486  ! Normal grid velocities of the faces.
487 
488  ! sFaceI=dot(sI, v)
489  ! =dot(sI, v_freestream + v_meshmotion)
490  ! =dot(sI, v_freestream) + dot(sI, v_meshmotion)
491 
492  ! sFaceJ, sFaceK follow the same rule.
493 
494  ! dot(sI, v_freestream)
495  ie_l = flowdoms(nn, 1, sps)%ie
496  je_l = flowdoms(nn, 1, sps)%je
497  ke_l = flowdoms(nn, 1, sps)%ke
498 
499  ! i
500  do k = 1, ke_l
501  do j = 1, je_l
502  do i = 0, ie_l
503 
504  sfacei(i, j, k) = velxfreestream * si(i, j, k, 1) + velyfreestream * si(i, j, k, 2) &
505  + velzfreestream * si(i, j, k, 3)
506 
507  end do
508  end do
509  end do
510 
511  ! j
512  do k = 1, ke_l
513  do j = 0, je_l
514  do i = 1, ie_l
515 
516  sfacej(i, j, k) = velxfreestream * sj(i, j, k, 1) + velyfreestream * sj(i, j, k, 2) &
517  + velzfreestream * sj(i, j, k, 3)
518 
519  end do
520  end do
521  end do
522 
523  ! k
524  do k = 0, ke_l
525  do j = 1, je_l
526  do i = 1, ie_l
527 
528  sfacek(i, j, k) = velxfreestream * sk(i, j, k, 1) + velyfreestream * sk(i, j, k, 2) &
529  + velzfreestream * sk(i, j, k, 3)
530 
531  end do
532  end do
533  end do
534 
535  ! dot(sI, v_meshmotion)
536 
537  do mm = 1, ntimeintervalsspectral
538 
539  ie_l = flowdoms(nn, 1, mm)%ie
540  je_l = flowdoms(nn, 1, mm)%je
541  ke_l = flowdoms(nn, 1, mm)%ke
542 
543  ! i
544  do k = 1, ke_l
545  do j = 1, je_l
546  do i = 0, ie_l
547 
548  x_fc = fourth * (flowdoms(nn, 1, mm)%x(i, j - 1, k - 1, 1) + &
549  flowdoms(nn, 1, mm)%x(i, j, k, 1) &
550  + flowdoms(nn, 1, mm)%x(i, j - 1, k, 1) + &
551  flowdoms(nn, 1, mm)%x(i, j, k - 1, 1))
552  y_fc = fourth * (flowdoms(nn, 1, mm)%x(i, j - 1, k - 1, 2) + &
553  flowdoms(nn, 1, mm)%x(i, j, k, 2) &
554  + flowdoms(nn, 1, mm)%x(i, j - 1, k, 2) + &
555  flowdoms(nn, 1, mm)%x(i, j, k - 1, 2))
556  z_fc = fourth * (flowdoms(nn, 1, mm)%x(i, j - 1, k - 1, 3) + &
557  flowdoms(nn, 1, mm)%x(i, j, k, 3) &
558  + flowdoms(nn, 1, mm)%x(i, j - 1, k, 3) + &
559  flowdoms(nn, 1, mm)%x(i, j, k - 1, 3))
560 
561  sfacei(i, j, k) = sfacei(i, j, k) &
562  + dscalar(1, sps, mm) * x_fc * si(i, j, k, 1) &
563  + dscalar(1, sps, mm) * y_fc * si(i, j, k, 2) &
564  + dscalar(1, sps, mm) * z_fc * si(i, j, k, 3)
565 
566  end do
567  end do
568  end do
569 
570  ! j
571  do k = 1, ke_l
572  do j = 0, je_l
573  do i = 1, ie_l
574 
575  x_fc = fourth * (flowdoms(nn, 1, mm)%x(i - 1, j, k - 1, 1) + &
576  flowdoms(nn, 1, mm)%x(i, j, k, 1) &
577  + flowdoms(nn, 1, mm)%x(i - 1, j, k, 1) + &
578  flowdoms(nn, 1, mm)%x(i, j, k - 1, 1))
579  y_fc = fourth * (flowdoms(nn, 1, mm)%x(i - 1, j, k - 1, 2) + &
580  flowdoms(nn, 1, mm)%x(i, j, k, 2) &
581  + flowdoms(nn, 1, mm)%x(i - 1, j, k, 2) + &
582  flowdoms(nn, 1, mm)%x(i, j, k - 1, 2))
583  z_fc = fourth * (flowdoms(nn, 1, mm)%x(i - 1, j, k - 1, 3) + &
584  flowdoms(nn, 1, mm)%x(i, j, k, 3) &
585  + flowdoms(nn, 1, mm)%x(i - 1, j, k, 3) + &
586  flowdoms(nn, 1, mm)%x(i, j, k - 1, 3))
587 
588  sfacej(i, j, k) = sfacej(i, j, k) &
589  + dscalar(1, sps, mm) * x_fc * sj(i, j, k, 1) &
590  + dscalar(1, sps, mm) * y_fc * sj(i, j, k, 2) &
591  + dscalar(1, sps, mm) * z_fc * sj(i, j, k, 3)
592 
593  end do
594  end do
595  end do
596 
597  ! k
598  do k = 0, ke_l
599  do j = 1, je_l
600  do i = 1, ie_l
601 
602  x_fc = fourth * (flowdoms(nn, 1, mm)%x(i - 1, j - 1, k, 1) + &
603  flowdoms(nn, 1, mm)%x(i, j, k, 1) &
604  + flowdoms(nn, 1, mm)%x(i, j - 1, k, 1) + &
605  flowdoms(nn, 1, mm)%x(i - 1, j, k, 1))
606  y_fc = fourth * (flowdoms(nn, 1, mm)%x(i - 1, j - 1, k, 2) + &
607  flowdoms(nn, 1, mm)%x(i, j, k, 2) &
608  + flowdoms(nn, 1, mm)%x(i, j - 1, k, 2) + &
609  flowdoms(nn, 1, mm)%x(i - 1, j, k, 2))
610  z_fc = fourth * (flowdoms(nn, 1, mm)%x(i - 1, j - 1, k, 3) + &
611  flowdoms(nn, 1, mm)%x(i, j, k, 3) &
612  + flowdoms(nn, 1, mm)%x(i, j - 1, k, 3) + &
613  flowdoms(nn, 1, mm)%x(i - 1, j, k, 3))
614 
615  sfacek(i, j, k) = sfacek(i, j, k) &
616  + dscalar(1, sps, mm) * x_fc * sk(i, j, k, 1) &
617  + dscalar(1, sps, mm) * y_fc * sk(i, j, k, 2) &
618  + dscalar(1, sps, mm) * z_fc * sk(i, j, k, 3)
619 
620  end do
621  end do
622  end do
623 
624  end do
625 
626  end subroutine gridvelocitiesfinelevel_ts_block
627 #endif
628  subroutine gridvelocitiesfinelevel_block(useOldCoor, t, sps, nn)
629  !
630  ! gridVelocitiesFineLevel computes the grid velocities for
631  ! the cell centers and the normal grid velocities for the faces
632  ! of moving blocks for the currently finest grid, i.e.
633  ! groundLevel. The velocities are computed at time t for
634  ! spectral mode sps. If useOldCoor is .true. the velocities
635  ! are determined using the unsteady time integrator in
636  ! combination with the old coordinates; otherwise the analytic
637  ! form is used.
638  !
639  use blockpointers
640  use cgnsgrid
641  use flowvarrefstate
642  use inputmotion
643  use inputunsteady
644  use iteration
645  use inputphysics
646  use inputtsstabderiv
647  use monitor
648  use communication
652 
653  implicit none
654  !
655  ! Subroutine arguments.
656  !
657  integer(kind=intType), intent(in) :: sps, nn
658  logical, intent(in) :: useOldCoor
659 
660  real(kind=realtype), dimension(*), intent(in) :: t
661  !
662  ! Local variables.
663  !
664  integer(kind=intType) :: mm
665  integer(kind=intType) :: i, j, k, ii, iie, jje, kke
666 
667  real(kind=realtype) :: oneover4dt, oneover8dt
668  real(kind=realtype) :: velxgrid, velygrid, velzgrid, ainf
669  real(kind=realtype) :: velxgrid0, velygrid0, velzgrid0
670 
671  real(kind=realtype), dimension(3) :: sc, xc, xxc
672  real(kind=realtype), dimension(3) :: rotcenter, rotrate
673 
674  real(kind=realtype), dimension(3) :: rotationpoint
675  real(kind=realtype), dimension(3, 3) :: rotationmatrix, &
676  derivrotationmatrix
677 
678  real(kind=realtype) :: tnew, told
679  real(kind=realtype), dimension(:, :), pointer :: sface
680 
681  real(kind=realtype), dimension(:, :, :), pointer :: xx, ss
682  real(kind=realtype), dimension(:, :, :, :), pointer :: xxold
683 
684  real(kind=realtype) :: intervalmach, alphats, alphaincrement, &
685  betats, betaincrement
686  real(kind=realtype), dimension(3) :: veldir
687  real(kind=realtype), dimension(3) :: refdirection
688 
689  ! Compute the mesh velocity from the given mesh Mach number.
690 
691  ! vel{x,y,z}Grid0 is the ACTUAL velocity you want at the
692  ! geometry.
693  ainf = sqrt(gammainf * pinf / rhoinf)
694  velxgrid0 = (ainf * machgrid) * (-veldirfreestream(1))
695  velygrid0 = (ainf * machgrid) * (-veldirfreestream(2))
696  velzgrid0 = (ainf * machgrid) * (-veldirfreestream(3))
697 
698  ! Compute the derivative of the rotation matrix and the rotation
699  ! point; needed for velocity due to the rigid body rotation of
700  ! the entire grid. It is assumed that the rigid body motion of
701  ! the grid is only specified if there is only 1 section present.
702 
703  call derivativerotmatrixrigid(derivrotationmatrix, rotationpoint, t(1))
704 
705  !compute the rotation matrix to update the velocities for the time
706  !spectral stability derivative case...
707 
708 #ifndef USE_TAPENADE
709 ! We do not differentiate the time spectral stability stuff for now
710  if (tsstability) then
711  ! Determine the time values of the old and new time level.
712  ! It is assumed that the rigid body rotation of the mesh is only
713  ! used when only 1 section is present.
714 
716  told = tnew - t(1)
717 
718  if (tspmode .or. tsqmode .or. tsrmode) then
719  ! Compute the rotation matrix of the rigid body rotation as
720  ! well as the rotation point; the latter may vary in time due
721  ! to rigid body translation.
722 
723  call rotmatrixrigidbody(tnew, told, rotationmatrix, rotationpoint)
724 
725  if (tsalphafollowing) then
726 
727  velxgrid0 = rotationmatrix(1, 1) * velxgrid0 &
728  + rotationmatrix(1, 2) * velygrid0 &
729  + rotationmatrix(1, 3) * velzgrid0
730  velygrid0 = rotationmatrix(2, 1) * velxgrid0 &
731  + rotationmatrix(2, 2) * velygrid0 &
732  + rotationmatrix(2, 3) * velzgrid0
733  velzgrid0 = rotationmatrix(3, 1) * velxgrid0 &
734  + rotationmatrix(3, 2) * velygrid0 &
735  + rotationmatrix(3, 3) * velzgrid0
736 
737  end if
738 
739  elseif (tsalphamode) then
740 
741  !Determine the alpha for this time instance
742  alphaincrement = tsalpha(degreepolalpha, coefpolalpha, &
745 
746  alphats = alpha + alphaincrement
747  !Determine the grid velocity for this alpha
748  refdirection(:) = zero
749  refdirection(1) = one
750  call getdirvector(refdirection, alphats, beta, veldir, liftindex)
751 
752  !do I need to update the lift direction and drag direction as well?
753  !set the effictive grid velocity for this time interval
754  velxgrid0 = (ainf * machgrid) * (-veldir(1))
755  velygrid0 = (ainf * machgrid) * (-veldir(2))
756  velzgrid0 = (ainf * machgrid) * (-veldir(3))
757 
758  elseif (tsbetamode) then
759 
760  !Determine the alpha for this time instance
761  betaincrement = tsbeta(degreepolbeta, coefpolbeta, &
764 
765  betats = beta + betaincrement
766  !Determine the grid velocity for this alpha
767  refdirection(:) = zero
768  refdirection(1) = one
769  call getdirvector(refdirection, alpha, betats, veldir, liftindex)
770 
771  !do I need to update the lift direction and drag direction as well?
772  !set the effictive grid velocity for this time interval
773  velxgrid0 = (ainf * machgrid) * (-veldir(1))
774  velygrid0 = (ainf * machgrid) * (-veldir(2))
775  velzgrid0 = (ainf * machgrid) * (-veldir(3))
776  elseif (tsmachmode) then
777  !determine the mach number at this time interval
778  intervalmach = tsmach(degreepolmach, coefpolmach, &
781  !set the effective grid velocity
782  velxgrid0 = (ainf * (intervalmach + machgrid)) * (-veldirfreestream(1))
783  velygrid0 = (ainf * (intervalmach + machgrid)) * (-veldirfreestream(2))
784  velzgrid0 = (ainf * (intervalmach + machgrid)) * (-veldirfreestream(3))
785 
786  elseif (tsaltitudemode) then
787  call terminate('gridVelocityFineLevel', 'altitude motion not yet implemented...')
788  else
789  call terminate('gridVelocityFineLevel', 'Not a recognized Stability Motion')
790  end if
791  end if
792 #endif
793 
794  testmoving: if (blockismoving) then
795  ! Determine the situation we are having here.
796 
797  testuseoldcoor: if (useoldcoor) then
798 #ifndef USE_TAPENADE
799 ! We do not consider the finite difference based velocity computation for now
800  !
801  ! The velocities must be determined via a finite
802  ! difference formula using the coordinates of the old
803  ! levels.
804  !
805  ! Set the coefficients for the time integrator and store
806  ! the inverse of the physical nonDimensional time step,
807  ! divided by 4 and 8, a bit easier.
808 
810  oneover4dt = fourth * timeref / deltat
811  oneover8dt = half * oneover4dt
812  !
813  ! Grid velocities of the cell centers, including the
814  ! 1st level halo cells.
815  !
816  ! Loop over the cells, including the 1st level halo's.
817 
818  do k = 1, ke
819  do j = 1, je
820  do i = 1, ie
821 
822  ! The velocity of the cell center is determined
823  ! by a finite difference formula. First store
824  ! the current coordinate, multiplied by 8 and
825  ! coefTime(0) in sc.
826 
827  sc(1) = (x(i - 1, j - 1, k - 1, 1) + x(i, j - 1, k - 1, 1) &
828  + x(i - 1, j, k - 1, 1) + x(i, j, k - 1, 1) &
829  + x(i - 1, j - 1, k, 1) + x(i, j - 1, k, 1) &
830  + x(i - 1, j, k, 1) + x(i, j, k, 1)) &
831  * coeftime(0)
832  sc(2) = (x(i - 1, j - 1, k - 1, 2) + x(i, j - 1, k - 1, 2) &
833  + x(i - 1, j, k - 1, 2) + x(i, j, k - 1, 2) &
834  + x(i - 1, j - 1, k, 2) + x(i, j - 1, k, 2) &
835  + x(i - 1, j, k, 2) + x(i, j, k, 2)) &
836  * coeftime(0)
837  sc(3) = (x(i - 1, j - 1, k - 1, 3) + x(i, j - 1, k - 1, 3) &
838  + x(i - 1, j, k - 1, 3) + x(i, j, k - 1, 3) &
839  + x(i - 1, j - 1, k, 3) + x(i, j - 1, k, 3) &
840  + x(i - 1, j, k, 3) + x(i, j, k, 3)) &
841  * coeftime(0)
842 
843  ! Loop over the older levels to complete the
844  ! finite difference formula.
845 
846  do ii = 1, noldlevels
847  sc(1) = sc(1) + (xold(ii, i - 1, j - 1, k - 1, 1) &
848  + xold(ii, i, j - 1, k - 1, 1) &
849  + xold(ii, i - 1, j, k - 1, 1) &
850  + xold(ii, i, j, k - 1, 1) &
851  + xold(ii, i - 1, j - 1, k, 1) &
852  + xold(ii, i, j - 1, k, 1) &
853  + xold(ii, i - 1, j, k, 1) &
854  + xold(ii, i, j, k, 1)) &
855  * coeftime(ii)
856  sc(2) = sc(2) + (xold(ii, i - 1, j - 1, k - 1, 2) &
857  + xold(ii, i, j - 1, k - 1, 2) &
858  + xold(ii, i - 1, j, k - 1, 2) &
859  + xold(ii, i, j, k - 1, 2) &
860  + xold(ii, i - 1, j - 1, k, 2) &
861  + xold(ii, i, j - 1, k, 2) &
862  + xold(ii, i - 1, j, k, 2) &
863  + xold(ii, i, j, k, 2)) &
864  * coeftime(ii)
865  sc(3) = sc(3) + (xold(ii, i - 1, j - 1, k - 1, 3) &
866  + xold(ii, i, j - 1, k - 1, 3) &
867  + xold(ii, i - 1, j, k - 1, 3) &
868  + xold(ii, i, j, k - 1, 3) &
869  + xold(ii, i - 1, j - 1, k, 3) &
870  + xold(ii, i, j - 1, k, 3) &
871  + xold(ii, i - 1, j, k, 3) &
872  + xold(ii, i, j, k, 3)) &
873  * coeftime(ii)
874  end do
875 
876  ! Divide by 8 delta t to obtain the correct
877  ! velocities.
878 
879  s(i, j, k, 1) = sc(1) * oneover8dt
880  s(i, j, k, 2) = sc(2) * oneover8dt
881  s(i, j, k, 3) = sc(3) * oneover8dt
882  end do
883  end do
884  end do
885  !
886  ! Normal grid velocities of the faces.
887  !
888  ! Loop over the three directions.
889 
890  loopdir: do mm = 1, 3
891 
892  ! Set the upper boundaries depending on the direction.
893 
894  select case (mm)
895  case (1_inttype) ! normals in i-direction
896  iie = ie; jje = je; kke = ke
897 
898  case (2_inttype) ! normals in j-direction
899  iie = je; jje = ie; kke = ke
900 
901  case (3_inttype) ! normals in k-direction
902  iie = ke; jje = ie; kke = je
903  end select
904  !
905  ! Normal grid velocities in generalized i-direction.
906  ! Mm == 1: i-direction
907  ! mm == 2: j-direction
908  ! mm == 3: k-direction
909  !
910  do i = 0, iie
911 
912  ! Set the pointers for the coordinates, normals and
913  ! normal velocities for this generalized i-plane.
914  ! This depends on the value of mm.
915 
916  select case (mm)
917  case (1_inttype) ! normals in i-direction
918  xx => x(i, :, :, :); xxold => xold(:, i, :, :, :)
919  ss => si(i, :, :, :); sface => sfacei(i, :, :)
920 
921  case (2_inttype) ! normals in j-direction
922  xx => x(:, i, :, :); xxold => xold(:, :, i, :, :)
923  ss => sj(:, i, :, :); sface => sfacej(:, i, :)
924 
925  case (3_inttype) ! normals in k-direction
926  xx => x(:, :, i, :); xxold => xold(:, :, :, i, :)
927  ss => sk(:, :, i, :); sface => sfacek(:, :, i)
928  end select
929 
930  ! Loop over the k and j-direction of this
931  ! generalized i-face. Note that due to the usage of
932  ! the pointers xx and xxOld an offset of +1 must be
933  ! used in the coordinate arrays, because x and xOld
934  ! originally start at 0 for the i, j and k indices.
935 
936  do k = 1, kke
937  do j = 1, jje
938 
939  ! The velocity of the face center is determined
940  ! by a finite difference formula. First store
941  ! the current coordinate, multiplied by 4 and
942  ! coefTime(0) in sc.
943 
944  sc(1) = coeftime(0) * (xx(j + 1, k + 1, 1) + xx(j, k + 1, 1) &
945  + xx(j + 1, k, 1) + xx(j, k, 1))
946  sc(2) = coeftime(0) * (xx(j + 1, k + 1, 2) + xx(j, k + 1, 2) &
947  + xx(j + 1, k, 2) + xx(j, k, 2))
948  sc(3) = coeftime(0) * (xx(j + 1, k + 1, 3) + xx(j, k + 1, 3) &
949  + xx(j + 1, k, 3) + xx(j, k, 3))
950 
951  ! Loop over the older levels to complete the
952  ! finite difference.
953 
954  do ii = 1, noldlevels
955 
956  sc(1) = sc(1) + coeftime(ii) &
957  * (xxold(ii, j + 1, k + 1, 1) &
958  + xxold(ii, j, k + 1, 1) &
959  + xxold(ii, j + 1, k, 1) &
960  + xxold(ii, j, k, 1))
961  sc(2) = sc(2) + coeftime(ii) &
962  * (xxold(ii, j + 1, k + 1, 2) &
963  + xxold(ii, j, k + 1, 2) &
964  + xxold(ii, j + 1, k, 2) &
965  + xxold(ii, j, k, 2))
966  sc(3) = sc(3) + coeftime(ii) &
967  * (xxold(ii, j + 1, k + 1, 3) &
968  + xxold(ii, j, k + 1, 3) &
969  + xxold(ii, j + 1, k, 3) &
970  + xxold(ii, j, k, 3))
971  end do
972 
973  ! Determine the dot product of sc and the normal
974  ! and divide by 4 deltaT to obtain the correct
975  ! value of the normal velocity.
976 
977  sface(j, k) = sc(1) * ss(j, k, 1) + sc(2) * ss(j, k, 2) &
978  + sc(3) * ss(j, k, 3)
979  sface(j, k) = sface(j, k) * oneover4dt
980 
981  end do
982  end do
983  end do
984 
985  end do loopdir
986 #endif
987  else testuseoldcoor
988  !
989  ! The velocities must be determined analytically.
990  !
991  ! Store the rotation center and determine the
992  ! nonDimensional rotation rate of this block. As the
993  ! reference length is 1 timeRef == 1/uRef and at the end
994  ! the nonDimensional velocity is computed.
995 
996  j = nbkglobal
997 
998  rotcenter = cgnsdoms(j)%rotCenter
999  rotrate = timeref * cgnsdoms(j)%rotRate
1000 
1001  velxgrid = velxgrid0
1002  velygrid = velygrid0
1003  velzgrid = velzgrid0
1004  !
1005  ! Grid velocities of the cell centers, including the
1006  ! 1st level halo cells.
1007  !
1008  ! Loop over the cells, including the 1st level halo's.
1009 
1010  do k = 1, ke
1011  do j = 1, je
1012  do i = 1, ie
1013 
1014  ! Determine the coordinates of the cell center,
1015  ! which are stored in xc.
1016 
1017  xc(1) = eighth * (flowdoms(nn, groundlevel, sps)%x(i - 1, j - 1, k - 1, 1) &
1018  + flowdoms(nn, groundlevel, sps)%x(i, j - 1, k - 1, 1) &
1019  + flowdoms(nn, groundlevel, sps)%x(i - 1, j, k - 1, 1) &
1020  + flowdoms(nn, groundlevel, sps)%x(i, j, k - 1, 1) &
1021  + flowdoms(nn, groundlevel, sps)%x(i - 1, j - 1, k, 1) &
1022  + flowdoms(nn, groundlevel, sps)%x(i, j - 1, k, 1) &
1023  + flowdoms(nn, groundlevel, sps)%x(i - 1, j, k, 1) &
1024  + flowdoms(nn, groundlevel, sps)%x(i, j, k, 1))
1025  xc(2) = eighth * (flowdoms(nn, groundlevel, sps)%x(i - 1, j - 1, k - 1, 2) &
1026  + flowdoms(nn, groundlevel, sps)%x(i, j - 1, k - 1, 2) &
1027  + flowdoms(nn, groundlevel, sps)%x(i - 1, j, k - 1, 2) &
1028  + flowdoms(nn, groundlevel, sps)%x(i, j, k - 1, 2) &
1029  + flowdoms(nn, groundlevel, sps)%x(i - 1, j - 1, k, 2) &
1030  + flowdoms(nn, groundlevel, sps)%x(i, j - 1, k, 2) &
1031  + flowdoms(nn, groundlevel, sps)%x(i - 1, j, k, 2) &
1032  + flowdoms(nn, groundlevel, sps)%x(i, j, k, 2))
1033  xc(3) = eighth * (flowdoms(nn, groundlevel, sps)%x(i - 1, j - 1, k - 1, 3) &
1034  + flowdoms(nn, groundlevel, sps)%x(i, j - 1, k - 1, 3) &
1035  + flowdoms(nn, groundlevel, sps)%x(i - 1, j, k - 1, 3) &
1036  + flowdoms(nn, groundlevel, sps)%x(i, j, k - 1, 3) &
1037  + flowdoms(nn, groundlevel, sps)%x(i - 1, j - 1, k, 3) &
1038  + flowdoms(nn, groundlevel, sps)%x(i, j - 1, k, 3) &
1039  + flowdoms(nn, groundlevel, sps)%x(i - 1, j, k, 3) &
1040  + flowdoms(nn, groundlevel, sps)%x(i, j, k, 3))
1041 
1042  ! Determine the coordinates relative to the
1043  ! center of rotation.
1044 
1045  xxc(1) = xc(1) - rotcenter(1)
1046  xxc(2) = xc(2) - rotcenter(2)
1047  xxc(3) = xc(3) - rotcenter(3)
1048 
1049  ! Determine the rotation speed of the cell center,
1050  ! which is omega*r.
1051 
1052  sc(1) = rotrate(2) * xxc(3) - rotrate(3) * xxc(2)
1053  sc(2) = rotrate(3) * xxc(1) - rotrate(1) * xxc(3)
1054  sc(3) = rotrate(1) * xxc(2) - rotrate(2) * xxc(1)
1055 
1056  ! Determine the coordinates relative to the
1057  ! rigid body rotation point.
1058 
1059  xxc(1) = xc(1) - rotationpoint(1)
1060  xxc(2) = xc(2) - rotationpoint(2)
1061  xxc(3) = xc(3) - rotationpoint(3)
1062 
1063  ! Determine the total velocity of the cell center.
1064  ! This is a combination of rotation speed of this
1065  ! block and the entire rigid body rotation.
1066 
1067  s(i, j, k, 1) = sc(1) + velxgrid &
1068  + derivrotationmatrix(1, 1) * xxc(1) &
1069  + derivrotationmatrix(1, 2) * xxc(2) &
1070  + derivrotationmatrix(1, 3) * xxc(3)
1071  s(i, j, k, 2) = sc(2) + velygrid &
1072  + derivrotationmatrix(2, 1) * xxc(1) &
1073  + derivrotationmatrix(2, 2) * xxc(2) &
1074  + derivrotationmatrix(2, 3) * xxc(3)
1075  s(i, j, k, 3) = sc(3) + velzgrid &
1076  + derivrotationmatrix(3, 1) * xxc(1) &
1077  + derivrotationmatrix(3, 2) * xxc(2) &
1078  + derivrotationmatrix(3, 3) * xxc(3)
1079  end do
1080  end do
1081  end do
1082  !
1083  ! Normal grid velocities of the faces.
1084  !
1085  ! Loop over the three directions.
1086 
1087  ! The original code is elegant but the Tapenade has a difficult time
1088  ! to understand it. Thus, we unfold it and make it easier for the
1089  ! Tapenade.
1090 
1091  ! i-direction
1092  do k = 1, ke
1093  do j = 1, je
1094  do i = 0, ie
1095 
1096  ! Determine the coordinates of the face center,
1097  ! which are stored in xc.
1098 
1099  xc(1) = fourth * (flowdoms(nn, groundlevel, sps)%x(i, j - 1, k - 1, 1) + &
1100  flowdoms(nn, groundlevel, sps)%x(i, j, k - 1, 1) &
1101  + flowdoms(nn, groundlevel, sps)%x(i, j - 1, k, 1) + &
1102  flowdoms(nn, groundlevel, sps)%x(i, j, k, 1))
1103  xc(2) = fourth * (flowdoms(nn, groundlevel, sps)%x(i, j - 1, k - 1, 2) + &
1104  flowdoms(nn, groundlevel, sps)%x(i, j, k - 1, 2) &
1105  + flowdoms(nn, groundlevel, sps)%x(i, j - 1, k, 2) + &
1106  flowdoms(nn, groundlevel, sps)%x(i, j, k, 2))
1107  xc(3) = fourth * (flowdoms(nn, groundlevel, sps)%x(i, j - 1, k - 1, 3) + &
1108  flowdoms(nn, groundlevel, sps)%x(i, j, k - 1, 3) &
1109  + flowdoms(nn, groundlevel, sps)%x(i, j - 1, k, 3) + &
1110  flowdoms(nn, groundlevel, sps)%x(i, j, k, 3))
1111 
1112  call cellfacevelocities(xc, rotcenter, rotrate, &
1113  velxgrid, velygrid, velzgrid, derivrotationmatrix, sc)
1114 
1115  ! Store the dot product of grid velocity sc and
1116  ! the normal ss in sFace.
1117 
1118  sfacei(i, j, k) = sc(1) * si(i, j, k, 1) + sc(2) * si(i, j, k, 2) &
1119  + sc(3) * si(i, j, k, 3)
1120  end do
1121  end do
1122  end do
1123 
1124  ! j-direction
1125  do k = 1, ke
1126  do j = 0, je
1127  do i = 1, ie
1128 
1129  ! Determine the coordinates of the face center,
1130  ! which are stored in xc.
1131 
1132  xc(1) = fourth * (flowdoms(nn, groundlevel, sps)%x(i - 1, j, k, 1) + &
1133  flowdoms(nn, groundlevel, sps)%x(i, j, k - 1, 1) &
1134  + flowdoms(nn, groundlevel, sps)%x(i - 1, j, k - 1, 1) + &
1135  flowdoms(nn, groundlevel, sps)%x(i, j, k, 1))
1136  xc(2) = fourth * (flowdoms(nn, groundlevel, sps)%x(i - 1, j, k, 2) + &
1137  flowdoms(nn, groundlevel, sps)%x(i, j, k - 1, 2) &
1138  + flowdoms(nn, groundlevel, sps)%x(i - 1, j, k - 1, 2) + &
1139  flowdoms(nn, groundlevel, sps)%x(i, j, k, 2))
1140  xc(3) = fourth * (flowdoms(nn, groundlevel, sps)%x(i - 1, j, k, 3) + &
1141  flowdoms(nn, groundlevel, sps)%x(i, j, k - 1, 3) &
1142  + flowdoms(nn, groundlevel, sps)%x(i - 1, j, k - 1, 3) + &
1143  flowdoms(nn, groundlevel, sps)%x(i, j, k, 3))
1144 
1145  call cellfacevelocities(xc, rotcenter, rotrate, &
1146  velxgrid, velygrid, velzgrid, derivrotationmatrix, sc)
1147 
1148  ! Store the dot product of grid velocity sc and
1149  ! the normal ss in sFace.
1150 
1151  sfacej(i, j, k) = sc(1) * sj(i, j, k, 1) + sc(2) * sj(i, j, k, 2) &
1152  + sc(3) * sj(i, j, k, 3)
1153  end do
1154  end do
1155  end do
1156 
1157  ! k-direction
1158  do k = 0, ke
1159  do j = 1, je
1160  do i = 1, ie
1161 
1162  ! Determine the coordinates of the face center,
1163  ! which are stored in xc.
1164 
1165  xc(1) = fourth * (flowdoms(nn, groundlevel, sps)%x(i, j - 1, k, 1) + &
1166  flowdoms(nn, groundlevel, sps)%x(i - 1, j, k, 1) &
1167  + flowdoms(nn, groundlevel, sps)%x(i - 1, j - 1, k, 1) + &
1168  flowdoms(nn, groundlevel, sps)%x(i, j, k, 1))
1169  xc(2) = fourth * (flowdoms(nn, groundlevel, sps)%x(i, j - 1, k, 2) + &
1170  flowdoms(nn, groundlevel, sps)%x(i - 1, j, k, 2) &
1171  + flowdoms(nn, groundlevel, sps)%x(i - 1, j - 1, k, 2) + &
1172  flowdoms(nn, groundlevel, sps)%x(i, j, k, 2))
1173  xc(3) = fourth * (flowdoms(nn, groundlevel, sps)%x(i, j - 1, k, 3) + &
1174  flowdoms(nn, groundlevel, sps)%x(i - 1, j, k, 3) &
1175  + flowdoms(nn, groundlevel, sps)%x(i - 1, j - 1, k, 3) + &
1176  flowdoms(nn, groundlevel, sps)%x(i, j, k, 3))
1177 
1178  call cellfacevelocities(xc, rotcenter, rotrate, &
1179  velxgrid, velygrid, velzgrid, derivrotationmatrix, sc)
1180 
1181  ! Store the dot product of grid velocity sc and
1182  ! the normal ss in sFace.
1183 
1184  sfacek(i, j, k) = sc(1) * sk(i, j, k, 1) + sc(2) * sk(i, j, k, 2) &
1185  + sc(3) * sk(i, j, k, 3)
1186  end do
1187  end do
1188  end do
1189 
1190  end if testuseoldcoor
1191  end if testmoving
1192 
1193  end subroutine gridvelocitiesfinelevel_block
1194 
1195  subroutine cellfacevelocities(xc, rotCenter, rotRate, velxGrid, velyGrid, velzGrid, derivRotationMatrix, sc)
1196  !
1197  ! Returns the cell face velocities for a given face center
1198  !
1199  use constants
1200 
1201  implicit none
1202  !
1203  ! Subroutine arguments.
1204  !
1205  real(kind=realtype), dimension(3), intent(in) :: xc, rotcenter, rotrate
1206  real(kind=realtype), intent(in) :: velxgrid, velygrid, velzgrid
1207  real(kind=realtype), dimension(3, 3), intent(in) :: derivrotationmatrix
1208  real(kind=realtype), dimension(3), intent(out) :: sc
1209  !
1210  ! Local variables.
1211  !
1212  real(kind=realtype), dimension(3) :: rotationpoint, xxc
1213 
1214  ! Determine the coordinates relative to the
1215  ! center of rotation.
1216 
1217  xxc(1) = xc(1) - rotcenter(1)
1218  xxc(2) = xc(2) - rotcenter(2)
1219  xxc(3) = xc(3) - rotcenter(3)
1220 
1221  ! Determine the rotation speed of the face center,
1222  ! which is omega*r.
1223 
1224  sc(1) = rotrate(2) * xxc(3) - rotrate(3) * xxc(2)
1225  sc(2) = rotrate(3) * xxc(1) - rotrate(1) * xxc(3)
1226  sc(3) = rotrate(1) * xxc(2) - rotrate(2) * xxc(1)
1227 
1228  ! Determine the coordinates relative to the
1229  ! rigid body rotation point.
1230 
1231  xxc(1) = xc(1) - rotationpoint(1)
1232  xxc(2) = xc(2) - rotationpoint(2)
1233  xxc(3) = xc(3) - rotationpoint(3)
1234 
1235  ! Determine the total velocity of the cell face.
1236  ! This is a combination of rotation speed of this
1237  ! block and the entire rigid body rotation.
1238 
1239  sc(1) = sc(1) + velxgrid &
1240  + derivrotationmatrix(1, 1) * xxc(1) &
1241  + derivrotationmatrix(1, 2) * xxc(2) &
1242  + derivrotationmatrix(1, 3) * xxc(3)
1243  sc(2) = sc(2) + velygrid &
1244  + derivrotationmatrix(2, 1) * xxc(1) &
1245  + derivrotationmatrix(2, 2) * xxc(2) &
1246  + derivrotationmatrix(2, 3) * xxc(3)
1247  sc(3) = sc(3) + velzgrid &
1248  + derivrotationmatrix(3, 1) * xxc(1) &
1249  + derivrotationmatrix(3, 2) * xxc(2) &
1250  + derivrotationmatrix(3, 3) * xxc(3)
1251 
1252  end subroutine cellfacevelocities
1253 
1254 #ifndef USE_TAPENADE
1255  subroutine slipvelocitiesfinelevel(useOldCoor, t, sps)
1256  !
1257  ! Shell function to call slipVelocitiesFineLevel on all blocks
1258  !
1259  use constants
1260  use blockpointers, only: ndom
1262  use iteration, only: groundlevel
1263  use utils, only: setpointers
1264  implicit none
1265  !
1266  ! Subroutine arguments.
1267  !
1268  integer(kind=intType), intent(in) :: sps
1269  logical, intent(in) :: useOldCoor
1270  real(kind=realtype), dimension(*), intent(in) :: t !
1271  ! Local variables.
1272  !
1273  integer(kind=intType) :: nn
1274 
1275  ! Loop over the number of blocks.
1276 
1277  domains: do nn = 1, ndom
1278 
1279  ! Set the pointers for this block.
1280 
1281  call setpointers(nn, groundlevel, sps)
1282 
1283  call slipvelocitiesfinelevel_block(useoldcoor, t, sps, nn)
1284 
1285  end do domains
1286 
1287  end subroutine slipvelocitiesfinelevel
1288 #endif
1289 
1290  subroutine slipvelocitiesfinelevel_block(useOldCoor, t, sps, nn)
1291  !
1292  ! slipVelocitiesFineLevel computes the slip velocities for
1293  ! viscous subfaces on all viscous boundaries on groundLevel for
1294  ! the given spectral solution. If useOldCoor is .true. the
1295  ! velocities are determined using the unsteady time integrator;
1296  ! otherwise the analytic form is used.
1297  !
1298  use constants
1299  use inputtimespectral
1300  use blockpointers
1301  use cgnsgrid
1302  use flowvarrefstate
1303  use inputmotion
1304  use inputunsteady
1305  use iteration
1306  use inputphysics
1307  use inputtsstabderiv
1308  use monitor
1309  use communication
1313  implicit none
1314  !
1315  ! Subroutine arguments.
1316  !
1317  integer(kind=intType), intent(in) :: sps, nn
1318  logical, intent(in) :: useOldCoor
1319 
1320  real(kind=realtype), dimension(*), intent(in) :: t
1321  !
1322  ! Local variables.
1323  !
1324  integer(kind=intType) :: mm, i, j, level, ii
1325 
1326  real(kind=realtype) :: oneover4dt
1327  real(kind=realtype) :: velxgrid, velygrid, velzgrid, ainf
1328  real(kind=realtype) :: velxgrid0, velygrid0, velzgrid0
1329 
1330  real(kind=realtype), dimension(3) :: xc, xxc
1331  real(kind=realtype), dimension(3) :: rotcenter, rotrate
1332 
1333  real(kind=realtype), dimension(3) :: rotationpoint
1334  real(kind=realtype), dimension(3, 3) :: rotationmatrix, &
1335  derivrotationmatrix
1336 
1337  real(kind=realtype) :: tnew, told
1338 
1339  real(kind=realtype), dimension(:, :, :), pointer :: uslip
1340  real(kind=realtype), dimension(:, :, :), pointer :: xface
1341  real(kind=realtype), dimension(:, :, :, :), pointer :: xfaceold
1342 
1343  real(kind=realtype) :: intervalmach, alphats, alphaincrement, &
1344  betats, betaincrement
1345  real(kind=realtype), dimension(3) :: veldir
1346  real(kind=realtype), dimension(3) :: refdirection
1347 
1348  ! Determine the situation we are having here.
1349 
1350  testuseoldcoor: if (useoldcoor) then
1351 
1352 #ifndef USE_TAPENADE
1353 ! the time-stepping portion is not ADed.
1354 
1355  ! The velocities must be determined via a finite difference
1356  ! formula using the coordinates of the old levels.
1357 
1358  ! Set the coefficients for the time integrator and store the
1359  ! inverse of the physical nonDimensional time step, divided
1360  ! by 4, a bit easier.
1361 
1363  oneover4dt = fourth * timeref / deltat
1364 
1365  ! Loop over the number of viscous subfaces.
1366 
1367  bocoloop1: do mm = 1, nviscbocos
1368 
1369  ! Set the pointer for uSlip to make the code more
1370  ! readable.
1371 
1372  uslip => bcdata(mm)%uSlip
1373 
1374  ! Determine the grid face on which the subface is located
1375  ! and set some variables accordingly.
1376 
1377  select case (bcfaceid(mm))
1378 
1379  case (imin)
1380  xface => x(1, :, :, :); xfaceold => xold(:, 1, :, :, :)
1381 
1382  case (imax)
1383  xface => x(il, :, :, :); xfaceold => xold(:, il, :, :, :)
1384 
1385  case (jmin)
1386  xface => x(:, 1, :, :); xfaceold => xold(:, :, 1, :, :)
1387 
1388  case (jmax)
1389  xface => x(:, jl, :, :); xfaceold => xold(:, :, jl, :, :)
1390 
1391  case (kmin)
1392  xface => x(:, :, 1, :); xfaceold => xold(:, :, :, 1, :)
1393 
1394  case (kmax)
1395  xface => x(:, :, kl, :); xfaceold => xold(:, :, :, kl, :)
1396 
1397  end select
1398 
1399  ! Some boundary faces have a different rotation speed than
1400  ! the corresponding block. This happens e.g. in the tip gap
1401  ! region of turboMachinary problems where the casing does
1402  ! not rotate. As the coordinate difference corresponds to
1403  ! the rotation rate of the block, a correction must be
1404  ! computed. Therefore compute the difference in rotation
1405  ! rate and store the rotation center a bit easier. Note that
1406  ! the rotation center of subface is taken, because if there
1407  ! is a difference in rotation rate this info for the subface
1408  ! must always be specified.
1409 
1410  j = nbkglobal
1411  i = cgnssubface(mm)
1412 
1413  rotcenter = cgnsdoms(j)%bocoInfo(i)%rotCenter
1414  rotrate = timeref * (cgnsdoms(j)%bocoInfo(i)%rotRate &
1415  - cgnsdoms(j)%rotRate)
1416 
1417  ! Loop over the quadrilateral faces of the viscous subface.
1418  ! Note that due to the usage of the pointers xFace and
1419  ! xFaceOld an offset of +1 must be used in the coordinate
1420  ! arrays, because x and xOld originally start at 0 for the
1421  ! i, j and k indices.
1422 
1423  do j = bcdata(mm)%jcBeg, bcdata(mm)%jcEnd
1424  do i = bcdata(mm)%icBeg, bcdata(mm)%icEnd
1425 
1426  ! Determine the coordinates of the centroid of the
1427  ! face, multiplied by 4.
1428 
1429  xc(1) = xface(i + 1, j + 1, 1) + xface(i + 1, j, 1) &
1430  + xface(i, j + 1, 1) + xface(i, j, 1)
1431  xc(2) = xface(i + 1, j + 1, 2) + xface(i + 1, j, 2) &
1432  + xface(i, j + 1, 2) + xface(i, j, 2)
1433  xc(3) = xface(i + 1, j + 1, 3) + xface(i + 1, j, 3) &
1434  + xface(i, j + 1, 3) + xface(i, j, 3)
1435 
1436  ! Multiply the sum of the 4 vertex coordinates with
1437  ! coefTime(0) to obtain the contribution for the
1438  ! current time level. The division by 4*deltaT will
1439  ! take place later. This is both more efficient and
1440  ! more accurate for extremely small time steps.
1441 
1442  uslip(i, j, 1) = coeftime(0) * xc(1)
1443  uslip(i, j, 2) = coeftime(0) * xc(2)
1444  uslip(i, j, 3) = coeftime(0) * xc(3)
1445 
1446  ! Loop over the older time levels and take their
1447  ! contribution into account.
1448 
1449  do level = 1, noldlevels
1450 
1451  uslip(i, j, 1) = uslip(i, j, 1) + coeftime(level) &
1452  * (xfaceold(level, i + 1, j + 1, 1) &
1453  + xfaceold(level, i + 1, j, 1) &
1454  + xfaceold(level, i, j + 1, 1) &
1455  + xfaceold(level, i, j, 1))
1456 
1457  uslip(i, j, 2) = uslip(i, j, 2) + coeftime(level) &
1458  * (xfaceold(level, i + 1, j + 1, 2) &
1459  + xfaceold(level, i + 1, j, 2) &
1460  + xfaceold(level, i, j + 1, 2) &
1461  + xfaceold(level, i, j, 2))
1462 
1463  uslip(i, j, 3) = uslip(i, j, 3) + coeftime(level) &
1464  * (xfaceold(level, i + 1, j + 1, 3) &
1465  + xfaceold(level, i + 1, j, 3) &
1466  + xfaceold(level, i, j + 1, 3) &
1467  + xfaceold(level, i, j, 3))
1468  end do
1469 
1470  ! Divide by 4 times the time step to obtain the
1471  ! correct velocity.
1472 
1473  uslip(i, j, 1) = uslip(i, j, 1) * oneover4dt
1474  uslip(i, j, 2) = uslip(i, j, 2) * oneover4dt
1475  uslip(i, j, 3) = uslip(i, j, 3) * oneover4dt
1476 
1477  ! Determine the correction due to the difference
1478  ! in rotation rate between the block and subface.
1479 
1480  ! First determine the coordinates relative to the
1481  ! rotation center. Remember that 4 times this value
1482  ! is currently stored in xc.
1483 
1484  xc(1) = fourth * xc(1) - rotcenter(1)
1485  xc(2) = fourth * xc(2) - rotcenter(2)
1486  xc(3) = fourth * xc(3) - rotcenter(3)
1487 
1488  ! Compute the velocity, which is the cross product
1489  ! of rotRate and xc and add it to uSlip.
1490 
1491  uslip(i, j, 1) = uslip(i, j, 1) &
1492  + rotrate(2) * xc(3) - rotrate(3) * xc(2)
1493  uslip(i, j, 2) = uslip(i, j, 2) &
1494  + rotrate(3) * xc(1) - rotrate(1) * xc(3)
1495  uslip(i, j, 3) = uslip(i, j, 3) &
1496  + rotrate(1) * xc(2) - rotrate(2) * xc(1)
1497 
1498  end do
1499  end do
1500 
1501  end do bocoloop1
1502 #else
1503  continue
1504 #endif
1505  else
1506 
1507  ! The velocities must be determined analytically.
1508 
1509  ! Compute the mesh velocity from the given mesh Mach number.
1510 
1511  ! aInf = sqrt(gammaInf*pInf/rhoInf)
1512  ! velxGrid = aInf*MachGrid(1)
1513  ! velyGrid = aInf*MachGrid(2)
1514  ! velzGrid = aInf*MachGrid(3)
1515 
1516  ainf = sqrt(gammainf * pinf / rhoinf)
1517  velxgrid0 = (ainf * machgrid) * (-veldirfreestream(1))
1518  velygrid0 = (ainf * machgrid) * (-veldirfreestream(2))
1519  velzgrid0 = (ainf * machgrid) * (-veldirfreestream(3))
1520 
1521  ! Compute the derivative of the rotation matrix and the rotation
1522  ! point; needed for velocity due to the rigid body rotation of
1523  ! the entire grid. It is assumed that the rigid body motion of
1524  ! the grid is only specified if there is only 1 section present.
1525 
1526  call derivativerotmatrixrigid(derivrotationmatrix, rotationpoint, &
1527  t(1))
1528 
1529  !compute the rotation matrix to update the velocities for the time
1530  !spectral stability derivative case...
1531 
1532 #ifndef USE_TAPENADE
1533 ! the stability portion is not ADed.
1534 
1535  if (tsstability) then
1536  ! Determine the time values of the old and new time level.
1537  ! It is assumed that the rigid body rotation of the mesh is only
1538  ! used when only 1 section is present.
1539 
1541  told = tnew - t(1)
1542 
1543  if (tspmode .or. tsqmode .or. tsrmode) then
1544  ! Compute the rotation matrix of the rigid body rotation as
1545  ! well as the rotation point; the latter may vary in time due
1546  ! to rigid body translation.
1547 
1548  call rotmatrixrigidbody(tnew, told, rotationmatrix, rotationpoint)
1549 
1550  if (tsalphafollowing) then
1551 
1552  velxgrid0 = rotationmatrix(1, 1) * velxgrid0 &
1553  + rotationmatrix(1, 2) * velygrid0 &
1554  + rotationmatrix(1, 3) * velzgrid0
1555  velygrid0 = rotationmatrix(2, 1) * velxgrid0 &
1556  + rotationmatrix(2, 2) * velygrid0 &
1557  + rotationmatrix(2, 3) * velzgrid0
1558  velzgrid0 = rotationmatrix(3, 1) * velxgrid0 &
1559  + rotationmatrix(3, 2) * velygrid0 &
1560  + rotationmatrix(3, 3) * velzgrid0
1561 
1562  end if
1563  elseif (tsalphamode) then
1564  !Determine the alpha for this time instance
1565  alphaincrement = tsalpha(degreepolalpha, coefpolalpha, &
1568 
1569  alphats = alpha + alphaincrement
1570  !Determine the grid velocity for this alpha
1571  refdirection(:) = zero
1572  refdirection(1) = one
1573  call getdirvector(refdirection, alphats, beta, veldir, liftindex)
1574 
1575  !do I need to update the lift direction and drag direction as well?
1576  !set the effictive grid velocity for this time interval
1577  velxgrid0 = (ainf * machgrid) * (-veldir(1))
1578  velygrid0 = (ainf * machgrid) * (-veldir(2))
1579  velzgrid0 = (ainf * machgrid) * (-veldir(3))
1580 
1581  elseif (tsbetamode) then
1582 
1583  !Determine the alpha for this time instance
1584  betaincrement = tsbeta(degreepolbeta, coefpolbeta, &
1587 
1588  betats = beta + betaincrement
1589  !Determine the grid velocity for this alpha
1590  refdirection(:) = zero
1591  refdirection(1) = one
1592  call getdirvector(refdirection, alpha, betats, veldir, liftindex)
1593 
1594  !do I need to update the lift direction and drag direction as well?
1595  !set the effictive grid velocity for this time interval
1596  velxgrid0 = (ainf * machgrid) * (-veldir(1))
1597  velygrid0 = (ainf * machgrid) * (-veldir(2))
1598  velzgrid0 = (ainf * machgrid) * (-veldir(3))
1599  elseif (tsmachmode) then
1600  !determine the mach number at this time interval
1601  intervalmach = tsmach(degreepolmach, coefpolmach, &
1604  !set the effective grid velocity
1605  velxgrid0 = (ainf * (intervalmach + machgrid)) * (-veldirfreestream(1))
1606  velygrid0 = (ainf * (intervalmach + machgrid)) * (-veldirfreestream(2))
1607  velzgrid0 = (ainf * (intervalmach + machgrid)) * (-veldirfreestream(3))
1608 
1609  elseif (tsaltitudemode) then
1610  call terminate('gridVelocityFineLevel', 'altitude motion not yet implemented...')
1611  else
1612  call terminate('gridVelocityFineLevel', 'Not a recognized Stability Motion')
1613  end if
1614  end if
1615 #endif
1616 
1617  ! Loop over the number of viscous subfaces.
1618 
1619  bocoloop2: do mm = 1, nviscbocos
1620 
1621  ! Store the rotation center and the rotation rate
1622  ! for this subface.
1623 
1624  ii = cgnssubface(mm)
1625 
1626  rotcenter = cgnsdoms(nbkglobal)%bocoInfo(ii)%rotCenter
1627  rotrate = timeref * cgnsdoms(nbkglobal)%bocoInfo(ii)%rotRate
1628 
1629  ! useWindAxis should go back here!
1630  velxgrid = velxgrid0
1631  velygrid = velygrid0
1632  velzgrid = velzgrid0
1633 
1634  ! Loop over the quadrilateral faces of the viscous
1635  ! subface.
1636 
1637  ! The new procedure is less elegant as the previous one.
1638  ! But the new stands up to Tapenade.
1639  if (bcfaceid(mm) == imin) then
1640 
1641  do j = bcdata(mm)%jcBeg, bcdata(mm)%jcEnd
1642  do i = bcdata(mm)%icBeg, bcdata(mm)%icEnd
1643 
1644  ! Compute the coordinates of the centroid of the face.
1645  ! Normally this would be an average of i-1 and i, but
1646  ! due to the usage of the pointer xFace and the fact
1647  ! that x starts at index 0 this is shifted 1 index.
1648 
1649  xc(1) = fourth * (flowdoms(nn, groundlevel, sps)%x(1, i, j, 1) &
1650  + flowdoms(nn, groundlevel, sps)%x(1, i, j - 1, 1) &
1651  + flowdoms(nn, groundlevel, sps)%x(1, i - 1, j, 1) &
1652  + flowdoms(nn, groundlevel, sps)%x(1, i - 1, j - 1, 1))
1653  xc(2) = fourth * (flowdoms(nn, groundlevel, sps)%x(1, i, j, 2) &
1654  + flowdoms(nn, groundlevel, sps)%x(1, i, j - 1, 2) &
1655  + flowdoms(nn, groundlevel, sps)%x(1, i - 1, j, 2) &
1656  + flowdoms(nn, groundlevel, sps)%x(1, i - 1, j - 1, 2))
1657  xc(3) = fourth * (flowdoms(nn, groundlevel, sps)%x(1, i, j, 3) &
1658  + flowdoms(nn, groundlevel, sps)%x(1, i, j - 1, 3) &
1659  + flowdoms(nn, groundlevel, sps)%x(1, i - 1, j, 3) &
1660  + flowdoms(nn, groundlevel, sps)%x(1, i - 1, j - 1, 3))
1661 
1662  ! Determine the coordinates relative to the center
1663  ! of rotation.
1664 
1665  xxc(1) = xc(1) - rotcenter(1)
1666  xxc(2) = xc(2) - rotcenter(2)
1667  xxc(3) = xc(3) - rotcenter(3)
1668 
1669  ! Compute the velocity, which is the cross product
1670  ! of rotRate and xc.
1671 
1672  bcdata(mm)%uSlip(i, j, 1) = rotrate(2) * xxc(3) - rotrate(3) * xxc(2)
1673  bcdata(mm)%uSlip(i, j, 2) = rotrate(3) * xxc(1) - rotrate(1) * xxc(3)
1674  bcdata(mm)%uSlip(i, j, 3) = rotrate(1) * xxc(2) - rotrate(2) * xxc(1)
1675 
1676  ! Determine the coordinates relative to the
1677  ! rigid body rotation point.
1678 
1679  xxc(1) = xc(1) - rotationpoint(1)
1680  xxc(2) = xc(2) - rotationpoint(2)
1681  xxc(3) = xc(3) - rotationpoint(3)
1682 
1683  ! Determine the total velocity of the cell center.
1684  ! This is a combination of rotation speed of this
1685  ! block and the entire rigid body rotation.
1686 
1687  bcdata(mm)%uSlip(i, j, 1) = bcdata(mm)%uSlip(i, j, 1) + velxgrid &
1688  + derivrotationmatrix(1, 1) * xxc(1) &
1689  + derivrotationmatrix(1, 2) * xxc(2) &
1690  + derivrotationmatrix(1, 3) * xxc(3)
1691  bcdata(mm)%uSlip(i, j, 2) = bcdata(mm)%uSlip(i, j, 2) + velygrid &
1692  + derivrotationmatrix(2, 1) * xxc(1) &
1693  + derivrotationmatrix(2, 2) * xxc(2) &
1694  + derivrotationmatrix(2, 3) * xxc(3)
1695  bcdata(mm)%uSlip(i, j, 3) = bcdata(mm)%uSlip(i, j, 3) + velzgrid &
1696  + derivrotationmatrix(3, 1) * xxc(1) &
1697  + derivrotationmatrix(3, 2) * xxc(2) &
1698  + derivrotationmatrix(3, 3) * xxc(3)
1699  end do
1700  end do
1701 
1702  else if (bcfaceid(mm) == imax) then
1703 
1704  do j = bcdata(mm)%jcBeg, bcdata(mm)%jcEnd
1705  do i = bcdata(mm)%icBeg, bcdata(mm)%icEnd
1706 
1707  ! Compute the coordinates of the centroid of the face.
1708  ! Normally this would be an average of i-1 and i, but
1709  ! due to the usage of the pointer xFace and the fact
1710  ! that x starts at index 0 this is shifted 1 index.
1711 
1712  xc(1) = fourth * (flowdoms(nn, groundlevel, sps)%x(il, i, j, 1) &
1713  + flowdoms(nn, groundlevel, sps)%x(il, i, j - 1, 1) &
1714  + flowdoms(nn, groundlevel, sps)%x(il, i - 1, j, 1) &
1715  + flowdoms(nn, groundlevel, sps)%x(il, i - 1, j - 1, 1))
1716  xc(2) = fourth * (flowdoms(nn, groundlevel, sps)%x(il, i, j, 2) &
1717  + flowdoms(nn, groundlevel, sps)%x(il, i, j - 1, 2) &
1718  + flowdoms(nn, groundlevel, sps)%x(il, i - 1, j, 2) &
1719  + flowdoms(nn, groundlevel, sps)%x(il, i - 1, j - 1, 2))
1720  xc(3) = fourth * (flowdoms(nn, groundlevel, sps)%x(il, i, j, 3) &
1721  + flowdoms(nn, groundlevel, sps)%x(il, i, j - 1, 3) &
1722  + flowdoms(nn, groundlevel, sps)%x(il, i - 1, j, 3) &
1723  + flowdoms(nn, groundlevel, sps)%x(il, i - 1, j - 1, 3))
1724 
1725  ! Determine the coordinates relative to the center
1726  ! of rotation.
1727 
1728  xxc(1) = xc(1) - rotcenter(1)
1729  xxc(2) = xc(2) - rotcenter(2)
1730  xxc(3) = xc(3) - rotcenter(3)
1731 
1732  ! Compute the velocity, which is the cross product
1733  ! of rotRate and xc.
1734 
1735  bcdata(mm)%uSlip(i, j, 1) = rotrate(2) * xxc(3) - rotrate(3) * xxc(2)
1736  bcdata(mm)%uSlip(i, j, 2) = rotrate(3) * xxc(1) - rotrate(1) * xxc(3)
1737  bcdata(mm)%uSlip(i, j, 3) = rotrate(1) * xxc(2) - rotrate(2) * xxc(1)
1738 
1739  ! Determine the coordinates relative to the
1740  ! rigid body rotation point.
1741 
1742  xxc(1) = xc(1) - rotationpoint(1)
1743  xxc(2) = xc(2) - rotationpoint(2)
1744  xxc(3) = xc(3) - rotationpoint(3)
1745 
1746  ! Determine the total velocity of the cell center.
1747  ! This is a combination of rotation speed of this
1748  ! block and the entire rigid body rotation.
1749 
1750  bcdata(mm)%uSlip(i, j, 1) = bcdata(mm)%uSlip(i, j, 1) + velxgrid &
1751  + derivrotationmatrix(1, 1) * xxc(1) &
1752  + derivrotationmatrix(1, 2) * xxc(2) &
1753  + derivrotationmatrix(1, 3) * xxc(3)
1754  bcdata(mm)%uSlip(i, j, 2) = bcdata(mm)%uSlip(i, j, 2) + velygrid &
1755  + derivrotationmatrix(2, 1) * xxc(1) &
1756  + derivrotationmatrix(2, 2) * xxc(2) &
1757  + derivrotationmatrix(2, 3) * xxc(3)
1758  bcdata(mm)%uSlip(i, j, 3) = bcdata(mm)%uSlip(i, j, 3) + velzgrid &
1759  + derivrotationmatrix(3, 1) * xxc(1) &
1760  + derivrotationmatrix(3, 2) * xxc(2) &
1761  + derivrotationmatrix(3, 3) * xxc(3)
1762  end do
1763  end do
1764 
1765  else if (bcfaceid(mm) == jmin) then
1766 
1767  do j = bcdata(mm)%jcBeg, bcdata(mm)%jcEnd
1768  do i = bcdata(mm)%icBeg, bcdata(mm)%icEnd
1769 
1770  ! Compute the coordinates of the centroid of the face.
1771  ! Normally this would be an average of i-1 and i, but
1772  ! due to the usage of the pointer xFace and the fact
1773  ! that x starts at index 0 this is shifted 1 index.
1774 
1775  xc(1) = fourth * (flowdoms(nn, groundlevel, sps)%x(i, 1, j, 1) &
1776  + flowdoms(nn, groundlevel, sps)%x(i, 1, j - 1, 1) &
1777  + flowdoms(nn, groundlevel, sps)%x(i - 1, 1, j, 1) &
1778  + flowdoms(nn, groundlevel, sps)%x(i - 1, 1, j - 1, 1))
1779  xc(2) = fourth * (flowdoms(nn, groundlevel, sps)%x(i, 1, j, 2) &
1780  + flowdoms(nn, groundlevel, sps)%x(i, 1, j - 1, 2) &
1781  + flowdoms(nn, groundlevel, sps)%x(i - 1, 1, j, 2) &
1782  + flowdoms(nn, groundlevel, sps)%x(i - 1, 1, j - 1, 2))
1783  xc(3) = fourth * (flowdoms(nn, groundlevel, sps)%x(i, 1, j, 3) &
1784  + flowdoms(nn, groundlevel, sps)%x(i, 1, j - 1, 3) &
1785  + flowdoms(nn, groundlevel, sps)%x(i - 1, 1, j, 3) &
1786  + flowdoms(nn, groundlevel, sps)%x(i - 1, 1, j - 1, 3))
1787 
1788  ! Determine the coordinates relative to the center
1789  ! of rotation.
1790 
1791  xxc(1) = xc(1) - rotcenter(1)
1792  xxc(2) = xc(2) - rotcenter(2)
1793  xxc(3) = xc(3) - rotcenter(3)
1794 
1795  ! Compute the velocity, which is the cross product
1796  ! of rotRate and xc.
1797 
1798  bcdata(mm)%uSlip(i, j, 1) = rotrate(2) * xxc(3) - rotrate(3) * xxc(2)
1799  bcdata(mm)%uSlip(i, j, 2) = rotrate(3) * xxc(1) - rotrate(1) * xxc(3)
1800  bcdata(mm)%uSlip(i, j, 3) = rotrate(1) * xxc(2) - rotrate(2) * xxc(1)
1801 
1802  ! Determine the coordinates relative to the
1803  ! rigid body rotation point.
1804 
1805  xxc(1) = xc(1) - rotationpoint(1)
1806  xxc(2) = xc(2) - rotationpoint(2)
1807  xxc(3) = xc(3) - rotationpoint(3)
1808 
1809  ! Determine the total velocity of the cell center.
1810  ! This is a combination of rotation speed of this
1811  ! block and the entire rigid body rotation.
1812 
1813  bcdata(mm)%uSlip(i, j, 1) = bcdata(mm)%uSlip(i, j, 1) + velxgrid &
1814  + derivrotationmatrix(1, 1) * xxc(1) &
1815  + derivrotationmatrix(1, 2) * xxc(2) &
1816  + derivrotationmatrix(1, 3) * xxc(3)
1817  bcdata(mm)%uSlip(i, j, 2) = bcdata(mm)%uSlip(i, j, 2) + velygrid &
1818  + derivrotationmatrix(2, 1) * xxc(1) &
1819  + derivrotationmatrix(2, 2) * xxc(2) &
1820  + derivrotationmatrix(2, 3) * xxc(3)
1821  bcdata(mm)%uSlip(i, j, 3) = bcdata(mm)%uSlip(i, j, 3) + velzgrid &
1822  + derivrotationmatrix(3, 1) * xxc(1) &
1823  + derivrotationmatrix(3, 2) * xxc(2) &
1824  + derivrotationmatrix(3, 3) * xxc(3)
1825  end do
1826  end do
1827 
1828  else if (bcfaceid(mm) == jmax) then
1829 
1830  do j = bcdata(mm)%jcBeg, bcdata(mm)%jcEnd
1831  do i = bcdata(mm)%icBeg, bcdata(mm)%icEnd
1832 
1833  ! Compute the coordinates of the centroid of the face.
1834  ! Normally this would be an average of i-1 and i, but
1835  ! due to the usage of the pointer xFace and the fact
1836  ! that x starts at index 0 this is shifted 1 index.
1837 
1838  xc(1) = fourth * (flowdoms(nn, groundlevel, sps)%x(i, jl, j, 1) &
1839  + flowdoms(nn, groundlevel, sps)%x(i, jl, j - 1, 1) &
1840  + flowdoms(nn, groundlevel, sps)%x(i - 1, jl, j, 1) &
1841  + flowdoms(nn, groundlevel, sps)%x(i - 1, jl, j - 1, 1))
1842  xc(2) = fourth * (flowdoms(nn, groundlevel, sps)%x(i, jl, j, 2) &
1843  + flowdoms(nn, groundlevel, sps)%x(i, jl, j - 1, 2) &
1844  + flowdoms(nn, groundlevel, sps)%x(i - 1, jl, j, 2) &
1845  + flowdoms(nn, groundlevel, sps)%x(i - 1, jl, j - 1, 2))
1846  xc(3) = fourth * (flowdoms(nn, groundlevel, sps)%x(i, jl, j, 3) &
1847  + flowdoms(nn, groundlevel, sps)%x(i, jl, j - 1, 3) &
1848  + flowdoms(nn, groundlevel, sps)%x(i - 1, jl, j, 3) &
1849  + flowdoms(nn, groundlevel, sps)%x(i - 1, jl, j - 1, 3))
1850 
1851  ! Determine the coordinates relative to the center
1852  ! of rotation.
1853 
1854  xxc(1) = xc(1) - rotcenter(1)
1855  xxc(2) = xc(2) - rotcenter(2)
1856  xxc(3) = xc(3) - rotcenter(3)
1857 
1858  ! Compute the velocity, which is the cross product
1859  ! of rotRate and xc.
1860 
1861  bcdata(mm)%uSlip(i, j, 1) = rotrate(2) * xxc(3) - rotrate(3) * xxc(2)
1862  bcdata(mm)%uSlip(i, j, 2) = rotrate(3) * xxc(1) - rotrate(1) * xxc(3)
1863  bcdata(mm)%uSlip(i, j, 3) = rotrate(1) * xxc(2) - rotrate(2) * xxc(1)
1864 
1865  ! Determine the coordinates relative to the
1866  ! rigid body rotation point.
1867 
1868  xxc(1) = xc(1) - rotationpoint(1)
1869  xxc(2) = xc(2) - rotationpoint(2)
1870  xxc(3) = xc(3) - rotationpoint(3)
1871 
1872  ! Determine the total velocity of the cell center.
1873  ! This is a combination of rotation speed of this
1874  ! block and the entire rigid body rotation.
1875 
1876  bcdata(mm)%uSlip(i, j, 1) = bcdata(mm)%uSlip(i, j, 1) + velxgrid &
1877  + derivrotationmatrix(1, 1) * xxc(1) &
1878  + derivrotationmatrix(1, 2) * xxc(2) &
1879  + derivrotationmatrix(1, 3) * xxc(3)
1880  bcdata(mm)%uSlip(i, j, 2) = bcdata(mm)%uSlip(i, j, 2) + velygrid &
1881  + derivrotationmatrix(2, 1) * xxc(1) &
1882  + derivrotationmatrix(2, 2) * xxc(2) &
1883  + derivrotationmatrix(2, 3) * xxc(3)
1884  bcdata(mm)%uSlip(i, j, 3) = bcdata(mm)%uSlip(i, j, 3) + velzgrid &
1885  + derivrotationmatrix(3, 1) * xxc(1) &
1886  + derivrotationmatrix(3, 2) * xxc(2) &
1887  + derivrotationmatrix(3, 3) * xxc(3)
1888  end do
1889  end do
1890 
1891  else if (bcfaceid(mm) == kmin) then
1892 
1893  do j = bcdata(mm)%jcBeg, bcdata(mm)%jcEnd
1894  do i = bcdata(mm)%icBeg, bcdata(mm)%icEnd
1895 
1896  ! Compute the coordinates of the centroid of the face.
1897  ! Normally this would be an average of i-1 and i, but
1898  ! due to the usage of the pointer xFace and the fact
1899  ! that x starts at index 0 this is shifted 1 index.
1900 
1901  xc(1) = fourth * (flowdoms(nn, groundlevel, sps)%x(i, j, 1, 1) &
1902  + flowdoms(nn, groundlevel, sps)%x(i, j - 1, 1, 1) &
1903  + flowdoms(nn, groundlevel, sps)%x(i - 1, j, 1, 1) &
1904  + flowdoms(nn, groundlevel, sps)%x(i - 1, j - 1, 1, 1))
1905  xc(2) = fourth * (flowdoms(nn, groundlevel, sps)%x(i, j, 1, 2) &
1906  + flowdoms(nn, groundlevel, sps)%x(i, j - 1, 1, 2) &
1907  + flowdoms(nn, groundlevel, sps)%x(i - 1, j, 1, 2) &
1908  + flowdoms(nn, groundlevel, sps)%x(i - 1, j - 1, 1, 2))
1909  xc(3) = fourth * (flowdoms(nn, groundlevel, sps)%x(i, j, 1, 3) &
1910  + flowdoms(nn, groundlevel, sps)%x(i, j - 1, 1, 3) &
1911  + flowdoms(nn, groundlevel, sps)%x(i - 1, j, 1, 3) &
1912  + flowdoms(nn, groundlevel, sps)%x(i - 1, j - 1, 1, 3))
1913 
1914  ! Determine the coordinates relative to the center
1915  ! of rotation.
1916 
1917  xxc(1) = xc(1) - rotcenter(1)
1918  xxc(2) = xc(2) - rotcenter(2)
1919  xxc(3) = xc(3) - rotcenter(3)
1920 
1921  ! Compute the velocity, which is the cross product
1922  ! of rotRate and xc.
1923 
1924  bcdata(mm)%uSlip(i, j, 1) = rotrate(2) * xxc(3) - rotrate(3) * xxc(2)
1925  bcdata(mm)%uSlip(i, j, 2) = rotrate(3) * xxc(1) - rotrate(1) * xxc(3)
1926  bcdata(mm)%uSlip(i, j, 3) = rotrate(1) * xxc(2) - rotrate(2) * xxc(1)
1927 
1928  ! Determine the coordinates relative to the
1929  ! rigid body rotation point.
1930 
1931  xxc(1) = xc(1) - rotationpoint(1)
1932  xxc(2) = xc(2) - rotationpoint(2)
1933  xxc(3) = xc(3) - rotationpoint(3)
1934 
1935  ! Determine the total velocity of the cell center.
1936  ! This is a combination of rotation speed of this
1937  ! block and the entire rigid body rotation.
1938 
1939  bcdata(mm)%uSlip(i, j, 1) = bcdata(mm)%uSlip(i, j, 1) + velxgrid &
1940  + derivrotationmatrix(1, 1) * xxc(1) &
1941  + derivrotationmatrix(1, 2) * xxc(2) &
1942  + derivrotationmatrix(1, 3) * xxc(3)
1943  bcdata(mm)%uSlip(i, j, 2) = bcdata(mm)%uSlip(i, j, 2) + velygrid &
1944  + derivrotationmatrix(2, 1) * xxc(1) &
1945  + derivrotationmatrix(2, 2) * xxc(2) &
1946  + derivrotationmatrix(2, 3) * xxc(3)
1947  bcdata(mm)%uSlip(i, j, 3) = bcdata(mm)%uSlip(i, j, 3) + velzgrid &
1948  + derivrotationmatrix(3, 1) * xxc(1) &
1949  + derivrotationmatrix(3, 2) * xxc(2) &
1950  + derivrotationmatrix(3, 3) * xxc(3)
1951  end do
1952  end do
1953 
1954  else if (bcfaceid(mm) == kmax) then
1955 
1956  do j = bcdata(mm)%jcBeg, bcdata(mm)%jcEnd
1957  do i = bcdata(mm)%icBeg, bcdata(mm)%icEnd
1958 
1959  ! Compute the coordinates of the centroid of the face.
1960  ! Normally this would be an average of i-1 and i, but
1961  ! due to the usage of the pointer xFace and the fact
1962  ! that x starts at index 0 this is shifted 1 index.
1963 
1964  xc(1) = fourth * (flowdoms(nn, groundlevel, sps)%x(i, j, kl, 1) &
1965  + flowdoms(nn, groundlevel, sps)%x(i, j - 1, kl, 1) &
1966  + flowdoms(nn, groundlevel, sps)%x(i - 1, j, kl, 1) &
1967  + flowdoms(nn, groundlevel, sps)%x(i - 1, j - 1, kl, 1))
1968  xc(2) = fourth * (flowdoms(nn, groundlevel, sps)%x(i, j, kl, 2) &
1969  + flowdoms(nn, groundlevel, sps)%x(i, j - 1, kl, 2) &
1970  + flowdoms(nn, groundlevel, sps)%x(i - 1, j, kl, 2) &
1971  + flowdoms(nn, groundlevel, sps)%x(i - 1, j - 1, kl, 2))
1972  xc(3) = fourth * (flowdoms(nn, groundlevel, sps)%x(i, j, kl, 3) &
1973  + flowdoms(nn, groundlevel, sps)%x(i, j - 1, kl, 3) &
1974  + flowdoms(nn, groundlevel, sps)%x(i - 1, j, kl, 3) &
1975  + flowdoms(nn, groundlevel, sps)%x(i - 1, j - 1, kl, 3))
1976 
1977  ! Determine the coordinates relative to the center
1978  ! of rotation.
1979 
1980  xxc(1) = xc(1) - rotcenter(1)
1981  xxc(2) = xc(2) - rotcenter(2)
1982  xxc(3) = xc(3) - rotcenter(3)
1983 
1984  ! Compute the velocity, which is the cross product
1985  ! of rotRate and xc.
1986 
1987  bcdata(mm)%uSlip(i, j, 1) = rotrate(2) * xxc(3) - rotrate(3) * xxc(2)
1988  bcdata(mm)%uSlip(i, j, 2) = rotrate(3) * xxc(1) - rotrate(1) * xxc(3)
1989  bcdata(mm)%uSlip(i, j, 3) = rotrate(1) * xxc(2) - rotrate(2) * xxc(1)
1990 
1991  ! Determine the coordinates relative to the
1992  ! rigid body rotation point.
1993 
1994  xxc(1) = xc(1) - rotationpoint(1)
1995  xxc(2) = xc(2) - rotationpoint(2)
1996  xxc(3) = xc(3) - rotationpoint(3)
1997 
1998  ! Determine the total velocity of the cell center.
1999  ! This is a combination of rotation speed of this
2000  ! block and the entire rigid body rotation.
2001 
2002  bcdata(mm)%uSlip(i, j, 1) = bcdata(mm)%uSlip(i, j, 1) + velxgrid &
2003  + derivrotationmatrix(1, 1) * xxc(1) &
2004  + derivrotationmatrix(1, 2) * xxc(2) &
2005  + derivrotationmatrix(1, 3) * xxc(3)
2006  bcdata(mm)%uSlip(i, j, 2) = bcdata(mm)%uSlip(i, j, 2) + velygrid &
2007  + derivrotationmatrix(2, 1) * xxc(1) &
2008  + derivrotationmatrix(2, 2) * xxc(2) &
2009  + derivrotationmatrix(2, 3) * xxc(3)
2010  bcdata(mm)%uSlip(i, j, 3) = bcdata(mm)%uSlip(i, j, 3) + velzgrid &
2011  + derivrotationmatrix(3, 1) * xxc(1) &
2012  + derivrotationmatrix(3, 2) * xxc(2) &
2013  + derivrotationmatrix(3, 3) * xxc(3)
2014  end do
2015  end do
2016 
2017  end if
2018 
2019  end do bocoloop2
2020 
2021  end if testuseoldcoor
2022 
2023  end subroutine slipvelocitiesfinelevel_block
2024 
2025 #ifndef USE_TAPENADE
2027  !
2028  ! Shell function to call normalVelocities_block on all blocks/levels
2029  !
2030  use constants
2031  use blockpointers, only: ndom, flowdoms
2033  use iteration, only: groundlevel
2034  use utils, only: setpointers
2035  implicit none
2036  !
2037  ! Subroutine arguments.
2038  !
2039  integer(kind=intType), intent(in) :: sps
2040  ! Local variables.
2041  !
2042  integer(kind=intType) :: nn, level, nLevels
2043 
2044  nlevels = ubound(flowdoms, 2)
2045  levelloop: do level = groundlevel, nlevels
2046  domains: do nn = 1, ndom
2047 
2048  ! Set the pointers for this block.
2049 
2050  call setpointers(nn, level, sps)
2051 
2052  call normalvelocities_block(sps)
2053 
2054  end do domains
2055  end do levelloop
2056  end subroutine normalvelocitiesalllevels
2057 #endif
2058 
2059  subroutine normalvelocities_block(sps)
2060  !
2061  ! normalVelocitiesAllLevels computes the normal grid
2062  ! velocities of some boundary faces of the moving blocks for
2063  ! spectral mode sps. All grid levels from ground level to the
2064  ! coarsest level are considered.
2065  !
2066  use constants
2067  use blockpointers, only: il, jl, kl, addgridvelocities, nbocos, bcdata, &
2069  !use iteration
2070  implicit none
2071  !
2072  ! Subroutine arguments.
2073  !
2074  integer(kind=intType), intent(in) :: sps
2075  !
2076  ! Local variables.
2077  !
2078  integer(kind=intType) :: mm
2079  integer(kind=intType) :: i, j
2080 
2081  real(kind=realtype) :: weight, mult
2082 
2083  real(kind=realtype), dimension(:, :), pointer :: sface
2084  real(kind=realtype), dimension(:, :, :), pointer :: ss
2085 
2086  ! Check for a moving block. As it is possible that in a
2087  ! multidisicplinary environment additional grid velocities
2088  ! are set, the test should be done on addGridVelocities
2089  ! and not on blockIsMoving.
2090 
2091  testmoving: if (addgridvelocities) then
2092  !
2093  ! Determine the normal grid velocities of the boundaries.
2094  ! As these values are based on the unit normal. A division
2095  ! by the length of the normal is needed.
2096  ! Furthermore the boundary unit normals are per definition
2097  ! outward pointing, while on the iMin, jMin and kMin
2098  ! boundaries the face normals are inward pointing. This
2099  ! is taken into account by the factor mult.
2100  !
2101  ! Loop over the boundary subfaces.
2102 
2103  bocoloop: do mm = 1, nbocos
2104 
2105  ! Check whether rFace is allocated.
2106 
2107  testassoc: if (associated(bcdata(mm)%rFace)) then
2108 
2109  ! Determine the block face on which the subface is
2110  ! located and set some variables accordingly.
2111 
2112  ! The new procedure is less elegant as the previous one.
2113  ! But the new stands up to Tapenade.
2114  if (bcfaceid(mm) == imin) then
2115 
2116  mult = -one
2117 
2118  do j = bcdata(mm)%jcBeg, bcdata(mm)%jcEnd
2119  do i = bcdata(mm)%icBeg, bcdata(mm)%icEnd
2120 
2121  ! Compute the inverse of the length of the normal
2122  ! vector and possibly correct for inward pointing.
2123 
2124  weight = sqrt(si(1, i, j, 1)**2 + si(1, i, j, 2)**2 &
2125  + si(1, i, j, 3)**2)
2126  if (weight > zero) weight = mult / weight
2127 
2128  ! Compute the normal velocity based on the outward
2129  ! pointing unit normal.
2130 
2131  bcdata(mm)%rFace(i, j) = weight * sfacei(1, i, j)
2132  end do
2133  end do
2134 
2135  else if (bcfaceid(mm) == imax) then
2136 
2137  mult = one
2138 
2139  do j = bcdata(mm)%jcBeg, bcdata(mm)%jcEnd
2140  do i = bcdata(mm)%icBeg, bcdata(mm)%icEnd
2141 
2142  ! Compute the inverse of the length of the normal
2143  ! vector and possibly correct for inward pointing.
2144 
2145  weight = sqrt(si(il, i, j, 1)**2 + si(il, i, j, 2)**2 &
2146  + si(il, i, j, 3)**2)
2147  if (weight > zero) weight = mult / weight
2148 
2149  ! Compute the normal velocity based on the outward
2150  ! pointing unit normal.
2151 
2152  bcdata(mm)%rFace(i, j) = weight * sfacei(il, i, j)
2153  end do
2154  end do
2155 
2156  else if (bcfaceid(mm) == jmin) then
2157 
2158  mult = -one
2159 
2160  do j = bcdata(mm)%jcBeg, bcdata(mm)%jcEnd
2161  do i = bcdata(mm)%icBeg, bcdata(mm)%icEnd
2162 
2163  ! Compute the inverse of the length of the normal
2164  ! vector and possibly correct for inward pointing.
2165 
2166  weight = sqrt(sj(i, 1, j, 1)**2 + sj(i, 1, j, 2)**2 &
2167  + sj(i, 1, j, 3)**2)
2168  if (weight > zero) weight = mult / weight
2169 
2170  ! Compute the normal velocity based on the outward
2171  ! pointing unit normal.
2172 
2173  bcdata(mm)%rFace(i, j) = weight * sfacej(i, 1, j)
2174  end do
2175  end do
2176 
2177  else if (bcfaceid(mm) == jmax) then
2178 
2179  mult = one
2180 
2181  do j = bcdata(mm)%jcBeg, bcdata(mm)%jcEnd
2182  do i = bcdata(mm)%icBeg, bcdata(mm)%icEnd
2183 
2184  ! Compute the inverse of the length of the normal
2185  ! vector and possibly correct for inward pointing.
2186 
2187  weight = sqrt(sj(i, jl, j, 1)**2 + sj(i, jl, j, 2)**2 &
2188  + sj(i, jl, j, 3)**2)
2189  if (weight > zero) weight = mult / weight
2190 
2191  ! Compute the normal velocity based on the outward
2192  ! pointing unit normal.
2193 
2194  bcdata(mm)%rFace(i, j) = weight * sfacej(i, jl, j)
2195  end do
2196  end do
2197 
2198  else if (bcfaceid(mm) == kmin) then
2199 
2200  mult = -one
2201 
2202  do j = bcdata(mm)%jcBeg, bcdata(mm)%jcEnd
2203  do i = bcdata(mm)%icBeg, bcdata(mm)%icEnd
2204 
2205  ! Compute the inverse of the length of the normal
2206  ! vector and possibly correct for inward pointing.
2207 
2208  weight = sqrt(sk(i, j, 1, 1)**2 + sk(i, j, 1, 2)**2 &
2209  + sk(i, j, 1, 3)**2)
2210  if (weight > zero) weight = mult / weight
2211 
2212  ! Compute the normal velocity based on the outward
2213  ! pointing unit normal.
2214 
2215  bcdata(mm)%rFace(i, j) = weight * sfacek(i, j, 1)
2216  end do
2217  end do
2218 
2219  else if (bcfaceid(mm) == kmax) then
2220 
2221  mult = one
2222 
2223  do j = bcdata(mm)%jcBeg, bcdata(mm)%jcEnd
2224  do i = bcdata(mm)%icBeg, bcdata(mm)%icEnd
2225 
2226  ! Compute the inverse of the length of the normal
2227  ! vector and possibly correct for inward pointing.
2228 
2229  weight = sqrt(sk(i, j, kl, 1)**2 + sk(i, j, kl, 2)**2 &
2230  + sk(i, j, kl, 3)**2)
2231  if (weight > zero) weight = mult / weight
2232 
2233  ! Compute the normal velocity based on the outward
2234  ! pointing unit normal.
2235 
2236  bcdata(mm)%rFace(i, j) = weight * sfacek(i, j, kl)
2237  end do
2238  end do
2239 
2240  end if
2241 
2242  end if testassoc
2243  end do bocoloop
2244 
2245  else testmoving
2246 
2247  ! Block is not moving. Loop over the boundary faces and set
2248  ! the normal grid velocity to zero if allocated.
2249 
2250  do mm = 1, nbocos
2251  if (associated(bcdata(mm)%rFace)) &
2252  bcdata(mm)%rFace = zero
2253  end do
2254 
2255  end if testmoving
2256 
2257  end subroutine normalvelocities_block
2258 
2259  ! ----------------------------------------------------------------------
2260  ! |
2261  ! No Tapenade Routine below this line |
2262  ! |
2263  ! ----------------------------------------------------------------------
2264 
2265 #ifndef USE_TAPENADE
2266 
2267  subroutine shiftsolution
2268  !
2269  ! shiftSolution shifts the solution of the older time levels,
2270  ! such that a new time step can be started.
2271  !
2272  use constants
2273  use blockpointers, only: il, jl, kl, nbkglobal, wold, w, ndom
2274  use cgnsgrid, only: cgnsdoms
2275  use flowvarrefstate, only: nw
2276  use iteration, only: groundlevel, noldlevels
2278  use inputunsteady, only: deltat
2281  implicit none
2282  !
2283  ! Local variables.
2284  !
2285  integer(kind=intType) :: i, j, k, l, sps, nn, mm, ll
2286 
2287  real(kind=realtype) :: told, tnew
2288  real(kind=realtype) :: vvx, vvy, vvz, vxi, veta, vzeta
2289  real(kind=realtype) :: t, anglex, angley, anglez
2290  real(kind=realtype) :: phi, cosphi, sinphi
2291  real(kind=realtype) :: xix, xiy, xiz, etax, etay, etaz
2292  real(kind=realtype) :: zetax, zetay, zetaz
2293 
2294  real(kind=realtype), dimension(3) :: rotationpoint
2295  real(kind=realtype), dimension(3, 3) :: rotationmatrix
2296 
2297  ! Compute the rotation matrix of the rigid body rotation as well
2298  ! as the rotation point; the latter is not needed to correct the
2299  ! velocities, but the routine rotMatrixRigidBody is also used
2300  ! for coordinates.
2301 
2303  told = tnew - deltat
2304 
2305  call rotmatrixrigidbody(tnew, told, rotationmatrix, rotationpoint)
2306 
2307  ! Loop over the number of spectral solutions and local blocks.
2308  ! Although this routine is only called in unsteady mode where the
2309  ! number of spectral solutions is 1, this loop is there just for
2310  ! consistency.
2311 
2312  spectralloop: do sps = 1, ntimeintervalsspectral
2313  domains: do nn = 1, ndom
2314 
2315  ! Set the pointers for this block on the ground level.
2316 
2317  call setpointers(nn, groundlevel, sps)
2318 
2319  ! Shift the solution already stored in wOld.
2320 
2321  loopoldlevels: do mm = noldlevels, 2, -1
2322 
2323  ! Shift the owned solution variables from level mm-1 to mm.
2324 
2325  ll = mm - 1
2326 
2327  do l = 1, nw
2328  do k = 2, kl
2329  do j = 2, jl
2330  do i = 2, il
2331  wold(mm, i, j, k, l) = wold(ll, i, j, k, l)
2332  end do
2333  end do
2334  end do
2335  end do
2336 
2337  end do loopoldlevels
2338 
2339  ! Shift the current solution into the 1st level of wOld.
2340  ! Note that in wOld the conservative flow variables are stored,
2341  ! while in w the velocity components are stored and not
2342  ! the momentum. Therefore this must be corrected.
2343  ! Also the turbulent primitive variables are stored, but this
2344  ! is okay, because the quasi-linear form of the turbulent
2345  ! transport equations is solved and not the conservative one.
2346 
2347  do l = 1, nw
2348  do k = 2, kl
2349  do j = 2, jl
2350  do i = 2, il
2351  wold(1, i, j, k, l) = w(i, j, k, l)
2352  end do
2353  end do
2354  end do
2355  end do
2356 
2357  ! Make sure that the momentum variables are stored in wOld.
2358 
2359  do k = 2, kl
2360  do j = 2, jl
2361  do i = 2, il
2362  wold(1, i, j, k, ivx) = wold(1, i, j, k, ivx) * wold(1, i, j, k, irho)
2363  wold(1, i, j, k, ivy) = wold(1, i, j, k, ivy) * wold(1, i, j, k, irho)
2364  wold(1, i, j, k, ivz) = wold(1, i, j, k, ivz) * wold(1, i, j, k, irho)
2365  end do
2366  end do
2367  end do
2368 
2369  ! To improve the initial guess of the velocity field the
2370  ! velocity of rotating parts is rotated. First the rigid
2371  ! body motion.
2372 
2373  do k = 2, kl
2374  do j = 2, jl
2375  do i = 2, il
2376  vvx = w(i, j, k, ivx)
2377  vvy = w(i, j, k, ivy)
2378  vvz = w(i, j, k, ivz)
2379 
2380  w(i, j, k, ivx) = rotationmatrix(1, 1) * vvx &
2381  + rotationmatrix(1, 2) * vvy &
2382  + rotationmatrix(1, 3) * vvz
2383  w(i, j, k, ivy) = rotationmatrix(2, 1) * vvx &
2384  + rotationmatrix(2, 2) * vvy &
2385  + rotationmatrix(2, 3) * vvz
2386  w(i, j, k, ivz) = rotationmatrix(3, 1) * vvx &
2387  + rotationmatrix(3, 2) * vvy &
2388  + rotationmatrix(3, 3) * vvz
2389  end do
2390  end do
2391  end do
2392 
2393  ! Apply an additional correction for the velocity components
2394  ! if a rotation rate is prescribed for this block.
2395 
2396  rottest: if (cgnsdoms(nbkglobal)%rotatingFrameSpecified) then
2397 
2398  ! Compute the rotation angles.
2399 
2400  anglex = deltat * cgnsdoms(nbkglobal)%rotRate(1)
2401  angley = deltat * cgnsdoms(nbkglobal)%rotRate(2)
2402  anglez = deltat * cgnsdoms(nbkglobal)%rotRate(3)
2403 
2404  ! Compute the unit vector in the direction of the rotation
2405  ! axis, which will be called the xi-direction.
2406 
2407  t = one / max(eps, sqrt(anglex**2 + angley**2 + anglez**2))
2408  xix = t * anglex
2409  xiy = t * angley
2410  xiz = t * anglez
2411 
2412  ! Determine the rotation angle in xi-direction and its sine
2413  ! and cosine. Due to the definition of the xi-direction this
2414  ! angle will always be positive.
2415 
2416  phi = xix * anglex + xiy * angley + xiz * anglez
2417  cosphi = cos(phi)
2418  sinphi = sin(phi)
2419 
2420  ! Loop over the cell centers.
2421 
2422  do k = 2, kl
2423  do j = 2, jl
2424  do i = 2, il
2425 
2426  ! Abbreviate the velocity components a bit easier.
2427 
2428  vvx = w(i, j, k, ivx)
2429  vvy = w(i, j, k, ivy)
2430  vvz = w(i, j, k, ivz)
2431 
2432  ! Determine the component of the velocity vector
2433  ! in xi direction and determine the direction eta,
2434  ! the direction of the velocity when the xi component
2435  ! is substracted.
2436 
2437  vxi = vvx * xix + vvy * xiy + vvz * xiz
2438 
2439  etax = vvx - vxi * xix
2440  etay = vvy - vxi * xiy
2441  etaz = vvz - vxi * xiz
2442 
2443  t = one / max(eps, sqrt(etax**2 + etay**2 + etaz**2))
2444  etax = t * etax
2445  etay = t * etay
2446  etaz = t * etaz
2447 
2448  ! Determine the velocity component in eta direction.
2449 
2450  veta = vvx * etax + vvy * etay + vvz * etaz
2451 
2452  ! Determine the unit vector in zeta-direction. This is
2453  ! the cross product of the unit vectors in xi and in
2454  ! eta-direction.
2455 
2456  zetax = xiy * etaz - xiz * etay
2457  zetay = xiz * etax - xix * etaz
2458  zetaz = xix * etay - xiy * etax
2459 
2460  ! Determine the velocity components in eta and zeta
2461  ! direction after the rotation.
2462 
2463  vzeta = veta * sinphi
2464  veta = veta * cosphi
2465 
2466  ! Compute the new Cartesian velocity components.
2467 
2468  w(i, j, k, ivx) = vxi * xix + veta * etax + vzeta * zetax
2469  w(i, j, k, ivy) = vxi * xiy + veta * etay + vzeta * zetay
2470  w(i, j, k, ivz) = vxi * xiz + veta * etaz + vzeta * zetaz
2471 
2472  end do
2473  end do
2474  end do
2475 
2476  end if rottest
2477 
2478  end do domains
2479  end do spectralloop
2480 
2481  end subroutine shiftsolution
2482 
2483  subroutine computeutau
2484  !
2485  ! Shell function to call computUTau on all blocks
2486  !
2487  use constants
2488  use blockpointers, only: ndom
2490  use iteration, only: groundlevel
2491  use utils, only: setpointers
2492  implicit none
2493  !
2494  ! Local variables.
2495  !
2496  integer(kind=intType) :: sps, nn
2497 
2498  ! Loop over the number of spectral solutions.
2499 
2500  spectralloop: do sps = 1, ntimeintervalsspectral
2501 
2502  ! Loop over the number of blocks.
2503 
2504  domains: do nn = 1, ndom
2505 
2506  ! Set the pointers for this block.
2507 
2508  call setpointers(nn, groundlevel, sps)
2509 
2510  call computeutau_block
2511 
2512  end do domains
2513 
2514  end do spectralloop
2515 
2516  end subroutine computeutau
2517 
2519  !
2520  ! computeUtau computes the skin friction velocity for the
2521  ! viscous subfaces. This data is only needed if wall functions
2522  ! are used.
2523  !
2524  use constants
2525  use blockpointers
2526  use inputphysics
2527  use inputtimespectral
2528  use iteration
2529  use turbcurvefits, only: curveupre
2530 
2531  implicit none
2532  !
2533  ! Local variables.
2534  !
2535  integer(kind=intType) :: mm, i, j
2536 
2537  real(kind=realtype) :: re, vvx, vvy, vvz, veln, veltmag
2538 
2539  real(kind=realtype), dimension(:, :, :), pointer :: ww, norm, uslip
2540  real(kind=realtype), dimension(:, :), pointer :: dd2wall, rrlv
2541  real(kind=realtype), dimension(:, :), pointer :: utau
2542 
2543  ! Return immediately if no wall functions must be used.
2544 
2545  if (.not. wallfunctions) return
2546 
2547  ! Loop over the viscous subfaces of this block.
2548 
2549  viscsubfaces: do mm = 1, nviscbocos
2550 
2551  ! Set a bunch of pointers depending on the face id to make
2552  ! a generic treatment possible.
2553 
2554  select case (bcfaceid(mm))
2555 
2556  case (imin)
2557  ww => w(2, 1:, 1:, :);
2558  dd2wall => d2wall(2, :, :); rrlv => rlv(2, 1:, 1:)
2559 
2560  !=========================================================
2561 
2562  case (imax)
2563  ww => w(il, 1:, 1:, :)
2564  dd2wall => d2wall(il, :, :); rrlv => rlv(il, 1:, 1:)
2565 
2566  !=========================================================
2567 
2568  case (jmin)
2569  ww => w(1:, 2, 1:, :)
2570  dd2wall => d2wall(:, 2, :); rrlv => rlv(1:, 2, 1:)
2571 
2572  !=========================================================
2573 
2574  case (jmax)
2575  ww => w(1:, jl, 1:, :)
2576  dd2wall => d2wall(:, jl, :); rrlv => rlv(1:, jl, 1:)
2577 
2578  !=========================================================
2579 
2580  case (kmin)
2581  ww => w(1:, 1:, 2, :)
2582  dd2wall => d2wall(:, :, 2); rrlv => rlv(1:, 1:, 2)
2583 
2584  !=========================================================
2585 
2586  case (kmax)
2587  ww => w(1:, 1:, kl, :)
2588  dd2wall => d2wall(:, :, kl); rrlv => rlv(1:, 1:, kl)
2589 
2590  end select
2591 
2592  ! Set the pointers for the unit outward normals, uSlip
2593  ! and utau to make the code more readable.
2594 
2595  norm => bcdata(mm)%norm
2596  uslip => bcdata(mm)%uSlip
2597  utau => viscsubface(mm)%utau
2598 
2599  ! Loop over the quadrilateral faces of the subface. Note
2600  ! that the nodal range of BCData must be used and not the
2601  ! cell range, because the latter may include the halo's in i
2602  ! and j-direction. The offset +1 is there, because inBeg and
2603  ! jnBeg refer to nodal ranges and not to cell ranges.
2604  ! Note that an offset of -1 must be used in dd2Wall, because
2605  ! the original array d2Wall starts at 2.
2606 
2607  do j = (bcdata(mm)%jnBeg + 1), bcdata(mm)%jnEnd
2608  do i = (bcdata(mm)%inBeg + 1), bcdata(mm)%inEnd
2609 
2610  ! Compute the velocity difference between the internal
2611  ! cell and the wall.
2612 
2613  vvx = ww(i, j, ivx) - uslip(i, j, 1)
2614  vvy = ww(i, j, ivy) - uslip(i, j, 2)
2615  vvz = ww(i, j, ivz) - uslip(i, j, 3)
2616 
2617  ! Compute the normal velocity of the internal cell.
2618 
2619  veln = vvx * norm(i, j, 1) + vvy * norm(i, j, 2) + vvz * norm(i, j, 3)
2620 
2621  ! Compute the magnitude of the tangential velocity.
2622 
2623  veltmag = max(eps, sqrt(vvx * vvx + vvy * vvy + vvz * vvz - veln * veln))
2624 
2625  ! Compute the Reynolds number. Note that an offset of -1
2626  ! must be used in dd2Wall, because the original array
2627  ! d2Wall starts at 2.
2628  ! Afterwards compute utau.
2629 
2630  re = ww(i, j, irho) * veltmag * dd2wall(i - 1, j - 1) / rrlv(i, j)
2631  utau(i, j) = veltmag / max(curveupre(re), eps)
2632 
2633  end do
2634  end do
2635 
2636  end do viscsubfaces
2637 
2638  end subroutine computeutau_block
2639 
2640  subroutine gridvelocitiesfinelevelpart1(useOldCoor, t, sps)
2641  !
2642  ! Shell function to call gridVelocitiesFineLevel on all blocks
2643  !
2644  use blockpointers
2645  use constants
2646  use inputtimespectral
2647  use iteration
2648  use utils, only: setpointers
2649  implicit none
2650  !
2651  ! Subroutine arguments.
2652  !
2653  integer(kind=intType), intent(in) :: sps
2654  logical, intent(in) :: useOldCoor
2655  real(kind=realtype), dimension(*), intent(in) :: t !
2656  ! Local variables.
2657  !
2658  integer(kind=intType) :: nn
2659 
2660  ! Loop over the number of blocks.
2661 
2662  domains: do nn = 1, ndom
2663 
2664  ! Set the pointers for this block.
2665 
2666  call setpointers(nn, groundlevel, sps)
2667  call gridvelocitiesfinelevelpart1_block(useoldcoor, t, sps)
2668 
2669  end do domains
2670 
2671  end subroutine gridvelocitiesfinelevelpart1
2672 
2673  subroutine gridvelocitiesfinelevelpart1_block(useOldCoor, t, sps)
2674  !
2675  ! gridVelocitiesFineLevel computes the grid velocities for
2676  ! the cell centers and the normal grid velocities for the faces
2677  ! of moving blocks for the currently finest grid, i.e.
2678  ! groundLevel. The velocities are computed at time t for
2679  ! spectral mode sps. If useOldCoor is .true. the velocities
2680  ! are determined using the unsteady time integrator in
2681  ! combination with the old coordinates; otherwise the analytic
2682  ! form is used.
2683  ! Now it is split up into two parts.
2684  ! First part calculate the grid velocity using FIRST order BDF.
2685  ! Second part calculate the surface normal and normal velocity.
2686  !
2687  use blockpointers
2688  use cgnsgrid
2689  use flowvarrefstate
2690  use inputmotion
2691  use inputunsteady
2692  use iteration
2693  use inputphysics
2694  use inputtsstabderiv
2695  use monitor
2696  use communication
2700  implicit none
2701  !
2702  ! Subroutine arguments.
2703  !
2704  integer(kind=intType), intent(in) :: sps
2705  logical, intent(in) :: useOldCoor
2706 
2707  real(kind=realtype), dimension(*), intent(in) :: t
2708  !
2709  ! Local variables.
2710  !
2711  integer(kind=intType) :: nn, mm
2712  integer(kind=intType) :: i, j, k, ii, iie, jje, kke
2713 
2714  real(kind=realtype) :: oneover4dt, oneover8dt
2715  real(kind=realtype) :: velxgrid, velygrid, velzgrid, ainf
2716  real(kind=realtype) :: velxgrid0, velygrid0, velzgrid0
2717 
2718  real(kind=realtype), dimension(3) :: sc, xc, xxc
2719  real(kind=realtype), dimension(3) :: rotcenter, rotrate
2720 
2721  real(kind=realtype), dimension(3) :: rotationpoint
2722  real(kind=realtype), dimension(3, 3) :: rotationmatrix, &
2723  derivrotationmatrix
2724 
2725  real(kind=realtype) :: tnew, told
2726  real(kind=realtype), dimension(:, :), pointer :: sface
2727  real(kind=realtype), dimension(:, :, :), pointer :: svelo
2728 
2729  real(kind=realtype), dimension(:, :, :), pointer :: xx, ss
2730  real(kind=realtype), dimension(:, :, :, :), pointer :: xxold
2731 
2732  real(kind=realtype) :: intervalmach, alphats, alphaincrement, &
2733  betats, betaincrement
2734  real(kind=realtype), dimension(3) :: veldir
2735  real(kind=realtype), dimension(3) :: refdirection
2736 
2737  ! Compute the mesh velocity from the given mesh Mach number.
2738 
2739  ! vel{x,y,z}Grid0 is the ACTUAL velocity you want at the
2740  ! geometry.
2741  ainf = sqrt(gammainf * pinf / rhoinf)
2742  velxgrid0 = (ainf * machgrid) * (-veldirfreestream(1))
2743  velygrid0 = (ainf * machgrid) * (-veldirfreestream(2))
2744  velzgrid0 = (ainf * machgrid) * (-veldirfreestream(3))
2745 
2746  ! Compute the derivative of the rotation matrix and the rotation
2747  ! point; needed for velocity due to the rigid body rotation of
2748  ! the entire grid. It is assumed that the rigid body motion of
2749  ! the grid is only specified if there is only 1 section present.
2750 
2751  call derivativerotmatrixrigid(derivrotationmatrix, rotationpoint, t(1))
2752 
2753  !compute the rotation matrix to update the velocities for the time
2754  !spectral stability derivative case...
2755 
2756  if (tsstability) then
2757  ! Determine the time values of the old and new time level.
2758  ! It is assumed that the rigid body rotation of the mesh is only
2759  ! used when only 1 section is present.
2760 
2762  told = tnew - t(1)
2763 
2764  if (tspmode .or. tsqmode .or. tsrmode) then
2765  ! Compute the rotation matrix of the rigid body rotation as
2766  ! well as the rotation point; the latter may vary in time due
2767  ! to rigid body translation.
2768 
2769  call rotmatrixrigidbody(tnew, told, rotationmatrix, rotationpoint)
2770 
2771  velxgrid0 = rotationmatrix(1, 1) * velxgrid0 &
2772  + rotationmatrix(1, 2) * velygrid0 &
2773  + rotationmatrix(1, 3) * velzgrid0
2774  velygrid0 = rotationmatrix(2, 1) * velxgrid0 &
2775  + rotationmatrix(2, 2) * velygrid0 &
2776  + rotationmatrix(2, 3) * velzgrid0
2777  velzgrid0 = rotationmatrix(3, 1) * velxgrid0 &
2778  + rotationmatrix(3, 2) * velygrid0 &
2779  + rotationmatrix(3, 3) * velzgrid0
2780 
2781  elseif (tsalphamode) then
2782  !Determine the alpha for this time instance
2783  alphaincrement = tsalpha(degreepolalpha, coefpolalpha, &
2786 
2787  alphats = alpha + alphaincrement
2788  !Determine the grid velocity for this alpha
2789  refdirection(:) = zero
2790  refdirection(1) = one
2791  call getdirvector(refdirection, alphats, beta, veldir, liftindex)
2792 
2793  !do I need to update the lift direction and drag direction as well?
2794  !set the effictive grid velocity for this time interval
2795  velxgrid0 = (ainf * machgrid) * (-veldir(1))
2796  velygrid0 = (ainf * machgrid) * (-veldir(2))
2797  velzgrid0 = (ainf * machgrid) * (-veldir(3))
2798 
2799  elseif (tsbetamode) then
2800 
2801  !Determine the alpha for this time instance
2802  betaincrement = tsbeta(degreepolbeta, coefpolbeta, &
2805 
2806  betats = beta + betaincrement
2807  !Determine the grid velocity for this alpha
2808  refdirection(:) = zero
2809  refdirection(1) = one
2810  call getdirvector(refdirection, alpha, betats, veldir, liftindex)
2811 
2812  !do I need to update the lift direction and drag direction as well?
2813  !set the effictive grid velocity for this time interval
2814  velxgrid0 = (ainf * machgrid) * (-veldir(1))
2815  velygrid0 = (ainf * machgrid) * (-veldir(2))
2816  velzgrid0 = (ainf * machgrid) * (-veldir(3))
2817  elseif (tsmachmode) then
2818  !determine the mach number at this time interval
2819  intervalmach = tsmach(degreepolmach, coefpolmach, &
2822  !set the effective grid velocity
2823  velxgrid0 = (ainf * (intervalmach + machgrid)) * (-veldirfreestream(1))
2824  velygrid0 = (ainf * (intervalmach + machgrid)) * (-veldirfreestream(2))
2825  velzgrid0 = (ainf * (intervalmach + machgrid)) * (-veldirfreestream(3))
2826 
2827  elseif (tsaltitudemode) then
2828  call terminate('gridVelocityFineLevel', 'altitude motion not yet implemented...')
2829  else
2830  call terminate('gridVelocityFineLevel', 'Not a recognized Stability Motion')
2831  end if
2832  end if
2833 
2834  testmoving: if (blockismoving) then
2835  ! REMOVED the rigid body rotation part for simplicity
2836 
2837  !
2838  ! The velocities must be determined via a finite
2839  ! difference formula using the coordinates of the old
2840  ! levels.
2841  !
2842  ! Set the coefficients for the time integrator and store
2843  ! the inverse of the physical nonDimensional time step,
2844  ! divided by 4 and 8, a bit easier.
2845 
2847  oneover4dt = fourth * timeref / deltat
2848  oneover8dt = half * oneover4dt
2849  !
2850  ! Grid velocities of the cell centers, including the
2851  ! 1st level halo cells.
2852  !
2853  ! Loop over the cells, including the 1st level halo's.
2854 
2855  do k = 1, ke
2856  do j = 1, je
2857  do i = 1, ie
2858 
2859  ! Using FIRST order BDF for all cases
2860  ! Refer to eq. 11b, found paper by C.Farhat http://dx.doi.org/10.1016/S0021-9991(03)00311-5
2861  ! Same applies for the velocities of the faces below. Theta(n+1) = 1, Theta(n) = -1 therfore
2862  ! it becoms a first order scheme.
2863 
2864  ! The velocity of the cell center is determined
2865  ! by a finite difference formula. First store
2866  ! the current coordinate, multiplied by 8 and
2867  ! coefTime(0) in sc.
2868 
2869  sc(1) = (x(i - 1, j - 1, k - 1, 1) + x(i, j - 1, k - 1, 1) &
2870  + x(i - 1, j, k - 1, 1) + x(i, j, k - 1, 1) &
2871  + x(i - 1, j - 1, k, 1) + x(i, j - 1, k, 1) &
2872  + x(i - 1, j, k, 1) + x(i, j, k, 1))
2873  sc(2) = (x(i - 1, j - 1, k - 1, 2) + x(i, j - 1, k - 1, 2) &
2874  + x(i - 1, j, k - 1, 2) + x(i, j, k - 1, 2) &
2875  + x(i - 1, j - 1, k, 2) + x(i, j - 1, k, 2) &
2876  + x(i - 1, j, k, 2) + x(i, j, k, 2))
2877  sc(3) = (x(i - 1, j - 1, k - 1, 3) + x(i, j - 1, k - 1, 3) &
2878  + x(i - 1, j, k - 1, 3) + x(i, j, k - 1, 3) &
2879  + x(i - 1, j - 1, k, 3) + x(i, j - 1, k, 3) &
2880  + x(i - 1, j, k, 3) + x(i, j, k, 3))
2881 
2882  ! Loop over the older levels to complete the
2883  ! finite difference formula.
2884 
2885  ii = 1 ! There was a loop over all old levels
2886  sc(1) = sc(1) + (xold(ii, i - 1, j - 1, k - 1, 1) &
2887  + xold(ii, i, j - 1, k - 1, 1) &
2888  + xold(ii, i - 1, j, k - 1, 1) &
2889  + xold(ii, i, j, k - 1, 1) &
2890  + xold(ii, i - 1, j - 1, k, 1) &
2891  + xold(ii, i, j - 1, k, 1) &
2892  + xold(ii, i - 1, j, k, 1) &
2893  + xold(ii, i, j, k, 1)) &
2894  * (-1.0_realtype)
2895  sc(2) = sc(2) + (xold(ii, i - 1, j - 1, k - 1, 2) &
2896  + xold(ii, i, j - 1, k - 1, 2) &
2897  + xold(ii, i - 1, j, k - 1, 2) &
2898  + xold(ii, i, j, k - 1, 2) &
2899  + xold(ii, i - 1, j - 1, k, 2) &
2900  + xold(ii, i, j - 1, k, 2) &
2901  + xold(ii, i - 1, j, k, 2) &
2902  + xold(ii, i, j, k, 2)) &
2903  * (-1.0_realtype)
2904  sc(3) = sc(3) + (xold(ii, i - 1, j - 1, k - 1, 3) &
2905  + xold(ii, i, j - 1, k - 1, 3) &
2906  + xold(ii, i - 1, j, k - 1, 3) &
2907  + xold(ii, i, j, k - 1, 3) &
2908  + xold(ii, i - 1, j - 1, k, 3) &
2909  + xold(ii, i, j - 1, k, 3) &
2910  + xold(ii, i - 1, j, k, 3) &
2911  + xold(ii, i, j, k, 3)) &
2912  * (-1.0_realtype)
2913 
2914  ! Divide by 8 delta t to obtain the correct
2915  ! velocities.
2916 
2917  s(i, j, k, 1) = sc(1) * oneover8dt
2918  s(i, j, k, 2) = sc(2) * oneover8dt
2919  s(i, j, k, 3) = sc(3) * oneover8dt
2920  end do
2921  end do
2922  end do
2923 
2924  !
2925  ! Velocities of the faces, vector.
2926  !
2927  ! Loop over the three directions.
2928 
2929  loopdir: do mm = 1, 3
2930 
2931  ! Set the upper boundaries depending on the direction.
2932 
2933  select case (mm)
2934  case (1_inttype) ! normals in i-direction
2935  iie = ie; jje = je; kke = ke
2936 
2937  case (2_inttype) ! normals in j-direction
2938  iie = je; jje = ie; kke = ke
2939 
2940  case (3_inttype) ! normals in k-direction
2941  iie = ke; jje = ie; kke = je
2942  end select
2943  !
2944  ! Face velocities in generalized i-direction.
2945  ! mm == 1: i-direction
2946  ! mm == 2: j-direction
2947  ! mm == 3: k-direction
2948  !
2949  do i = 0, iie
2950 
2951  ! Set the pointers for the coordinates, normals and
2952  ! normal velocities for this generalized i-plane.
2953  ! This depends on the value of mm.
2954 
2955  select case (mm)
2956  case (1_inttype) ! normals in i-direction
2957  xx => x(i, :, :, :); xxold => xold(:, i, :, :, :)
2958  svelo => sveloiale(i, :, :, :)
2959 
2960  case (2_inttype) ! normals in j-direction
2961  xx => x(:, i, :, :); xxold => xold(:, :, i, :, :)
2962  svelo => svelojale(:, i, :, :)
2963 
2964  case (3_inttype) ! normals in k-direction
2965  xx => x(:, :, i, :); xxold => xold(:, :, :, i, :)
2966  svelo => svelokale(:, :, i, :)
2967  end select
2968 
2969  ! Loop over the k and j-direction of this
2970  ! generalized i-face. Note that due to the usage of
2971  ! the pointers xx and xxOld an offset of +1 must be
2972  ! used in the coordinate arrays, because x and xOld
2973  ! originally start at 0 for the i, j and k indices.
2974  ! print *, mm
2975  do k = 1, kke
2976  do j = 1, jje
2977 
2978  ! The velocity of the face center is determined
2979  ! by a finite difference formula. First store
2980  ! the current coordinate, multiplied by 4 and
2981  ! coefTime(0) in sc.
2982 
2983  sc(1) = (xx(j + 1, k + 1, 1) + xx(j, k + 1, 1) &
2984  + xx(j + 1, k, 1) + xx(j, k, 1))
2985  sc(2) = (xx(j + 1, k + 1, 2) + xx(j, k + 1, 2) &
2986  + xx(j + 1, k, 2) + xx(j, k, 2))
2987  sc(3) = (xx(j + 1, k + 1, 3) + xx(j, k + 1, 3) &
2988  + xx(j + 1, k, 3) + xx(j, k, 3))
2989 
2990  ii = 1 ! There was a loop who looped over nOldLevels
2991  sc(1) = sc(1) + (xxold(ii, j + 1, k + 1, 1) &
2992  + xxold(ii, j, k + 1, 1) &
2993  + xxold(ii, j + 1, k, 1) &
2994  + xxold(ii, j, k, 1)) &
2995  * (-1.0_realtype)
2996  sc(2) = sc(2) + (xxold(ii, j + 1, k + 1, 2) &
2997  + xxold(ii, j, k + 1, 2) &
2998  + xxold(ii, j + 1, k, 2) &
2999  + xxold(ii, j, k, 2)) &
3000  * (-1.0_realtype)
3001  sc(3) = sc(3) + (xxold(ii, j + 1, k + 1, 3) &
3002  + xxold(ii, j, k + 1, 3) &
3003  + xxold(ii, j + 1, k, 3) &
3004  + xxold(ii, j, k, 3)) &
3005  * (-1.0_realtype)
3006 
3007  ! Determine the dot product of sc and the normal
3008  ! and divide by 4 deltaT to obtain the correct
3009  ! value of the normal velocity.
3010 
3011  svelo(j, k, 1) = sc(1) * oneover4dt
3012  svelo(j, k, 2) = sc(2) * oneover4dt
3013  svelo(j, k, 3) = sc(3) * oneover4dt
3014 
3015  ! if ((i.ge.2) .and. (i.le.3) .and. (j.ge.2) .and. (j.le.3) .and. (k.ge.2) .and. (k.le.3)) then
3016  ! print *, i,j,k, sVelo(j,k,:)
3017  ! print *, ' ', xx(j,k,:)
3018  ! print *, ' ', xxOld(1,j,k,:)
3019  ! end if
3020 
3021  end do
3022  end do
3023  end do
3024 
3025  end do loopdir
3026 
3027  end if testmoving
3028 
3029  end subroutine gridvelocitiesfinelevelpart1_block
3030 
3031  !
3032  ! Here begins the second part
3033  !
3034 
3035  subroutine gridvelocitiesfinelevelpart2(useOldCoor, t, sps)
3036  !
3037  ! Shell function to call gridVelocitiesFineLevel on all blocks
3038  !
3039  use blockpointers
3040  use constants
3041  use inputtimespectral
3042  use iteration
3043  use utils, only: setpointers
3044  implicit none
3045  !
3046  ! Subroutine arguments.
3047  !
3048  integer(kind=intType), intent(in) :: sps
3049  logical, intent(in) :: useOldCoor
3050  real(kind=realtype), dimension(*), intent(in) :: t !
3051  ! Local variables.
3052  !
3053  integer(kind=intType) :: nn
3054 
3055  ! Loop over the number of blocks.
3056 
3057  domains: do nn = 1, ndom
3058 
3059  ! Set the pointers for this block.
3060 
3061  call setpointers(nn, groundlevel, sps)
3062  call gridvelocitiesfinelevelpart2_block(useoldcoor, t, sps)
3063 
3064  end do domains
3065 
3066  end subroutine gridvelocitiesfinelevelpart2
3067 
3068  subroutine gridvelocitiesfinelevelpart2_block(useOldCoor, t, sps)
3069  !
3070  use blockpointers
3071  use cgnsgrid
3072  use flowvarrefstate
3073  use inputmotion
3074  use inputunsteady
3075  use iteration
3076  use inputphysics
3077  use inputtsstabderiv
3078  use monitor
3079  use communication
3080  implicit none
3081  !
3082  ! Subroutine arguments.
3083  !
3084  integer(kind=intType), intent(in) :: sps
3085  logical, intent(in) :: useOldCoor
3086  real(kind=realtype), dimension(*), intent(in) :: t
3087  !
3088  ! Local variables.
3089  !
3090  integer(kind=intType) :: nn, mm
3091  integer(kind=intType) :: i, j, k, ii, iie, jje, kke
3092 
3093  real(kind=realtype) :: oneover4dt, oneover8dt
3094  real(kind=realtype), dimension(3) :: sc, xc, xxc
3095  real(kind=realtype), dimension(:, :), pointer :: sface
3096  real(kind=realtype), dimension(:, :, :), pointer :: svelo
3097  real(kind=realtype), dimension(:, :, :), pointer :: xx, ss
3098  real(kind=realtype), dimension(:, :, :, :), pointer :: xxold
3099 
3100  testmoving: if (blockismoving) then
3101  !
3102  ! Normal grid velocities of the faces.
3103  !
3104  ! Loop over the three directions.
3105 
3106  loopdir: do mm = 1, 3
3107 
3108  ! Set the upper boundaries depending on the direction.
3109 
3110  select case (mm)
3111  case (1_inttype) ! normals in i-direction
3112  iie = ie; jje = je; kke = ke
3113 
3114  case (2_inttype) ! normals in j-direction
3115  iie = je; jje = ie; kke = ke
3116 
3117  case (3_inttype) ! normals in k-direction
3118  iie = ke; jje = ie; kke = je
3119  end select
3120  !
3121  ! Normal grid velocities in generalized i-direction.
3122  ! Mm == 1: i-direction
3123  ! mm == 2: j-direction
3124  ! mm == 3: k-direction
3125  !
3126  do i = 0, iie
3127 
3128  ! Set the pointers for the coordinates, normals and
3129  ! normal velocities for this generalized i-plane.
3130  ! This depends on the value of mm.
3131 
3132  select case (mm)
3133  case (1_inttype) ! normals in i-direction
3134  ss => si(i, :, :, :); sface => sfacei(i, :, :)
3135  svelo => sveloiale(i, :, :, :)
3136 
3137  case (2_inttype) ! normals in j-direction
3138  ss => sj(:, i, :, :); sface => sfacej(:, i, :)
3139  svelo => svelojale(:, i, :, :)
3140 
3141  case (3_inttype) ! normals in k-direction
3142  ss => sk(:, :, i, :); sface => sfacek(:, :, i)
3143  svelo => svelokale(:, :, i, :)
3144  end select
3145 
3146  ! Loop over the k and j-direction of this
3147  ! generalized i-face. Note that due to the usage of
3148  ! the pointers xx and xxOld an offset of +1 must be
3149  ! used in the coordinate arrays, because x and xOld
3150  ! originally start at 0 for the i, j and k indices.
3151 
3152  do k = 1, kke
3153  do j = 1, jje
3154 
3155  ! Determine the dot product of sc and the normal
3156  ! and divide by 4 deltaT to obtain the correct
3157  ! value of the normal velocity.
3158 
3159  sface(j, k) = svelo(j, k, 1) * ss(j, k, 1) &
3160  + svelo(j, k, 2) * ss(j, k, 2) &
3161  + svelo(j, k, 3) * ss(j, k, 3)
3162 
3163  end do
3164  end do
3165  end do
3166 
3167  end do loopdir
3168  end if testmoving
3169 
3170  end subroutine gridvelocitiesfinelevelpart2_block
3171 
3172  subroutine utauwf(rFilv)
3173  !
3174  ! utauWF substitutes the wall shear stress with values from a
3175  ! look-up table, if desired.
3176  !
3177  use constants
3178  use blockpointers, only: si, sj, sk, fw, rlv, d2wall, w, bcdata, viscsubface, &
3179  ie, je, ke, il, jl, kl, nviscbocos, bcfaceid
3180  use inputphysics, only: wallfunctions
3181  use turbcurvefits, only: curveupre
3182  implicit none
3183  !
3184  ! Subroutine argument.
3185  !
3186  real(kind=realtype), intent(in) :: rfilv
3187  !
3188  ! Local variables.
3189  !
3190  integer(kind=intType) :: i, j, nn
3191 
3192  real(kind=realtype) :: fact
3193  real(kind=realtype) :: tauxx, tauyy, tauzz
3194  real(kind=realtype) :: tauxy, tauxz, tauyz
3195  real(kind=realtype) :: rbar, ubar, vbar, wbar, vvx, vvy, vvz
3196  real(kind=realtype) :: fmx, fmy, fmz, frhoe
3197  real(kind=realtype) :: veln, velnx, velny, velnz, tx, ty, tz
3198  real(kind=realtype) :: veltx, velty, veltz, veltmag
3199  real(kind=realtype) :: txnx, txny, txnz, tynx, tyny, tynz
3200  real(kind=realtype) :: tznx, tzny, tznz
3201  real(kind=realtype) :: tautn, tauwall, utau, re
3202 
3203  real(kind=realtype), dimension(:, :, :), pointer :: ww1, ww2
3204  real(kind=realtype), dimension(:, :, :), pointer :: ss, rres
3205  real(kind=realtype), dimension(:, :, :), pointer :: norm
3206  real(kind=realtype), dimension(:, :), pointer :: rrlv2, dd2wall2
3207 
3208  ! Return immediately if no wall functions must be used.
3209 
3210  if (.not. wallfunctions) return
3211 
3212  ! Loop over the viscous subfaces of this block.
3213 
3214  viscsubfaces: do nn = 1, nviscbocos
3215 
3216  ! Set a bunch of variables depending on the face id to make
3217  ! a generic treatment possible.
3218 
3219  select case (bcfaceid(nn))
3220 
3221  case (imin)
3222  fact = -one
3223 
3224  ss => si(1, :, :, :); rres => fw(2, 1:, 1:, :)
3225  ww2 => w(2, 1:, 1:, :); ww1 => w(1, 1:, 1:, :)
3226  dd2wall2 => d2wall(2, :, :); rrlv2 => rlv(2, 1:, 1:)
3227 
3228  !===========================================================
3229 
3230  case (imax)
3231  fact = one
3232 
3233  ss => si(il, :, :, :); rres => fw(il, 1:, 1:, :)
3234  ww2 => w(il, 1:, 1:, :); ww1 => w(ie, 1:, 1:, :)
3235  dd2wall2 => d2wall(il, :, :); rrlv2 => rlv(il, 1:, 1:)
3236 
3237  !===========================================================
3238 
3239  case (jmin)
3240  fact = -one
3241 
3242  ss => sj(:, 1, :, :); rres => fw(1:, 2, 1:, :)
3243  ww2 => w(1:, 2, 1:, :); ww1 => w(1:, 1, 1:, :)
3244  dd2wall2 => d2wall(:, 2, :); rrlv2 => rlv(1:, 2, 1:)
3245 
3246  !===========================================================
3247 
3248  case (jmax)
3249  fact = one
3250 
3251  ss => sj(:, jl, :, :); rres => fw(1:, jl, 1:, :)
3252  ww2 => w(1:, jl, 1:, :); ww1 => w(1:, je, 1:, :)
3253  dd2wall2 => d2wall(:, jl, :); rrlv2 => rlv(1:, jl, 1:)
3254 
3255  !===========================================================
3256 
3257  case (kmin)
3258  fact = -one
3259 
3260  ss => sk(:, :, 1, :); rres => fw(1:, 1:, 2, :)
3261  ww2 => w(1:, 1:, 2, :); ww1 => w(1:, 1:, 1, :)
3262  dd2wall2 => d2wall(:, :, 2); rrlv2 => rlv(1:, 1:, 2)
3263 
3264  !===========================================================
3265 
3266  case (kmax)
3267  fact = one
3268 
3269  ss => sk(:, :, kl, :); rres => fw(1:, 1:, kl, :)
3270  ww2 => w(1:, 1:, kl, :); ww1 => w(1:, 1:, ke, :)
3271  dd2wall2 => d2wall(:, :, kl); rrlv2 => rlv(1:, 1:, kl)
3272 
3273  end select
3274 
3275  ! Set the pointer for the unit outward normals.
3276 
3277  norm => bcdata(nn)%norm
3278 
3279  ! Loop over the quadrilateral faces of the subface. Note
3280  ! that the nodal range of BCData must be used and not the
3281  ! cell range, because the latter may include the halo's in i
3282  ! and j-direction. The offset +1 is there, because inBeg and
3283  ! jnBeg refer to nodal ranges and not to cell ranges.
3284 
3285  do j = (bcdata(nn)%jnBeg + 1), bcdata(nn)%jnEnd
3286  do i = (bcdata(nn)%inBeg + 1), bcdata(nn)%inEnd
3287 
3288  ! Store the viscous stress tensor a bit easier.
3289 
3290  tauxx = viscsubface(nn)%tau(i, j, 1)
3291  tauyy = viscsubface(nn)%tau(i, j, 2)
3292  tauzz = viscsubface(nn)%tau(i, j, 3)
3293  tauxy = viscsubface(nn)%tau(i, j, 4)
3294  tauxz = viscsubface(nn)%tau(i, j, 5)
3295  tauyz = viscsubface(nn)%tau(i, j, 6)
3296 
3297  ! Compute the velocities at the wall face; these are only
3298  ! non-zero for moving a block. Also compute the density,
3299  ! which is needed to compute the wall shear stress via
3300  ! wall functions.
3301 
3302  rbar = half * (ww2(i, j, irho) + ww1(i, j, irho))
3303  ubar = half * (ww2(i, j, ivx) + ww1(i, j, ivx))
3304  vbar = half * (ww2(i, j, ivy) + ww1(i, j, ivy))
3305  wbar = half * (ww2(i, j, ivz) + ww1(i, j, ivz))
3306 
3307  ! Compute the velocity difference between the internal cell
3308  ! and the wall.
3309 
3310  vvx = ww2(i, j, ivx) - ubar
3311  vvy = ww2(i, j, ivy) - vbar
3312  vvz = ww2(i, j, ivz) - wbar
3313 
3314  ! Compute the normal velocity of the internal cell.
3315 
3316  veln = vvx * norm(i, j, 1) + vvy * norm(i, j, 2) + vvz * norm(i, j, 3)
3317  velnx = veln * norm(i, j, 1)
3318  velny = veln * norm(i, j, 2)
3319  velnz = veln * norm(i, j, 3)
3320 
3321  ! Compute the tangential velocity, its magnitude and its
3322  ! unit vector of the internal cell.
3323 
3324  veltx = vvx - velnx
3325  velty = vvy - velny
3326  veltz = vvz - velnz
3327 
3328  veltmag = max(eps, sqrt(veltx**2 + velty**2 + veltz**2))
3329 
3330  tx = veltx / veltmag
3331  ty = velty / veltmag
3332  tz = veltz / veltmag
3333 
3334  ! Compute some coefficients needed for the transformation
3335  ! between the cartesian frame and the frame defined by the
3336  ! tangential direction (tx,ty,tz) and the normal direction.
3337  ! The minus sign is present, because for this transformation
3338  ! the normal direction should be inward pointing and norm
3339  ! is outward pointing.
3340 
3341  txnx = -tx * norm(i, j, 1)
3342  txny = -tx * norm(i, j, 2)
3343  txnz = -tx * norm(i, j, 3)
3344 
3345  tynx = -ty * norm(i, j, 1)
3346  tyny = -ty * norm(i, j, 2)
3347  tynz = -ty * norm(i, j, 3)
3348 
3349  tznx = -tz * norm(i, j, 1)
3350  tzny = -tz * norm(i, j, 2)
3351  tznz = -tz * norm(i, j, 3)
3352 
3353  ! Compute the tn component of the wall shear stress
3354  ! tensor. Normally this is the only nonzero shear
3355  ! stress component in the t-n frame.
3356 
3357  tautn = tauxx * txnx + tauyy * tyny + tauzz * tznz &
3358  + tauxy * (txny + tynx) &
3359  + tauxz * (txnz + tznx) &
3360  + tauyz * (tynz + tzny)
3361 
3362  ! Compute the Reynolds number using the velocity, density,
3363  ! laminar viscosity and wall distance. Note that an offset
3364  ! of -1 must be used in dd2Wall2, because the original array
3365  ! d2Wall starts at 2.
3366 
3367  re = ww2(i, j, irho) * veltmag * dd2wall2(i - 1, j - 1) / rrlv2(i, j)
3368 
3369  ! Determine the friction velocity from the table and
3370  ! compute the wall shear stress from it.
3371 
3372  utau = veltmag / max(curveupre(re), eps)
3373  tauwall = rbar * utau * utau
3374 
3375  ! Compute the correction to the wall shear stress tautn and
3376  ! transform this correction back to the cartesian frame.
3377  ! Take rFilv into account, such that the correction to the
3378  ! stress tensor is computed correctly.
3379 
3380  tautn = rfilv * tauwall - tautn
3381 
3382  tauxx = two * tautn * txnx
3383  tauyy = two * tautn * tyny
3384  tauzz = two * tautn * tznz
3385 
3386  tauxy = tautn * (txny + tynx)
3387  tauxz = tautn * (txnz + tznx)
3388  tauyz = tautn * (tynz + tzny)
3389 
3390  ! Compute the correction to the viscous flux at the wall.
3391 
3392  fmx = tauxx * ss(i, j, 1) + tauxy * ss(i, j, 2) &
3393  + tauxz * ss(i, j, 3)
3394  fmy = tauxy * ss(i, j, 1) + tauyy * ss(i, j, 2) &
3395  + tauyz * ss(i, j, 3)
3396  fmz = tauxz * ss(i, j, 1) + tauyz * ss(i, j, 2) &
3397  + tauzz * ss(i, j, 3)
3398  frhoe = (ubar * tauxx + vbar * tauxy + wbar * tauxz) * ss(i, j, 1) &
3399  + (ubar * tauxy + vbar * tauyy + wbar * tauyz) * ss(i, j, 2) &
3400  + (ubar * tauxz + vbar * tauyz + wbar * tauzz) * ss(i, j, 3)
3401 
3402  ! Add them to the residual. Note that now the factor rFilv
3403  ! is already taken into account via tau. Fact is present to
3404  ! take inward/outward pointing normals into account
3405 
3406  rres(i, j, imx) = rres(i, j, imx) - fact * fmx
3407  rres(i, j, imy) = rres(i, j, imy) - fact * fmy
3408  rres(i, j, imz) = rres(i, j, imz) - fact * fmz
3409  rres(i, j, irhoe) = rres(i, j, irhoe) - fact * frhoe
3410 
3411  ! Store the friction velocity for later use.
3412 
3413  viscsubface(nn)%utau(i, j) = utau
3414 
3415  ! Also add the correction to the wall stress tensor.
3416 
3417  viscsubface(nn)%tau(i, j, 1) = &
3418  viscsubface(nn)%tau(i, j, 1) + tauxx
3419  viscsubface(nn)%tau(i, j, 2) = &
3420  viscsubface(nn)%tau(i, j, 2) + tauyy
3421  viscsubface(nn)%tau(i, j, 3) = &
3422  viscsubface(nn)%tau(i, j, 3) + tauzz
3423  viscsubface(nn)%tau(i, j, 4) = &
3424  viscsubface(nn)%tau(i, j, 4) + tauxy
3425  viscsubface(nn)%tau(i, j, 5) = &
3426  viscsubface(nn)%tau(i, j, 5) + tauxz
3427  viscsubface(nn)%tau(i, j, 6) = &
3428  viscsubface(nn)%tau(i, j, 6) + tauyz
3429  end do
3430  end do
3431 
3432  end do viscsubfaces
3433 
3434  end subroutine utauwf
3435 
3436 #ifndef USE_TAPENADE
3438  !
3439  ! slipVelocitiesCoarseLevels determines the slip velocities
3440  ! for the given spectral solution starting from the known
3441  ! velocities on the finer level.
3442  !
3443  use constants
3444  use blockpointers
3445  use iteration
3446  use utils, only: setpointers
3447  implicit none
3448  !
3449  ! Subroutine arguments.
3450  !
3451  integer(kind=intType), intent(in) :: sps
3452  !
3453  ! Local variables.
3454  !
3455  integer(kind=intType) :: i, j, iiMax, jjMax
3456  integer(kind=intType) :: if1, if2, jf1, jf2
3457  integer(kind=intType) :: nLevels, level, levm1, nn, mm
3458 
3459  integer(kind=intType), dimension(:, :), pointer :: iFine, jFine
3460 
3461  real(kind=realtype), dimension(:, :, :), pointer :: uslip
3462  real(kind=realtype), dimension(:, :, :), pointer :: uslipfine
3463 
3464  ! Determine the number of multigrid levels.
3465 
3466  nlevels = ubound(flowdoms, 2)
3467 
3468  ! Loop over coarser grid levels, where ground level is considered
3469  ! as the finest grid.
3470 
3471  levelloop: do level = (groundlevel + 1), nlevels
3472 
3473  ! Set levm1 for the finer level.
3474 
3475  levm1 = level - 1
3476 
3477  ! Loop over the number of local blocks.
3478 
3479  domains: do nn = 1, ndom
3480 
3481  ! Set the pointers to the coarse block.
3482 
3483  call setpointers(nn, level, sps)
3484 
3485  ! Loop over the number of viscous subfaces.
3486 
3487  bocoloop: do mm = 1, nviscbocos
3488 
3489  ! Set the pointers for uSlip and uSlipFine to make the
3490  ! code more readable.
3491 
3492  uslip => bcdata(mm)%uSlip
3493  uslipfine => flowdoms(nn, levm1, sps)%BCData(mm)%uSlip
3494 
3495  ! Determine the grid face on which the subface is located
3496  ! and set some variables accordingly.
3497 
3498  select case (bcfaceid(mm))
3499 
3500  case (imin, imax)
3501  iimax = jl; jjmax = kl
3502  ifine => mgjfine; jfine => mgkfine
3503 
3504  case (jmin, jmax)
3505  iimax = il; jjmax = kl
3506  ifine => mgifine; jfine => mgkfine
3507 
3508  case (kmin, kmax)
3509  iimax = il; jjmax = jl
3510  ifine => mgifine; jfine => mgjfine
3511 
3512  end select
3513 
3514  ! Loop over the number of faces of the viscous subface.
3515  ! First in the generalized j-direction.
3516 
3517  do j = bcdata(mm)%jcBeg, bcdata(mm)%jcEnd
3518 
3519  ! Determine the two children in this direction.
3520  ! Take care of the halo's, as this info is only
3521  ! available for owned cells.
3522 
3523  if (j < 2) then
3524  jf1 = 1; jf2 = 1
3525  else if (j > jjmax) then
3526  jf1 = jfine(jjmax, 2) + 1; jf2 = jf1
3527  else
3528  jf1 = jfine(j, 1); jf2 = jfine(j, 2)
3529  end if
3530 
3531  ! Loop in the generalized i-direction.
3532 
3533  do i = bcdata(mm)%icBeg, bcdata(mm)%icEnd
3534 
3535  ! Determine the two children in this direction.
3536  ! Same story as in j-direction.
3537 
3538  if (i < 2) then
3539  if1 = 1; if2 = 1
3540  else if (i > iimax) then
3541  if1 = ifine(iimax, 2) + 1; if2 = if1
3542  else
3543  if1 = ifine(i, 1); if2 = ifine(i, 2)
3544  end if
3545 
3546  ! Average the fine grid velocities to the
3547  ! coarse grid velocities.
3548 
3549  uslip(i, j, 1) = fourth * (uslipfine(if1, jf1, 1) &
3550  + uslipfine(if2, jf1, 1) &
3551  + uslipfine(if1, jf2, 1) &
3552  + uslipfine(if2, jf2, 1))
3553 
3554  uslip(i, j, 2) = fourth * (uslipfine(if1, jf1, 2) &
3555  + uslipfine(if2, jf1, 2) &
3556  + uslipfine(if1, jf2, 2) &
3557  + uslipfine(if2, jf2, 2))
3558 
3559  uslip(i, j, 3) = fourth * (uslipfine(if1, jf1, 3) &
3560  + uslipfine(if2, jf1, 3) &
3561  + uslipfine(if1, jf2, 3) &
3562  + uslipfine(if2, jf2, 3))
3563  end do
3564  end do
3565 
3566  end do bocoloop
3567  end do domains
3568  end do levelloop
3569 
3570  end subroutine slipvelocitiescoarselevels
3571 #endif
3572 
3574  !
3575  ! gridVelocitiesCoarseLevels computes the grid velocities for
3576  ! the cell centers and the normal grid velocities for the faces
3577  ! of moving blocks on the coarser grid levels. GroundLevel is
3578  ! considered the fine grid level.
3579  !
3580  use constants
3581  use blockpointers
3582  use iteration
3583  use utils, only: setpointers
3584  implicit none
3585  !
3586  ! Subroutine arguments.
3587  !
3588  integer(kind=intType), intent(in) :: sps
3589  !
3590  ! Local variables.
3591  !
3592  integer(kind=intType) :: nLevels, level, levm1, nn, mm
3593  integer(kind=intType) :: i, j, k, iie, jje, kke
3594  integer(kind=intType) :: ii, ii1, jj, jj1, kk, kk1
3595 
3596  integer(kind=intType), dimension(:, :), pointer :: iFine, jFine
3597  integer(kind=intType), dimension(:, :), pointer :: kFine
3598 
3599  real(kind=realtype) :: jjweight, kkweight, weight
3600 
3601  real(kind=realtype), dimension(:), pointer :: jweight, kweight
3602 
3603  real(kind=realtype), dimension(:, :), pointer :: sfine, sface
3604  real(kind=realtype), dimension(:, :, :, :), pointer :: sf
3605 
3606  ! Loop over the number of coarse grid levels, starting at
3607  ! groundLevel+1,
3608 
3609  nlevels = ubound(flowdoms, 2)
3610  levelloop: do level = groundlevel + 1, nlevels
3611 
3612  ! Loop over the number of local blocks.
3613 
3614  domains: do nn = 1, ndom
3615 
3616  ! Set the pointers for this block.
3617 
3618  call setpointers(nn, level, sps)
3619 
3620  ! Check for a moving block. As it is possible that in a
3621  ! multidisicplinary environment additional grid velocities
3622  ! are set, the test should be done on addGridVelocities
3623  ! and not on blockIsMoving.
3624 
3625  testmoving: if (addgridvelocities) then
3626  !
3627  ! Grid velocities of the cell centers, including the 1st
3628  ! level halo cells. These are determined by accumulating
3629  ! the fine grid values. At the end the internal halo's are
3630  ! communicated to obtain the correct values.
3631  !
3632  levm1 = level - 1
3633 
3634  ! Set the pointer sf to the cell velocities on the fine mesh.
3635 
3636  sf => flowdoms(nn, levm1, sps)%s
3637 
3638  ! Loop over the cells, including the 1st level halo's.
3639  ! The indices kk, kk1 contain the corresponding fine
3640  ! grid indices in k-direction. Idem for jj, jj1, ii
3641  ! and ii1.
3642 
3643  do k = 1, ke
3644  if (k == 1) then
3645  kk = 1; kk1 = 1
3646  else if (k == ke) then
3647  kk = flowdoms(nn, levm1, sps)%ke; kk1 = kk
3648  else
3649  kk = mgkfine(k, 1); kk1 = mgkfine(k, 2)
3650  end if
3651 
3652  do j = 1, je
3653  if (j == 1) then
3654  jj = 1; jj1 = 1
3655  else if (j == je) then
3656  jj = flowdoms(nn, levm1, sps)%je; jj1 = jj
3657  else
3658  jj = mgjfine(j, 1); jj1 = mgjfine(j, 2)
3659  end if
3660 
3661  do i = 1, ie
3662  if (i == 1) then
3663  ii = 1; ii1 = 1
3664  else if (i == ie) then
3665  ii = flowdoms(nn, levm1, sps)%ie; ii1 = ii
3666  else
3667  ii = mgifine(i, 1); ii1 = mgifine(i, 2)
3668  end if
3669 
3670  ! Determine the coarse grid velocity by
3671  ! averaging the fine grid values.
3672 
3673  s(i, j, k, 1) = (sf(ii1, jj1, kk1, 1) + sf(ii, jj1, kk1, 1) &
3674  + sf(ii1, jj, kk1, 1) + sf(ii, jj, kk1, 1) &
3675  + sf(ii1, jj1, kk, 1) + sf(ii, jj1, kk, 1) &
3676  + sf(ii1, jj, kk, 1) + sf(ii, jj, kk, 1)) &
3677  * eighth
3678  s(i, j, k, 2) = (sf(ii1, jj1, kk1, 2) + sf(ii, jj1, kk1, 2) &
3679  + sf(ii1, jj, kk1, 2) + sf(ii, jj, kk1, 2) &
3680  + sf(ii1, jj1, kk, 2) + sf(ii, jj1, kk, 2) &
3681  + sf(ii1, jj, kk, 2) + sf(ii, jj, kk, 2)) &
3682  * eighth
3683  s(i, j, k, 3) = (sf(ii1, jj1, kk1, 3) + sf(ii, jj1, kk1, 3) &
3684  + sf(ii1, jj, kk1, 3) + sf(ii, jj, kk1, 3) &
3685  + sf(ii1, jj1, kk, 3) + sf(ii, jj1, kk, 3) &
3686  + sf(ii1, jj, kk, 3) + sf(ii, jj, kk, 3)) &
3687  * eighth
3688  end do
3689  end do
3690  end do
3691  !
3692  ! Normal grid velocities of the faces.
3693  !
3694  ! Loop over the three directions.
3695 
3696  loopcoarsedir: do mm = 1, 3
3697 
3698  ! Set some values depending on the situation.
3699 
3700  select case (mm)
3701 
3702  case (1_inttype) ! Normals in i-direction
3703  iie = ie; jje = je; kke = ke
3704  ifine => mgifine; jfine => mgjfine; kfine => mgkfine
3705  jweight => mgjweight; kweight => mgkweight
3706 
3707  case (2_inttype) ! Normals in j-direction
3708  iie = je; jje = ie; kke = ke
3709  ifine => mgjfine; jfine => mgifine; kfine => mgkfine
3710  jweight => mgiweight; kweight => mgkweight
3711 
3712  case (3_inttype) ! Normals in k-direction
3713  iie = ke; jje = ie; kke = je
3714  ifine => mgkfine; jfine => mgifine; kfine => mgjfine
3715  jweight => mgiweight; kweight => mgjweight
3716 
3717  end select
3718  !
3719  ! Normal grid velocities in generalized i-direction.
3720  ! mm == 1: i-direction
3721  ! mm == 2: j-direction
3722  ! mm == 3: k-direction
3723  !
3724  do i = 0, iie
3725 
3726  ! Determine the i-index of the corresponding plane on
3727  ! the fine grid. Note that halo planes are not entirely
3728  ! correct. This is not really a problem.
3729 
3730  if (i < 2) then
3731  ii = i
3732  else if (i < iie) then
3733  ii = ifine(i, 2)
3734  else
3735  ii = ifine(iie - 1, 2) + 1
3736  end if
3737 
3738  ! Set the pointers for sFine and sFace, which will
3739  ! contain the mesh velocities for this particular
3740  ! plane. The index depends on the value of mm.
3741 
3742  select case (mm)
3743  case (1_inttype)
3744  sfine => flowdoms(nn, levm1, sps)%sFaceI(ii, :, :)
3745  sface => sfacei(i, :, :)
3746  case (2_inttype)
3747  sfine => flowdoms(nn, levm1, sps)%sFaceJ(:, ii, :)
3748  sface => sfacej(:, i, :)
3749  case (3_inttype)
3750  sfine => flowdoms(nn, levm1, sps)%sFaceK(:, :, ii)
3751  sface => sfacek(:, :, i)
3752  end select
3753 
3754  ! Loop over the k and j faces for this general i-plane.
3755  ! Again the halo's are not entirely correct. Kk, kk1,
3756  ! jj and jj1 are the children in k and j-direction
3757  ! respectively.
3758 
3759  do k = 1, kke
3760  if (k == 1) then
3761  kk = 1; kk1 = 1
3762  kkweight = kweight(2)
3763  else if (k == kke) then
3764  kk = kfine(kke - 1, 2) + 1; kk1 = kk
3765  kkweight = kweight(kke - 1)
3766  else
3767  kk = kfine(k, 1); kk1 = kfine(k, 2)
3768  kweight = kweight(k)
3769  end if
3770 
3771  do j = 1, jje
3772  if (j == 1) then
3773  jj = 1; jj1 = 1
3774  jjweight = jweight(2)
3775  else if (j == jje) then
3776  jj = jfine(jje - 1, 2) + 1; jj1 = jj
3777  jweight = jweight(jje - 1)
3778  else
3779  jj = jfine(j, 1); jj1 = jfine(j, 2)
3780  jjweight = jweight(j)
3781  end if
3782 
3783  ! Determine the coarse grid normal velocity.
3784  ! Take the averaging weight into account; for
3785  ! a normal coarsening this weight is 1.0.
3786 
3787  weight = kkweight * jjweight
3788  sface(j, k) = weight * (sfine(jj1, kk1) &
3789  + sfine(jj, kk1) &
3790  + sfine(jj1, kk) &
3791  + sfine(jj, kk))
3792  end do
3793  end do
3794  end do
3795 
3796  end do loopcoarsedir
3797  end if testmoving
3798  end do domains
3799 
3800  ! Exchange the cell centered velocities.
3801 
3802  call exchangecellgridvelocities(level, sps)
3803 
3804  end do levelloop
3805 
3806  end subroutine gridvelocitiescoarselevels
3807 
3808  ! ==================================================================
3809 
3810  subroutine exchangecellgridvelocities(level, sps)
3811  !
3812  ! exchangeCellGridVelocities exchanges the grid velocities in
3813  ! the cell centers for the given grid level and spectral
3814  ! solution.
3815  !
3816  use constants
3817  use block
3818  use communication
3819  implicit none
3820  !
3821  ! Subroutine arguments.
3822  !
3823  integer(kind=intType), intent(in) :: level, sps
3824  !
3825  ! Local variables.
3826  !
3827  integer :: size, procID, ierr, index
3828  integer, dimension(mpi_status_size) :: mpiStatus
3829 
3830  integer(kind=intType) :: i, j, ii, jj
3831  integer(kind=intType) :: d1, i1, j1, k1, d2, i2, j2, k2
3832 
3833  real(kind=realtype) :: alp
3834  real(kind=realtype), dimension(3) :: vv
3835 
3836  ! The 1 to 1 communication.
3837  !
3838  ! Send the variables. The data is first copied into
3839  ! the send buffer after which the buffer is sent asap.
3840 
3841  ii = 1
3842  sends: do i = 1, commpatterncell_1st(level)%nProcSend
3843 
3844  ! Store the processor id and the size of the message
3845  ! a bit easier.
3846 
3847  procid = commpatterncell_1st(level)%sendProc(i)
3848  size = 3 * commpatterncell_1st(level)%nSend(i)
3849 
3850  ! Copy the data in the correct part of the send buffer.
3851 
3852  jj = ii
3853  do j = 1, commpatterncell_1st(level)%nSend(i)
3854 
3855  ! Store the block id and the indices of the donor
3856  ! a bit easier.
3857 
3858  d1 = commpatterncell_1st(level)%sendList(i)%block(j)
3859  i1 = commpatterncell_1st(level)%sendList(i)%indices(j, 1)
3860  j1 = commpatterncell_1st(level)%sendList(i)%indices(j, 2)
3861  k1 = commpatterncell_1st(level)%sendList(i)%indices(j, 3)
3862 
3863  ! Store the grid velocities in sendBuffer, if they
3864  ! are allocated. Otherwise they are simply zero.
3865 
3866  if (flowdoms(d1, level, sps)%addGridVelocities) then
3867  sendbuffer(jj) = flowdoms(d1, level, sps)%s(i1, j1, k1, 1)
3868  sendbuffer(jj + 1) = flowdoms(d1, level, sps)%s(i1, j1, k1, 2)
3869  sendbuffer(jj + 2) = flowdoms(d1, level, sps)%s(i1, j1, k1, 3)
3870  else
3871  sendbuffer(jj) = zero
3872  sendbuffer(jj + 1) = zero
3873  sendbuffer(jj + 2) = zero
3874  end if
3875 
3876  jj = jj + 3
3877  end do
3878 
3879  ! Send the data.
3880 
3881  call mpi_isend(sendbuffer(ii), size, adflow_real, procid, &
3882  procid, adflow_comm_world, sendrequests(i), &
3883  ierr)
3884 
3885  ! Set ii to jj for the next processor.
3886 
3887  ii = jj
3888  end do sends
3889 
3890  ! Post the nonblocking receives.
3891 
3892  ii = 1
3893  receives: do i = 1, commpatterncell_1st(level)%nProcRecv
3894 
3895  ! Store the processor id and the size of the message
3896  ! a bit easier.
3897 
3898  procid = commpatterncell_1st(level)%recvProc(i)
3899  size = 3 * commpatterncell_1st(level)%nRecv(i)
3900 
3901  ! Post the receive.
3902 
3903  call mpi_irecv(recvbuffer(ii), size, adflow_real, procid, &
3904  myid, adflow_comm_world, recvrequests(i), ierr)
3905 
3906  ! And update ii.
3907 
3908  ii = ii + size
3909  end do receives
3910 
3911  ! Copy the local data.
3912 
3913  localcopy: do i = 1, internalcell_1st(level)%nCopy
3914 
3915  ! Store the block and the indices of the donor a bit easier.
3916 
3917  d1 = internalcell_1st(level)%donorBlock(i)
3918  i1 = internalcell_1st(level)%donorIndices(i, 1)
3919  j1 = internalcell_1st(level)%donorIndices(i, 2)
3920  k1 = internalcell_1st(level)%donorIndices(i, 3)
3921 
3922  ! Idem for the halo's.
3923 
3924  d2 = internalcell_1st(level)%haloBlock(i)
3925  i2 = internalcell_1st(level)%haloIndices(i, 1)
3926  j2 = internalcell_1st(level)%haloIndices(i, 2)
3927  k2 = internalcell_1st(level)%haloIndices(i, 3)
3928 
3929  ! Copy the grid velocities, if they are both allocated.
3930  ! Otherwise they are either set to zero or nothing is done.
3931 
3932  if (flowdoms(d2, level, sps)%addGridVelocities) then
3933  if (flowdoms(d1, level, sps)%addGridVelocities) then
3934  flowdoms(d2, level, sps)%s(i2, j2, k2, 1) = &
3935  flowdoms(d1, level, sps)%s(i1, j1, k1, 1)
3936  flowdoms(d2, level, sps)%s(i2, j2, k2, 2) = &
3937  flowdoms(d1, level, sps)%s(i1, j1, k1, 2)
3938  flowdoms(d2, level, sps)%s(i2, j2, k2, 3) = &
3939  flowdoms(d1, level, sps)%s(i1, j1, k1, 3)
3940  else
3941  flowdoms(d2, level, sps)%s(i2, j2, k2, 1) = zero
3942  flowdoms(d2, level, sps)%s(i2, j2, k2, 2) = zero
3943  flowdoms(d2, level, sps)%s(i2, j2, k2, 3) = zero
3944  end if
3945  end if
3946 
3947  end do localcopy
3948 
3949  ! Correct the periodic halo's of the internal communication
3950  ! pattern, if present.
3951 
3952  if (internalcell_1st(level)%nPeriodic > 0) &
3953  call correctperiodicgridvel(level, sps, &
3954  internalcell_1st(level)%nPeriodic, &
3955  internalcell_1st(level)%periodicData)
3956 
3957  ! Complete the nonblocking receives in an arbitrary sequence and
3958  ! copy the variables from the buffer into the halo's.
3959 
3960  size = commpatterncell_1st(level)%nProcRecv
3961  completerecvs: do i = 1, commpatterncell_1st(level)%nProcRecv
3962 
3963  ! Complete any of the requests.
3964 
3965  call mpi_waitany(size, recvrequests, index, mpistatus, ierr)
3966 
3967  ! Copy the data just arrived in the halo's.
3968 
3969  ii = index
3970  jj = 3 * commpatterncell_1st(level)%nRecvCum(ii - 1)
3971  do j = 1, commpatterncell_1st(level)%nRecv(ii)
3972 
3973  ! Store the block and the indices of the halo a bit easier.
3974 
3975  d2 = commpatterncell_1st(level)%recvList(ii)%block(j)
3976  i2 = commpatterncell_1st(level)%recvList(ii)%indices(j, 1)
3977  j2 = commpatterncell_1st(level)%recvList(ii)%indices(j, 2)
3978  k2 = commpatterncell_1st(level)%recvList(ii)%indices(j, 3)
3979 
3980  ! Copy the grid velocities from recvBuffer if they are
3981  ! both allocated.
3982 
3983  if (flowdoms(d2, level, sps)%addGridVelocities) then
3984  flowdoms(d2, level, sps)%s(i2, j2, k2, 1) = recvbuffer(jj + 1)
3985  flowdoms(d2, level, sps)%s(i2, j2, k2, 2) = recvbuffer(jj + 2)
3986  flowdoms(d2, level, sps)%s(i2, j2, k2, 3) = recvbuffer(jj + 3)
3987  end if
3988 
3989  jj = jj + 3
3990  end do
3991 
3992  end do completerecvs
3993 
3994  ! Correct the periodic halo's of the external communication
3995  ! pattern, if present.
3996 
3997  if (commpatterncell_1st(level)%nPeriodic > 0) &
3998  call correctperiodicgridvel(level, sps, &
3999  commpatterncell_1st(level)%nPeriodic, &
4000  commpatterncell_1st(level)%periodicData)
4001 
4002  ! Complete the nonblocking sends.
4003 
4004  size = commpatterncell_1st(level)%nProcSend
4005  do i = 1, commpatterncell_1st(level)%nProcSend
4006  call mpi_waitany(size, sendrequests, index, mpistatus, ierr)
4007  end do
4008 
4009  end subroutine exchangecellgridvelocities
4010 
4011  ! ==================================================================
4012 
4013  subroutine correctperiodicgridvel(level, sps, nPeriodic, &
4014  periodicData)
4015  !
4016  ! correctPeriodicGridVel applies the periodic transformation
4017  ! to the grid velocities of the cell halo's in periodicData.
4018  !
4019  use block
4020  use communication
4021  implicit none
4022  !
4023  ! Subroutine arguments.
4024  !
4025  integer(kind=intType), intent(in) :: level, sps, nPeriodic
4026  type(periodicdatatype), dimension(:), pointer :: periodicData
4027  !
4028  ! Local variables.
4029  !
4030  integer(kind=intType) :: nn, mm, ii, i, j, k
4031  real(kind=realtype) :: vx, vy, vz
4032 
4033  real(kind=realtype), dimension(3, 3) :: rotmatrix
4034 
4035  ! Loop over the number of periodic transformations.
4036 
4037  do nn = 1, nperiodic
4038 
4039  ! Store the rotation matrix a bit easier.
4040 
4041  rotmatrix = periodicdata(nn)%rotMatrix
4042 
4043  ! Loop over the number of halo cells for this transformation.
4044 
4045  do ii = 1, periodicdata(nn)%nHalos
4046 
4047  ! Store the block and the indices a bit easier.
4048 
4049  mm = periodicdata(nn)%block(ii)
4050  i = periodicdata(nn)%indices(ii, 1)
4051  j = periodicdata(nn)%indices(ii, 2)
4052  k = periodicdata(nn)%indices(ii, 3)
4053 
4054  ! Check if the grid velocities have been allocated.
4055 
4056  if (flowdoms(mm, level, sps)%addGridVelocities) then
4057 
4058  ! Store the original velocities in vx, vy, vz.
4059 
4060  vx = flowdoms(mm, level, sps)%s(i, j, k, 1)
4061  vy = flowdoms(mm, level, sps)%s(i, j, k, 2)
4062  vz = flowdoms(mm, level, sps)%s(i, j, k, 3)
4063 
4064  ! Compute the new velocity vector.
4065 
4066  flowdoms(mm, level, sps)%s(i, j, k, 1) = rotmatrix(1, 1) * vx &
4067  + rotmatrix(1, 2) * vy &
4068  + rotmatrix(1, 3) * vz
4069  flowdoms(mm, level, sps)%s(i, j, k, 2) = rotmatrix(2, 1) * vx &
4070  + rotmatrix(2, 2) * vy &
4071  + rotmatrix(2, 3) * vz
4072  flowdoms(mm, level, sps)%s(i, j, k, 3) = rotmatrix(3, 1) * vx &
4073  + rotmatrix(3, 2) * vy &
4074  + rotmatrix(3, 3) * vz
4075 
4076  end if
4077  end do
4078 
4079  end do
4080 
4081  end subroutine correctperiodicgridvel
4082 
4083  ! ==================================================================
4084 
4085 #endif
4086 end module solverutils
Definition: BCData.F90:1
Definition: block.F90:1
type(blocktype), dimension(:, :, :), allocatable, target flowdoms
Definition: block.F90:771
real(kind=realtype), dimension(:, :, :), pointer sfacek
real(kind=realtype), dimension(:, :, :), pointer gamma
logical addgridvelocities
integer(kind=inttype) jl
real(kind=realtype), dimension(:, :, :), pointer radk
real(kind=realtype), dimension(:, :, :, :), pointer svelokale
integer(kind=inttype) nviscbocos
logical blockismoving
integer(kind=inttype), dimension(:, :), pointer mgifine
real(kind=realtype), dimension(:, :, :, :, :), pointer xold
real(kind=realtype), dimension(:, :, :), pointer p
real(kind=realtype), dimension(:, :, :), pointer radj
integer(kind=inttype) ie
real(kind=realtype), dimension(:, :, :, :), pointer w
real(kind=realtype), dimension(:, :, :), pointer sfacei
type(viscsubfacetype), dimension(:), pointer viscsubface
integer(kind=inttype), dimension(:), pointer cgnssubface
real(kind=realtype), dimension(:, :, :), pointer d2wall
integer(kind=inttype), dimension(:, :), pointer mgjfine
real(kind=realtype), dimension(:, :, :, :), pointer svelojale
integer(kind=inttype) nbkglobal
real(kind=realtype), dimension(:, :, :), pointer rlv
integer(kind=inttype), dimension(:), pointer bcfaceid
real(kind=realtype), dimension(:, :, :, :), pointer sveloiale
real(kind=realtype), dimension(:, :, :, :), pointer si
integer(kind=inttype) nbocos
real(kind=realtype), dimension(:, :, :, :), pointer sj
integer(kind=inttype), dimension(:, :), pointer mgkfine
integer(kind=inttype) sectionid
real(kind=realtype), dimension(:, :, :, :), pointer s
real(kind=realtype), dimension(:, :, :), pointer rev
real(kind=realtype), dimension(:, :, :, :), pointer sk
real(kind=realtype), dimension(:), pointer mgkweight
real(kind=realtype), dimension(:, :, :), pointer vol
real(kind=realtype), dimension(:), pointer mgiweight
real(kind=realtype), dimension(:, :, :), pointer dtl
real(kind=realtype), dimension(:, :, :), pointer sfacej
real(kind=realtype), dimension(:, :, :, :), pointer fw
integer(kind=inttype) je
real(kind=realtype), dimension(:, :, :), pointer radi
integer(kind=inttype) ke
real(kind=realtype), dimension(:, :, :, :), pointer x
real(kind=realtype), dimension(:), pointer mgjweight
real(kind=realtype), dimension(:, :, :, :, :), pointer wold
integer(kind=inttype) kl
integer(kind=inttype) il
type(cgnsblockinfotype), dimension(:), allocatable cgnsdoms
Definition: cgnsGrid.F90:495
real(kind=realtype), dimension(:), allocatable recvbuffer
integer, dimension(:), allocatable recvrequests
real(kind=realtype), dimension(:), allocatable sendbuffer
type(internalcommtype), dimension(:), allocatable internalcell_1st
integer, dimension(:), allocatable sendrequests
type(commtype), dimension(:), allocatable commpatterncell_1st
integer adflow_comm_world
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
real(kind=realtype), parameter pi
Definition: constants.F90:22
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 turkel
Definition: constants.F90:165
integer, parameter irho
Definition: constants.F90:34
integer, parameter imx
Definition: constants.F90:65
integer(kind=inttype), parameter choimerkle
Definition: constants.F90:165
integer(kind=inttype), parameter timespectral
Definition: constants.F90:115
integer, parameter ivx
Definition: constants.F90:35
integer, parameter irhoe
Definition: constants.F90:38
integer(kind=inttype), parameter noprecond
Definition: constants.F90:165
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
integer, parameter ivz
Definition: constants.F90:37
real(kind=realtype), parameter two
Definition: constants.F90:73
real(kind=realtype), parameter fourth
Definition: constants.F90:82
integer, parameter imz
Definition: constants.F90:67
integer, parameter imy
Definition: constants.F90:66
integer(kind=inttype), parameter kmax
Definition: constants.F90:297
integer, parameter ivy
Definition: constants.F90:36
integer(kind=inttype), parameter jmin
Definition: constants.F90:294
subroutine getdirvector(refDirection, alpha, beta, windDirection, liftIndex)
Definition: flowUtils.F90:1533
subroutine derivativerotmatrixrigid(rotationMatrix, rotationPoint, t)
Definition: flowUtils.F90:1368
real(kind=realtype) gammainf
real(kind=realtype) pinfcorr
real(kind=realtype) pinf
integer(kind=inttype) nw
real(kind=realtype) rhoinf
real(kind=realtype) timeref
logical radiineededcoarse
Definition: inputParam.F90:92
real(kind=realtype) adis
Definition: inputParam.F90:78
real(kind=realtype) acousticscalefactor
Definition: inputParam.F90:79
integer(kind=inttype) precond
Definition: inputParam.F90:74
real(kind=realtype), dimension(:), allocatable sincoeffourmach
Definition: inputParam.F90:475
integer(kind=inttype) degreefourmach
Definition: inputParam.F90:459
real(kind=realtype) omegafouralpha
Definition: inputParam.F90:404
integer(kind=inttype) degreepolbeta
Definition: inputParam.F90:420
real(kind=realtype) omegafourbeta
Definition: inputParam.F90:434
integer(kind=inttype) degreepolmach
Definition: inputParam.F90:450
real(kind=realtype) omegafourmach
Definition: inputParam.F90:464
real(kind=realtype), dimension(:), allocatable sincoeffouralpha
Definition: inputParam.F90:415
real(kind=realtype), dimension(:), allocatable sincoeffourbeta
Definition: inputParam.F90:445
real(kind=realtype), dimension(:), allocatable coefpolmach
Definition: inputParam.F90:454
real(kind=realtype), dimension(:), allocatable coefpolalpha
Definition: inputParam.F90:394
integer(kind=inttype) degreefourbeta
Definition: inputParam.F90:429
real(kind=realtype), dimension(:), allocatable coscoeffouralpha
Definition: inputParam.F90:409
real(kind=realtype), dimension(:), allocatable coscoeffourmach
Definition: inputParam.F90:469
integer(kind=inttype) degreepolalpha
Definition: inputParam.F90:390
integer(kind=inttype) degreefouralpha
Definition: inputParam.F90:399
real(kind=realtype), dimension(:), allocatable coscoeffourbeta
Definition: inputParam.F90:439
real(kind=realtype), dimension(:), allocatable coefpolbeta
Definition: inputParam.F90:424
integer(kind=inttype) equationmode
Definition: inputParam.F90:583
integer(kind=inttype) liftindex
Definition: inputParam.F90:592
real(kind=realtype) beta
Definition: inputParam.F90:591
real(kind=realtype) machgrid
Definition: inputParam.F90:593
logical wallfunctions
Definition: inputParam.F90:589
real(kind=realtype), dimension(3) veldirfreestream
Definition: inputParam.F90:599
real(kind=realtype) alpha
Definition: inputParam.F90:591
integer(kind=inttype) ntimeintervalsspectral
Definition: inputParam.F90:645
logical usetsinterpolatedgridvelocity
Definition: inputParam.F90:697
real(kind=realtype), dimension(:, :, :), allocatable dscalar
Definition: inputParam.F90:659
logical tsaltitudemode
Definition: inputParam.F90:863
logical tsalphafollowing
Definition: inputParam.F90:866
real(kind=realtype) deltat
Definition: inputParam.F90:733
integer(kind=inttype) noldlevels
Definition: iteration.f90:79
integer(kind=inttype) currentlevel
Definition: iteration.f90:18
integer(kind=inttype) groundlevel
Definition: iteration.f90:18
real(kind=realtype), dimension(:), allocatable coeftime
Definition: iteration.f90:80
real(kind=realtype) timeunsteady
Definition: monitor.f90:98
real(kind=realtype) timeunsteadyrestart
Definition: monitor.f90:98
integer, parameter realtype
Definition: precision.F90:112
type(sectiontype), dimension(:), allocatable sections
Definition: section.f90:46
subroutine cellfacevelocities(xc, rotCenter, rotRate, velxGrid, velyGrid, velzGrid, derivRotationMatrix, sc)
subroutine correctperiodicgridvel(level, sps, nPeriodic, periodicData)
subroutine gridvelocitiescoarselevels(sps)
subroutine shiftsolution
subroutine gridvelocitiesfinelevel_ts_block(nn, sps)
subroutine slipvelocitiesfinelevel(useOldCoor, t, sps)
subroutine slipvelocitiescoarselevels(sps)
subroutine computeutau
subroutine gridvelocitiesfinelevelpart2_block(useOldCoor, t, sps)
subroutine normalvelocities_block(sps)
subroutine normalvelocitiesalllevels(sps)
subroutine slipvelocitiesfinelevel_block(useOldCoor, t, sps, nn)
subroutine gridvelocitiesfinelevel_block(useOldCoor, t, sps, nn)
subroutine gridvelocitiesfinelevelpart2(useOldCoor, t, sps)
subroutine timestep_block(onlyRadii)
Definition: solverUtils.F90:44
subroutine gridvelocitiesfinelevelpart1(useOldCoor, t, sps)
subroutine utauwf(rFilv)
subroutine gridvelocitiesfinelevel(useOldCoor, t, sps)
subroutine exchangecellgridvelocities(level, sps)
subroutine timestep(onlyRadii)
Definition: solverUtils.F90:5
subroutine gridvelocitiesfinelevelpart1_block(useOldCoor, t, sps)
subroutine computeutau_block
real(kind=realtype) function curveupre(Re)
Definition: utils.F90:1
real(kind=realtype) function tsmach(degreePolMach, coefPolMach, degreeFourMach, omegaFourMach, cosCoefFourMach, sinCoefFourMach, t)
Definition: utils.F90:159
subroutine setcoeftimeintegrator
Definition: utils.F90:1536
real(kind=realtype) function tsalpha(degreePolAlpha, coefPolAlpha, degreeFourAlpha, omegaFourAlpha, cosCoefFourAlpha, sinCoefFourAlpha, t)
Definition: utils.F90:284
real(kind=realtype) function tsbeta(degreePolBeta, coefPolBeta, degreeFourBeta, omegaFourBeta, cosCoefFourBeta, sinCoefFourBeta, t)
Definition: utils.F90:34
subroutine rotmatrixrigidbody(tNew, tOld, rotationMatrix, rotationPoint)
Definition: utils.F90:614
subroutine getdirangle(freeStreamAxis, liftAxis, liftIndex, alpha, beta)
Definition: utils.F90:1428
subroutine setpointers(nn, mm, ll)
Definition: utils.F90:3237
subroutine terminate(routineName, errorMessage)
Definition: utils.F90:502