ADflow  v1.0
ADflow is a finite volume RANS solver tailored for gradient-based aerodynamic design optimization.
flowUtils_d.f90
Go to the documentation of this file.
1 ! generated by tapenade (inria, ecuador team)
2 ! tapenade 3.16 (develop) - 22 aug 2023 15:51
3 !
4 module flowutils_d
5  implicit none
6 
7 contains
8 ! differentiation of computettot in forward (tangent) mode (with options i4 dr8 r8):
9 ! variations of useful results: ttot
10 ! with respect to varying inputs: rgas p u v w ttot rho
11  subroutine computettot_d(rho, rhod, u, ud, v, vd, w, wd, p, pd, ttot, &
12 & ttotd)
13 !
14 ! computettot computes the total temperature for the given
15 ! pressures, densities and velocities.
16 !
17  use constants
18  use inputphysics, only : cpmodel
19  use flowvarrefstate, only : rgas, rgasd, gammainf
20  use utils_d, only : terminate
21  implicit none
22 !
23 ! subroutine arguments.
24 !
25  real(kind=realtype), intent(in) :: rho, p, u, v, w
26  real(kind=realtype), intent(in) :: rhod, pd, ud, vd, wd
27  real(kind=realtype), intent(out) :: ttot
28  real(kind=realtype), intent(out) :: ttotd
29 !
30 ! local variables.
31 !
32  integer(kind=inttype) :: i
33  real(kind=realtype) :: govgm1, t, kin
34  real(kind=realtype) :: td, kind0
35  real(kind=realtype) :: temp
36 ! determine the cp model used.
37  select case (cpmodel)
38  case (cpconstant)
39 ! constant cp and thus constant gamma. the well-known
40 ! formula is valid.
41  govgm1 = gammainf/(gammainf-one)
42  temp = p/(rho*rgas)
43  td = (pd-temp*(rgas*rhod+rho*rgasd))/(rho*rgas)
44  t = temp
45  kind0 = half*(2*u*ud+2*v*vd+2*w*wd)
46  kin = half*(u*u+v*v+w*w)
47  temp = rho*kin/(govgm1*p)
48  ttotd = (one+temp)*td + t*(kin*rhod+rho*kind0-temp*govgm1*pd)/(&
49 & govgm1*p)
50  ttot = t*(one+temp)
51 !===============================================================
52  case (cptempcurvefits)
53 ! cp is a function of the temperature. the formula used for
54 ! constant cp is not valid anymore and a more complicated
55 ! procedure must be followed.
56  call terminate('computettot', &
57 & 'variable cp formulation not implemented yet')
58  end select
59  end subroutine computettot_d
60 
61  subroutine computettot(rho, u, v, w, p, ttot)
62 !
63 ! computettot computes the total temperature for the given
64 ! pressures, densities and velocities.
65 !
66  use constants
67  use inputphysics, only : cpmodel
68  use flowvarrefstate, only : rgas, gammainf
69  use utils_d, only : terminate
70  implicit none
71 !
72 ! subroutine arguments.
73 !
74  real(kind=realtype), intent(in) :: rho, p, u, v, w
75  real(kind=realtype), intent(out) :: ttot
76 !
77 ! local variables.
78 !
79  integer(kind=inttype) :: i
80  real(kind=realtype) :: govgm1, t, kin
81 ! determine the cp model used.
82  select case (cpmodel)
83  case (cpconstant)
84 ! constant cp and thus constant gamma. the well-known
85 ! formula is valid.
86  govgm1 = gammainf/(gammainf-one)
87  t = p/(rho*rgas)
88  kin = half*(u*u+v*v+w*w)
89  ttot = t*(one+rho*kin/(govgm1*p))
90 !===============================================================
91  case (cptempcurvefits)
92 ! cp is a function of the temperature. the formula used for
93 ! constant cp is not valid anymore and a more complicated
94 ! procedure must be followed.
95  call terminate('computettot', &
96 & 'variable cp formulation not implemented yet')
97  end select
98  end subroutine computettot
99 
100  subroutine computegamma(t, gamma, mm)
101 !
102 ! computegamma computes the corresponding values of gamma for
103 ! the given dimensional temperatures.
104 !
105  use constants
106  use cpcurvefits
107  use inputphysics, only : cpmodel, gammaconstant
108  implicit none
109 !
110 ! subroutine arguments.
111 !
112  integer(kind=inttype), intent(in) :: mm
113  real(kind=realtype), dimension(mm), intent(in) :: t
114  real(kind=realtype), dimension(mm), intent(out) :: gamma
115 !
116 ! local variables.
117 !
118  integer(kind=inttype) :: i, ii, nn, start
119  real(kind=realtype) :: cp, t2
120 ! determine the cp model used in the computation.
121  select case (cpmodel)
122  case (cpconstant)
123 ! constant cp and thus constant gamma. set the values.
124  do i=1,mm
125  gamma(i) = gammaconstant
126  end do
127  end select
128 ! ================================================================
129 
130  end subroutine computegamma
131 
132 ! differentiation of computeptot in forward (tangent) mode (with options i4 dr8 r8):
133 ! variations of useful results: ptot
134 ! with respect to varying inputs: p u v w ptot rho
135  subroutine computeptot_d(rho, rhod, u, ud, v, vd, w, wd, p, pd, ptot, &
136 & ptotd)
137 !
138 ! computeptot computes the total pressure for the given
139 ! pressures, densities and velocities.
140 !
141  use constants
142  use cpcurvefits
143  use flowvarrefstate, only : tref, trefd, rgas, rgasd, gammainf
144  use inputphysics, only : cpmodel
145  implicit none
146  real(kind=realtype), intent(in) :: rho, p, u, v, w
147  real(kind=realtype), intent(in) :: rhod, pd, ud, vd, wd
148  real(kind=realtype), intent(out) :: ptot
149  real(kind=realtype), intent(out) :: ptotd
150 !
151 ! local parameters.
152 !
153  real(kind=realtype), parameter :: dtstop=0.01_realtype
154 !
155 ! local variables.
156 !
157  integer(kind=inttype) :: i, ii, mm, nn, nnt, start
158  real(kind=realtype) :: govgm1, kin
159  real(kind=realtype) :: kind0
160  real(kind=realtype) :: t, t2, tt, dt, h, htot, cp, scale, alp
161  real(kind=realtype) :: intcport, intcportt, intcporttt
162  real(kind=realtype) :: temp
163  real(kind=realtype) :: temp0
164  real(kind=realtype) :: tempd
165 !
166 ! determine the cp model used.
167  select case (cpmodel)
168  case (cpconstant)
169 ! constant cp and thus constant gamma. the well-known
170 ! formula is valid.
171  govgm1 = gammainf/(gammainf-one)
172  kind0 = half*(2*u*ud+2*v*vd+2*w*wd)
173  kin = half*(u*u+v*v+w*w)
174  temp = rho*kin/(govgm1*p)
175  temp0 = (one+temp)**govgm1
176  if (one + temp .le. 0.0_8 .and. (govgm1 .eq. 0.0_8 .or. govgm1 &
177 & .ne. int(govgm1))) then
178  tempd = 0.0_8
179  else
180  tempd = (one+temp)**(govgm1-1)*(kin*rhod+rho*kind0-temp*govgm1*&
181 & pd)/p
182  end if
183  ptotd = temp0*pd + p*tempd
184  ptot = p*temp0
185 !===============================================================
186  end select
187  end subroutine computeptot_d
188 
189  subroutine computeptot(rho, u, v, w, p, ptot)
190 !
191 ! computeptot computes the total pressure for the given
192 ! pressures, densities and velocities.
193 !
194  use constants
195  use cpcurvefits
196  use flowvarrefstate, only : tref, rgas, gammainf
197  use inputphysics, only : cpmodel
198  implicit none
199  real(kind=realtype), intent(in) :: rho, p, u, v, w
200  real(kind=realtype), intent(out) :: ptot
201 !
202 ! local parameters.
203 !
204  real(kind=realtype), parameter :: dtstop=0.01_realtype
205 !
206 ! local variables.
207 !
208  integer(kind=inttype) :: i, ii, mm, nn, nnt, start
209  real(kind=realtype) :: govgm1, kin
210  real(kind=realtype) :: t, t2, tt, dt, h, htot, cp, scale, alp
211  real(kind=realtype) :: intcport, intcportt, intcporttt
212 !
213 ! determine the cp model used.
214  select case (cpmodel)
215  case (cpconstant)
216 ! constant cp and thus constant gamma. the well-known
217 ! formula is valid.
218  govgm1 = gammainf/(gammainf-one)
219  kin = half*(u*u+v*v+w*w)
220  ptot = p*(one+rho*kin/(govgm1*p))**govgm1
221 !===============================================================
222  end select
223  end subroutine computeptot
224 
225 ! differentiation of computespeedofsoundsquared in forward (tangent) mode (with options i4 dr8 r8):
226 ! variations of useful results: *aa
227 ! with respect to varying inputs: *p *w
228 ! rw status of diff variables: *aa:out *p:in *w:in
229 ! plus diff mem management of: aa:in p:in w:in
231 !
232 ! computespeedofsoundsquared does what it says.
233 !
234  use constants
235  use blockpointers, only : ie, je, ke, w, wd, p, pd, aa, aad, gamma
236  use utils_d, only : getcorrectfork
237  implicit none
238 !
239 ! local variables.
240 !
241  real(kind=realtype), parameter :: twothird=two*third
242  integer(kind=inttype) :: i, j, k, ii
243  real(kind=realtype) :: pp
244  real(kind=realtype) :: ppd
245  logical :: correctfork
246  real(kind=realtype) :: temp
247  real(kind=realtype) :: temp0
248 ! determine if we need to correct for k
249  correctfork = getcorrectfork()
250  if (correctfork) then
251  if (associated(aad)) aad = 0.0_8
252  do k=1,ke
253  do j=1,je
254  do i=1,ie
255  temp = w(i, j, k, itu1)
256  temp0 = w(i, j, k, irho)
257  ppd = pd(i, j, k) - twothird*(temp*wd(i, j, k, irho)+temp0*&
258 & wd(i, j, k, itu1))
259  pp = p(i, j, k) - twothird*(temp0*temp)
260  temp0 = w(i, j, k, irho)
261  aad(i, j, k) = gamma(i, j, k)*(ppd-pp*wd(i, j, k, irho)/&
262 & temp0)/temp0
263  aa(i, j, k) = gamma(i, j, k)*(pp/temp0)
264  end do
265  end do
266  end do
267  else
268  if (associated(aad)) aad = 0.0_8
269  do k=1,ke
270  do j=1,je
271  do i=1,ie
272  temp0 = w(i, j, k, irho)
273  temp = p(i, j, k)/temp0
274  aad(i, j, k) = gamma(i, j, k)*(pd(i, j, k)-temp*wd(i, j, k, &
275 & irho))/temp0
276  aa(i, j, k) = gamma(i, j, k)*temp
277  end do
278  end do
279  end do
280  end if
281  end subroutine computespeedofsoundsquared_d
282 
284 !
285 ! computespeedofsoundsquared does what it says.
286 !
287  use constants
288  use blockpointers, only : ie, je, ke, w, p, aa, gamma
289  use utils_d, only : getcorrectfork
290  implicit none
291 !
292 ! local variables.
293 !
294  real(kind=realtype), parameter :: twothird=two*third
295  integer(kind=inttype) :: i, j, k, ii
296  real(kind=realtype) :: pp
297  logical :: correctfork
298 ! determine if we need to correct for k
299  correctfork = getcorrectfork()
300  if (correctfork) then
301  do k=1,ke
302  do j=1,je
303  do i=1,ie
304  pp = p(i, j, k) - twothird*w(i, j, k, irho)*w(i, j, k, itu1)
305  aa(i, j, k) = gamma(i, j, k)*pp/w(i, j, k, irho)
306  end do
307  end do
308  end do
309  else
310  do k=1,ke
311  do j=1,je
312  do i=1,ie
313  aa(i, j, k) = gamma(i, j, k)*p(i, j, k)/w(i, j, k, irho)
314  end do
315  end do
316  end do
317  end if
318  end subroutine computespeedofsoundsquared
319 
320 ! differentiation of computeetotblock in forward (tangent) mode (with options i4 dr8 r8):
321 ! variations of useful results: *w
322 ! with respect to varying inputs: *p *w
323 ! rw status of diff variables: *p:in *w:in-out
324 ! plus diff mem management of: p:in w:in
325  subroutine computeetotblock_d(istart, iend, jstart, jend, kstart, kend&
326 & , correctfork)
327 !
328 ! computeetot computes the total energy from the given density,
329 ! velocity and presssure. for a calorically and thermally
330 ! perfect gas the well-known expression is used; for only a
331 ! thermally perfect gas, cp is a function of temperature, curve
332 ! fits are used and a more complex expression is obtained.
333 ! it is assumed that the pointers in blockpointers already
334 ! point to the correct block.
335 !
336  use constants
337  use blockpointers, only : w, wd, p, pd
338  use flowvarrefstate, only : rgas, rgasd, tref, trefd
339  use inputphysics, only : cpmodel, gammaconstant
340  implicit none
341 !
342 ! subroutine arguments.
343 !
344  integer(kind=inttype), intent(in) :: istart, iend, jstart, jend
345  integer(kind=inttype), intent(in) :: kstart, kend
346  logical, intent(in) :: correctfork
347 !
348 ! local variables.
349 !
350  integer(kind=inttype) :: i, j, k, ii, isize, jsize, ksize
351  real(kind=realtype) :: ovgm1, factk, scale
352  real(kind=realtype) :: temp
353  real(kind=realtype) :: temp0
354  real(kind=realtype) :: temp1
355  real(kind=realtype) :: temp2
356  real(kind=realtype) :: temp3
357  real(kind=realtype) :: temp4
358  real(kind=realtype) :: temp5
359 !
360 ! determine the cp model used in the computation.
361  select case (cpmodel)
362  case (cpconstant)
363 ! constant cp and thus constant gamma.
364 ! abbreviate 1/(gamma -1) a bit easier.
365  ovgm1 = one/(gammaconstant-one)
366 ! loop over the given range of the block and compute the first
367 ! step of the energy.
368  isize = iend - istart + 1
369  jsize = jend - jstart + 1
370  ksize = kend - kstart + 1
371  factk = ovgm1*(five*third-gammaconstant)
372  if (correctfork) then
373  do k=kstart,kend
374  do j=jstart,jend
375  do i=istart,iend
376  temp = w(i, j, k, ivz)
377  temp0 = w(i, j, k, ivy)
378  temp1 = w(i, j, k, ivx)
379  temp2 = temp1*temp1 + temp0*temp0 + temp*temp
380  temp3 = w(i, j, k, irho)
381  temp4 = w(i, j, k, itu1)
382  temp5 = w(i, j, k, irho)
383  wd(i, j, k, irhoe) = ovgm1*pd(i, j, k) + half*(temp2*wd(i&
384 & , j, k, irho)+temp3*(2*temp1*wd(i, j, k, ivx)+2*temp0*wd&
385 & (i, j, k, ivy)+2*temp*wd(i, j, k, ivz))) - factk*(temp4*&
386 & wd(i, j, k, irho)+temp5*wd(i, j, k, itu1))
387  w(i, j, k, irhoe) = ovgm1*p(i, j, k) + half*(temp3*temp2) &
388 & - factk*(temp5*temp4)
389  end do
390  end do
391  end do
392  else
393  do k=kstart,kend
394  do j=jstart,jend
395  do i=istart,iend
396  temp5 = w(i, j, k, ivz)
397  temp4 = w(i, j, k, ivy)
398  temp3 = w(i, j, k, ivx)
399  temp2 = temp3*temp3 + temp4*temp4 + temp5*temp5
400  temp1 = w(i, j, k, irho)
401  wd(i, j, k, irhoe) = ovgm1*pd(i, j, k) + half*(temp2*wd(i&
402 & , j, k, irho)+temp1*(2*temp3*wd(i, j, k, ivx)+2*temp4*wd&
403 & (i, j, k, ivy)+2*temp5*wd(i, j, k, ivz)))
404  w(i, j, k, irhoe) = ovgm1*p(i, j, k) + half*(temp1*temp2)
405  end do
406  end do
407  end do
408  end if
409  end select
410  end subroutine computeetotblock_d
411 
412  subroutine computeetotblock(istart, iend, jstart, jend, kstart, kend, &
413 & correctfork)
414 !
415 ! computeetot computes the total energy from the given density,
416 ! velocity and presssure. for a calorically and thermally
417 ! perfect gas the well-known expression is used; for only a
418 ! thermally perfect gas, cp is a function of temperature, curve
419 ! fits are used and a more complex expression is obtained.
420 ! it is assumed that the pointers in blockpointers already
421 ! point to the correct block.
422 !
423  use constants
424  use blockpointers, only : w, p
425  use flowvarrefstate, only : rgas, tref
426  use inputphysics, only : cpmodel, gammaconstant
427  implicit none
428 !
429 ! subroutine arguments.
430 !
431  integer(kind=inttype), intent(in) :: istart, iend, jstart, jend
432  integer(kind=inttype), intent(in) :: kstart, kend
433  logical, intent(in) :: correctfork
434 !
435 ! local variables.
436 !
437  integer(kind=inttype) :: i, j, k, ii, isize, jsize, ksize
438  real(kind=realtype) :: ovgm1, factk, scale
439 !
440 ! determine the cp model used in the computation.
441  select case (cpmodel)
442  case (cpconstant)
443 ! constant cp and thus constant gamma.
444 ! abbreviate 1/(gamma -1) a bit easier.
445  ovgm1 = one/(gammaconstant-one)
446 ! loop over the given range of the block and compute the first
447 ! step of the energy.
448  isize = iend - istart + 1
449  jsize = jend - jstart + 1
450  ksize = kend - kstart + 1
451  factk = ovgm1*(five*third-gammaconstant)
452  if (correctfork) then
453  do k=kstart,kend
454  do j=jstart,jend
455  do i=istart,iend
456  w(i, j, k, irhoe) = ovgm1*p(i, j, k) + half*w(i, j, k, &
457 & irho)*(w(i, j, k, ivx)**2+w(i, j, k, ivy)**2+w(i, j, k, &
458 & ivz)**2) - factk*w(i, j, k, irho)*w(i, j, k, itu1)
459  end do
460  end do
461  end do
462  else
463  do k=kstart,kend
464  do j=jstart,jend
465  do i=istart,iend
466  w(i, j, k, irhoe) = ovgm1*p(i, j, k) + half*w(i, j, k, &
467 & irho)*(w(i, j, k, ivx)**2+w(i, j, k, ivy)**2+w(i, j, k, &
468 & ivz)**2)
469  end do
470  end do
471  end do
472  end if
473  end select
474  end subroutine computeetotblock
475 
476 ! differentiation of etot in forward (tangent) mode (with options i4 dr8 r8):
477 ! variations of useful results: etotal
478 ! with respect to varying inputs: k p u v w etotal rho
479  subroutine etot_d(rho, rhod, u, ud, v, vd, w, wd, p, pd, k, kd, etotal&
480 & , etotald, correctfork)
481 !
482 ! etotarray computes the total energy from the given density,
483 ! velocity and presssure.
484 ! first the internal energy per unit mass is computed and after
485 ! that the kinetic energy is added as well the conversion to
486 ! energy per unit volume.
487 !
488  use constants
489  implicit none
490 !
491 ! subroutine arguments.
492 !
493  real(kind=realtype), intent(in) :: rho, p, k
494  real(kind=realtype), intent(in) :: rhod, pd, kd
495  real(kind=realtype), intent(in) :: u, v, w
496  real(kind=realtype), intent(in) :: ud, vd, wd
497  real(kind=realtype), intent(out) :: etotal
498  real(kind=realtype), intent(out) :: etotald
499  logical, intent(in) :: correctfork
500 !
501 ! local variables.
502 !
503  integer(kind=inttype) :: i
504  real(kind=realtype) :: temp
505 ! compute the internal energy for unit mass.
506  call eint_d(rho, rhod, p, pd, k, kd, etotal, etotald, correctfork)
507  temp = etotal + half*(u*u+v*v+w*w)
508  etotald = temp*rhod + rho*(etotald+half*(2*u*ud+2*v*vd+2*w*wd))
509  etotal = rho*temp
510  end subroutine etot_d
511 
512  subroutine etot(rho, u, v, w, p, k, etotal, correctfork)
513 !
514 ! etotarray computes the total energy from the given density,
515 ! velocity and presssure.
516 ! first the internal energy per unit mass is computed and after
517 ! that the kinetic energy is added as well the conversion to
518 ! energy per unit volume.
519 !
520  use constants
521  implicit none
522 !
523 ! subroutine arguments.
524 !
525  real(kind=realtype), intent(in) :: rho, p, k
526  real(kind=realtype), intent(in) :: u, v, w
527  real(kind=realtype), intent(out) :: etotal
528  logical, intent(in) :: correctfork
529 !
530 ! local variables.
531 !
532  integer(kind=inttype) :: i
533 ! compute the internal energy for unit mass.
534  call eint(rho, p, k, etotal, correctfork)
535  etotal = rho*(etotal+half*(u*u+v*v+w*w))
536  end subroutine etot
537 
538 ! differentiation of eint in forward (tangent) mode (with options i4 dr8 r8):
539 ! variations of useful results: einternal
540 ! with respect to varying inputs: k p einternal rho
541 ! ==================================================================
542  subroutine eint_d(rho, rhod, p, pd, k, kd, einternal, einternald, &
543 & correctfork)
544 !
545 ! eintarray computes the internal energy per unit mass from the
546 ! given density and pressure (and possibly turbulent energy)
547 ! for a calorically and thermally perfect gas the well-known
548 ! expression is used; for only a thermally perfect gas, cp is a
549 ! function of temperature, curve fits are used and a more
550 ! complex expression is obtained.
551 !
552  use constants
553  use cpcurvefits
554  use flowvarrefstate, only : rgas, rgasd, tref, trefd
555  use inputphysics, only : cpmodel, gammaconstant
556  implicit none
557 !
558 ! subroutine arguments.
559 !
560  real(kind=realtype), intent(in) :: rho, p, k
561  real(kind=realtype), intent(in) :: rhod, pd, kd
562  real(kind=realtype), intent(out) :: einternal
563  real(kind=realtype), intent(out) :: einternald
564  logical, intent(in) :: correctfork
565 !
566 ! local parameter.
567 !
568  real(kind=realtype), parameter :: twothird=two*third
569 !
570 ! local variables.
571 !
572  integer(kind=inttype) :: i, nn, mm, ii, start
573  real(kind=realtype) :: ovgm1, factk, pp, t, t2, scale
574 ! determine the cp model used in the computation.
575  select case (cpmodel)
576  case (cpconstant)
577 ! abbreviate 1/(gamma -1) a bit easier.
578  ovgm1 = one/(gammaconstant-one)
579 ! loop over the number of elements of the array and compute
580 ! the total energy.
581  einternald = ovgm1*(pd-p*rhod/rho)/rho
582  einternal = ovgm1*p/rho
583 ! second step. correct the energy in case a turbulent kinetic
584 ! energy is present.
585  if (correctfork) then
586  factk = ovgm1*(five*third-gammaconstant)
587  einternald = einternald - factk*kd
588  einternal = einternal - factk*k
589  end if
590  end select
591  end subroutine eint_d
592 
593 ! ==================================================================
594  subroutine eint(rho, p, k, einternal, correctfork)
595 !
596 ! eintarray computes the internal energy per unit mass from the
597 ! given density and pressure (and possibly turbulent energy)
598 ! for a calorically and thermally perfect gas the well-known
599 ! expression is used; for only a thermally perfect gas, cp is a
600 ! function of temperature, curve fits are used and a more
601 ! complex expression is obtained.
602 !
603  use constants
604  use cpcurvefits
605  use flowvarrefstate, only : rgas, tref
606  use inputphysics, only : cpmodel, gammaconstant
607  implicit none
608 !
609 ! subroutine arguments.
610 !
611  real(kind=realtype), intent(in) :: rho, p, k
612  real(kind=realtype), intent(out) :: einternal
613  logical, intent(in) :: correctfork
614 !
615 ! local parameter.
616 !
617  real(kind=realtype), parameter :: twothird=two*third
618 !
619 ! local variables.
620 !
621  integer(kind=inttype) :: i, nn, mm, ii, start
622  real(kind=realtype) :: ovgm1, factk, pp, t, t2, scale
623 ! determine the cp model used in the computation.
624  select case (cpmodel)
625  case (cpconstant)
626 ! abbreviate 1/(gamma -1) a bit easier.
627  ovgm1 = one/(gammaconstant-one)
628 ! loop over the number of elements of the array and compute
629 ! the total energy.
630  einternal = ovgm1*p/rho
631 ! second step. correct the energy in case a turbulent kinetic
632 ! energy is present.
633  if (correctfork) then
634  factk = ovgm1*(five*third-gammaconstant)
635  einternal = einternal - factk*k
636  end if
637  end select
638  end subroutine eint
639 
640 ! differentiation of computepressuresimple in forward (tangent) mode (with options i4 dr8 r8):
641 ! variations of useful results: *p
642 ! with respect to varying inputs: pinfcorr *w
643 ! rw status of diff variables: pinfcorr:in *p:out *w:in
644 ! plus diff mem management of: p:in w:in
645  subroutine computepressuresimple_d(includehalos)
646 ! compute the pressure on a block with the pointers already set. this
647 ! routine is used by the forward mode ad code only.
648  use constants
649  use blockpointers
650  use flowvarrefstate
651  use inputphysics
652  implicit none
653 ! input parameter
654  logical, intent(in) :: includehalos
655 ! local variables
656  integer(kind=inttype) :: i, j, k, ii
657  real(kind=realtype) :: gm1, v2
658  real(kind=realtype) :: v2d
659  integer(kind=inttype) :: ibeg, iend, isize, jbeg, jend, jsize, kbeg&
660 & , kend, ksize
661  intrinsic max
662  real(kind=realtype) :: temp
663  real(kind=realtype) :: temp0
664  real(kind=realtype) :: temp1
665 ! compute the pressures
666  gm1 = gammaconstant - one
667  if (includehalos) then
668  ibeg = 0
669  jbeg = 0
670  kbeg = 0
671  iend = ib
672  jend = jb
673  kend = kb
674  if (associated(pd)) pd = 0.0_8
675  else
676  ibeg = 2
677  jbeg = 2
678  kbeg = 2
679  iend = il
680  jend = jl
681  kend = kl
682  if (associated(pd)) pd = 0.0_8
683  end if
684  do k=kbeg,kend
685  do j=jbeg,jend
686  do i=ibeg,iend
687  temp = w(i, j, k, ivx)
688  temp0 = w(i, j, k, ivy)
689  temp1 = w(i, j, k, ivz)
690  v2d = 2*temp*wd(i, j, k, ivx) + 2*temp0*wd(i, j, k, ivy) + 2*&
691 & temp1*wd(i, j, k, ivz)
692  v2 = temp*temp + temp0*temp0 + temp1*temp1
693  temp1 = w(i, j, k, irho)
694  pd(i, j, k) = gm1*(wd(i, j, k, irhoe)-half*(v2*wd(i, j, k, &
695 & irho)+temp1*v2d))
696  p(i, j, k) = gm1*(w(i, j, k, irhoe)-half*(temp1*v2))
697  if (p(i, j, k) .lt. 1.e-4_realtype*pinfcorr) then
698  pd(i, j, k) = 1.e-4_realtype*pinfcorrd
699  p(i, j, k) = 1.e-4_realtype*pinfcorr
700  else
701  p(i, j, k) = p(i, j, k)
702  end if
703  end do
704  end do
705  end do
706  end subroutine computepressuresimple_d
707 
708  subroutine computepressuresimple(includehalos)
709 ! compute the pressure on a block with the pointers already set. this
710 ! routine is used by the forward mode ad code only.
711  use constants
712  use blockpointers
713  use flowvarrefstate
714  use inputphysics
715  implicit none
716 ! input parameter
717  logical, intent(in) :: includehalos
718 ! local variables
719  integer(kind=inttype) :: i, j, k, ii
720  real(kind=realtype) :: gm1, v2
721  integer(kind=inttype) :: ibeg, iend, isize, jbeg, jend, jsize, kbeg&
722 & , kend, ksize
723  intrinsic max
724 ! compute the pressures
725  gm1 = gammaconstant - one
726  if (includehalos) then
727  ibeg = 0
728  jbeg = 0
729  kbeg = 0
730  iend = ib
731  jend = jb
732  kend = kb
733  else
734  ibeg = 2
735  jbeg = 2
736  kbeg = 2
737  iend = il
738  jend = jl
739  kend = kl
740  end if
741  do k=kbeg,kend
742  do j=jbeg,jend
743  do i=ibeg,iend
744  v2 = w(i, j, k, ivx)**2 + w(i, j, k, ivy)**2 + w(i, j, k, ivz)&
745 & **2
746  p(i, j, k) = gm1*(w(i, j, k, irhoe)-half*w(i, j, k, irho)*v2)
747  if (p(i, j, k) .lt. 1.e-4_realtype*pinfcorr) then
748  p(i, j, k) = 1.e-4_realtype*pinfcorr
749  else
750  p(i, j, k) = p(i, j, k)
751  end if
752  end do
753  end do
754  end do
755  end subroutine computepressuresimple
756 
757  subroutine computepressure(ibeg, iend, jbeg, jend, kbeg, kend, &
758 & pointeroffset)
759 !
760 ! computepressure computes the pressure from the total energy,
761 ! density and velocities in the given cell range of the block to
762 ! which the pointers in blockpointers currently point.
763 ! it is possible to specify a possible pointer offset, because
764 ! this routine is also used when reading a restart file.
765 !
766  use constants
767  use inputphysics, only : cpmodel, gammaconstant
768  use blockpointers, only : w, p
769  use flowvarrefstate, only : kpresent, pinf, rgas, tref
770  use cpcurvefits
771  implicit none
772 !
773 ! subroutine arguments.
774 !
775  integer(kind=inttype), intent(in) :: ibeg, iend, jbeg, jend, kbeg, &
776 & kend
777  integer(kind=inttype), intent(in) :: pointeroffset
778 !
779 ! local parameters.
780 !
781  real(kind=realtype), parameter :: dtstop=0.01_realtype
782  real(kind=realtype), parameter :: twothird=two*third
783 !
784 ! local variables.
785 !
786  integer(kind=inttype) :: i, j, k, ip, jp, kp, nn, ii, start
787  real(kind=realtype) :: gm1, factk, v2, scale, e0, e
788  real(kind=realtype) :: trefinv, t, dt, t2, alp, cv
789  intrinsic max
790  intrinsic log
791  intrinsic abs
792  real(kind=realtype) :: abs0
793 ! determine the cp model used in the computation.
794  select case (cpmodel)
795  case (cpconstant)
796 ! constant cp and thus constant gamma. the relation
797 ! eint = cv*t can be used and consequently the standard
798 ! relation between pressure and internal energy is valid.
799 ! abbreviate some constants that occur in the pressure
800 ! computation.
801  gm1 = gammaconstant - one
802  factk = five*third - gammaconstant
803 ! loop over the cells. take the possible pointer
804 ! offset into account and store the pressure in the
805 ! position w(:,:,:, irhoe).
806  do k=kbeg,kend
807  kp = k + pointeroffset
808  do j=jbeg,jend
809  jp = j + pointeroffset
810  do i=ibeg,iend
811  ip = i + pointeroffset
812  v2 = w(ip, jp, kp, ivx)**2 + w(ip, jp, kp, ivy)**2 + w(ip, &
813 & jp, kp, ivz)**2
814  w(i, j, k, irhoe) = gm1*(w(ip, jp, kp, irhoe)-half*w(ip, jp&
815 & , kp, irho)*v2)
816  if (w(i, j, k, irhoe) .lt. 1.e-5_realtype*pinf) then
817  w(i, j, k, irhoe) = 1.e-5_realtype*pinf
818  else
819  w(i, j, k, irhoe) = w(i, j, k, irhoe)
820  end if
821  end do
822  end do
823  end do
824 ! correct p if a k-equation is present.
825  if (kpresent) then
826  do k=kbeg,kend
827  kp = k + pointeroffset
828  do j=jbeg,jend
829  jp = j + pointeroffset
830  do i=ibeg,iend
831  ip = i + pointeroffset
832  w(i, j, k, irhoe) = w(i, j, k, irhoe) + factk*w(ip, jp, kp&
833 & , irho)*w(ip, jp, kp, itu1)
834  end do
835  end do
836  end do
837  end if
838  case (cptempcurvefits)
839 ! ================================================================
840 ! cp as function of the temperature is given via curve fits.
841 ! store a scale factor when converting the nondimensional
842 ! energy to the units of cpeint
843  trefinv = one/tref
844  scale = tref/rgas
845 ! loop over the cells to compute the internal energy per
846 ! unit mass. this is stored in w(:,:,:,irhoe) for the moment.
847  do k=kbeg,kend
848  kp = k + pointeroffset
849  do j=jbeg,jend
850  jp = j + pointeroffset
851  do i=ibeg,iend
852  ip = i + pointeroffset
853  w(i, j, k, irhoe) = w(ip, jp, kp, irhoe)/w(ip, jp, kp, irho)
854  if (kpresent) w(i, j, k, irhoe) = w(i, j, k, irhoe) - w(ip, &
855 & jp, kp, itu1)
856  v2 = w(ip, jp, kp, ivx)**2 + w(ip, jp, kp, ivy)**2 + w(ip, &
857 & jp, kp, ivz)**2
858  w(i, j, k, irhoe) = w(i, j, k, irhoe) - half*v2
859  end do
860  end do
861  end do
862 ! newton algorithm to compute the temperature from the known
863 ! value of the internal energy.
864  do k=kbeg,kend
865  kp = k + pointeroffset
866  do j=jbeg,jend
867  jp = j + pointeroffset
868  do i=ibeg,iend
869  ip = i + pointeroffset
870 ! store the internal energy in the same dimensional
871 ! units as cpeint.
872  e0 = scale*w(i, j, k, irhoe)
873 ! take care of the exceptional cases.
874  if (e0 .le. cpeint(0)) then
875 ! energy smaller than the lowest value of the curve
876 ! fit. use extrapolation using constant cv.
877  t = trefinv*(cptrange(0)+(e0-cpeint(0))/cv0)
878  else if (e0 .ge. cpeint(cpnparts)) then
879 ! energy larger than the largest value of the curve
880 ! fit. use extrapolation using constant cv.
881  t = trefinv*(cptrange(cpnparts)+(e0-cpeint(cpnparts))/cvn)
882  else
883 ! the value is in the range of the curve fits.
884 ! a newton algorithm is used to find the temperature.
885 ! first find the curve fit interval to be searched.
886  ii = cpnparts
887  start = 1
888  interval:do
889 ! next guess for the interval.
890  nn = start + ii/2
891 ! determine the situation we are having here.
892  if (e0 .gt. cpeint(nn)) then
893 ! energy is larger than the upper boundary of
894 ! the current interval. update the lower
895 ! boundary.
896  start = nn + 1
897  ii = ii - 1
898  else if (e0 .ge. cpeint(nn-1)) then
899 ! nn contains the range in which the newton algorithm
900 ! must be applied.
901 ! initial guess of the dimensional temperature.
902  alp = (cpeint(nn)-e0)/(cpeint(nn)-cpeint(nn-1))
903  t = alp*cptrange(nn-1) + (one-alp)*cptrange(nn)
904 ! the actual newton algorithm to compute the
905 ! temperature.
906  newton:do
907 ! compute the internal energy as well as the
908 ! value of cv/r for the given temperature.
909 ! cv/r = cp/r - 1.0
910  cv = -one
911 ! e = integral of cv,
912  e = cptempfit(nn)%eint0 - t
913 ! not of cp.
914  do ii=1,cptempfit(nn)%nterm
915 ! update cv.
916  t2 = t**cptempfit(nn)%exponents(ii)
917  cv = cv + cptempfit(nn)%constants(ii)*t2
918 ! update e, for which this contribution must be
919 ! integrated. take the exceptional case that the
920 ! exponent == -1 into account.
921  if (cptempfit(nn)%exponents(ii) .eq. -1_inttype) &
922 & then
923  e = e + cptempfit(nn)%constants(ii)*log(t)
924  else
925  e = e + cptempfit(nn)%constants(ii)*t2*t/(&
926 & cptempfit(nn)%exponents(ii)+1)
927  end if
928  end do
929 ! compute the update and the new temperature.
930  dt = (e0-e)/cv
931  t = t + dt
932  if (dt .ge. 0.) then
933  abs0 = dt
934  else
935  abs0 = -dt
936  end if
937 ! exit the newton loop if the update is smaller
938 ! than the threshold value.
939  if (abs0 .lt. dtstop) then
940 ! create the nondimensional temperature.
941  t = t*trefinv
942  goto 100
943  end if
944  end do newton
945  end if
946 ! this is the correct range. exit the do-loop.
947 ! modify ii for the next branch to search.
948  ii = ii/2
949  end do interval
950  end if
951 ! compute the pressure from the known temperature
952 ! and density. include the correction if a k-equation
953 ! is present.
954  100 w(i, j, k, irhoe) = w(ip, jp, kp, irho)*rgas*t
955  if (w(i, j, k, irhoe) .lt. 1.e-5_realtype*pinf) then
956  w(i, j, k, irhoe) = 1.e-5_realtype*pinf
957  else
958  w(i, j, k, irhoe) = w(i, j, k, irhoe)
959  end if
960  if (kpresent) w(i, j, k, irhoe) = w(i, j, k, irhoe) + &
961 & twothird*w(ip, jp, kp, irho)*w(ip, jp, kp, itu1)
962  end do
963  end do
964  end do
965  end select
966  end subroutine computepressure
967 
968 ! differentiation of computelamviscosity in forward (tangent) mode (with options i4 dr8 r8):
969 ! variations of useful results: *rlv
970 ! with respect to varying inputs: muref tref rgas *p *w
971 ! rw status of diff variables: muref:in tref:in rgas:in *p:in
972 ! *w:in *rlv:out
973 ! plus diff mem management of: p:in w:in rlv:in
974  subroutine computelamviscosity_d(includehalos)
975 !
976 ! computelamviscosity computes the laminar viscosity ratio in
977 ! the owned cell centers of the given block. sutherland's law is
978 ! used. it is assumed that the pointes already point to the
979 ! correct block before entering this subroutine.
980 !
981  use blockpointers
982  use constants
983  use flowvarrefstate
984  use inputphysics
985  use iteration
986  use utils_d, only : getcorrectfork
987  implicit none
988 ! input variables
989  logical, intent(in) :: includehalos
990 !
991 ! local parameter.
992 !
993  real(kind=realtype), parameter :: twothird=two*third
994 !
995 ! local variables.
996 !
997  integer(kind=inttype) :: i, j, k, ii
998  real(kind=realtype) :: musuth, tsuth, ssuth, t, pp
999  real(kind=realtype) :: musuthd, tsuthd, ssuthd, td, ppd
1000  logical :: correctfork
1001  integer(kind=inttype) :: ibeg, iend, isize, jbeg, jend, jsize, kbeg&
1002 & , kend, ksize
1003  real(kind=realtype) :: temp
1004  real(kind=realtype) :: temp0
1005  real(kind=realtype) :: temp1
1006 ! return immediately if no laminar viscosity needs to be computed.
1007  if (.not.viscous) then
1008  if (associated(rlvd)) rlvd = 0.0_8
1009  return
1010  else
1011 ! determine whether or not the pressure must be corrected
1012 ! for the presence of the turbulent kinetic energy.
1013  correctfork = getcorrectfork()
1014 ! compute the nondimensional constants in sutherland's law.
1015  musuthd = -(musuthdim*murefd/muref**2)
1016  musuth = musuthdim/muref
1017  tsuthd = -(tsuthdim*trefd/tref**2)
1018  tsuth = tsuthdim/tref
1019  ssuthd = -(ssuthdim*trefd/tref**2)
1020  ssuth = ssuthdim/tref
1021  if (includehalos) then
1022  ibeg = 1
1023  jbeg = 1
1024  kbeg = 1
1025  iend = ie
1026  jend = je
1027  kend = ke
1028  else
1029  ibeg = 2
1030  jbeg = 2
1031  kbeg = 2
1032  iend = il
1033  jend = jl
1034  kend = kl
1035  end if
1036 ! substract 2/3 rho k, which is a part of the normal turbulent
1037 ! stresses, in case the pressure must be corrected.
1038  if (correctfork) then
1039  if (associated(rlvd)) rlvd = 0.0_8
1040  do k=kbeg,kend
1041  do j=jbeg,jend
1042  do i=ibeg,iend
1043  temp = w(i, j, k, itu1)
1044  temp0 = w(i, j, k, irho)
1045  ppd = pd(i, j, k) - twothird*(temp*wd(i, j, k, irho)+temp0&
1046 & *wd(i, j, k, itu1))
1047  pp = p(i, j, k) - twothird*(temp0*temp)
1048  temp0 = w(i, j, k, irho)
1049  temp = rgas*temp0
1050  td = (ppd-pp*(temp0*rgasd+rgas*wd(i, j, k, irho))/temp)/&
1051 & temp
1052  t = pp/temp
1053  temp0 = t/tsuth
1054  temp = temp0**1.5_realtype
1055  temp1 = musuth*(tsuth+ssuth)/(t+ssuth)
1056  rlvd(i, j, k) = temp*((tsuth+ssuth)*musuthd+musuth*(tsuthd&
1057 & +ssuthd)-temp1*(td+ssuthd))/(t+ssuth) + temp1*&
1058 & 1.5_realtype*temp0**0.5*(td-temp0*tsuthd)/tsuth
1059  rlv(i, j, k) = temp1*temp
1060  end do
1061  end do
1062  end do
1063  else
1064  if (associated(rlvd)) rlvd = 0.0_8
1065 ! loop over the owned cells *and* first level halos of this
1066 ! block and compute the laminar viscosity ratio.
1067  do k=kbeg,kend
1068  do j=jbeg,jend
1069  do i=ibeg,iend
1070 ! compute the nondimensional temperature and the
1071 ! nondimensional laminar viscosity.
1072  temp1 = w(i, j, k, irho)
1073  temp0 = p(i, j, k)/(rgas*temp1)
1074  td = (pd(i, j, k)-temp0*(temp1*rgasd+rgas*wd(i, j, k, irho&
1075 & )))/(rgas*temp1)
1076  t = temp0
1077  temp1 = t/tsuth
1078  temp0 = temp1**1.5_realtype
1079  temp = musuth*(tsuth+ssuth)/(t+ssuth)
1080  rlvd(i, j, k) = temp0*((tsuth+ssuth)*musuthd+musuth*(&
1081 & tsuthd+ssuthd)-temp*(td+ssuthd))/(t+ssuth) + temp*&
1082 & 1.5_realtype*temp1**0.5*(td-temp1*tsuthd)/tsuth
1083  rlv(i, j, k) = temp*temp0
1084  end do
1085  end do
1086  end do
1087  end if
1088  end if
1089  end subroutine computelamviscosity_d
1090 
1091  subroutine computelamviscosity(includehalos)
1092 !
1093 ! computelamviscosity computes the laminar viscosity ratio in
1094 ! the owned cell centers of the given block. sutherland's law is
1095 ! used. it is assumed that the pointes already point to the
1096 ! correct block before entering this subroutine.
1097 !
1098  use blockpointers
1099  use constants
1100  use flowvarrefstate
1101  use inputphysics
1102  use iteration
1103  use utils_d, only : getcorrectfork
1104  implicit none
1105 ! input variables
1106  logical, intent(in) :: includehalos
1107 !
1108 ! local parameter.
1109 !
1110  real(kind=realtype), parameter :: twothird=two*third
1111 !
1112 ! local variables.
1113 !
1114  integer(kind=inttype) :: i, j, k, ii
1115  real(kind=realtype) :: musuth, tsuth, ssuth, t, pp
1116  logical :: correctfork
1117  integer(kind=inttype) :: ibeg, iend, isize, jbeg, jend, jsize, kbeg&
1118 & , kend, ksize
1119 ! return immediately if no laminar viscosity needs to be computed.
1120  if (.not.viscous) then
1121  return
1122  else
1123 ! determine whether or not the pressure must be corrected
1124 ! for the presence of the turbulent kinetic energy.
1125  correctfork = getcorrectfork()
1126 ! compute the nondimensional constants in sutherland's law.
1127  musuth = musuthdim/muref
1128  tsuth = tsuthdim/tref
1129  ssuth = ssuthdim/tref
1130  if (includehalos) then
1131  ibeg = 1
1132  jbeg = 1
1133  kbeg = 1
1134  iend = ie
1135  jend = je
1136  kend = ke
1137  else
1138  ibeg = 2
1139  jbeg = 2
1140  kbeg = 2
1141  iend = il
1142  jend = jl
1143  kend = kl
1144  end if
1145 ! substract 2/3 rho k, which is a part of the normal turbulent
1146 ! stresses, in case the pressure must be corrected.
1147  if (correctfork) then
1148  do k=kbeg,kend
1149  do j=jbeg,jend
1150  do i=ibeg,iend
1151  pp = p(i, j, k) - twothird*w(i, j, k, irho)*w(i, j, k, &
1152 & itu1)
1153  t = pp/(rgas*w(i, j, k, irho))
1154  rlv(i, j, k) = musuth*((tsuth+ssuth)/(t+ssuth))*(t/tsuth)&
1155 & **1.5_realtype
1156  end do
1157  end do
1158  end do
1159  else
1160 ! loop over the owned cells *and* first level halos of this
1161 ! block and compute the laminar viscosity ratio.
1162  do k=kbeg,kend
1163  do j=jbeg,jend
1164  do i=ibeg,iend
1165 ! compute the nondimensional temperature and the
1166 ! nondimensional laminar viscosity.
1167  t = p(i, j, k)/(rgas*w(i, j, k, irho))
1168  rlv(i, j, k) = musuth*((tsuth+ssuth)/(t+ssuth))*(t/tsuth)&
1169 & **1.5_realtype
1170  end do
1171  end do
1172  end do
1173  end if
1174  end if
1175  end subroutine computelamviscosity
1176 
1177 ! differentiation of adjustinflowangle in forward (tangent) mode (with options i4 dr8 r8):
1178 ! variations of useful results: veldirfreestream dragdirection
1179 ! liftdirection
1180 ! with respect to varying inputs: alpha beta
1181 ! rw status of diff variables: alpha:in veldirfreestream:out
1182 ! beta:in dragdirection:out liftdirection:out
1183  subroutine adjustinflowangle_d()
1184  use constants
1185  use inputphysics, only : alpha, alphad, beta, betad, liftindex, &
1188  implicit none
1189 !local vars
1190  real(kind=realtype), dimension(3) :: refdir1, refdir2
1191 ! velocity direction given by the rotation of a unit vector
1192 ! initially aligned along the positive x-direction (1,0,0)
1193 ! 1) rotate alpha radians cw about y or z-axis
1194 ! 2) rotate beta radians ccw about z or y-axis
1195  refdir1(:) = zero
1196  refdir1(1) = one
1197  call getdirvector_d(refdir1, alpha, alphad, beta, betad, &
1199 ! drag direction given by the rotation of a unit vector
1200 ! initially aligned along the positive x-direction (1,0,0)
1201 ! 1) rotate alpha radians cw about y or z-axis
1202 ! 2) rotate beta radians ccw about z or y-axis
1203  call getdirvector_d(refdir1, alpha, alphad, beta, betad, &
1205 ! lift direction given by the rotation of a unit vector
1206 ! initially aligned along the positive z-direction (0,0,1)
1207 ! 1) rotate alpha radians cw about y or z-axis
1208 ! 2) rotate beta radians ccw about z or y-axis
1209  refdir2(:) = zero
1210  refdir2(liftindex) = one
1211  call getdirvector_d(refdir2, alpha, alphad, beta, betad, &
1213  end subroutine adjustinflowangle_d
1214 
1215  subroutine adjustinflowangle()
1216  use constants
1219  implicit none
1220 !local vars
1221  real(kind=realtype), dimension(3) :: refdir1, refdir2
1222 ! velocity direction given by the rotation of a unit vector
1223 ! initially aligned along the positive x-direction (1,0,0)
1224 ! 1) rotate alpha radians cw about y or z-axis
1225 ! 2) rotate beta radians ccw about z or y-axis
1226  refdir1(:) = zero
1227  refdir1(1) = one
1229 ! drag direction given by the rotation of a unit vector
1230 ! initially aligned along the positive x-direction (1,0,0)
1231 ! 1) rotate alpha radians cw about y or z-axis
1232 ! 2) rotate beta radians ccw about z or y-axis
1233  call getdirvector(refdir1, alpha, beta, dragdirection, liftindex)
1234 ! lift direction given by the rotation of a unit vector
1235 ! initially aligned along the positive z-direction (0,0,1)
1236 ! 1) rotate alpha radians cw about y or z-axis
1237 ! 2) rotate beta radians ccw about z or y-axis
1238  refdir2(:) = zero
1239  refdir2(liftindex) = one
1240  call getdirvector(refdir2, alpha, beta, liftdirection, liftindex)
1241  end subroutine adjustinflowangle
1242 
1243 ! differentiation of derivativerotmatrixrigid in forward (tangent) mode (with options i4 dr8 r8):
1244 ! variations of useful results: rotationmatrix
1245 ! with respect to varying inputs: timeref
1246  subroutine derivativerotmatrixrigid_d(rotationmatrix, rotationmatrixd&
1247 & , rotationpoint, t)
1248 !
1249 ! derivativerotmatrixrigid determines the derivative of the
1250 ! rotation matrix at the given time for the rigid body rotation,
1251 ! such that the grid velocities can be determined analytically.
1252 ! also the rotation point of the current time level is
1253 ! determined. this value can change due to translation of the
1254 ! entire grid.
1255 !
1256  use constants
1257  use flowvarrefstate
1258  use inputmotion
1259  use monitor
1262  implicit none
1263 !
1264 ! subroutine arguments.
1265 !
1266  real(kind=realtype), intent(in) :: t
1267  real(kind=realtype), dimension(3), intent(out) :: rotationpoint
1268  real(kind=realtype), dimension(3, 3), intent(out) :: rotationmatrix
1269  real(kind=realtype), dimension(3, 3), intent(out) :: rotationmatrixd
1270 !
1271 ! local variables.
1272 !
1273  integer(kind=inttype) :: i, j
1274  real(kind=realtype) :: phi, dphix, dphiy, dphiz
1275  real(kind=realtype) :: dphixd, dphiyd, dphizd
1276  real(kind=realtype) :: cosx, cosy, cosz, sinx, siny, sinz
1277  real(kind=realtype), dimension(3, 3) :: dm, m
1278  real(kind=realtype), dimension(3, 3) :: dmd
1279  intrinsic sin
1280  intrinsic cos
1281  real(kind=realtype) :: temp
1282 ! determine the rotation angle around the x-axis for the new
1283 ! time level and the corresponding values of the sine and cosine.
1286  sinx = sin(phi)
1287  cosx = cos(phi)
1288 ! idem for the y-axis.
1291  siny = sin(phi)
1292  cosy = cos(phi)
1293 ! idem for the z-axis.
1296  sinz = sin(phi)
1297  cosz = cos(phi)
1298 ! compute the time derivative of the rotation angles around the
1299 ! x-axis, y-axis and z-axis.
1302 & , dphix)
1305 & , dphiy)
1308 & , dphiz)
1309 ! compute the time derivative of the rotation matrix applied to
1310 ! the coordinates at t == 0.
1311 ! part 1. derivative of the z-rotation matrix multiplied by the
1312 ! x and y rotation matrix, i.e. dmz * my * mx
1313  dmd = 0.0_8
1314  dmd(1, 1) = -(cosy*sinz*dphizd)
1315  dm(1, 1) = -(cosy*sinz*dphiz)
1316  temp = -(cosx*cosz) - sinx*siny*sinz
1317  dmd(1, 2) = temp*dphizd
1318  dm(1, 2) = temp*dphiz
1319  temp = sinx*cosz - cosx*siny*sinz
1320  dmd(1, 3) = temp*dphizd
1321  dm(1, 3) = temp*dphiz
1322  dmd(2, 1) = cosy*cosz*dphizd
1323  dm(2, 1) = cosy*cosz*dphiz
1324  temp = sinx*siny*cosz - cosx*sinz
1325  dmd(2, 2) = temp*dphizd
1326  dm(2, 2) = temp*dphiz
1327  temp = cosx*siny*cosz + sinx*sinz
1328  dmd(2, 3) = temp*dphizd
1329  dm(2, 3) = temp*dphiz
1330  dmd(3, 1) = 0.0_8
1331  dm(3, 1) = zero
1332  dmd(3, 2) = 0.0_8
1333  dm(3, 2) = zero
1334  dmd(3, 3) = 0.0_8
1335  dm(3, 3) = zero
1336 ! part 2: mz * dmy * mx.
1337  dmd(1, 1) = dmd(1, 1) - siny*cosz*dphiyd
1338  dm(1, 1) = dm(1, 1) - siny*cosz*dphiy
1339  dmd(1, 2) = dmd(1, 2) + sinx*cosy*cosz*dphiyd
1340  dm(1, 2) = dm(1, 2) + sinx*cosy*cosz*dphiy
1341  dmd(1, 3) = dmd(1, 3) + cosx*cosy*cosz*dphiyd
1342  dm(1, 3) = dm(1, 3) + cosx*cosy*cosz*dphiy
1343  dmd(2, 1) = dmd(2, 1) - siny*sinz*dphiyd
1344  dm(2, 1) = dm(2, 1) - siny*sinz*dphiy
1345  dmd(2, 2) = dmd(2, 2) + sinx*cosy*sinz*dphiyd
1346  dm(2, 2) = dm(2, 2) + sinx*cosy*sinz*dphiy
1347  dmd(2, 3) = dmd(2, 3) + cosx*cosy*sinz*dphiyd
1348  dm(2, 3) = dm(2, 3) + cosx*cosy*sinz*dphiy
1349  dmd(3, 1) = dmd(3, 1) - cosy*dphiyd
1350  dm(3, 1) = dm(3, 1) - cosy*dphiy
1351  dmd(3, 2) = dmd(3, 2) - sinx*siny*dphiyd
1352  dm(3, 2) = dm(3, 2) - sinx*siny*dphiy
1353  dmd(3, 3) = dmd(3, 3) - cosx*siny*dphiyd
1354  dm(3, 3) = dm(3, 3) - cosx*siny*dphiy
1355 ! part 3: mz * my * dmx
1356  temp = sinx*sinz + cosx*siny*cosz
1357  dmd(1, 2) = dmd(1, 2) + temp*dphixd
1358  dm(1, 2) = dm(1, 2) + temp*dphix
1359  temp = cosx*sinz - sinx*siny*cosz
1360  dmd(1, 3) = dmd(1, 3) + temp*dphixd
1361  dm(1, 3) = dm(1, 3) + temp*dphix
1362  temp = cosx*siny*sinz - sinx*cosz
1363  dmd(2, 2) = dmd(2, 2) + temp*dphixd
1364  dm(2, 2) = dm(2, 2) + temp*dphix
1365  temp = sinx*siny*sinz + cosx*cosz
1366  dmd(2, 3) = dmd(2, 3) - temp*dphixd
1367  dm(2, 3) = dm(2, 3) - temp*dphix
1368  dmd(3, 2) = dmd(3, 2) + cosx*cosy*dphixd
1369  dm(3, 2) = dm(3, 2) + cosx*cosy*dphix
1370  dmd(3, 3) = dmd(3, 3) - sinx*cosy*dphixd
1371  dm(3, 3) = dm(3, 3) - sinx*cosy*dphix
1372 ! determine the rotation matrix at t == t.
1373  m(1, 1) = cosy*cosz
1374  m(2, 1) = cosy*sinz
1375  m(3, 1) = -siny
1376  m(1, 2) = sinx*siny*cosz - cosx*sinz
1377  m(2, 2) = sinx*siny*sinz + cosx*cosz
1378  m(3, 2) = sinx*cosy
1379  m(1, 3) = cosx*siny*cosz + sinx*sinz
1380  m(2, 3) = cosx*siny*sinz - sinx*cosz
1381  m(3, 3) = cosx*cosy
1382  rotationmatrixd = 0.0_8
1383 ! determine the matrix product dm * inverse(m), which will give
1384 ! the derivative of the rotation matrix when applied to the
1385 ! current coordinates. note that inverse(m) == transpose(m).
1386  do j=1,3
1387  do i=1,3
1388  rotationmatrixd(i, j) = m(j, 1)*dmd(i, 1) + m(j, 2)*dmd(i, 2) + &
1389 & m(j, 3)*dmd(i, 3)
1390  rotationmatrix(i, j) = dm(i, 1)*m(j, 1) + dm(i, 2)*m(j, 2) + dm(&
1391 & i, 3)*m(j, 3)
1392  end do
1393  end do
1394 ! determine the rotation point at the new time level; it is
1395 ! possible that this value changes due to translation of the grid.
1396 ! ainf = sqrt(gammainf*pinf/rhoinf)
1397 ! rotationpoint(1) = lref*rotpoint(1) &
1398 ! + machgrid(1)*ainf*t/timeref
1399 ! rotationpoint(2) = lref*rotpoint(2) &
1400 ! + machgrid(2)*ainf*t/timeref
1401 ! rotationpoint(3) = lref*rotpoint(3) &
1402 ! + machgrid(3)*ainf*t/timeref
1403  rotationpoint(1) = lref*rotpoint(1)
1404  rotationpoint(2) = lref*rotpoint(2)
1405  rotationpoint(3) = lref*rotpoint(3)
1406  end subroutine derivativerotmatrixrigid_d
1407 
1408  subroutine derivativerotmatrixrigid(rotationmatrix, rotationpoint, t)
1409 !
1410 ! derivativerotmatrixrigid determines the derivative of the
1411 ! rotation matrix at the given time for the rigid body rotation,
1412 ! such that the grid velocities can be determined analytically.
1413 ! also the rotation point of the current time level is
1414 ! determined. this value can change due to translation of the
1415 ! entire grid.
1416 !
1417  use constants
1418  use flowvarrefstate
1419  use inputmotion
1420  use monitor
1422  implicit none
1423 !
1424 ! subroutine arguments.
1425 !
1426  real(kind=realtype), intent(in) :: t
1427  real(kind=realtype), dimension(3), intent(out) :: rotationpoint
1428  real(kind=realtype), dimension(3, 3), intent(out) :: rotationmatrix
1429 !
1430 ! local variables.
1431 !
1432  integer(kind=inttype) :: i, j
1433  real(kind=realtype) :: phi, dphix, dphiy, dphiz
1434  real(kind=realtype) :: cosx, cosy, cosz, sinx, siny, sinz
1435  real(kind=realtype), dimension(3, 3) :: dm, m
1436  intrinsic sin
1437  intrinsic cos
1438 ! determine the rotation angle around the x-axis for the new
1439 ! time level and the corresponding values of the sine and cosine.
1442  sinx = sin(phi)
1443  cosx = cos(phi)
1444 ! idem for the y-axis.
1447  siny = sin(phi)
1448  cosy = cos(phi)
1449 ! idem for the z-axis.
1452  sinz = sin(phi)
1453  cosz = cos(phi)
1454 ! compute the time derivative of the rotation angles around the
1455 ! x-axis, y-axis and z-axis.
1458 & )
1461 & )
1464 & )
1465 ! compute the time derivative of the rotation matrix applied to
1466 ! the coordinates at t == 0.
1467 ! part 1. derivative of the z-rotation matrix multiplied by the
1468 ! x and y rotation matrix, i.e. dmz * my * mx
1469  dm(1, 1) = -(cosy*sinz*dphiz)
1470  dm(1, 2) = (-(cosx*cosz)-sinx*siny*sinz)*dphiz
1471  dm(1, 3) = (sinx*cosz-cosx*siny*sinz)*dphiz
1472  dm(2, 1) = cosy*cosz*dphiz
1473  dm(2, 2) = (sinx*siny*cosz-cosx*sinz)*dphiz
1474  dm(2, 3) = (cosx*siny*cosz+sinx*sinz)*dphiz
1475  dm(3, 1) = zero
1476  dm(3, 2) = zero
1477  dm(3, 3) = zero
1478 ! part 2: mz * dmy * mx.
1479  dm(1, 1) = dm(1, 1) - siny*cosz*dphiy
1480  dm(1, 2) = dm(1, 2) + sinx*cosy*cosz*dphiy
1481  dm(1, 3) = dm(1, 3) + cosx*cosy*cosz*dphiy
1482  dm(2, 1) = dm(2, 1) - siny*sinz*dphiy
1483  dm(2, 2) = dm(2, 2) + sinx*cosy*sinz*dphiy
1484  dm(2, 3) = dm(2, 3) + cosx*cosy*sinz*dphiy
1485  dm(3, 1) = dm(3, 1) - cosy*dphiy
1486  dm(3, 2) = dm(3, 2) - sinx*siny*dphiy
1487  dm(3, 3) = dm(3, 3) - cosx*siny*dphiy
1488 ! part 3: mz * my * dmx
1489  dm(1, 2) = dm(1, 2) + (sinx*sinz+cosx*siny*cosz)*dphix
1490  dm(1, 3) = dm(1, 3) + (cosx*sinz-sinx*siny*cosz)*dphix
1491  dm(2, 2) = dm(2, 2) + (cosx*siny*sinz-sinx*cosz)*dphix
1492  dm(2, 3) = dm(2, 3) - (sinx*siny*sinz+cosx*cosz)*dphix
1493  dm(3, 2) = dm(3, 2) + cosx*cosy*dphix
1494  dm(3, 3) = dm(3, 3) - sinx*cosy*dphix
1495 ! determine the rotation matrix at t == t.
1496  m(1, 1) = cosy*cosz
1497  m(2, 1) = cosy*sinz
1498  m(3, 1) = -siny
1499  m(1, 2) = sinx*siny*cosz - cosx*sinz
1500  m(2, 2) = sinx*siny*sinz + cosx*cosz
1501  m(3, 2) = sinx*cosy
1502  m(1, 3) = cosx*siny*cosz + sinx*sinz
1503  m(2, 3) = cosx*siny*sinz - sinx*cosz
1504  m(3, 3) = cosx*cosy
1505 ! determine the matrix product dm * inverse(m), which will give
1506 ! the derivative of the rotation matrix when applied to the
1507 ! current coordinates. note that inverse(m) == transpose(m).
1508  do j=1,3
1509  do i=1,3
1510  rotationmatrix(i, j) = dm(i, 1)*m(j, 1) + dm(i, 2)*m(j, 2) + dm(&
1511 & i, 3)*m(j, 3)
1512  end do
1513  end do
1514 ! determine the rotation point at the new time level; it is
1515 ! possible that this value changes due to translation of the grid.
1516 ! ainf = sqrt(gammainf*pinf/rhoinf)
1517 ! rotationpoint(1) = lref*rotpoint(1) &
1518 ! + machgrid(1)*ainf*t/timeref
1519 ! rotationpoint(2) = lref*rotpoint(2) &
1520 ! + machgrid(2)*ainf*t/timeref
1521 ! rotationpoint(3) = lref*rotpoint(3) &
1522 ! + machgrid(3)*ainf*t/timeref
1523  rotationpoint(1) = lref*rotpoint(1)
1524  rotationpoint(2) = lref*rotpoint(2)
1525  rotationpoint(3) = lref*rotpoint(3)
1526  end subroutine derivativerotmatrixrigid
1527 
1528 ! differentiation of getdirvector in forward (tangent) mode (with options i4 dr8 r8):
1529 ! variations of useful results: winddirection
1530 ! with respect to varying inputs: alpha beta
1531  subroutine getdirvector_d(refdirection, alpha, alphad, beta, betad, &
1532 & winddirection, winddirectiond, liftindex)
1533 !(xb,yb,zb,alpha,beta,xw,yw,zw)
1534 !
1535 ! convert the angle of attack and side slip angle to wind axes.
1536 ! the components of the wind direction vector (xw,yw,zw) are
1537 ! computed given the direction angles in radians and the body
1538 ! direction by performing two rotations on the original
1539 ! direction vector:
1540 ! 1) rotation about the zb or yb-axis: alpha clockwise (cw)
1541 ! (xb,yb,zb) -> (x1,y1,z1)
1542 ! 2) rotation about the yl or z1-axis: beta counter-clockwise
1543 ! (ccw) (x1,y1,z1) -> (xw,yw,zw)
1544 ! input arguments:
1545 ! alpha = angle of attack in radians
1546 ! beta = side slip angle in radians
1547 ! refdirection = reference direction vector
1548 ! output arguments:
1549 ! winddirection = unit wind vector in body axes
1550 !
1551  use constants
1552  use utils_d, only : terminate
1553  implicit none
1554 !
1555 ! subroutine arguments.
1556 !
1557  real(kind=realtype), dimension(3), intent(in) :: refdirection
1558  real(kind=realtype) :: alpha, beta
1559  real(kind=realtype) :: alphad, betad
1560  real(kind=realtype), dimension(3), intent(out) :: winddirection
1561  real(kind=realtype), dimension(3), intent(out) :: winddirectiond
1562  integer(kind=inttype) :: liftindex
1563 !
1564 ! local variables.
1565 !
1566  real(kind=realtype) :: rnorm, x1, y1, z1, xbn, ybn, zbn, xw, yw, zw
1567  real(kind=realtype) :: x1d, y1d, z1d, xbnd, ybnd, zbnd, xwd, ywd, &
1568 & zwd
1569  real(kind=realtype) :: tmp
1570  real(kind=realtype) :: tmpd
1571  intrinsic sqrt
1572  real(kind=realtype) :: arg1
1573 ! normalize the input vector.
1574  arg1 = refdirection(1)**2 + refdirection(2)**2 + refdirection(3)**2
1575  rnorm = sqrt(arg1)
1576  xbn = refdirection(1)/rnorm
1577  ybn = refdirection(2)/rnorm
1578  zbn = refdirection(3)/rnorm
1579 !!$ ! compute the wind direction vector.
1580 !!$
1581 !!$ ! 1) rotate alpha radians cw about y-axis
1582 !!$ ! ( <=> rotate y-axis alpha radians ccw)
1583 !!$
1584 !!$ call vectorrotation(x1, y1, z1, 2, alpha, xbn, ybn, zbn)
1585 !!$
1586 !!$ ! 2) rotate beta radians ccw about z-axis
1587 !!$ ! ( <=> rotate z-axis -beta radians ccw)
1588 !!$
1589 !!$ call vectorrotation(xw, yw, zw, 3, -beta, x1, y1, z1)
1590  if (liftindex .eq. 2) then
1591 ! compute the wind direction vector.aerosurf axes different!!
1592 ! 1) rotate alpha radians cw about z-axis
1593 ! ( <=> rotate z-axis alpha radians ccw)
1594  tmpd = -alphad
1595  tmp = -alpha
1596  zbnd = 0.0_8
1597  ybnd = 0.0_8
1598  xbnd = 0.0_8
1599  call vectorrotation_d(x1, x1d, y1, y1d, z1, z1d, 3, tmp, tmpd, xbn&
1600 & , xbnd, ybn, ybnd, zbn, zbnd)
1601 ! 2) rotate beta radians ccw about y-axis
1602 ! ( <=> rotate z-axis -beta radians ccw)
1603  tmpd = -betad
1604  tmp = -beta
1605  call vectorrotation_d(xw, xwd, yw, ywd, zw, zwd, 2, tmp, tmpd, x1&
1606 & , x1d, y1, y1d, z1, z1d)
1607  else if (liftindex .eq. 3) then
1608 ! compute the wind direction vector.aerosurf axes different!!
1609 ! 1) rotate alpha radians cw about z-axis
1610 ! ( <=> rotate z-axis alpha radians ccw)
1611  zbnd = 0.0_8
1612  ybnd = 0.0_8
1613  xbnd = 0.0_8
1614  call vectorrotation_d(x1, x1d, y1, y1d, z1, z1d, 2, alpha, alphad&
1615 & , xbn, xbnd, ybn, ybnd, zbn, zbnd)
1616 ! 2) rotate beta radians ccw about y-axis
1617 ! ( <=> rotate z-axis -beta radians ccw)
1618  call vectorrotation_d(xw, xwd, yw, ywd, zw, zwd, 3, beta, betad, &
1619 & x1, x1d, y1, y1d, z1, z1d)
1620  else
1621  call terminate('getdirvector', 'invalid lift direction')
1622  zwd = 0.0_8
1623  xwd = 0.0_8
1624  ywd = 0.0_8
1625  end if
1626  winddirectiond = 0.0_8
1627  winddirectiond(1) = xwd
1628  winddirection(1) = xw
1629  winddirectiond(2) = ywd
1630  winddirection(2) = yw
1631  winddirectiond(3) = zwd
1632  winddirection(3) = zw
1633  end subroutine getdirvector_d
1634 
1635  subroutine getdirvector(refdirection, alpha, beta, winddirection, &
1636 & liftindex)
1637 !(xb,yb,zb,alpha,beta,xw,yw,zw)
1638 !
1639 ! convert the angle of attack and side slip angle to wind axes.
1640 ! the components of the wind direction vector (xw,yw,zw) are
1641 ! computed given the direction angles in radians and the body
1642 ! direction by performing two rotations on the original
1643 ! direction vector:
1644 ! 1) rotation about the zb or yb-axis: alpha clockwise (cw)
1645 ! (xb,yb,zb) -> (x1,y1,z1)
1646 ! 2) rotation about the yl or z1-axis: beta counter-clockwise
1647 ! (ccw) (x1,y1,z1) -> (xw,yw,zw)
1648 ! input arguments:
1649 ! alpha = angle of attack in radians
1650 ! beta = side slip angle in radians
1651 ! refdirection = reference direction vector
1652 ! output arguments:
1653 ! winddirection = unit wind vector in body axes
1654 !
1655  use constants
1656  use utils_d, only : terminate
1657  implicit none
1658 !
1659 ! subroutine arguments.
1660 !
1661  real(kind=realtype), dimension(3), intent(in) :: refdirection
1662  real(kind=realtype) :: alpha, beta
1663  real(kind=realtype), dimension(3), intent(out) :: winddirection
1664  integer(kind=inttype) :: liftindex
1665 !
1666 ! local variables.
1667 !
1668  real(kind=realtype) :: rnorm, x1, y1, z1, xbn, ybn, zbn, xw, yw, zw
1669  real(kind=realtype) :: tmp
1670  intrinsic sqrt
1671  real(kind=realtype) :: arg1
1672 ! normalize the input vector.
1673  arg1 = refdirection(1)**2 + refdirection(2)**2 + refdirection(3)**2
1674  rnorm = sqrt(arg1)
1675  xbn = refdirection(1)/rnorm
1676  ybn = refdirection(2)/rnorm
1677  zbn = refdirection(3)/rnorm
1678 !!$ ! compute the wind direction vector.
1679 !!$
1680 !!$ ! 1) rotate alpha radians cw about y-axis
1681 !!$ ! ( <=> rotate y-axis alpha radians ccw)
1682 !!$
1683 !!$ call vectorrotation(x1, y1, z1, 2, alpha, xbn, ybn, zbn)
1684 !!$
1685 !!$ ! 2) rotate beta radians ccw about z-axis
1686 !!$ ! ( <=> rotate z-axis -beta radians ccw)
1687 !!$
1688 !!$ call vectorrotation(xw, yw, zw, 3, -beta, x1, y1, z1)
1689  if (liftindex .eq. 2) then
1690 ! compute the wind direction vector.aerosurf axes different!!
1691 ! 1) rotate alpha radians cw about z-axis
1692 ! ( <=> rotate z-axis alpha radians ccw)
1693  tmp = -alpha
1694  call vectorrotation(x1, y1, z1, 3, tmp, xbn, ybn, zbn)
1695 ! 2) rotate beta radians ccw about y-axis
1696 ! ( <=> rotate z-axis -beta radians ccw)
1697  tmp = -beta
1698  call vectorrotation(xw, yw, zw, 2, tmp, x1, y1, z1)
1699  else if (liftindex .eq. 3) then
1700 ! compute the wind direction vector.aerosurf axes different!!
1701 ! 1) rotate alpha radians cw about z-axis
1702 ! ( <=> rotate z-axis alpha radians ccw)
1703  call vectorrotation(x1, y1, z1, 2, alpha, xbn, ybn, zbn)
1704 ! 2) rotate beta radians ccw about y-axis
1705 ! ( <=> rotate z-axis -beta radians ccw)
1706  call vectorrotation(xw, yw, zw, 3, beta, x1, y1, z1)
1707  else
1708  call terminate('getdirvector', 'invalid lift direction')
1709  end if
1710  winddirection(1) = xw
1711  winddirection(2) = yw
1712  winddirection(3) = zw
1713  end subroutine getdirvector
1714 
1715 ! differentiation of vectorrotation in forward (tangent) mode (with options i4 dr8 r8):
1716 ! variations of useful results: xp yp zp
1717 ! with respect to varying inputs: x y z angle
1718  subroutine vectorrotation_d(xp, xpd, yp, ypd, zp, zpd, iaxis, angle, &
1719 & angled, x, xd, y, yd, z, zd)
1720 !
1721 ! vectorrotation rotates a given vector with respect to a
1722 ! specified axis by a given angle.
1723 ! input arguments:
1724 ! iaxis = rotation axis (1-x, 2-y, 3-z)
1725 ! angle = rotation angle (measured ccw in radians)
1726 ! x, y, z = coordinates in original system
1727 ! output arguments:
1728 ! xp, yp, zp = coordinates in rotated system
1729 !
1730  use precision
1731  implicit none
1732 !
1733 ! subroutine arguments.
1734 !
1735  integer(kind=inttype), intent(in) :: iaxis
1736  real(kind=realtype), intent(in) :: angle, x, y, z
1737  real(kind=realtype), intent(in) :: angled, xd, yd, zd
1738  real(kind=realtype), intent(out) :: xp, yp, zp
1739  real(kind=realtype), intent(out) :: xpd, ypd, zpd
1740  intrinsic cos
1741  intrinsic sin
1742  real(kind=realtype) :: temp
1743  real(kind=realtype) :: temp0
1744 ! rotation about specified axis by specified angle
1745  select case (iaxis)
1746  case (1)
1747 ! rotation about the x-axis
1748  xpd = xd
1749  xp = 1.*x + 0.*y + 0.*z
1750  temp = cos(angle)
1751  temp0 = sin(angle)
1752  ypd = temp*yd - (y*sin(angle)-z*cos(angle))*angled + temp0*zd
1753  yp = 0.*x + temp*y + temp0*z
1754  temp0 = sin(angle)
1755  temp = cos(angle)
1756  zpd = temp*zd - temp0*yd - (y*cos(angle)+z*sin(angle))*angled
1757  zp = 0.*x - temp0*y + temp*z
1758 ! rotation about the y-axis
1759  case (2)
1760  temp0 = cos(angle)
1761  temp = sin(angle)
1762  xpd = temp0*xd - (x*sin(angle)+z*cos(angle))*angled - temp*zd
1763  xp = temp0*x + 0.*y - temp*z
1764  ypd = yd
1765  yp = 0.*x + 1.*y + 0.*z
1766  temp0 = sin(angle)
1767  temp = cos(angle)
1768  zpd = (x*cos(angle)-z*sin(angle))*angled + temp0*xd + temp*zd
1769  zp = temp0*x + 0.*y + temp*z
1770 ! rotation about the z-axis
1771  case (3)
1772  temp0 = cos(angle)
1773  temp = sin(angle)
1774  xpd = temp0*xd - (x*sin(angle)-y*cos(angle))*angled + temp*yd
1775  xp = temp0*x + temp*y + 0.*z
1776  temp0 = cos(angle)
1777  temp = sin(angle)
1778  ypd = temp0*yd - (y*sin(angle)+x*cos(angle))*angled - temp*xd
1779  yp = temp0*y - temp*x + 0.*z
1780  zpd = zd
1781  zp = 0.*x + 0.*y + 1.*z
1782  case default
1783  write(*, *) 'vectorrotation called with invalid arguments'
1784  stop
1785  end select
1786  end subroutine vectorrotation_d
1787 
1788  subroutine vectorrotation(xp, yp, zp, iaxis, angle, x, y, z)
1789 !
1790 ! vectorrotation rotates a given vector with respect to a
1791 ! specified axis by a given angle.
1792 ! input arguments:
1793 ! iaxis = rotation axis (1-x, 2-y, 3-z)
1794 ! angle = rotation angle (measured ccw in radians)
1795 ! x, y, z = coordinates in original system
1796 ! output arguments:
1797 ! xp, yp, zp = coordinates in rotated system
1798 !
1799  use precision
1800  implicit none
1801 !
1802 ! subroutine arguments.
1803 !
1804  integer(kind=inttype), intent(in) :: iaxis
1805  real(kind=realtype), intent(in) :: angle, x, y, z
1806  real(kind=realtype), intent(out) :: xp, yp, zp
1807  intrinsic cos
1808  intrinsic sin
1809 ! rotation about specified axis by specified angle
1810  select case (iaxis)
1811  case (1)
1812 ! rotation about the x-axis
1813  xp = 1.*x + 0.*y + 0.*z
1814  yp = 0.*x + cos(angle)*y + sin(angle)*z
1815  zp = 0.*x - sin(angle)*y + cos(angle)*z
1816 ! rotation about the y-axis
1817  case (2)
1818  xp = cos(angle)*x + 0.*y - sin(angle)*z
1819  yp = 0.*x + 1.*y + 0.*z
1820  zp = sin(angle)*x + 0.*y + cos(angle)*z
1821 ! rotation about the z-axis
1822  case (3)
1823  xp = cos(angle)*x + sin(angle)*y + 0.*z
1824  yp = -(sin(angle)*x) + cos(angle)*y + 0.*z
1825  zp = 0.*x + 0.*y + 1.*z
1826  case default
1827  write(*, *) 'vectorrotation called with invalid arguments'
1828  stop
1829  end select
1830  end subroutine vectorrotation
1831 
1832 ! differentiation of allnodalgradients in forward (tangent) mode (with options i4 dr8 r8):
1833 ! variations of useful results: *wx *wy *wz *qx *qy *qz *ux
1834 ! *uy *uz *vx *vy *vz
1835 ! with respect to varying inputs: *aa *wx *wy *wz *w *qx *qy
1836 ! *qz *vol *ux *uy *uz *si *sj *sk *vx *vy *vz
1837 ! rw status of diff variables: *aa:in *wx:in-out *wy:in-out *wz:in-out
1838 ! *w:in *qx:in-out *qy:in-out *qz:in-out *vol:in
1839 ! *ux:in-out *uy:in-out *uz:in-out *si:in *sj:in
1840 ! *sk:in *vx:in-out *vy:in-out *vz:in-out
1841 ! plus diff mem management of: aa:in wx:in wy:in wz:in w:in qx:in
1842 ! qy:in qz:in vol:in ux:in uy:in uz:in si:in sj:in
1843 ! sk:in vx:in vy:in vz:in
1844  subroutine allnodalgradients_d()
1845 !
1846 ! nodalgradients computes the nodal velocity gradients and
1847 ! minus the gradient of the speed of sound squared. the minus
1848 ! sign is present, because this is the definition of the heat
1849 ! flux. these gradients are computed for all nodes.
1850 !
1851  use constants
1852  use blockpointers
1853  implicit none
1854 ! local variables.
1855  integer(kind=inttype) :: i, j, k
1856  integer(kind=inttype) :: k1, kk
1857  integer(kind=inttype) :: istart, iend, isize, ii
1858  integer(kind=inttype) :: jstart, jend, jsize
1859  integer(kind=inttype) :: kstart, kend, ksize
1860  real(kind=realtype) :: oneoverv, ubar, vbar, wbar, a2
1861  real(kind=realtype) :: oneovervd, ubard, vbard, wbard, a2d
1862  real(kind=realtype) :: sx, sx1, sy, sy1, sz, sz1
1863  real(kind=realtype) :: sxd, syd, szd
1864  real(kind=realtype) :: temp
1865 ! zero all nodeal gradients:
1866  uxd = 0.0_8
1867  ux = zero
1868  uyd = 0.0_8
1869  uy = zero
1870  uzd = 0.0_8
1871  uz = zero
1872  vxd = 0.0_8
1873  vx = zero
1874  vyd = 0.0_8
1875  vy = zero
1876  vzd = 0.0_8
1877  vz = zero
1878  wxd = 0.0_8
1879  wx = zero
1880  wyd = 0.0_8
1881  wy = zero
1882  wzd = 0.0_8
1883  wz = zero
1884  qxd = 0.0_8
1885  qx = zero
1886  qyd = 0.0_8
1887  qy = zero
1888  qzd = 0.0_8
1889  qz = zero
1890 ! first part. contribution in the k-direction.
1891 ! the contribution is scattered to both the left and right node
1892 ! in k-direction.
1893  do k=1,ke
1894  do j=1,jl
1895  do i=1,il
1896 ! compute 8 times the average normal for this part of
1897 ! the control volume. the factor 8 is taken care of later
1898 ! on when the division by the volume takes place.
1899  sxd = skd(i, j, k-1, 1) + skd(i+1, j, k-1, 1) + skd(i, j+1, k-&
1900 & 1, 1) + skd(i+1, j+1, k-1, 1) + skd(i, j, k, 1) + skd(i+1, j&
1901 & , k, 1) + skd(i, j+1, k, 1) + skd(i+1, j+1, k, 1)
1902  sx = sk(i, j, k-1, 1) + sk(i+1, j, k-1, 1) + sk(i, j+1, k-1, 1&
1903 & ) + sk(i+1, j+1, k-1, 1) + sk(i, j, k, 1) + sk(i+1, j, k, 1)&
1904 & + sk(i, j+1, k, 1) + sk(i+1, j+1, k, 1)
1905  syd = skd(i, j, k-1, 2) + skd(i+1, j, k-1, 2) + skd(i, j+1, k-&
1906 & 1, 2) + skd(i+1, j+1, k-1, 2) + skd(i, j, k, 2) + skd(i+1, j&
1907 & , k, 2) + skd(i, j+1, k, 2) + skd(i+1, j+1, k, 2)
1908  sy = sk(i, j, k-1, 2) + sk(i+1, j, k-1, 2) + sk(i, j+1, k-1, 2&
1909 & ) + sk(i+1, j+1, k-1, 2) + sk(i, j, k, 2) + sk(i+1, j, k, 2)&
1910 & + sk(i, j+1, k, 2) + sk(i+1, j+1, k, 2)
1911  szd = skd(i, j, k-1, 3) + skd(i+1, j, k-1, 3) + skd(i, j+1, k-&
1912 & 1, 3) + skd(i+1, j+1, k-1, 3) + skd(i, j, k, 3) + skd(i+1, j&
1913 & , k, 3) + skd(i, j+1, k, 3) + skd(i+1, j+1, k, 3)
1914  sz = sk(i, j, k-1, 3) + sk(i+1, j, k-1, 3) + sk(i, j+1, k-1, 3&
1915 & ) + sk(i+1, j+1, k-1, 3) + sk(i, j, k, 3) + sk(i+1, j, k, 3)&
1916 & + sk(i, j+1, k, 3) + sk(i+1, j+1, k, 3)
1917 ! compute the average velocities and speed of sound squared
1918 ! for this integration point. node that these variables are
1919 ! stored in w(ivx), w(ivy), w(ivz) and p.
1920  ubard = fourth*(wd(i, j, k, ivx)+wd(i+1, j, k, ivx)+wd(i, j+1&
1921 & , k, ivx)+wd(i+1, j+1, k, ivx))
1922  ubar = fourth*(w(i, j, k, ivx)+w(i+1, j, k, ivx)+w(i, j+1, k, &
1923 & ivx)+w(i+1, j+1, k, ivx))
1924  vbard = fourth*(wd(i, j, k, ivy)+wd(i+1, j, k, ivy)+wd(i, j+1&
1925 & , k, ivy)+wd(i+1, j+1, k, ivy))
1926  vbar = fourth*(w(i, j, k, ivy)+w(i+1, j, k, ivy)+w(i, j+1, k, &
1927 & ivy)+w(i+1, j+1, k, ivy))
1928  wbard = fourth*(wd(i, j, k, ivz)+wd(i+1, j, k, ivz)+wd(i, j+1&
1929 & , k, ivz)+wd(i+1, j+1, k, ivz))
1930  wbar = fourth*(w(i, j, k, ivz)+w(i+1, j, k, ivz)+w(i, j+1, k, &
1931 & ivz)+w(i+1, j+1, k, ivz))
1932  a2d = fourth*(aad(i, j, k)+aad(i+1, j, k)+aad(i, j+1, k)+aad(i&
1933 & +1, j+1, k))
1934  a2 = fourth*(aa(i, j, k)+aa(i+1, j, k)+aa(i, j+1, k)+aa(i+1, j&
1935 & +1, k))
1936 ! add the contributions to the surface integral to the node
1937 ! j-1 and substract it from the node j. for the heat flux it
1938 ! is reversed, because the negative of the gradient of the
1939 ! speed of sound must be computed.
1940  if (k .gt. 1) then
1941  uxd(i, j, k-1) = uxd(i, j, k-1) + sx*ubard + ubar*sxd
1942  ux(i, j, k-1) = ux(i, j, k-1) + ubar*sx
1943  uyd(i, j, k-1) = uyd(i, j, k-1) + sy*ubard + ubar*syd
1944  uy(i, j, k-1) = uy(i, j, k-1) + ubar*sy
1945  uzd(i, j, k-1) = uzd(i, j, k-1) + sz*ubard + ubar*szd
1946  uz(i, j, k-1) = uz(i, j, k-1) + ubar*sz
1947  vxd(i, j, k-1) = vxd(i, j, k-1) + sx*vbard + vbar*sxd
1948  vx(i, j, k-1) = vx(i, j, k-1) + vbar*sx
1949  vyd(i, j, k-1) = vyd(i, j, k-1) + sy*vbard + vbar*syd
1950  vy(i, j, k-1) = vy(i, j, k-1) + vbar*sy
1951  vzd(i, j, k-1) = vzd(i, j, k-1) + sz*vbard + vbar*szd
1952  vz(i, j, k-1) = vz(i, j, k-1) + vbar*sz
1953  wxd(i, j, k-1) = wxd(i, j, k-1) + sx*wbard + wbar*sxd
1954  wx(i, j, k-1) = wx(i, j, k-1) + wbar*sx
1955  wyd(i, j, k-1) = wyd(i, j, k-1) + sy*wbard + wbar*syd
1956  wy(i, j, k-1) = wy(i, j, k-1) + wbar*sy
1957  wzd(i, j, k-1) = wzd(i, j, k-1) + sz*wbard + wbar*szd
1958  wz(i, j, k-1) = wz(i, j, k-1) + wbar*sz
1959  qxd(i, j, k-1) = qxd(i, j, k-1) - sx*a2d - a2*sxd
1960  qx(i, j, k-1) = qx(i, j, k-1) - a2*sx
1961  qyd(i, j, k-1) = qyd(i, j, k-1) - sy*a2d - a2*syd
1962  qy(i, j, k-1) = qy(i, j, k-1) - a2*sy
1963  qzd(i, j, k-1) = qzd(i, j, k-1) - sz*a2d - a2*szd
1964  qz(i, j, k-1) = qz(i, j, k-1) - a2*sz
1965  end if
1966  if (k .lt. ke) then
1967  uxd(i, j, k) = uxd(i, j, k) - sx*ubard - ubar*sxd
1968  ux(i, j, k) = ux(i, j, k) - ubar*sx
1969  uyd(i, j, k) = uyd(i, j, k) - sy*ubard - ubar*syd
1970  uy(i, j, k) = uy(i, j, k) - ubar*sy
1971  uzd(i, j, k) = uzd(i, j, k) - sz*ubard - ubar*szd
1972  uz(i, j, k) = uz(i, j, k) - ubar*sz
1973  vxd(i, j, k) = vxd(i, j, k) - sx*vbard - vbar*sxd
1974  vx(i, j, k) = vx(i, j, k) - vbar*sx
1975  vyd(i, j, k) = vyd(i, j, k) - sy*vbard - vbar*syd
1976  vy(i, j, k) = vy(i, j, k) - vbar*sy
1977  vzd(i, j, k) = vzd(i, j, k) - sz*vbard - vbar*szd
1978  vz(i, j, k) = vz(i, j, k) - vbar*sz
1979  wxd(i, j, k) = wxd(i, j, k) - sx*wbard - wbar*sxd
1980  wx(i, j, k) = wx(i, j, k) - wbar*sx
1981  wyd(i, j, k) = wyd(i, j, k) - sy*wbard - wbar*syd
1982  wy(i, j, k) = wy(i, j, k) - wbar*sy
1983  wzd(i, j, k) = wzd(i, j, k) - sz*wbard - wbar*szd
1984  wz(i, j, k) = wz(i, j, k) - wbar*sz
1985  qxd(i, j, k) = qxd(i, j, k) + sx*a2d + a2*sxd
1986  qx(i, j, k) = qx(i, j, k) + a2*sx
1987  qyd(i, j, k) = qyd(i, j, k) + sy*a2d + a2*syd
1988  qy(i, j, k) = qy(i, j, k) + a2*sy
1989  qzd(i, j, k) = qzd(i, j, k) + sz*a2d + a2*szd
1990  qz(i, j, k) = qz(i, j, k) + a2*sz
1991  end if
1992  end do
1993  end do
1994  end do
1995 ! second part. contribution in the j-direction.
1996 ! the contribution is scattered to both the left and right node
1997 ! in j-direction.
1998  do k=1,kl
1999  do j=1,je
2000  do i=1,il
2001 ! compute 8 times the average normal for this part of
2002 ! the control volume. the factor 8 is taken care of later
2003 ! on when the division by the volume takes place.
2004  sxd = sjd(i, j-1, k, 1) + sjd(i+1, j-1, k, 1) + sjd(i, j-1, k+&
2005 & 1, 1) + sjd(i+1, j-1, k+1, 1) + sjd(i, j, k, 1) + sjd(i+1, j&
2006 & , k, 1) + sjd(i, j, k+1, 1) + sjd(i+1, j, k+1, 1)
2007  sx = sj(i, j-1, k, 1) + sj(i+1, j-1, k, 1) + sj(i, j-1, k+1, 1&
2008 & ) + sj(i+1, j-1, k+1, 1) + sj(i, j, k, 1) + sj(i+1, j, k, 1)&
2009 & + sj(i, j, k+1, 1) + sj(i+1, j, k+1, 1)
2010  syd = sjd(i, j-1, k, 2) + sjd(i+1, j-1, k, 2) + sjd(i, j-1, k+&
2011 & 1, 2) + sjd(i+1, j-1, k+1, 2) + sjd(i, j, k, 2) + sjd(i+1, j&
2012 & , k, 2) + sjd(i, j, k+1, 2) + sjd(i+1, j, k+1, 2)
2013  sy = sj(i, j-1, k, 2) + sj(i+1, j-1, k, 2) + sj(i, j-1, k+1, 2&
2014 & ) + sj(i+1, j-1, k+1, 2) + sj(i, j, k, 2) + sj(i+1, j, k, 2)&
2015 & + sj(i, j, k+1, 2) + sj(i+1, j, k+1, 2)
2016  szd = sjd(i, j-1, k, 3) + sjd(i+1, j-1, k, 3) + sjd(i, j-1, k+&
2017 & 1, 3) + sjd(i+1, j-1, k+1, 3) + sjd(i, j, k, 3) + sjd(i+1, j&
2018 & , k, 3) + sjd(i, j, k+1, 3) + sjd(i+1, j, k+1, 3)
2019  sz = sj(i, j-1, k, 3) + sj(i+1, j-1, k, 3) + sj(i, j-1, k+1, 3&
2020 & ) + sj(i+1, j-1, k+1, 3) + sj(i, j, k, 3) + sj(i+1, j, k, 3)&
2021 & + sj(i, j, k+1, 3) + sj(i+1, j, k+1, 3)
2022 ! compute the average velocities and speed of sound squared
2023 ! for this integration point. node that these variables are
2024 ! stored in w(ivx), w(ivy), w(ivz) and p.
2025  ubard = fourth*(wd(i, j, k, ivx)+wd(i+1, j, k, ivx)+wd(i, j, k&
2026 & +1, ivx)+wd(i+1, j, k+1, ivx))
2027  ubar = fourth*(w(i, j, k, ivx)+w(i+1, j, k, ivx)+w(i, j, k+1, &
2028 & ivx)+w(i+1, j, k+1, ivx))
2029  vbard = fourth*(wd(i, j, k, ivy)+wd(i+1, j, k, ivy)+wd(i, j, k&
2030 & +1, ivy)+wd(i+1, j, k+1, ivy))
2031  vbar = fourth*(w(i, j, k, ivy)+w(i+1, j, k, ivy)+w(i, j, k+1, &
2032 & ivy)+w(i+1, j, k+1, ivy))
2033  wbard = fourth*(wd(i, j, k, ivz)+wd(i+1, j, k, ivz)+wd(i, j, k&
2034 & +1, ivz)+wd(i+1, j, k+1, ivz))
2035  wbar = fourth*(w(i, j, k, ivz)+w(i+1, j, k, ivz)+w(i, j, k+1, &
2036 & ivz)+w(i+1, j, k+1, ivz))
2037  a2d = fourth*(aad(i, j, k)+aad(i+1, j, k)+aad(i, j, k+1)+aad(i&
2038 & +1, j, k+1))
2039  a2 = fourth*(aa(i, j, k)+aa(i+1, j, k)+aa(i, j, k+1)+aa(i+1, j&
2040 & , k+1))
2041 ! add the contributions to the surface integral to the node
2042 ! j-1 and substract it from the node j. for the heat flux it
2043 ! is reversed, because the negative of the gradient of the
2044 ! speed of sound must be computed.
2045  if (j .gt. 1) then
2046  uxd(i, j-1, k) = uxd(i, j-1, k) + sx*ubard + ubar*sxd
2047  ux(i, j-1, k) = ux(i, j-1, k) + ubar*sx
2048  uyd(i, j-1, k) = uyd(i, j-1, k) + sy*ubard + ubar*syd
2049  uy(i, j-1, k) = uy(i, j-1, k) + ubar*sy
2050  uzd(i, j-1, k) = uzd(i, j-1, k) + sz*ubard + ubar*szd
2051  uz(i, j-1, k) = uz(i, j-1, k) + ubar*sz
2052  vxd(i, j-1, k) = vxd(i, j-1, k) + sx*vbard + vbar*sxd
2053  vx(i, j-1, k) = vx(i, j-1, k) + vbar*sx
2054  vyd(i, j-1, k) = vyd(i, j-1, k) + sy*vbard + vbar*syd
2055  vy(i, j-1, k) = vy(i, j-1, k) + vbar*sy
2056  vzd(i, j-1, k) = vzd(i, j-1, k) + sz*vbard + vbar*szd
2057  vz(i, j-1, k) = vz(i, j-1, k) + vbar*sz
2058  wxd(i, j-1, k) = wxd(i, j-1, k) + sx*wbard + wbar*sxd
2059  wx(i, j-1, k) = wx(i, j-1, k) + wbar*sx
2060  wyd(i, j-1, k) = wyd(i, j-1, k) + sy*wbard + wbar*syd
2061  wy(i, j-1, k) = wy(i, j-1, k) + wbar*sy
2062  wzd(i, j-1, k) = wzd(i, j-1, k) + sz*wbard + wbar*szd
2063  wz(i, j-1, k) = wz(i, j-1, k) + wbar*sz
2064  qxd(i, j-1, k) = qxd(i, j-1, k) - sx*a2d - a2*sxd
2065  qx(i, j-1, k) = qx(i, j-1, k) - a2*sx
2066  qyd(i, j-1, k) = qyd(i, j-1, k) - sy*a2d - a2*syd
2067  qy(i, j-1, k) = qy(i, j-1, k) - a2*sy
2068  qzd(i, j-1, k) = qzd(i, j-1, k) - sz*a2d - a2*szd
2069  qz(i, j-1, k) = qz(i, j-1, k) - a2*sz
2070  end if
2071  if (j .lt. je) then
2072  uxd(i, j, k) = uxd(i, j, k) - sx*ubard - ubar*sxd
2073  ux(i, j, k) = ux(i, j, k) - ubar*sx
2074  uyd(i, j, k) = uyd(i, j, k) - sy*ubard - ubar*syd
2075  uy(i, j, k) = uy(i, j, k) - ubar*sy
2076  uzd(i, j, k) = uzd(i, j, k) - sz*ubard - ubar*szd
2077  uz(i, j, k) = uz(i, j, k) - ubar*sz
2078  vxd(i, j, k) = vxd(i, j, k) - sx*vbard - vbar*sxd
2079  vx(i, j, k) = vx(i, j, k) - vbar*sx
2080  vyd(i, j, k) = vyd(i, j, k) - sy*vbard - vbar*syd
2081  vy(i, j, k) = vy(i, j, k) - vbar*sy
2082  vzd(i, j, k) = vzd(i, j, k) - sz*vbard - vbar*szd
2083  vz(i, j, k) = vz(i, j, k) - vbar*sz
2084  wxd(i, j, k) = wxd(i, j, k) - sx*wbard - wbar*sxd
2085  wx(i, j, k) = wx(i, j, k) - wbar*sx
2086  wyd(i, j, k) = wyd(i, j, k) - sy*wbard - wbar*syd
2087  wy(i, j, k) = wy(i, j, k) - wbar*sy
2088  wzd(i, j, k) = wzd(i, j, k) - sz*wbard - wbar*szd
2089  wz(i, j, k) = wz(i, j, k) - wbar*sz
2090  qxd(i, j, k) = qxd(i, j, k) + sx*a2d + a2*sxd
2091  qx(i, j, k) = qx(i, j, k) + a2*sx
2092  qyd(i, j, k) = qyd(i, j, k) + sy*a2d + a2*syd
2093  qy(i, j, k) = qy(i, j, k) + a2*sy
2094  qzd(i, j, k) = qzd(i, j, k) + sz*a2d + a2*szd
2095  qz(i, j, k) = qz(i, j, k) + a2*sz
2096  end if
2097  end do
2098  end do
2099  end do
2100 ! third part. contribution in the i-direction.
2101 ! the contribution is scattered to both the left and right node
2102 ! in i-direction.
2103  do k=1,kl
2104  do j=1,jl
2105  do i=1,ie
2106 ! compute 8 times the average normal for this part of
2107 ! the control volume. the factor 8 is taken care of later
2108 ! on when the division by the volume takes place.
2109  sxd = sid(i-1, j, k, 1) + sid(i-1, j+1, k, 1) + sid(i-1, j, k+&
2110 & 1, 1) + sid(i-1, j+1, k+1, 1) + sid(i, j, k, 1) + sid(i, j+1&
2111 & , k, 1) + sid(i, j, k+1, 1) + sid(i, j+1, k+1, 1)
2112  sx = si(i-1, j, k, 1) + si(i-1, j+1, k, 1) + si(i-1, j, k+1, 1&
2113 & ) + si(i-1, j+1, k+1, 1) + si(i, j, k, 1) + si(i, j+1, k, 1)&
2114 & + si(i, j, k+1, 1) + si(i, j+1, k+1, 1)
2115  syd = sid(i-1, j, k, 2) + sid(i-1, j+1, k, 2) + sid(i-1, j, k+&
2116 & 1, 2) + sid(i-1, j+1, k+1, 2) + sid(i, j, k, 2) + sid(i, j+1&
2117 & , k, 2) + sid(i, j, k+1, 2) + sid(i, j+1, k+1, 2)
2118  sy = si(i-1, j, k, 2) + si(i-1, j+1, k, 2) + si(i-1, j, k+1, 2&
2119 & ) + si(i-1, j+1, k+1, 2) + si(i, j, k, 2) + si(i, j+1, k, 2)&
2120 & + si(i, j, k+1, 2) + si(i, j+1, k+1, 2)
2121  szd = sid(i-1, j, k, 3) + sid(i-1, j+1, k, 3) + sid(i-1, j, k+&
2122 & 1, 3) + sid(i-1, j+1, k+1, 3) + sid(i, j, k, 3) + sid(i, j+1&
2123 & , k, 3) + sid(i, j, k+1, 3) + sid(i, j+1, k+1, 3)
2124  sz = si(i-1, j, k, 3) + si(i-1, j+1, k, 3) + si(i-1, j, k+1, 3&
2125 & ) + si(i-1, j+1, k+1, 3) + si(i, j, k, 3) + si(i, j+1, k, 3)&
2126 & + si(i, j, k+1, 3) + si(i, j+1, k+1, 3)
2127 ! compute the average velocities and speed of sound squared
2128 ! for this integration point. node that these variables are
2129 ! stored in w(ivx), w(ivy), w(ivz) and p.
2130  ubard = fourth*(wd(i, j, k, ivx)+wd(i, j+1, k, ivx)+wd(i, j, k&
2131 & +1, ivx)+wd(i, j+1, k+1, ivx))
2132  ubar = fourth*(w(i, j, k, ivx)+w(i, j+1, k, ivx)+w(i, j, k+1, &
2133 & ivx)+w(i, j+1, k+1, ivx))
2134  vbard = fourth*(wd(i, j, k, ivy)+wd(i, j+1, k, ivy)+wd(i, j, k&
2135 & +1, ivy)+wd(i, j+1, k+1, ivy))
2136  vbar = fourth*(w(i, j, k, ivy)+w(i, j+1, k, ivy)+w(i, j, k+1, &
2137 & ivy)+w(i, j+1, k+1, ivy))
2138  wbard = fourth*(wd(i, j, k, ivz)+wd(i, j+1, k, ivz)+wd(i, j, k&
2139 & +1, ivz)+wd(i, j+1, k+1, ivz))
2140  wbar = fourth*(w(i, j, k, ivz)+w(i, j+1, k, ivz)+w(i, j, k+1, &
2141 & ivz)+w(i, j+1, k+1, ivz))
2142  a2d = fourth*(aad(i, j, k)+aad(i, j+1, k)+aad(i, j, k+1)+aad(i&
2143 & , j+1, k+1))
2144  a2 = fourth*(aa(i, j, k)+aa(i, j+1, k)+aa(i, j, k+1)+aa(i, j+1&
2145 & , k+1))
2146 ! add the contributions to the surface integral to the node
2147 ! j-1 and substract it from the node j. for the heat flux it
2148 ! is reversed, because the negative of the gradient of the
2149 ! speed of sound must be computed.
2150  if (i .gt. 1) then
2151  uxd(i-1, j, k) = uxd(i-1, j, k) + sx*ubard + ubar*sxd
2152  ux(i-1, j, k) = ux(i-1, j, k) + ubar*sx
2153  uyd(i-1, j, k) = uyd(i-1, j, k) + sy*ubard + ubar*syd
2154  uy(i-1, j, k) = uy(i-1, j, k) + ubar*sy
2155  uzd(i-1, j, k) = uzd(i-1, j, k) + sz*ubard + ubar*szd
2156  uz(i-1, j, k) = uz(i-1, j, k) + ubar*sz
2157  vxd(i-1, j, k) = vxd(i-1, j, k) + sx*vbard + vbar*sxd
2158  vx(i-1, j, k) = vx(i-1, j, k) + vbar*sx
2159  vyd(i-1, j, k) = vyd(i-1, j, k) + sy*vbard + vbar*syd
2160  vy(i-1, j, k) = vy(i-1, j, k) + vbar*sy
2161  vzd(i-1, j, k) = vzd(i-1, j, k) + sz*vbard + vbar*szd
2162  vz(i-1, j, k) = vz(i-1, j, k) + vbar*sz
2163  wxd(i-1, j, k) = wxd(i-1, j, k) + sx*wbard + wbar*sxd
2164  wx(i-1, j, k) = wx(i-1, j, k) + wbar*sx
2165  wyd(i-1, j, k) = wyd(i-1, j, k) + sy*wbard + wbar*syd
2166  wy(i-1, j, k) = wy(i-1, j, k) + wbar*sy
2167  wzd(i-1, j, k) = wzd(i-1, j, k) + sz*wbard + wbar*szd
2168  wz(i-1, j, k) = wz(i-1, j, k) + wbar*sz
2169  qxd(i-1, j, k) = qxd(i-1, j, k) - sx*a2d - a2*sxd
2170  qx(i-1, j, k) = qx(i-1, j, k) - a2*sx
2171  qyd(i-1, j, k) = qyd(i-1, j, k) - sy*a2d - a2*syd
2172  qy(i-1, j, k) = qy(i-1, j, k) - a2*sy
2173  qzd(i-1, j, k) = qzd(i-1, j, k) - sz*a2d - a2*szd
2174  qz(i-1, j, k) = qz(i-1, j, k) - a2*sz
2175  end if
2176  if (i .lt. ie) then
2177  uxd(i, j, k) = uxd(i, j, k) - sx*ubard - ubar*sxd
2178  ux(i, j, k) = ux(i, j, k) - ubar*sx
2179  uyd(i, j, k) = uyd(i, j, k) - sy*ubard - ubar*syd
2180  uy(i, j, k) = uy(i, j, k) - ubar*sy
2181  uzd(i, j, k) = uzd(i, j, k) - sz*ubard - ubar*szd
2182  uz(i, j, k) = uz(i, j, k) - ubar*sz
2183  vxd(i, j, k) = vxd(i, j, k) - sx*vbard - vbar*sxd
2184  vx(i, j, k) = vx(i, j, k) - vbar*sx
2185  vyd(i, j, k) = vyd(i, j, k) - sy*vbard - vbar*syd
2186  vy(i, j, k) = vy(i, j, k) - vbar*sy
2187  vzd(i, j, k) = vzd(i, j, k) - sz*vbard - vbar*szd
2188  vz(i, j, k) = vz(i, j, k) - vbar*sz
2189  wxd(i, j, k) = wxd(i, j, k) - sx*wbard - wbar*sxd
2190  wx(i, j, k) = wx(i, j, k) - wbar*sx
2191  wyd(i, j, k) = wyd(i, j, k) - sy*wbard - wbar*syd
2192  wy(i, j, k) = wy(i, j, k) - wbar*sy
2193  wzd(i, j, k) = wzd(i, j, k) - sz*wbard - wbar*szd
2194  wz(i, j, k) = wz(i, j, k) - wbar*sz
2195  qxd(i, j, k) = qxd(i, j, k) + sx*a2d + a2*sxd
2196  qx(i, j, k) = qx(i, j, k) + a2*sx
2197  qyd(i, j, k) = qyd(i, j, k) + sy*a2d + a2*syd
2198  qy(i, j, k) = qy(i, j, k) + a2*sy
2199  qzd(i, j, k) = qzd(i, j, k) + sz*a2d + a2*szd
2200  qz(i, j, k) = qz(i, j, k) + a2*sz
2201  end if
2202  end do
2203  end do
2204  end do
2205 ! divide by 8 times the volume to obtain the correct gradients.
2206  do k=1,kl
2207  do j=1,jl
2208  do i=1,il
2209 ! compute the inverse of 8 times the volume for this node.
2210  temp = one/(vol(i, j, k)+vol(i, j, k+1)+vol(i+1, j, k)+vol(i+1&
2211 & , j, k+1)+vol(i, j+1, k)+vol(i, j+1, k+1)+vol(i+1, j+1, k)+&
2212 & vol(i+1, j+1, k+1))
2213  oneovervd = -(temp*(vold(i, j, k)+vold(i, j, k+1)+vold(i+1, j&
2214 & , k)+vold(i+1, j, k+1)+vold(i, j+1, k)+vold(i, j+1, k+1)+&
2215 & vold(i+1, j+1, k)+vold(i+1, j+1, k+1))/(vol(i, j, k)+vol(i, &
2216 & j, k+1)+vol(i+1, j, k)+vol(i+1, j, k+1)+vol(i, j+1, k)+vol(i&
2217 & , j+1, k+1)+vol(i+1, j+1, k)+vol(i+1, j+1, k+1)))
2218  oneoverv = temp
2219 ! compute the correct velocity gradients and "unit" heat
2220 ! fluxes. the velocity gradients are stored in ux, etc.
2221  uxd(i, j, k) = oneoverv*uxd(i, j, k) + ux(i, j, k)*oneovervd
2222  ux(i, j, k) = ux(i, j, k)*oneoverv
2223  uyd(i, j, k) = oneoverv*uyd(i, j, k) + uy(i, j, k)*oneovervd
2224  uy(i, j, k) = uy(i, j, k)*oneoverv
2225  uzd(i, j, k) = oneoverv*uzd(i, j, k) + uz(i, j, k)*oneovervd
2226  uz(i, j, k) = uz(i, j, k)*oneoverv
2227  vxd(i, j, k) = oneoverv*vxd(i, j, k) + vx(i, j, k)*oneovervd
2228  vx(i, j, k) = vx(i, j, k)*oneoverv
2229  vyd(i, j, k) = oneoverv*vyd(i, j, k) + vy(i, j, k)*oneovervd
2230  vy(i, j, k) = vy(i, j, k)*oneoverv
2231  vzd(i, j, k) = oneoverv*vzd(i, j, k) + vz(i, j, k)*oneovervd
2232  vz(i, j, k) = vz(i, j, k)*oneoverv
2233  wxd(i, j, k) = oneoverv*wxd(i, j, k) + wx(i, j, k)*oneovervd
2234  wx(i, j, k) = wx(i, j, k)*oneoverv
2235  wyd(i, j, k) = oneoverv*wyd(i, j, k) + wy(i, j, k)*oneovervd
2236  wy(i, j, k) = wy(i, j, k)*oneoverv
2237  wzd(i, j, k) = oneoverv*wzd(i, j, k) + wz(i, j, k)*oneovervd
2238  wz(i, j, k) = wz(i, j, k)*oneoverv
2239  qxd(i, j, k) = oneoverv*qxd(i, j, k) + qx(i, j, k)*oneovervd
2240  qx(i, j, k) = qx(i, j, k)*oneoverv
2241  qyd(i, j, k) = oneoverv*qyd(i, j, k) + qy(i, j, k)*oneovervd
2242  qy(i, j, k) = qy(i, j, k)*oneoverv
2243  qzd(i, j, k) = oneoverv*qzd(i, j, k) + qz(i, j, k)*oneovervd
2244  qz(i, j, k) = qz(i, j, k)*oneoverv
2245  end do
2246  end do
2247  end do
2248  end subroutine allnodalgradients_d
2249 
2250  subroutine allnodalgradients()
2251 !
2252 ! nodalgradients computes the nodal velocity gradients and
2253 ! minus the gradient of the speed of sound squared. the minus
2254 ! sign is present, because this is the definition of the heat
2255 ! flux. these gradients are computed for all nodes.
2256 !
2257  use constants
2258  use blockpointers
2259  implicit none
2260 ! local variables.
2261  integer(kind=inttype) :: i, j, k
2262  integer(kind=inttype) :: k1, kk
2263  integer(kind=inttype) :: istart, iend, isize, ii
2264  integer(kind=inttype) :: jstart, jend, jsize
2265  integer(kind=inttype) :: kstart, kend, ksize
2266  real(kind=realtype) :: oneoverv, ubar, vbar, wbar, a2
2267  real(kind=realtype) :: sx, sx1, sy, sy1, sz, sz1
2268 ! zero all nodeal gradients:
2269  ux = zero
2270  uy = zero
2271  uz = zero
2272  vx = zero
2273  vy = zero
2274  vz = zero
2275  wx = zero
2276  wy = zero
2277  wz = zero
2278  qx = zero
2279  qy = zero
2280  qz = zero
2281 ! first part. contribution in the k-direction.
2282 ! the contribution is scattered to both the left and right node
2283 ! in k-direction.
2284  do k=1,ke
2285  do j=1,jl
2286  do i=1,il
2287 ! compute 8 times the average normal for this part of
2288 ! the control volume. the factor 8 is taken care of later
2289 ! on when the division by the volume takes place.
2290  sx = sk(i, j, k-1, 1) + sk(i+1, j, k-1, 1) + sk(i, j+1, k-1, 1&
2291 & ) + sk(i+1, j+1, k-1, 1) + sk(i, j, k, 1) + sk(i+1, j, k, 1)&
2292 & + sk(i, j+1, k, 1) + sk(i+1, j+1, k, 1)
2293  sy = sk(i, j, k-1, 2) + sk(i+1, j, k-1, 2) + sk(i, j+1, k-1, 2&
2294 & ) + sk(i+1, j+1, k-1, 2) + sk(i, j, k, 2) + sk(i+1, j, k, 2)&
2295 & + sk(i, j+1, k, 2) + sk(i+1, j+1, k, 2)
2296  sz = sk(i, j, k-1, 3) + sk(i+1, j, k-1, 3) + sk(i, j+1, k-1, 3&
2297 & ) + sk(i+1, j+1, k-1, 3) + sk(i, j, k, 3) + sk(i+1, j, k, 3)&
2298 & + sk(i, j+1, k, 3) + sk(i+1, j+1, k, 3)
2299 ! compute the average velocities and speed of sound squared
2300 ! for this integration point. node that these variables are
2301 ! stored in w(ivx), w(ivy), w(ivz) and p.
2302  ubar = fourth*(w(i, j, k, ivx)+w(i+1, j, k, ivx)+w(i, j+1, k, &
2303 & ivx)+w(i+1, j+1, k, ivx))
2304  vbar = fourth*(w(i, j, k, ivy)+w(i+1, j, k, ivy)+w(i, j+1, k, &
2305 & ivy)+w(i+1, j+1, k, ivy))
2306  wbar = fourth*(w(i, j, k, ivz)+w(i+1, j, k, ivz)+w(i, j+1, k, &
2307 & ivz)+w(i+1, j+1, k, ivz))
2308  a2 = fourth*(aa(i, j, k)+aa(i+1, j, k)+aa(i, j+1, k)+aa(i+1, j&
2309 & +1, k))
2310 ! add the contributions to the surface integral to the node
2311 ! j-1 and substract it from the node j. for the heat flux it
2312 ! is reversed, because the negative of the gradient of the
2313 ! speed of sound must be computed.
2314  if (k .gt. 1) then
2315  ux(i, j, k-1) = ux(i, j, k-1) + ubar*sx
2316  uy(i, j, k-1) = uy(i, j, k-1) + ubar*sy
2317  uz(i, j, k-1) = uz(i, j, k-1) + ubar*sz
2318  vx(i, j, k-1) = vx(i, j, k-1) + vbar*sx
2319  vy(i, j, k-1) = vy(i, j, k-1) + vbar*sy
2320  vz(i, j, k-1) = vz(i, j, k-1) + vbar*sz
2321  wx(i, j, k-1) = wx(i, j, k-1) + wbar*sx
2322  wy(i, j, k-1) = wy(i, j, k-1) + wbar*sy
2323  wz(i, j, k-1) = wz(i, j, k-1) + wbar*sz
2324  qx(i, j, k-1) = qx(i, j, k-1) - a2*sx
2325  qy(i, j, k-1) = qy(i, j, k-1) - a2*sy
2326  qz(i, j, k-1) = qz(i, j, k-1) - a2*sz
2327  end if
2328  if (k .lt. ke) then
2329  ux(i, j, k) = ux(i, j, k) - ubar*sx
2330  uy(i, j, k) = uy(i, j, k) - ubar*sy
2331  uz(i, j, k) = uz(i, j, k) - ubar*sz
2332  vx(i, j, k) = vx(i, j, k) - vbar*sx
2333  vy(i, j, k) = vy(i, j, k) - vbar*sy
2334  vz(i, j, k) = vz(i, j, k) - vbar*sz
2335  wx(i, j, k) = wx(i, j, k) - wbar*sx
2336  wy(i, j, k) = wy(i, j, k) - wbar*sy
2337  wz(i, j, k) = wz(i, j, k) - wbar*sz
2338  qx(i, j, k) = qx(i, j, k) + a2*sx
2339  qy(i, j, k) = qy(i, j, k) + a2*sy
2340  qz(i, j, k) = qz(i, j, k) + a2*sz
2341  end if
2342  end do
2343  end do
2344  end do
2345 ! second part. contribution in the j-direction.
2346 ! the contribution is scattered to both the left and right node
2347 ! in j-direction.
2348  do k=1,kl
2349  do j=1,je
2350  do i=1,il
2351 ! compute 8 times the average normal for this part of
2352 ! the control volume. the factor 8 is taken care of later
2353 ! on when the division by the volume takes place.
2354  sx = sj(i, j-1, k, 1) + sj(i+1, j-1, k, 1) + sj(i, j-1, k+1, 1&
2355 & ) + sj(i+1, j-1, k+1, 1) + sj(i, j, k, 1) + sj(i+1, j, k, 1)&
2356 & + sj(i, j, k+1, 1) + sj(i+1, j, k+1, 1)
2357  sy = sj(i, j-1, k, 2) + sj(i+1, j-1, k, 2) + sj(i, j-1, k+1, 2&
2358 & ) + sj(i+1, j-1, k+1, 2) + sj(i, j, k, 2) + sj(i+1, j, k, 2)&
2359 & + sj(i, j, k+1, 2) + sj(i+1, j, k+1, 2)
2360  sz = sj(i, j-1, k, 3) + sj(i+1, j-1, k, 3) + sj(i, j-1, k+1, 3&
2361 & ) + sj(i+1, j-1, k+1, 3) + sj(i, j, k, 3) + sj(i+1, j, k, 3)&
2362 & + sj(i, j, k+1, 3) + sj(i+1, j, k+1, 3)
2363 ! compute the average velocities and speed of sound squared
2364 ! for this integration point. node that these variables are
2365 ! stored in w(ivx), w(ivy), w(ivz) and p.
2366  ubar = fourth*(w(i, j, k, ivx)+w(i+1, j, k, ivx)+w(i, j, k+1, &
2367 & ivx)+w(i+1, j, k+1, ivx))
2368  vbar = fourth*(w(i, j, k, ivy)+w(i+1, j, k, ivy)+w(i, j, k+1, &
2369 & ivy)+w(i+1, j, k+1, ivy))
2370  wbar = fourth*(w(i, j, k, ivz)+w(i+1, j, k, ivz)+w(i, j, k+1, &
2371 & ivz)+w(i+1, j, k+1, ivz))
2372  a2 = fourth*(aa(i, j, k)+aa(i+1, j, k)+aa(i, j, k+1)+aa(i+1, j&
2373 & , k+1))
2374 ! add the contributions to the surface integral to the node
2375 ! j-1 and substract it from the node j. for the heat flux it
2376 ! is reversed, because the negative of the gradient of the
2377 ! speed of sound must be computed.
2378  if (j .gt. 1) then
2379  ux(i, j-1, k) = ux(i, j-1, k) + ubar*sx
2380  uy(i, j-1, k) = uy(i, j-1, k) + ubar*sy
2381  uz(i, j-1, k) = uz(i, j-1, k) + ubar*sz
2382  vx(i, j-1, k) = vx(i, j-1, k) + vbar*sx
2383  vy(i, j-1, k) = vy(i, j-1, k) + vbar*sy
2384  vz(i, j-1, k) = vz(i, j-1, k) + vbar*sz
2385  wx(i, j-1, k) = wx(i, j-1, k) + wbar*sx
2386  wy(i, j-1, k) = wy(i, j-1, k) + wbar*sy
2387  wz(i, j-1, k) = wz(i, j-1, k) + wbar*sz
2388  qx(i, j-1, k) = qx(i, j-1, k) - a2*sx
2389  qy(i, j-1, k) = qy(i, j-1, k) - a2*sy
2390  qz(i, j-1, k) = qz(i, j-1, k) - a2*sz
2391  end if
2392  if (j .lt. je) then
2393  ux(i, j, k) = ux(i, j, k) - ubar*sx
2394  uy(i, j, k) = uy(i, j, k) - ubar*sy
2395  uz(i, j, k) = uz(i, j, k) - ubar*sz
2396  vx(i, j, k) = vx(i, j, k) - vbar*sx
2397  vy(i, j, k) = vy(i, j, k) - vbar*sy
2398  vz(i, j, k) = vz(i, j, k) - vbar*sz
2399  wx(i, j, k) = wx(i, j, k) - wbar*sx
2400  wy(i, j, k) = wy(i, j, k) - wbar*sy
2401  wz(i, j, k) = wz(i, j, k) - wbar*sz
2402  qx(i, j, k) = qx(i, j, k) + a2*sx
2403  qy(i, j, k) = qy(i, j, k) + a2*sy
2404  qz(i, j, k) = qz(i, j, k) + a2*sz
2405  end if
2406  end do
2407  end do
2408  end do
2409 ! third part. contribution in the i-direction.
2410 ! the contribution is scattered to both the left and right node
2411 ! in i-direction.
2412  do k=1,kl
2413  do j=1,jl
2414  do i=1,ie
2415 ! compute 8 times the average normal for this part of
2416 ! the control volume. the factor 8 is taken care of later
2417 ! on when the division by the volume takes place.
2418  sx = si(i-1, j, k, 1) + si(i-1, j+1, k, 1) + si(i-1, j, k+1, 1&
2419 & ) + si(i-1, j+1, k+1, 1) + si(i, j, k, 1) + si(i, j+1, k, 1)&
2420 & + si(i, j, k+1, 1) + si(i, j+1, k+1, 1)
2421  sy = si(i-1, j, k, 2) + si(i-1, j+1, k, 2) + si(i-1, j, k+1, 2&
2422 & ) + si(i-1, j+1, k+1, 2) + si(i, j, k, 2) + si(i, j+1, k, 2)&
2423 & + si(i, j, k+1, 2) + si(i, j+1, k+1, 2)
2424  sz = si(i-1, j, k, 3) + si(i-1, j+1, k, 3) + si(i-1, j, k+1, 3&
2425 & ) + si(i-1, j+1, k+1, 3) + si(i, j, k, 3) + si(i, j+1, k, 3)&
2426 & + si(i, j, k+1, 3) + si(i, j+1, k+1, 3)
2427 ! compute the average velocities and speed of sound squared
2428 ! for this integration point. node that these variables are
2429 ! stored in w(ivx), w(ivy), w(ivz) and p.
2430  ubar = fourth*(w(i, j, k, ivx)+w(i, j+1, k, ivx)+w(i, j, k+1, &
2431 & ivx)+w(i, j+1, k+1, ivx))
2432  vbar = fourth*(w(i, j, k, ivy)+w(i, j+1, k, ivy)+w(i, j, k+1, &
2433 & ivy)+w(i, j+1, k+1, ivy))
2434  wbar = fourth*(w(i, j, k, ivz)+w(i, j+1, k, ivz)+w(i, j, k+1, &
2435 & ivz)+w(i, j+1, k+1, ivz))
2436  a2 = fourth*(aa(i, j, k)+aa(i, j+1, k)+aa(i, j, k+1)+aa(i, j+1&
2437 & , k+1))
2438 ! add the contributions to the surface integral to the node
2439 ! j-1 and substract it from the node j. for the heat flux it
2440 ! is reversed, because the negative of the gradient of the
2441 ! speed of sound must be computed.
2442  if (i .gt. 1) then
2443  ux(i-1, j, k) = ux(i-1, j, k) + ubar*sx
2444  uy(i-1, j, k) = uy(i-1, j, k) + ubar*sy
2445  uz(i-1, j, k) = uz(i-1, j, k) + ubar*sz
2446  vx(i-1, j, k) = vx(i-1, j, k) + vbar*sx
2447  vy(i-1, j, k) = vy(i-1, j, k) + vbar*sy
2448  vz(i-1, j, k) = vz(i-1, j, k) + vbar*sz
2449  wx(i-1, j, k) = wx(i-1, j, k) + wbar*sx
2450  wy(i-1, j, k) = wy(i-1, j, k) + wbar*sy
2451  wz(i-1, j, k) = wz(i-1, j, k) + wbar*sz
2452  qx(i-1, j, k) = qx(i-1, j, k) - a2*sx
2453  qy(i-1, j, k) = qy(i-1, j, k) - a2*sy
2454  qz(i-1, j, k) = qz(i-1, j, k) - a2*sz
2455  end if
2456  if (i .lt. ie) then
2457  ux(i, j, k) = ux(i, j, k) - ubar*sx
2458  uy(i, j, k) = uy(i, j, k) - ubar*sy
2459  uz(i, j, k) = uz(i, j, k) - ubar*sz
2460  vx(i, j, k) = vx(i, j, k) - vbar*sx
2461  vy(i, j, k) = vy(i, j, k) - vbar*sy
2462  vz(i, j, k) = vz(i, j, k) - vbar*sz
2463  wx(i, j, k) = wx(i, j, k) - wbar*sx
2464  wy(i, j, k) = wy(i, j, k) - wbar*sy
2465  wz(i, j, k) = wz(i, j, k) - wbar*sz
2466  qx(i, j, k) = qx(i, j, k) + a2*sx
2467  qy(i, j, k) = qy(i, j, k) + a2*sy
2468  qz(i, j, k) = qz(i, j, k) + a2*sz
2469  end if
2470  end do
2471  end do
2472  end do
2473 ! divide by 8 times the volume to obtain the correct gradients.
2474  do k=1,kl
2475  do j=1,jl
2476  do i=1,il
2477 ! compute the inverse of 8 times the volume for this node.
2478  oneoverv = one/(vol(i, j, k)+vol(i, j, k+1)+vol(i+1, j, k)+vol&
2479 & (i+1, j, k+1)+vol(i, j+1, k)+vol(i, j+1, k+1)+vol(i+1, j+1, &
2480 & k)+vol(i+1, j+1, k+1))
2481 ! compute the correct velocity gradients and "unit" heat
2482 ! fluxes. the velocity gradients are stored in ux, etc.
2483  ux(i, j, k) = ux(i, j, k)*oneoverv
2484  uy(i, j, k) = uy(i, j, k)*oneoverv
2485  uz(i, j, k) = uz(i, j, k)*oneoverv
2486  vx(i, j, k) = vx(i, j, k)*oneoverv
2487  vy(i, j, k) = vy(i, j, k)*oneoverv
2488  vz(i, j, k) = vz(i, j, k)*oneoverv
2489  wx(i, j, k) = wx(i, j, k)*oneoverv
2490  wy(i, j, k) = wy(i, j, k)*oneoverv
2491  wz(i, j, k) = wz(i, j, k)*oneoverv
2492  qx(i, j, k) = qx(i, j, k)*oneoverv
2493  qy(i, j, k) = qy(i, j, k)*oneoverv
2494  qz(i, j, k) = qz(i, j, k)*oneoverv
2495  end do
2496  end do
2497  end do
2498  end subroutine allnodalgradients
2499 ! ----------------------------------------------------------------------
2500 ! |
2501 ! no tapenade routine below this line |
2502 ! |
2503 ! ----------------------------------------------------------------------
2504 
2505 end module flowutils_d
2506 
real(kind=realtype), dimension(:, :, :), pointer gamma
real(kind=realtype), dimension(:, :, :), pointer qz
integer(kind=inttype) jl
real(kind=realtype), dimension(:, :, :), pointer wzd
real(kind=realtype), dimension(:, :, :), pointer aad
real(kind=realtype), dimension(:, :, :, :), pointer sjd
real(kind=realtype), dimension(:, :, :), pointer vxd
real(kind=realtype), dimension(:, :, :), pointer qy
real(kind=realtype), dimension(:, :, :), pointer aa
real(kind=realtype), dimension(:, :, :), pointer uz
real(kind=realtype), dimension(:, :, :, :), pointer wd
real(kind=realtype), dimension(:, :, :), pointer uzd
real(kind=realtype), dimension(:, :, :), pointer vold
real(kind=realtype), dimension(:, :, :), pointer qxd
real(kind=realtype), dimension(:, :, :), pointer p
integer(kind=inttype) ie
real(kind=realtype), dimension(:, :, :, :), pointer w
real(kind=realtype), dimension(:, :, :), pointer uy
real(kind=realtype), dimension(:, :, :), pointer wyd
real(kind=realtype), dimension(:, :, :), pointer wx
real(kind=realtype), dimension(:, :, :, :), pointer skd
integer(kind=inttype) jb
integer(kind=inttype) kb
real(kind=realtype), dimension(:, :, :), pointer rlv
real(kind=realtype), dimension(:, :, :, :), pointer si
real(kind=realtype), dimension(:, :, :, :), pointer sid
real(kind=realtype), dimension(:, :, :, :), pointer sj
real(kind=realtype), dimension(:, :, :), pointer uyd
real(kind=realtype), dimension(:, :, :), pointer qx
real(kind=realtype), dimension(:, :, :), pointer uxd
real(kind=realtype), dimension(:, :, :), pointer vz
real(kind=realtype), dimension(:, :, :), pointer qyd
real(kind=realtype), dimension(:, :, :, :), pointer sk
real(kind=realtype), dimension(:, :, :), pointer ux
real(kind=realtype), dimension(:, :, :), pointer wy
real(kind=realtype), dimension(:, :, :), pointer rlvd
real(kind=realtype), dimension(:, :, :), pointer wz
real(kind=realtype), dimension(:, :, :), pointer vol
real(kind=realtype), dimension(:, :, :), pointer wxd
integer(kind=inttype) ib
real(kind=realtype), dimension(:, :, :), pointer vy
real(kind=realtype), dimension(:, :, :), pointer vx
integer(kind=inttype) je
integer(kind=inttype) ke
real(kind=realtype), dimension(:, :, :), pointer qzd
real(kind=realtype), dimension(:, :, :), pointer vzd
real(kind=realtype), dimension(:, :, :), pointer pd
real(kind=realtype), dimension(:, :, :), pointer vyd
integer(kind=inttype) kl
integer(kind=inttype) il
integer(kind=inttype), parameter cptempcurvefits
Definition: constants.F90:124
real(kind=realtype), parameter zero
Definition: constants.F90:71
real(kind=realtype), parameter third
Definition: constants.F90:81
integer, parameter itu1
Definition: constants.F90:40
integer, parameter irho
Definition: constants.F90:34
integer, parameter ivx
Definition: constants.F90:35
integer, parameter irhoe
Definition: constants.F90:38
real(kind=realtype), parameter five
Definition: constants.F90:76
real(kind=realtype), parameter one
Definition: constants.F90:72
real(kind=realtype), parameter half
Definition: constants.F90:80
integer, parameter ivz
Definition: constants.F90:37
real(kind=realtype), parameter two
Definition: constants.F90:73
integer(kind=inttype), parameter cpconstant
Definition: constants.F90:124
real(kind=realtype), parameter fourth
Definition: constants.F90:82
integer, parameter ivy
Definition: constants.F90:36
real(kind=realtype) cvn
Definition: CpCurveFits.f90:58
real(kind=realtype), dimension(:), allocatable cptrange
Definition: CpCurveFits.f90:46
integer(kind=inttype) cpnparts
Definition: CpCurveFits.f90:44
real(kind=realtype) cv0
Definition: CpCurveFits.f90:58
type(cptempfittype), dimension(:), allocatable cptempfit
Definition: CpCurveFits.f90:49
real(kind=realtype), dimension(:), allocatable cpeint
Definition: CpCurveFits.f90:47
subroutine computespeedofsoundsquared()
subroutine getdirvector(refdirection, alpha, beta, winddirection, liftindex)
subroutine computeetotblock_d(istart, iend, jstart, jend, kstart, kend, correctfork)
subroutine getdirvector_d(refdirection, alpha, alphad, beta, betad, winddirection, winddirectiond, liftindex)
subroutine adjustinflowangle()
subroutine adjustinflowangle_d()
subroutine allnodalgradients_d()
subroutine computeptot(rho, u, v, w, p, ptot)
subroutine allnodalgradients()
subroutine etot(rho, u, v, w, p, k, etotal, correctfork)
subroutine vectorrotation(xp, yp, zp, iaxis, angle, x, y, z)
subroutine vectorrotation_d(xp, xpd, yp, ypd, zp, zpd, iaxis, angle, angled, x, xd, y, yd, z, zd)
subroutine eint(rho, p, k, einternal, correctfork)
subroutine computespeedofsoundsquared_d()
subroutine computeetotblock(istart, iend, jstart, jend, kstart, kend, correctfork)
subroutine computepressure(ibeg, iend, jbeg, jend, kbeg, kend, pointeroffset)
subroutine computettot_d(rho, rhod, u, ud, v, vd, w, wd, p, pd, ttot, ttotd)
Definition: flowUtils_d.f90:13
subroutine derivativerotmatrixrigid(rotationmatrix, rotationpoint, t)
subroutine eint_d(rho, rhod, p, pd, k, kd, einternal, einternald, correctfork)
subroutine etot_d(rho, rhod, u, ud, v, vd, w, wd, p, pd, k, kd, etotal, etotald, correctfork)
subroutine computeptot_d(rho, rhod, u, ud, v, vd, w, wd, p, pd, ptot, ptotd)
subroutine computelamviscosity(includehalos)
subroutine derivativerotmatrixrigid_d(rotationmatrix, rotationmatrixd, rotationpoint, t)
subroutine computelamviscosity_d(includehalos)
subroutine computepressuresimple_d(includehalos)
subroutine computegamma(t, gamma, mm)
subroutine computettot(rho, u, v, w, p, ttot)
Definition: flowUtils_d.f90:62
subroutine computepressuresimple(includehalos)
real(kind=realtype) gammainf
real(kind=realtype) pinfcorr
real(kind=realtype) pinfcorrd
real(kind=realtype) pinf
real(kind=realtype) rgas
real(kind=realtype) trefd
real(kind=realtype) muref
real(kind=realtype) rgasd
real(kind=realtype) tref
real(kind=realtype) murefd
real(kind=realtype) lref
integer(kind=inttype) degreefouryrot
Definition: inputParam.F90:354
integer(kind=inttype) degreefourxrot
Definition: inputParam.F90:353
integer(kind=inttype) degreepolxrot
Definition: inputParam.F90:337
real(kind=realtype) omegafouryrot
Definition: inputParam.F90:363
integer(kind=inttype) degreepolyrot
Definition: inputParam.F90:338
real(kind=realtype), dimension(:), allocatable coefpolxrot
Definition: inputParam.F90:345
real(kind=realtype) omegafourzrot
Definition: inputParam.F90:364
real(kind=realtype) omegafourxrot
Definition: inputParam.F90:362
real(kind=realtype), dimension(:), allocatable sincoeffouryrot
Definition: inputParam.F90:385
real(kind=realtype), dimension(:), allocatable coscoeffourxrot
Definition: inputParam.F90:373
real(kind=realtype), dimension(:), allocatable sincoeffourzrot
Definition: inputParam.F90:386
integer(kind=inttype) degreepolzrot
Definition: inputParam.F90:339
real(kind=realtype), dimension(:), allocatable coscoeffouryrot
Definition: inputParam.F90:374
integer(kind=inttype) degreefourzrot
Definition: inputParam.F90:355
real(kind=realtype), dimension(:), allocatable coefpolzrot
Definition: inputParam.F90:347
real(kind=realtype), dimension(:), allocatable coefpolyrot
Definition: inputParam.F90:346
real(kind=realtype), dimension(3) rotpoint
Definition: inputParam.F90:330
real(kind=realtype), dimension(:), allocatable coscoeffourzrot
Definition: inputParam.F90:375
real(kind=realtype), dimension(:), allocatable sincoeffourxrot
Definition: inputParam.F90:384
real(kind=realtype) ssuthdim
Definition: inputParam.F90:604
real(kind=realtype) gammaconstant
Definition: inputParam.F90:595
real(kind=realtype) betad
Definition: inputParam.F90:612
real(kind=realtype) tsuthdim
Definition: inputParam.F90:604
real(kind=realtype), dimension(3) liftdirectiond
Definition: inputParam.F90:614
real(kind=realtype), dimension(3) dragdirectiond
Definition: inputParam.F90:615
integer(kind=inttype) liftindex
Definition: inputParam.F90:592
real(kind=realtype), dimension(3) dragdirection
Definition: inputParam.F90:601
real(kind=realtype), dimension(3) veldirfreestreamd
Definition: inputParam.F90:613
real(kind=realtype) alphad
Definition: inputParam.F90:612
real(kind=realtype) beta
Definition: inputParam.F90:591
real(kind=realtype), dimension(3) liftdirection
Definition: inputParam.F90:600
integer(kind=inttype) cpmodel
Definition: inputParam.F90:584
real(kind=realtype), dimension(3) veldirfreestream
Definition: inputParam.F90:599
real(kind=realtype) musuthdim
Definition: inputParam.F90:604
real(kind=realtype) alpha
Definition: inputParam.F90:591
integer, parameter realtype
Definition: precision.F90:112
real(kind=realtype) function derivativerigidrotangle(degreepolrot, coefpolrot, degreefourrot, omegafourrot, coscoeffourrot, sincoeffourrot, t)
Definition: utils_d.f90:408
real(kind=realtype) function derivativerigidrotangle_d(degreepolrot, coefpolrot, degreefourrot, omegafourrot, coscoeffourrot, sincoeffourrot, t, derivativerigidrotangle)
Definition: utils_d.f90:352
logical function getcorrectfork()
Definition: utils_d.f90:487
real(kind=realtype) function rigidrotangle(degreepolrot, coefpolrot, degreefourrot, omegafourrot, coscoeffourrot, sincoeffourrot, t)
Definition: utils_d.f90:673
subroutine terminate(routinename, errormessage)
Definition: utils_d.f90:500