ADflow  v1.0
ADflow is a finite volume RANS solver tailored for gradient-based aerodynamic design optimization.
turbUtils_b.f90
Go to the documentation of this file.
1 ! generated by tapenade (inria, ecuador team)
2 ! tapenade 3.16 (develop) - 22 aug 2023 15:51
3 !
4 module turbutils_b
5  implicit none
6 
7 contains
8  subroutine prodkatolaunder()
9 !
10 ! prodkatolaunder computes the turbulent production term using
11 ! the kato-launder formulation.
12 !
13  use constants
14  use blockpointers, only : nx, ny, nz, il, jl, kl, w, si, sj, sk, &
16  use flowvarrefstate, only : timeref
17  use section, only : sections
18  use turbmod, only : prod
19  implicit none
20 !
21 ! local variables.
22 !
23  integer(kind=inttype) :: i, j, k, ii
24  real(kind=realtype) :: uux, uuy, uuz, vvx, vvy, vvz, wwx, wwy, wwz
25  real(kind=realtype) :: qxx, qyy, qzz, qxy, qxz, qyz, sijsij
26  real(kind=realtype) :: oxy, oxz, oyz, oijoij
27  real(kind=realtype) :: fact, omegax, omegay, omegaz
28  intrinsic mod
29  intrinsic sqrt
30 ! determine the non-dimensional wheel speed of this block.
31 ! the vorticity term, which appears in kato-launder is of course
32 ! not frame invariant. to approximate frame invariance the wheel
33 ! speed should be substracted from oxy, oxz and oyz, which results
34 ! in the vorticity in the rotating frame. however some people
35 ! claim that the absolute vorticity should be used to obtain the
36 ! best results. in that omega should be set to zero.
37  omegax = timeref*sections(sectionid)%rotrate(1)
38  omegay = timeref*sections(sectionid)%rotrate(2)
39  omegaz = timeref*sections(sectionid)%rotrate(3)
40 !$ad ii-loop
41 ! loop over the cell centers of the given block. it may be more
42 ! efficient to loop over the faces and to scatter the gradient,
43 ! but in that case the gradients for u, v and w must be stored.
44 ! in the current approach no extra memory is needed.
45  do ii=0,nx*ny*nz-1
46  i = mod(ii, nx) + 2
47  j = mod(ii/nx, ny) + 2
48  k = ii/(nx*ny) + 2
49 ! compute the gradient of u in the cell center. use is made
50 ! of the fact that the surrounding normals sum up to zero,
51 ! such that the cell i,j,k does not give a contribution.
52 ! the gradient is scaled by a factor 2*vol.
53  uux = w(i+1, j, k, ivx)*si(i, j, k, 1) - w(i-1, j, k, ivx)*si(i-1&
54 & , j, k, 1) + w(i, j+1, k, ivx)*sj(i, j, k, 1) - w(i, j-1, k, ivx&
55 & )*sj(i, j-1, k, 1) + w(i, j, k+1, ivx)*sk(i, j, k, 1) - w(i, j, &
56 & k-1, ivx)*sk(i, j, k-1, 1)
57  uuy = w(i+1, j, k, ivx)*si(i, j, k, 2) - w(i-1, j, k, ivx)*si(i-1&
58 & , j, k, 2) + w(i, j+1, k, ivx)*sj(i, j, k, 2) - w(i, j-1, k, ivx&
59 & )*sj(i, j-1, k, 2) + w(i, j, k+1, ivx)*sk(i, j, k, 2) - w(i, j, &
60 & k-1, ivx)*sk(i, j, k-1, 2)
61  uuz = w(i+1, j, k, ivx)*si(i, j, k, 3) - w(i-1, j, k, ivx)*si(i-1&
62 & , j, k, 3) + w(i, j+1, k, ivx)*sj(i, j, k, 3) - w(i, j-1, k, ivx&
63 & )*sj(i, j-1, k, 3) + w(i, j, k+1, ivx)*sk(i, j, k, 3) - w(i, j, &
64 & k-1, ivx)*sk(i, j, k-1, 3)
65 ! idem for the gradient of v.
66  vvx = w(i+1, j, k, ivy)*si(i, j, k, 1) - w(i-1, j, k, ivy)*si(i-1&
67 & , j, k, 1) + w(i, j+1, k, ivy)*sj(i, j, k, 1) - w(i, j-1, k, ivy&
68 & )*sj(i, j-1, k, 1) + w(i, j, k+1, ivy)*sk(i, j, k, 1) - w(i, j, &
69 & k-1, ivy)*sk(i, j, k-1, 1)
70  vvy = w(i+1, j, k, ivy)*si(i, j, k, 2) - w(i-1, j, k, ivy)*si(i-1&
71 & , j, k, 2) + w(i, j+1, k, ivy)*sj(i, j, k, 2) - w(i, j-1, k, ivy&
72 & )*sj(i, j-1, k, 2) + w(i, j, k+1, ivy)*sk(i, j, k, 2) - w(i, j, &
73 & k-1, ivy)*sk(i, j, k-1, 2)
74  vvz = w(i+1, j, k, ivy)*si(i, j, k, 3) - w(i-1, j, k, ivy)*si(i-1&
75 & , j, k, 3) + w(i, j+1, k, ivy)*sj(i, j, k, 3) - w(i, j-1, k, ivy&
76 & )*sj(i, j-1, k, 3) + w(i, j, k+1, ivy)*sk(i, j, k, 3) - w(i, j, &
77 & k-1, ivy)*sk(i, j, k-1, 3)
78 ! and for the gradient of w.
79  wwx = w(i+1, j, k, ivz)*si(i, j, k, 1) - w(i-1, j, k, ivz)*si(i-1&
80 & , j, k, 1) + w(i, j+1, k, ivz)*sj(i, j, k, 1) - w(i, j-1, k, ivz&
81 & )*sj(i, j-1, k, 1) + w(i, j, k+1, ivz)*sk(i, j, k, 1) - w(i, j, &
82 & k-1, ivz)*sk(i, j, k-1, 1)
83  wwy = w(i+1, j, k, ivz)*si(i, j, k, 2) - w(i-1, j, k, ivz)*si(i-1&
84 & , j, k, 2) + w(i, j+1, k, ivz)*sj(i, j, k, 2) - w(i, j-1, k, ivz&
85 & )*sj(i, j-1, k, 2) + w(i, j, k+1, ivz)*sk(i, j, k, 2) - w(i, j, &
86 & k-1, ivz)*sk(i, j, k-1, 2)
87  wwz = w(i+1, j, k, ivz)*si(i, j, k, 3) - w(i-1, j, k, ivz)*si(i-1&
88 & , j, k, 3) + w(i, j+1, k, ivz)*sj(i, j, k, 3) - w(i, j-1, k, ivz&
89 & )*sj(i, j-1, k, 3) + w(i, j, k+1, ivz)*sk(i, j, k, 3) - w(i, j, &
90 & k-1, ivz)*sk(i, j, k-1, 3)
91 ! compute the strain and vorticity terms. the multiplication
92 ! is present to obtain the correct gradients. note that
93 ! the wheel speed is substracted from the vorticity terms.
94  fact = half/vol(i, j, k)
95  qxx = fact*uux
96  qyy = fact*vvy
97  qzz = fact*wwz
98  qxy = fact*half*(uuy+vvx)
99  qxz = fact*half*(uuz+wwx)
100  qyz = fact*half*(vvz+wwy)
101  oxy = fact*half*(vvx-uuy) - omegaz
102  oxz = fact*half*(uuz-wwx) - omegay
103  oyz = fact*half*(wwy-vvz) - omegax
104 ! compute the summation of the strain and vorticity tensors.
105  sijsij = two*(qxy**2+qxz**2+qyz**2) + qxx**2 + qyy**2 + qzz**2
106  oijoij = two*(oxy**2+oxz**2+oyz**2)
107 ! compute the production term.
108  scratch(i, j, k, iprod) = two*sqrt(sijsij*oijoij)
109  end do
110  end subroutine prodkatolaunder
111 
112  subroutine prodsmag2()
113 !
114 ! prodsmag2 computes the term:
115 ! 2*sij*sij - 2/3 div(u)**2 with sij=0.5*(duidxj+dujdxi)
116 ! which is used for the turbulence equations.
117 ! it is assumed that the pointer prod, stored in turbmod, is
118 ! already set to the correct entry.
119 !
120  use constants
121  use blockpointers, only : nx, ny, nz, il, jl, kl, w, si, sj, sk, &
123  implicit none
124 !
125 ! local parameter
126 !
127  real(kind=realtype), parameter :: f23=two*third
128 !
129 ! local variables.
130 !
131  integer(kind=inttype) :: i, j, k, ii
132  real(kind=realtype) :: uux, uuy, uuz, vvx, vvy, vvz, wwx, wwy, wwz
133  real(kind=realtype) :: div2, fact, sxx, syy, szz, sxy, sxz, syz
134  intrinsic mod
135 !$ad ii-loop
136 ! loop over the cell centers of the given block. it may be more
137 ! efficient to loop over the faces and to scatter the gradient,
138 ! but in that case the gradients for u, v and w must be stored.
139 ! in the current approach no extra memory is needed.
140  do ii=0,nx*ny*nz-1
141  i = mod(ii, nx) + 2
142  j = mod(ii/nx, ny) + 2
143  k = ii/(nx*ny) + 2
144 ! compute the gradient of u in the cell center. use is made
145 ! of the fact that the surrounding normals sum up to zero,
146 ! such that the cell i,j,k does not give a contribution.
147 ! the gradient is scaled by the factor 2*vol.
148  uux = w(i+1, j, k, ivx)*si(i, j, k, 1) - w(i-1, j, k, ivx)*si(i-1&
149 & , j, k, 1) + w(i, j+1, k, ivx)*sj(i, j, k, 1) - w(i, j-1, k, ivx&
150 & )*sj(i, j-1, k, 1) + w(i, j, k+1, ivx)*sk(i, j, k, 1) - w(i, j, &
151 & k-1, ivx)*sk(i, j, k-1, 1)
152  uuy = w(i+1, j, k, ivx)*si(i, j, k, 2) - w(i-1, j, k, ivx)*si(i-1&
153 & , j, k, 2) + w(i, j+1, k, ivx)*sj(i, j, k, 2) - w(i, j-1, k, ivx&
154 & )*sj(i, j-1, k, 2) + w(i, j, k+1, ivx)*sk(i, j, k, 2) - w(i, j, &
155 & k-1, ivx)*sk(i, j, k-1, 2)
156  uuz = w(i+1, j, k, ivx)*si(i, j, k, 3) - w(i-1, j, k, ivx)*si(i-1&
157 & , j, k, 3) + w(i, j+1, k, ivx)*sj(i, j, k, 3) - w(i, j-1, k, ivx&
158 & )*sj(i, j-1, k, 3) + w(i, j, k+1, ivx)*sk(i, j, k, 3) - w(i, j, &
159 & k-1, ivx)*sk(i, j, k-1, 3)
160 ! idem for the gradient of v.
161  vvx = w(i+1, j, k, ivy)*si(i, j, k, 1) - w(i-1, j, k, ivy)*si(i-1&
162 & , j, k, 1) + w(i, j+1, k, ivy)*sj(i, j, k, 1) - w(i, j-1, k, ivy&
163 & )*sj(i, j-1, k, 1) + w(i, j, k+1, ivy)*sk(i, j, k, 1) - w(i, j, &
164 & k-1, ivy)*sk(i, j, k-1, 1)
165  vvy = w(i+1, j, k, ivy)*si(i, j, k, 2) - w(i-1, j, k, ivy)*si(i-1&
166 & , j, k, 2) + w(i, j+1, k, ivy)*sj(i, j, k, 2) - w(i, j-1, k, ivy&
167 & )*sj(i, j-1, k, 2) + w(i, j, k+1, ivy)*sk(i, j, k, 2) - w(i, j, &
168 & k-1, ivy)*sk(i, j, k-1, 2)
169  vvz = w(i+1, j, k, ivy)*si(i, j, k, 3) - w(i-1, j, k, ivy)*si(i-1&
170 & , j, k, 3) + w(i, j+1, k, ivy)*sj(i, j, k, 3) - w(i, j-1, k, ivy&
171 & )*sj(i, j-1, k, 3) + w(i, j, k+1, ivy)*sk(i, j, k, 3) - w(i, j, &
172 & k-1, ivy)*sk(i, j, k-1, 3)
173 ! and for the gradient of w.
174  wwx = w(i+1, j, k, ivz)*si(i, j, k, 1) - w(i-1, j, k, ivz)*si(i-1&
175 & , j, k, 1) + w(i, j+1, k, ivz)*sj(i, j, k, 1) - w(i, j-1, k, ivz&
176 & )*sj(i, j-1, k, 1) + w(i, j, k+1, ivz)*sk(i, j, k, 1) - w(i, j, &
177 & k-1, ivz)*sk(i, j, k-1, 1)
178  wwy = w(i+1, j, k, ivz)*si(i, j, k, 2) - w(i-1, j, k, ivz)*si(i-1&
179 & , j, k, 2) + w(i, j+1, k, ivz)*sj(i, j, k, 2) - w(i, j-1, k, ivz&
180 & )*sj(i, j-1, k, 2) + w(i, j, k+1, ivz)*sk(i, j, k, 2) - w(i, j, &
181 & k-1, ivz)*sk(i, j, k-1, 2)
182  wwz = w(i+1, j, k, ivz)*si(i, j, k, 3) - w(i-1, j, k, ivz)*si(i-1&
183 & , j, k, 3) + w(i, j+1, k, ivz)*sj(i, j, k, 3) - w(i, j-1, k, ivz&
184 & )*sj(i, j-1, k, 3) + w(i, j, k+1, ivz)*sk(i, j, k, 3) - w(i, j, &
185 & k-1, ivz)*sk(i, j, k-1, 3)
186 ! compute the components of the stress tensor.
187 ! the combination of the current scaling of the velocity
188 ! gradients (2*vol) and the definition of the stress tensor,
189 ! leads to the factor 1/(4*vol).
190  fact = fourth/vol(i, j, k)
191  sxx = two*fact*uux
192  syy = two*fact*vvy
193  szz = two*fact*wwz
194  sxy = fact*(uuy+vvx)
195  sxz = fact*(uuz+wwx)
196  syz = fact*(vvz+wwy)
197 ! compute 2/3 * divergence of velocity squared
198  div2 = f23*(sxx+syy+szz)**2
199 ! store the square of strain as the production term.
200  scratch(i, j, k, iprod) = two*(two*(sxy**2+sxz**2+syz**2)+sxx**2+&
201 & syy**2+szz**2) - div2
202  end do
203  end subroutine prodsmag2
204 
205  subroutine prodwmag2()
206 !
207 ! prodwmag2 computes the term:
208 ! 2*oij*oij with oij=0.5*(duidxj - dujdxi).
209 ! this is equal to the magnitude squared of the vorticity.
210 ! it is assumed that the pointer vort, stored in turbmod, is
211 ! already set to the correct entry.
212 !
213  use constants
214  use blockpointers, only : nx, ny, nz, il, jl, kl, w, si, sj, sk, &
216  use flowvarrefstate, only : timeref
217  use section, only : sections
218  implicit none
219 !
220 ! local variables.
221 !
222  integer :: i, j, k, ii
223  real(kind=realtype) :: uuy, uuz, vvx, vvz, wwx, wwy
224  real(kind=realtype) :: fact, vortx, vorty, vortz
225  real(kind=realtype) :: omegax, omegay, omegaz
226  intrinsic mod
227 ! determine the non-dimensional wheel speed of this block.
228  omegax = timeref*sections(sectionid)%rotrate(1)
229  omegay = timeref*sections(sectionid)%rotrate(2)
230  omegaz = timeref*sections(sectionid)%rotrate(3)
231 !$ad ii-loop
232 ! loop over the cell centers of the given block. it may be more
233 ! efficient to loop over the faces and to scatter the gradient,
234 ! but in that case the gradients for u, v and w must be stored.
235 ! in the current approach no extra memory is needed.
236  do ii=0,nx*ny*nz-1
237  i = mod(ii, nx) + 2
238  j = mod(ii/nx, ny) + 2
239  k = ii/(nx*ny) + 2
240 ! compute the necessary derivatives of u in the cell center.
241 ! use is made of the fact that the surrounding normals sum up
242 ! to zero, such that the cell i,j,k does not give a
243 ! contribution. the gradient is scaled by a factor 2*vol.
244  uuy = w(i+1, j, k, ivx)*si(i, j, k, 2) - w(i-1, j, k, ivx)*si(i-1&
245 & , j, k, 2) + w(i, j+1, k, ivx)*sj(i, j, k, 2) - w(i, j-1, k, ivx&
246 & )*sj(i, j-1, k, 2) + w(i, j, k+1, ivx)*sk(i, j, k, 2) - w(i, j, &
247 & k-1, ivx)*sk(i, j, k-1, 2)
248  uuz = w(i+1, j, k, ivx)*si(i, j, k, 3) - w(i-1, j, k, ivx)*si(i-1&
249 & , j, k, 3) + w(i, j+1, k, ivx)*sj(i, j, k, 3) - w(i, j-1, k, ivx&
250 & )*sj(i, j-1, k, 3) + w(i, j, k+1, ivx)*sk(i, j, k, 3) - w(i, j, &
251 & k-1, ivx)*sk(i, j, k-1, 3)
252 ! idem for the gradient of v.
253  vvx = w(i+1, j, k, ivy)*si(i, j, k, 1) - w(i-1, j, k, ivy)*si(i-1&
254 & , j, k, 1) + w(i, j+1, k, ivy)*sj(i, j, k, 1) - w(i, j-1, k, ivy&
255 & )*sj(i, j-1, k, 1) + w(i, j, k+1, ivy)*sk(i, j, k, 1) - w(i, j, &
256 & k-1, ivy)*sk(i, j, k-1, 1)
257  vvz = w(i+1, j, k, ivy)*si(i, j, k, 3) - w(i-1, j, k, ivy)*si(i-1&
258 & , j, k, 3) + w(i, j+1, k, ivy)*sj(i, j, k, 3) - w(i, j-1, k, ivy&
259 & )*sj(i, j-1, k, 3) + w(i, j, k+1, ivy)*sk(i, j, k, 3) - w(i, j, &
260 & k-1, ivy)*sk(i, j, k-1, 3)
261 ! and for the gradient of w.
262  wwx = w(i+1, j, k, ivz)*si(i, j, k, 1) - w(i-1, j, k, ivz)*si(i-1&
263 & , j, k, 1) + w(i, j+1, k, ivz)*sj(i, j, k, 1) - w(i, j-1, k, ivz&
264 & )*sj(i, j-1, k, 1) + w(i, j, k+1, ivz)*sk(i, j, k, 1) - w(i, j, &
265 & k-1, ivz)*sk(i, j, k-1, 1)
266  wwy = w(i+1, j, k, ivz)*si(i, j, k, 2) - w(i-1, j, k, ivz)*si(i-1&
267 & , j, k, 2) + w(i, j+1, k, ivz)*sj(i, j, k, 2) - w(i, j-1, k, ivz&
268 & )*sj(i, j-1, k, 2) + w(i, j, k+1, ivz)*sk(i, j, k, 2) - w(i, j, &
269 & k-1, ivz)*sk(i, j, k-1, 2)
270 ! compute the three components of the vorticity vector.
271 ! substract the part coming from the rotating frame.
272  fact = half/vol(i, j, k)
273  vortx = fact*(wwy-vvz) - two*omegax
274  vorty = fact*(uuz-wwx) - two*omegay
275  vortz = fact*(vvx-uuy) - two*omegaz
276 ! compute the magnitude squared of the vorticity.
277  scratch(i, j, k, ivort) = vortx**2 + vorty**2 + vortz**2
278  end do
279  end subroutine prodwmag2
280 
281 ! differentiation of sanuknowneddyratio in reverse (adjoint) mode (with options noisize i4 dr8 r8):
282 ! gradient of useful results: sanuknowneddyratio
283 ! with respect to varying inputs: nulam
284  subroutine sanuknowneddyratio_b(eddyratio, nulam, nulamd, &
285 & sanuknowneddyratiod)
286 !
287 ! sanuknowneddyratio computes the spalart-allmaras transport
288 ! variable nu for the given eddy viscosity ratio.
289 !
290  use constants
291  use paramturb
292  implicit none
293 !
294 ! function type.
295 !
296  real(kind=realtype) :: sanuknowneddyratio
297  real(kind=realtype) :: sanuknowneddyratiod
298 !
299 ! function arguments.
300 !
301  real(kind=realtype), intent(in) :: eddyratio, nulam
302  real(kind=realtype) :: nulamd
303 !
304 ! local variables.
305 !
306  real(kind=realtype) :: cv13, chi, chi2, chi3, chi4, f, df, dchi
307  intrinsic abs
308  real(kind=realtype) :: abs0
309  integer :: ad_count
310  integer :: i
311  integer :: branch
312 ! take care of the exceptional cases.
313  if (eddyratio .le. zero) then
314  nulamd = 0.0_8
315  else
316 ! set the value of cv1^3, which is the constant appearing in the
317 ! sa function fv1 to compute the eddy viscosity
318  cv13 = rsacv1**3
319 ! determine the value of chi, which is given by the quartic
320 ! polynomial chi^4 - ratio*(chi^3 + cv1^3) = 0.
321 ! first determine the start value, depending on the eddyratio.
322  if (eddyratio .lt. 1.e-4_realtype) then
323  call pushcontrol2b(2)
324  chi = 0.5_realtype
325  else if (eddyratio .lt. 1.0_realtype) then
326  call pushcontrol2b(1)
327  chi = 5.0_realtype
328  else if (eddyratio .lt. 10.0_realtype) then
329  call pushcontrol2b(0)
330  chi = 10.0_realtype
331  else
332  call pushcontrol2b(0)
333  chi = eddyratio
334  end if
335  ad_count = 1
336 ! the actual newton algorithm.
337  do
338 ! compute the function value and the derivative.
339  chi2 = chi*chi
340  chi3 = chi*chi2
341  chi4 = chi*chi3
342  f = chi4 - eddyratio*(chi3+cv13)
343  df = four*chi3 - three*eddyratio*chi2
344 ! compute the negative update and the new value of chi.
345  dchi = f/df
346  chi = chi - dchi
347  if (dchi/chi .ge. 0.) then
348  abs0 = dchi/chi
349  else
350  abs0 = -(dchi/chi)
351  end if
352 ! condition to exit the loop.
353  if (abs0 .le. thresholdreal) then
354  exit
355  else
356  ad_count = ad_count + 1
357  end if
358  end do
359  call pushinteger4(ad_count)
360  nulamd = chi*sanuknowneddyratiod
361  call popinteger4(ad_count)
362  i = ad_count + 1
363  call popcontrol2b(branch)
364  end if
365  end subroutine sanuknowneddyratio_b
366 
367  function sanuknowneddyratio(eddyratio, nulam)
368 !
369 ! sanuknowneddyratio computes the spalart-allmaras transport
370 ! variable nu for the given eddy viscosity ratio.
371 !
372  use constants
373  use paramturb
374  implicit none
375 !
376 ! function type.
377 !
378  real(kind=realtype) :: sanuknowneddyratio
379 !
380 ! function arguments.
381 !
382  real(kind=realtype), intent(in) :: eddyratio, nulam
383 !
384 ! local variables.
385 !
386  real(kind=realtype) :: cv13, chi, chi2, chi3, chi4, f, df, dchi
387  intrinsic abs
388  real(kind=realtype) :: abs0
389 ! take care of the exceptional cases.
390  if (eddyratio .le. zero) then
392  return
393  else
394 ! set the value of cv1^3, which is the constant appearing in the
395 ! sa function fv1 to compute the eddy viscosity
396  cv13 = rsacv1**3
397 ! determine the value of chi, which is given by the quartic
398 ! polynomial chi^4 - ratio*(chi^3 + cv1^3) = 0.
399 ! first determine the start value, depending on the eddyratio.
400  if (eddyratio .lt. 1.e-4_realtype) then
401  chi = 0.5_realtype
402  else if (eddyratio .lt. 1.0_realtype) then
403  chi = 5.0_realtype
404  else if (eddyratio .lt. 10.0_realtype) then
405  chi = 10.0_realtype
406  else
407  chi = eddyratio
408  end if
409 ! the actual newton algorithm.
410  do
411 ! compute the function value and the derivative.
412  chi2 = chi*chi
413  chi3 = chi*chi2
414  chi4 = chi*chi3
415  f = chi4 - eddyratio*(chi3+cv13)
416  df = four*chi3 - three*eddyratio*chi2
417 ! compute the negative update and the new value of chi.
418  dchi = f/df
419  chi = chi - dchi
420  if (dchi/chi .ge. 0.) then
421  abs0 = dchi/chi
422  else
423  abs0 = -(dchi/chi)
424  end if
425 ! condition to exit the loop.
426  if (abs0 .le. thresholdreal) then
427 ! chi is the ratio of the spalart allmaras transport variable and
428 ! the laminar viscosity. so multiply chi with the laminar viscosity
429 ! to obtain the correct value.
430  sanuknowneddyratio = nulam*chi
431  goto 100
432  end if
433  end do
434  end if
435  100 continue
436  end function sanuknowneddyratio
437 
438  subroutine unsteadyturbterm(madv, nadv, offset, qq)
439 !
440 ! unsteadyturbterm discretizes the time derivative of the
441 ! turbulence transport equations and add it to the residual.
442 ! as the time derivative is the same for all turbulence models,
443 ! this generic routine can be used; both the discretization of
444 ! the time derivative and its contribution to the central
445 ! jacobian are computed by this routine.
446 ! only nadv equations are treated, while the actual system has
447 ! size madv. the reason is that some equations for some
448 ! turbulence equations do not have a time derivative, e.g. the
449 ! f equation in the v2-f model. the argument offset indicates
450 ! the offset in the w vector where this subsystem starts. as a
451 ! consequence it is assumed that the indices of the current
452 ! subsystem are contiguous, e.g. if a 2*2 system is solved the
453 ! last index in w is offset+1 and offset+2 respectively.
454 !
455  use blockpointers
456  use flowvarrefstate
457  use inputphysics
459  use inputunsteady
460  use iteration
461  use section
462  use turbmod
463  implicit none
464 !
465 ! subroutine arguments.
466 !
467  integer(kind=inttype), intent(in) :: madv, nadv, offset
468  real(kind=realtype), dimension(2:il, 2:jl, 2:kl, madv, madv), &
469 & intent(inout) :: qq
470 !
471 ! local variables.
472 !
473  integer(kind=inttype) :: i, j, k, ii, jj, nn
474  real(kind=realtype) :: oneoverdt, tmp
475 ! determine the equation mode.
476  select case (equationmode)
477  case (steady)
478 ! steady computation. no time derivative present.
479  return
480 !===============================================================
481  case (unsteady)
482 ! the time deritvative term depends on the integration
483 ! scheme used.
484  select case (timeintegrationscheme)
485  case (bdf)
486 ! backward difference formula is used as time
487 ! integration scheme.
488 ! store the inverse of the physical nondimensional
489 ! time step a bit easier.
490  oneoverdt = timeref/deltat
491 ! loop over the number of turbulent transport equations.
492 nadvloopunsteady:do ii=1,nadv
493 ! store the index of the current turbulent variable in jj.
494  jj = ii + offset
495 ! loop over the owned cells of this block to compute the
496 ! time derivative.
497  do k=2,kl
498  do j=2,jl
499  do i=2,il
500 ! initialize tmp to the value of the current
501 ! level multiplied by the corresponding coefficient
502 ! in the time integration scheme.
503  tmp = coeftime(0)*w(i, j, k, jj)
504 ! loop over the old time levels and add the
505 ! corresponding contribution to tmp.
506  do nn=1,noldlevels
507  tmp = tmp + coeftime(nn)*wold(nn, i, j, k, jj)
508  end do
509 ! update the residual. note that in the turbulent
510 ! routines the residual is defined with an opposite
511 ! sign compared to the residual of the flow equations.
512 ! therefore the time derivative must be substracted
513 ! from dvt.
514  scratch(i, j, k, idvt+ii-1) = scratch(i, j, k, idvt+ii-1&
515 & ) - oneoverdt*tmp
516 ! update the central jacobian.
517  qq(i, j, k, ii, ii) = qq(i, j, k, ii, ii) + coeftime(0)*&
518 & oneoverdt
519  end do
520  end do
521  end do
522  end do nadvloopunsteady
523  case (explicitrk)
524 !===========================================================
525 ! explicit time integration scheme. the time derivative
526 ! is handled differently.
527  return
528  end select
529 !===============================================================
530  case (timespectral)
531 ! time spectral method.
532 ! loop over the number of turbulent transport equations.
533 nadvloopspectral:do ii=1,nadv
534 ! store the index of the current turbulent variable in jj.
535  jj = ii + offset
536 ! the time derivative has been computed earlier in
537 ! unsteadyturbspectral and stored in entry jj of scratch.
538 ! substract this value for all owned cells. it must be
539 ! substracted, because in the turbulent routines the
540 ! residual is defined with an opposite sign compared to
541 ! the residual of the flow equations.
542 ! also add a term to the diagonal matrix, which corresponds
543 ! to to the contribution of the highest frequency. this is
544 ! equivalent to an explicit treatment of the time derivative
545 ! and may need to be changed.
547 & timeperiod
548  do k=2,kl
549  do j=2,jl
550  do i=2,il
551  scratch(i, j, k, idvt+ii-1) = scratch(i, j, k, idvt+ii-1) &
552 & - dw(i, j, k, jj)
553  qq(i, j, k, ii, ii) = qq(i, j, k, ii, ii) + tmp
554  end do
555  end do
556  end do
557  end do nadvloopspectral
558  end select
559  end subroutine unsteadyturbterm
560 
561 ! differentiation of computeeddyviscosity in reverse (adjoint) mode (with options noisize i4 dr8 r8):
562 ! gradient of useful results: *rev *w *rlv
563 ! with respect to varying inputs: *rev *w *rlv
564 ! rw status of diff variables: *rev:in-out *w:incr *rlv:incr
565 ! plus diff mem management of: rev:in w:in rlv:in
566  subroutine computeeddyviscosity_b(includehalos)
567 !
568 ! computeeddyviscosity computes the eddy viscosity in the
569 ! owned cell centers of the given block. it is assumed that the
570 ! pointes already point to the correct block before entering
571 ! this subroutine.
572 !
573  use constants
574  use flowvarrefstate
575  use inputphysics
576  use iteration
577  use blockpointers
578  implicit none
579 ! input parameter
580  logical, intent(in) :: includehalos
581 !
582 ! local variables.
583 !
584  logical :: returnimmediately
585  integer(kind=inttype) :: ibeg, iend, jbeg, jend, kbeg, kend
586  integer :: branch
587 ! check if an immediate return can be made.
588  if (eddymodel) then
589  if (currentlevel .le. groundlevel) then
590  call pushcontrol1b(0)
591  returnimmediately = .false.
592  else
593  call pushcontrol1b(0)
594  returnimmediately = .true.
595  end if
596  else
597  call pushcontrol1b(1)
598  returnimmediately = .true.
599  end if
600  if (.not.returnimmediately) then
601 ! determine the turbulence model and call the appropriate
602 ! routine to compute the eddy viscosity.
603  if (includehalos) then
604  ibeg = 1
605  iend = ie
606  jbeg = 1
607  jend = je
608  kbeg = 1
609  kend = ke
610  else
611  ibeg = 2
612  iend = il
613  jbeg = 2
614  jend = jl
615  kbeg = 2
616  kend = kl
617  end if
618  select case (turbmodel)
620  call saeddyviscosity_b(ibeg, iend, jbeg, jend, kbeg, kend)
621  end select
622  end if
623  call popcontrol1b(branch)
624  end subroutine computeeddyviscosity_b
625 
626  subroutine computeeddyviscosity(includehalos)
627 !
628 ! computeeddyviscosity computes the eddy viscosity in the
629 ! owned cell centers of the given block. it is assumed that the
630 ! pointes already point to the correct block before entering
631 ! this subroutine.
632 !
633  use constants
634  use flowvarrefstate
635  use inputphysics
636  use iteration
637  use blockpointers
638  implicit none
639 ! input parameter
640  logical, intent(in) :: includehalos
641 !
642 ! local variables.
643 !
644  logical :: returnimmediately
645  integer(kind=inttype) :: ibeg, iend, jbeg, jend, kbeg, kend
646 ! check if an immediate return can be made.
647  if (eddymodel) then
648  if (currentlevel .le. groundlevel) then
649  returnimmediately = .false.
650  else
651  returnimmediately = .true.
652  end if
653  else
654  returnimmediately = .true.
655  end if
656  if (returnimmediately) then
657  return
658  else
659 ! determine the turbulence model and call the appropriate
660 ! routine to compute the eddy viscosity.
661  if (includehalos) then
662  ibeg = 1
663  iend = ie
664  jbeg = 1
665  jend = je
666  kbeg = 1
667  kend = ke
668  else
669  ibeg = 2
670  iend = il
671  jbeg = 2
672  jend = jl
673  kbeg = 2
674  kend = kl
675  end if
676  select case (turbmodel)
678  call saeddyviscosity(ibeg, iend, jbeg, jend, kbeg, kend)
679  end select
680  end if
681  end subroutine computeeddyviscosity
682 
683 ! differentiation of saeddyviscosity in reverse (adjoint) mode (with options noisize i4 dr8 r8):
684 ! gradient of useful results: *rev *w *rlv
685 ! with respect to varying inputs: *rev *w *rlv
686 ! plus diff mem management of: rev:in w:in rlv:in
687  subroutine saeddyviscosity_b(ibeg, iend, jbeg, jend, kbeg, kend)
688 !
689 ! saeddyviscosity computes the eddy-viscosity according to the
690 ! spalart-allmaras model for the block given in blockpointers.
691 ! this routine for both the original version as well as the
692 ! modified version according to edwards.
693 !
694  use constants
695  use blockpointers
696  use constants
697  use paramturb
698  implicit none
699 ! input variables
700  integer(kind=inttype) :: ibeg, iend, jbeg, jend, kbeg, kend
701 !
702 ! local variables.
703 !
704  integer(kind=inttype) :: i, j, k, ii, isize, jsize, ksize
705  real(kind=realtype) :: chi, chi3, fv1, rnusa, cv13
706  real(kind=realtype) :: chid, chi3d, fv1d, rnusad
707  intrinsic mod
708  real(kind=realtype) :: tempd
709 ! store the cv1^3; cv1 is a constant of the spalart-allmaras model.
710  cv13 = rsacv1**3
711 ! loop over the cells of this block and compute the eddy viscosity.
712 ! do not include halo's.
713  isize = iend - ibeg + 1
714  jsize = jend - jbeg + 1
715  ksize = kend - kbeg + 1
716 !$bwd-of ii-loop
717  do ii=0,isize*jsize*ksize-1
718  i = mod(ii, isize) + ibeg
719  j = mod(ii/isize, jsize) + jbeg
720  k = ii/(isize*jsize) + kbeg
721  rnusa = w(i, j, k, itu1)*w(i, j, k, irho)
722  chi = rnusa/rlv(i, j, k)
723  chi3 = chi**3
724  fv1 = chi3/(chi3+cv13)
725  fv1d = rnusa*revd(i, j, k)
726  tempd = fv1d/(cv13+chi3)
727  chi3d = (1.0-chi3/(cv13+chi3))*tempd
728  chid = 3*chi**2*chi3d
729  tempd = chid/rlv(i, j, k)
730  rnusad = fv1*revd(i, j, k) + tempd
731  revd(i, j, k) = 0.0_8
732  rlvd(i, j, k) = rlvd(i, j, k) - rnusa*tempd/rlv(i, j, k)
733  wd(i, j, k, itu1) = wd(i, j, k, itu1) + w(i, j, k, irho)*rnusad
734  wd(i, j, k, irho) = wd(i, j, k, irho) + w(i, j, k, itu1)*rnusad
735  end do
736  end subroutine saeddyviscosity_b
737 
738  subroutine saeddyviscosity(ibeg, iend, jbeg, jend, kbeg, kend)
739 !
740 ! saeddyviscosity computes the eddy-viscosity according to the
741 ! spalart-allmaras model for the block given in blockpointers.
742 ! this routine for both the original version as well as the
743 ! modified version according to edwards.
744 !
745  use constants
746  use blockpointers
747  use constants
748  use paramturb
749  implicit none
750 ! input variables
751  integer(kind=inttype) :: ibeg, iend, jbeg, jend, kbeg, kend
752 !
753 ! local variables.
754 !
755  integer(kind=inttype) :: i, j, k, ii, isize, jsize, ksize
756  real(kind=realtype) :: chi, chi3, fv1, rnusa, cv13
757  intrinsic mod
758 ! store the cv1^3; cv1 is a constant of the spalart-allmaras model.
759  cv13 = rsacv1**3
760 ! loop over the cells of this block and compute the eddy viscosity.
761 ! do not include halo's.
762  isize = iend - ibeg + 1
763  jsize = jend - jbeg + 1
764  ksize = kend - kbeg + 1
765 !$ad ii-loop
766  do ii=0,isize*jsize*ksize-1
767  i = mod(ii, isize) + ibeg
768  j = mod(ii/isize, jsize) + jbeg
769  k = ii/(isize*jsize) + kbeg
770  rnusa = w(i, j, k, itu1)*w(i, j, k, irho)
771  chi = rnusa/rlv(i, j, k)
772  chi3 = chi**3
773  fv1 = chi3/(chi3+cv13)
774  rev(i, j, k) = fv1*rnusa
775  end do
776  end subroutine saeddyviscosity
777 
778  subroutine kweddyviscosity(ibeg, iend, jbeg, jend, kbeg, kend)
779 !
780 ! kweddyviscosity computes the eddy viscosity according to the
781 ! k-omega models (both the original wilcox as well as the
782 ! modified version) for the block given in blockpointers.
783 !
784  use constants
785  use blockpointers
786  implicit none
787 ! input variables
788  integer(kind=inttype) :: ibeg, iend, jbeg, jend, kbeg, kend
789 !
790 ! local variables.
791 !
792  integer(kind=inttype) :: i, j, k, ii, isize, jsize, ksize
793  intrinsic mod
794  intrinsic abs
795  real(kind=realtype) :: x1
796 ! loop over the cells of this block and compute the eddy viscosity.
797 ! do not include halo's.
798  isize = iend - ibeg + 1
799  jsize = jend - jbeg + 1
800  ksize = kend - kbeg + 1
801 !$ad ii-loop
802  do ii=0,isize*jsize*ksize-1
803  i = mod(ii, isize) + ibeg
804  j = mod(ii/isize, jsize) + jbeg
805  k = ii/(isize*jsize) + kbeg
806  x1 = w(i, j, k, irho)*w(i, j, k, itu1)/w(i, j, k, itu2)
807  if (x1 .ge. 0.) then
808  rev(i, j, k) = x1
809  else
810  rev(i, j, k) = -x1
811  end if
812  end do
813  end subroutine kweddyviscosity
814 
815  subroutine ssteddyviscosity(ibeg, iend, jbeg, jend, kbeg, kend)
816 !
817 ! ssteddyviscosity computes the eddy viscosity according to
818 ! menter's sst variant of the k-omega turbulence model for the
819 ! block given in blockpointers.
820 !
821  use constants
822  use blockpointers
823  use paramturb
824  use turbmod
825  implicit none
826 ! input variables
827  integer(kind=inttype) :: ibeg, iend, jbeg, jend, kbeg, kend
828 !
829 ! local variables.
830 !
831  integer(kind=inttype) :: i, j, k, ii, isize, jsize, ksize
832  real(kind=realtype) :: t1, t2, arg2, f2, vortmag
833  intrinsic mod
834  intrinsic sqrt
835  intrinsic max
836  intrinsic tanh
837  real(kind=realtype) :: max1
838 ! compute the vorticity squared in the cell centers. the reason
839 ! for computing the vorticity squared is that a routine exists
840 ! for it; for the actual eddy viscosity computation the vorticity
841 ! itself is needed.
842  call prodwmag2()
843 ! loop over the cells of this block and compute the eddy viscosity.
844 ! do not include halo's.
845  isize = iend - ibeg + 1
846  jsize = jend - jbeg + 1
847  ksize = kend - kbeg + 1
848 !$ad ii-loop
849  do ii=0,isize*jsize*ksize-1
850  i = mod(ii, isize) + ibeg
851  j = mod(ii/isize, jsize) + jbeg
852  k = ii/(isize*jsize) + kbeg
853 ! compute the value of the function f2, which occurs in the
854 ! eddy-viscosity computation.
855  t1 = two*sqrt(w(i, j, k, itu1))/(0.09_realtype*w(i, j, k, itu2)*&
856 & d2wall(i, j, k))
857  t2 = 500.0_realtype*rlv(i, j, k)/(w(i, j, k, irho)*w(i, j, k, itu2&
858 & )*d2wall(i, j, k)**2)
859  if (t1 .lt. t2) then
860  arg2 = t2
861  else
862  arg2 = t1
863  end if
864  f2 = tanh(arg2**2)
865 ! and compute the eddy viscosity.
866  vortmag = sqrt(scratch(i, j, k, iprod))
867  if (rssta1*w(i, j, k, itu2) .lt. f2*vortmag) then
868  max1 = f2*vortmag
869  else
870  max1 = rssta1*w(i, j, k, itu2)
871  end if
872  rev(i, j, k) = w(i, j, k, irho)*rssta1*w(i, j, k, itu1)/max1
873  end do
874  end subroutine ssteddyviscosity
875 
876 ! differentiation of turbadvection in reverse (adjoint) mode (with options noisize i4 dr8 r8):
877 ! gradient of useful results: *sfacei *sfacej *sfacek *w
878 ! *scratch *vol *si *sj *sk
879 ! with respect to varying inputs: *sfacei *sfacej *sfacek *w
880 ! *scratch *vol *si *sj *sk
881 ! rw status of diff variables: *sfacei:incr *sfacej:incr *sfacek:incr
882 ! *w:incr *scratch:in-out *vol:incr *si:incr *sj:incr
883 ! *sk:incr
884 ! plus diff mem management of: sfacei:in sfacej:in sfacek:in
885 ! w:in scratch:in vol:in si:in sj:in sk:in
886  subroutine turbadvection_b(madv, nadv, offset, qq)
887 !
888 ! turbadvection discretizes the advection part of the turbulent
889 ! transport equations. as the advection part is the same for all
890 ! models, this generic routine can be used. both the
891 ! discretization and the central jacobian are computed in this
892 ! subroutine. the former can either be 1st or 2nd order
893 ! accurate; the latter is always based on the 1st order upwind
894 ! discretization. when the discretization must be second order
895 ! accurate, the fully upwind (kappa = -1) scheme in combination
896 ! with the minmod limiter is used.
897 ! only nadv equations are treated, while the actual system has
898 ! size madv. the reason is that some equations for some
899 ! turbulence equations do not have an advection part, e.g. the
900 ! f equation in the v2-f model. the argument offset indicates
901 ! the offset in the w vector where this subsystem starts. as a
902 ! consequence it is assumed that the indices of the current
903 ! subsystem are contiguous, e.g. if a 2*2 system is solved the
904 ! last index in w is offset+1 and offset+2 respectively.
905 !
906  use constants
907  use blockpointers, only : nx, ny, nz, il, jl, kl, vol, vold, &
911  use inputdiscretization, only : orderturb
912  use iteration, only : groundlevel
913  use turbmod, only : secondord
914  implicit none
915 !
916 ! subroutine arguments.
917 !
918  integer(kind=inttype), intent(in) :: nadv, madv, offset
919  real(kind=realtype), dimension(2:il, 2:jl, 2:kl, madv, madv), &
920 & intent(inout) :: qq
921 !
922 ! local variables.
923 !
924  integer(kind=inttype) :: i, j, k, ii, jj, kk, iii
925  real(kind=realtype) :: qs, voli, xa, ya, za
926  real(kind=realtype) :: qsd, volid, xad, yad, zad
927  real(kind=realtype) :: uu, dwt, dwtm1, dwtp1, dwti, dwtj, dwtk
928  real(kind=realtype) :: uud, dwtd, dwtm1d, dwtp1d, dwtid, dwtjd, &
929 & dwtkd
930  real(kind=realtype), dimension(madv) :: impl
931  intrinsic mod
932  intrinsic abs
933  real(kind=realtype) :: abs0
934  real(kind=realtype) :: abs1
935  real(kind=realtype) :: abs2
936  real(kind=realtype) :: abs3
937  real(kind=realtype) :: abs4
938  real(kind=realtype) :: abs5
939  real(kind=realtype) :: abs6
940  real(kind=realtype) :: abs7
941  real(kind=realtype) :: abs8
942  real(kind=realtype) :: abs9
943  real(kind=realtype) :: abs10
944  real(kind=realtype) :: abs11
945  real(kind=realtype) :: abs12
946  real(kind=realtype) :: abs13
947  real(kind=realtype) :: abs14
948  real(kind=realtype) :: abs15
949  real(kind=realtype) :: abs16
950  real(kind=realtype) :: abs17
951  real(kind=realtype) :: abs18
952  real(kind=realtype) :: abs19
953  real(kind=realtype) :: abs20
954  real(kind=realtype) :: abs21
955  real(kind=realtype) :: abs22
956  real(kind=realtype) :: abs23
957  integer :: branch
958 ! determine whether or not a second order discretization for the
959 ! advective terms must be used.
960  secondord = .false.
961  if (groundlevel .eq. 1_inttype .and. orderturb .eq. secondorder) &
962 & secondord = .true.
963  qsd = 0.0_8
964  qs = zero
965  qsd = 0.0_8
966 !$bwd-of ii-loop
967  do iii=0,nx*ny*nz-1
968  i = mod(iii, nx) + 2
969  j = mod(iii/nx, ny) + 2
970  k = iii/(nx*ny) + 2
971 ! compute the grid velocity if present.
972 ! it is taken as the average of i and i-1,
973  voli = half/vol(i, j, k)
974  if (addgridvelocities) then
975  qs = (sfacei(i, j, k)+sfacei(i-1, j, k))*voli
976  call pushcontrol1b(0)
977  else
978  call pushcontrol1b(1)
979  end if
980 ! compute the normal velocity, where the normal direction
981 ! is taken as the average of faces i and i-1.
982  xa = (si(i, j, k, 1)+si(i-1, j, k, 1))*voli
983  ya = (si(i, j, k, 2)+si(i-1, j, k, 2))*voli
984  za = (si(i, j, k, 3)+si(i-1, j, k, 3))*voli
985  uu = xa*w(i, j, k, ivx) + ya*w(i, j, k, ivy) + za*w(i, j, k, ivz) &
986 & - qs
987 ! determine the situation we are having here, i.e. positive
988 ! or negative normal velocity.
989  if (uu .gt. zero) then
990  uud = 0.0_8
991 !$bwd-of ii-loop
992  do 100 ii=1,nadv
993 ! set the value of jj such that it corresponds to the
994 ! turbulent entry in w.
995  jj = ii + offset
996 ! check whether a first or a second order discretization
997 ! must be used.
998  if (secondord) then
999 ! second order; store the three differences for the
1000 ! discretization of the derivative in i-direction.
1001  dwtm1 = w(i-1, j, k, jj) - w(i-2, j, k, jj)
1002  dwt = w(i, j, k, jj) - w(i-1, j, k, jj)
1003  dwtp1 = w(i+1, j, k, jj) - w(i, j, k, jj)
1004 ! construct the derivative in this cell center. this is
1005 ! the first order upwind derivative with two nonlinear
1006 ! corrections.
1007  dwti = dwt
1008  if (dwt*dwtp1 .gt. zero) then
1009  if (dwt .ge. 0.) then
1010  abs8 = dwt
1011  else
1012  abs8 = -dwt
1013  end if
1014  if (dwtp1 .ge. 0.) then
1015  abs20 = dwtp1
1016  else
1017  abs20 = -dwtp1
1018  end if
1019  if (abs8 .lt. abs20) then
1020  dwti = dwti + half*dwt
1021  call pushcontrol2b(0)
1022  else
1023  dwti = dwti + half*dwtp1
1024  call pushcontrol2b(1)
1025  end if
1026  else
1027  call pushcontrol2b(2)
1028  end if
1029  if (dwt*dwtm1 .gt. zero) then
1030  if (dwt .ge. 0.) then
1031  abs9 = dwt
1032  else
1033  abs9 = -dwt
1034  end if
1035  if (dwtm1 .ge. 0.) then
1036  abs21 = dwtm1
1037  else
1038  abs21 = -dwtm1
1039  end if
1040  if (abs9 .lt. abs21) then
1041  dwti = dwti - half*dwt
1042  call pushcontrol2b(0)
1043  else
1044  dwti = dwti - half*dwtm1
1045  call pushcontrol2b(1)
1046  end if
1047  else
1048  call pushcontrol2b(2)
1049  end if
1050  else
1051 ! 1st order upwind scheme.
1052  dwti = w(i, j, k, jj) - w(i-1, j, k, jj)
1053  call pushcontrol2b(3)
1054  end if
1055  uud = uud - dwti*scratchd(i, j, k, idvt+ii-1)
1056  dwtid = -(uu*scratchd(i, j, k, idvt+ii-1))
1057  call popcontrol2b(branch)
1058  if (branch .lt. 2) then
1059  if (branch .eq. 0) then
1060  dwtd = -(half*dwtid)
1061  dwtm1d = 0.0_8
1062  else
1063  dwtm1d = -(half*dwtid)
1064  dwtd = 0.0_8
1065  end if
1066  else if (branch .eq. 2) then
1067  dwtd = 0.0_8
1068  dwtm1d = 0.0_8
1069  else
1070  wd(i, j, k, jj) = wd(i, j, k, jj) + dwtid
1071  wd(i-1, j, k, jj) = wd(i-1, j, k, jj) - dwtid
1072  goto 100
1073  end if
1074  call popcontrol2b(branch)
1075  if (branch .eq. 0) then
1076  dwtd = dwtd + half*dwtid
1077  dwtp1d = 0.0_8
1078  else if (branch .eq. 1) then
1079  dwtp1d = half*dwtid
1080  else
1081  dwtp1d = 0.0_8
1082  end if
1083  dwtd = dwtd + dwtid
1084  wd(i+1, j, k, jj) = wd(i+1, j, k, jj) + dwtp1d
1085  wd(i, j, k, jj) = wd(i, j, k, jj) + dwtd - dwtp1d
1086  wd(i-1, j, k, jj) = wd(i-1, j, k, jj) + dwtm1d - dwtd
1087  wd(i-2, j, k, jj) = wd(i-2, j, k, jj) - dwtm1d
1088  100 continue
1089  else
1090  uud = 0.0_8
1091 !$bwd-of ii-loop
1092  do 110 ii=1,nadv
1093 ! set the value of jj such that it corresponds to the
1094 ! turbulent entry in w.
1095  jj = ii + offset
1096 ! check whether a first or a second order discretization
1097 ! must be used.
1098  if (secondord) then
1099 ! second order; store the three differences for the
1100 ! discretization of the derivative in i-direction.
1101  dwtm1 = w(i, j, k, jj) - w(i-1, j, k, jj)
1102  dwt = w(i+1, j, k, jj) - w(i, j, k, jj)
1103  dwtp1 = w(i+2, j, k, jj) - w(i+1, j, k, jj)
1104 ! construct the derivative in this cell center. this is
1105 ! the first order upwind derivative with two nonlinear
1106 ! corrections.
1107  dwti = dwt
1108  if (dwt*dwtp1 .gt. zero) then
1109  if (dwt .ge. 0.) then
1110  abs10 = dwt
1111  else
1112  abs10 = -dwt
1113  end if
1114  if (dwtp1 .ge. 0.) then
1115  abs22 = dwtp1
1116  else
1117  abs22 = -dwtp1
1118  end if
1119  if (abs10 .lt. abs22) then
1120  dwti = dwti - half*dwt
1121  call pushcontrol2b(0)
1122  else
1123  dwti = dwti - half*dwtp1
1124  call pushcontrol2b(1)
1125  end if
1126  else
1127  call pushcontrol2b(2)
1128  end if
1129  if (dwt*dwtm1 .gt. zero) then
1130  if (dwt .ge. 0.) then
1131  abs11 = dwt
1132  else
1133  abs11 = -dwt
1134  end if
1135  if (dwtm1 .ge. 0.) then
1136  abs23 = dwtm1
1137  else
1138  abs23 = -dwtm1
1139  end if
1140  if (abs11 .lt. abs23) then
1141  dwti = dwti + half*dwt
1142  call pushcontrol2b(0)
1143  else
1144  dwti = dwti + half*dwtm1
1145  call pushcontrol2b(1)
1146  end if
1147  else
1148  call pushcontrol2b(2)
1149  end if
1150  else
1151 ! 1st order upwind scheme.
1152  dwti = w(i+1, j, k, jj) - w(i, j, k, jj)
1153  call pushcontrol2b(3)
1154  end if
1155  uud = uud - dwti*scratchd(i, j, k, idvt+ii-1)
1156  dwtid = -(uu*scratchd(i, j, k, idvt+ii-1))
1157  call popcontrol2b(branch)
1158  if (branch .lt. 2) then
1159  if (branch .eq. 0) then
1160  dwtd = half*dwtid
1161  dwtm1d = 0.0_8
1162  else
1163  dwtm1d = half*dwtid
1164  dwtd = 0.0_8
1165  end if
1166  else if (branch .eq. 2) then
1167  dwtd = 0.0_8
1168  dwtm1d = 0.0_8
1169  else
1170  wd(i+1, j, k, jj) = wd(i+1, j, k, jj) + dwtid
1171  wd(i, j, k, jj) = wd(i, j, k, jj) - dwtid
1172  goto 110
1173  end if
1174  call popcontrol2b(branch)
1175  if (branch .eq. 0) then
1176  dwtd = dwtd - half*dwtid
1177  dwtp1d = 0.0_8
1178  else if (branch .eq. 1) then
1179  dwtp1d = -(half*dwtid)
1180  else
1181  dwtp1d = 0.0_8
1182  end if
1183  dwtd = dwtd + dwtid
1184  wd(i+2, j, k, jj) = wd(i+2, j, k, jj) + dwtp1d
1185  wd(i+1, j, k, jj) = wd(i+1, j, k, jj) + dwtd - dwtp1d
1186  wd(i, j, k, jj) = wd(i, j, k, jj) + dwtm1d - dwtd
1187  wd(i-1, j, k, jj) = wd(i-1, j, k, jj) - dwtm1d
1188  110 continue
1189  end if
1190  xad = w(i, j, k, ivx)*uud
1191  wd(i, j, k, ivx) = wd(i, j, k, ivx) + xa*uud
1192  yad = w(i, j, k, ivy)*uud
1193  wd(i, j, k, ivy) = wd(i, j, k, ivy) + ya*uud
1194  zad = w(i, j, k, ivz)*uud
1195  wd(i, j, k, ivz) = wd(i, j, k, ivz) + za*uud
1196  qsd = qsd - uud
1197  sid(i, j, k, 3) = sid(i, j, k, 3) + voli*zad
1198  sid(i-1, j, k, 3) = sid(i-1, j, k, 3) + voli*zad
1199  volid = (si(i, j, k, 3)+si(i-1, j, k, 3))*zad + (si(i, j, k, 2)+si&
1200 & (i-1, j, k, 2))*yad + (si(i, j, k, 1)+si(i-1, j, k, 1))*xad
1201  sid(i, j, k, 2) = sid(i, j, k, 2) + voli*yad
1202  sid(i-1, j, k, 2) = sid(i-1, j, k, 2) + voli*yad
1203  sid(i, j, k, 1) = sid(i, j, k, 1) + voli*xad
1204  sid(i-1, j, k, 1) = sid(i-1, j, k, 1) + voli*xad
1205  call popcontrol1b(branch)
1206  if (branch .eq. 0) then
1207  sfaceid(i, j, k) = sfaceid(i, j, k) + voli*qsd
1208  sfaceid(i-1, j, k) = sfaceid(i-1, j, k) + voli*qsd
1209  volid = volid + (sfacei(i, j, k)+sfacei(i-1, j, k))*qsd
1210  qsd = 0.0_8
1211  end if
1212  vold(i, j, k) = vold(i, j, k) - half*volid/vol(i, j, k)**2
1213  end do
1214  qsd = 0.0_8
1215  qs = zero
1216  qsd = 0.0_8
1217 !$bwd-of ii-loop
1218  do iii=0,nx*ny*nz-1
1219  i = mod(iii, nx) + 2
1220  j = mod(iii/nx, ny) + 2
1221  k = iii/(nx*ny) + 2
1222 ! compute the grid velocity if present.
1223 ! it is taken as the average of j and j-1,
1224  voli = half/vol(i, j, k)
1225  if (addgridvelocities) then
1226  qs = (sfacej(i, j, k)+sfacej(i, j-1, k))*voli
1227  call pushcontrol1b(0)
1228  else
1229  call pushcontrol1b(1)
1230  end if
1231 ! compute the normal velocity, where the normal direction
1232 ! is taken as the average of faces j and j-1.
1233  xa = (sj(i, j, k, 1)+sj(i, j-1, k, 1))*voli
1234  ya = (sj(i, j, k, 2)+sj(i, j-1, k, 2))*voli
1235  za = (sj(i, j, k, 3)+sj(i, j-1, k, 3))*voli
1236  uu = xa*w(i, j, k, ivx) + ya*w(i, j, k, ivy) + za*w(i, j, k, ivz) &
1237 & - qs
1238 ! determine the situation we are having here, i.e. positive
1239 ! or negative normal velocity.
1240  if (uu .gt. zero) then
1241  uud = 0.0_8
1242 !$bwd-of ii-loop
1243  do 120 ii=1,nadv
1244 ! set the value of jj such that it corresponds to the
1245 ! turbulent entry in w.
1246  jj = ii + offset
1247 ! check whether a first or a second order discretization
1248 ! must be used.
1249  if (secondord) then
1250 ! second order; store the three differences for the
1251 ! discretization of the derivative in j-direction.
1252  dwtm1 = w(i, j-1, k, jj) - w(i, j-2, k, jj)
1253  dwt = w(i, j, k, jj) - w(i, j-1, k, jj)
1254  dwtp1 = w(i, j+1, k, jj) - w(i, j, k, jj)
1255 ! construct the derivative in this cell center. this is
1256 ! the first order upwind derivative with two nonlinear
1257 ! corrections.
1258  dwtj = dwt
1259  if (dwt*dwtp1 .gt. zero) then
1260  if (dwt .ge. 0.) then
1261  abs4 = dwt
1262  else
1263  abs4 = -dwt
1264  end if
1265  if (dwtp1 .ge. 0.) then
1266  abs16 = dwtp1
1267  else
1268  abs16 = -dwtp1
1269  end if
1270  if (abs4 .lt. abs16) then
1271  dwtj = dwtj + half*dwt
1272  call pushcontrol2b(0)
1273  else
1274  dwtj = dwtj + half*dwtp1
1275  call pushcontrol2b(1)
1276  end if
1277  else
1278  call pushcontrol2b(2)
1279  end if
1280  if (dwt*dwtm1 .gt. zero) then
1281  if (dwt .ge. 0.) then
1282  abs5 = dwt
1283  else
1284  abs5 = -dwt
1285  end if
1286  if (dwtm1 .ge. 0.) then
1287  abs17 = dwtm1
1288  else
1289  abs17 = -dwtm1
1290  end if
1291  if (abs5 .lt. abs17) then
1292  dwtj = dwtj - half*dwt
1293  call pushcontrol2b(0)
1294  else
1295  dwtj = dwtj - half*dwtm1
1296  call pushcontrol2b(1)
1297  end if
1298  else
1299  call pushcontrol2b(2)
1300  end if
1301  else
1302 ! 1st order upwind scheme.
1303  dwtj = w(i, j, k, jj) - w(i, j-1, k, jj)
1304  call pushcontrol2b(3)
1305  end if
1306  uud = uud - dwtj*scratchd(i, j, k, idvt+ii-1)
1307  dwtjd = -(uu*scratchd(i, j, k, idvt+ii-1))
1308  call popcontrol2b(branch)
1309  if (branch .lt. 2) then
1310  if (branch .eq. 0) then
1311  dwtd = -(half*dwtjd)
1312  dwtm1d = 0.0_8
1313  else
1314  dwtm1d = -(half*dwtjd)
1315  dwtd = 0.0_8
1316  end if
1317  else if (branch .eq. 2) then
1318  dwtd = 0.0_8
1319  dwtm1d = 0.0_8
1320  else
1321  wd(i, j, k, jj) = wd(i, j, k, jj) + dwtjd
1322  wd(i, j-1, k, jj) = wd(i, j-1, k, jj) - dwtjd
1323  goto 120
1324  end if
1325  call popcontrol2b(branch)
1326  if (branch .eq. 0) then
1327  dwtd = dwtd + half*dwtjd
1328  dwtp1d = 0.0_8
1329  else if (branch .eq. 1) then
1330  dwtp1d = half*dwtjd
1331  else
1332  dwtp1d = 0.0_8
1333  end if
1334  dwtd = dwtd + dwtjd
1335  wd(i, j+1, k, jj) = wd(i, j+1, k, jj) + dwtp1d
1336  wd(i, j, k, jj) = wd(i, j, k, jj) + dwtd - dwtp1d
1337  wd(i, j-1, k, jj) = wd(i, j-1, k, jj) + dwtm1d - dwtd
1338  wd(i, j-2, k, jj) = wd(i, j-2, k, jj) - dwtm1d
1339  120 continue
1340  else
1341  uud = 0.0_8
1342 !$bwd-of ii-loop
1343  do 130 ii=1,nadv
1344 ! set the value of jj such that it corresponds to the
1345 ! turbulent entry in w.
1346  jj = ii + offset
1347 ! check whether a first or a second order discretization
1348 ! must be used.
1349  if (secondord) then
1350 ! store the three differences for the discretization of
1351 ! the derivative in j-direction.
1352  dwtm1 = w(i, j, k, jj) - w(i, j-1, k, jj)
1353  dwt = w(i, j+1, k, jj) - w(i, j, k, jj)
1354  dwtp1 = w(i, j+2, k, jj) - w(i, j+1, k, jj)
1355 ! construct the derivative in this cell center. this is
1356 ! the first order upwind derivative with two nonlinear
1357 ! corrections.
1358  dwtj = dwt
1359  if (dwt*dwtp1 .gt. zero) then
1360  if (dwt .ge. 0.) then
1361  abs6 = dwt
1362  else
1363  abs6 = -dwt
1364  end if
1365  if (dwtp1 .ge. 0.) then
1366  abs18 = dwtp1
1367  else
1368  abs18 = -dwtp1
1369  end if
1370  if (abs6 .lt. abs18) then
1371  dwtj = dwtj - half*dwt
1372  call pushcontrol2b(0)
1373  else
1374  dwtj = dwtj - half*dwtp1
1375  call pushcontrol2b(1)
1376  end if
1377  else
1378  call pushcontrol2b(2)
1379  end if
1380  if (dwt*dwtm1 .gt. zero) then
1381  if (dwt .ge. 0.) then
1382  abs7 = dwt
1383  else
1384  abs7 = -dwt
1385  end if
1386  if (dwtm1 .ge. 0.) then
1387  abs19 = dwtm1
1388  else
1389  abs19 = -dwtm1
1390  end if
1391  if (abs7 .lt. abs19) then
1392  dwtj = dwtj + half*dwt
1393  call pushcontrol2b(0)
1394  else
1395  dwtj = dwtj + half*dwtm1
1396  call pushcontrol2b(1)
1397  end if
1398  else
1399  call pushcontrol2b(2)
1400  end if
1401  else
1402 ! 1st order upwind scheme.
1403  dwtj = w(i, j+1, k, jj) - w(i, j, k, jj)
1404  call pushcontrol2b(3)
1405  end if
1406  uud = uud - dwtj*scratchd(i, j, k, idvt+ii-1)
1407  dwtjd = -(uu*scratchd(i, j, k, idvt+ii-1))
1408  call popcontrol2b(branch)
1409  if (branch .lt. 2) then
1410  if (branch .eq. 0) then
1411  dwtd = half*dwtjd
1412  dwtm1d = 0.0_8
1413  else
1414  dwtm1d = half*dwtjd
1415  dwtd = 0.0_8
1416  end if
1417  else if (branch .eq. 2) then
1418  dwtd = 0.0_8
1419  dwtm1d = 0.0_8
1420  else
1421  wd(i, j+1, k, jj) = wd(i, j+1, k, jj) + dwtjd
1422  wd(i, j, k, jj) = wd(i, j, k, jj) - dwtjd
1423  goto 130
1424  end if
1425  call popcontrol2b(branch)
1426  if (branch .eq. 0) then
1427  dwtd = dwtd - half*dwtjd
1428  dwtp1d = 0.0_8
1429  else if (branch .eq. 1) then
1430  dwtp1d = -(half*dwtjd)
1431  else
1432  dwtp1d = 0.0_8
1433  end if
1434  dwtd = dwtd + dwtjd
1435  wd(i, j+2, k, jj) = wd(i, j+2, k, jj) + dwtp1d
1436  wd(i, j+1, k, jj) = wd(i, j+1, k, jj) + dwtd - dwtp1d
1437  wd(i, j, k, jj) = wd(i, j, k, jj) + dwtm1d - dwtd
1438  wd(i, j-1, k, jj) = wd(i, j-1, k, jj) - dwtm1d
1439  130 continue
1440  end if
1441  xad = w(i, j, k, ivx)*uud
1442  wd(i, j, k, ivx) = wd(i, j, k, ivx) + xa*uud
1443  yad = w(i, j, k, ivy)*uud
1444  wd(i, j, k, ivy) = wd(i, j, k, ivy) + ya*uud
1445  zad = w(i, j, k, ivz)*uud
1446  wd(i, j, k, ivz) = wd(i, j, k, ivz) + za*uud
1447  qsd = qsd - uud
1448  sjd(i, j, k, 3) = sjd(i, j, k, 3) + voli*zad
1449  sjd(i, j-1, k, 3) = sjd(i, j-1, k, 3) + voli*zad
1450  volid = (sj(i, j, k, 3)+sj(i, j-1, k, 3))*zad + (sj(i, j, k, 2)+sj&
1451 & (i, j-1, k, 2))*yad + (sj(i, j, k, 1)+sj(i, j-1, k, 1))*xad
1452  sjd(i, j, k, 2) = sjd(i, j, k, 2) + voli*yad
1453  sjd(i, j-1, k, 2) = sjd(i, j-1, k, 2) + voli*yad
1454  sjd(i, j, k, 1) = sjd(i, j, k, 1) + voli*xad
1455  sjd(i, j-1, k, 1) = sjd(i, j-1, k, 1) + voli*xad
1456  call popcontrol1b(branch)
1457  if (branch .eq. 0) then
1458  sfacejd(i, j, k) = sfacejd(i, j, k) + voli*qsd
1459  sfacejd(i, j-1, k) = sfacejd(i, j-1, k) + voli*qsd
1460  volid = volid + (sfacej(i, j, k)+sfacej(i, j-1, k))*qsd
1461  qsd = 0.0_8
1462  end if
1463  vold(i, j, k) = vold(i, j, k) - half*volid/vol(i, j, k)**2
1464  end do
1465  qsd = 0.0_8
1466 ! initialize the grid velocity to zero. this value will be used
1467 ! if the block is not moving.
1468  qs = zero
1469  qsd = 0.0_8
1470 !$bwd-of ii-loop
1471  do iii=0,nx*ny*nz-1
1472  i = mod(iii, nx) + 2
1473  j = mod(iii/nx, ny) + 2
1474  k = iii/(nx*ny) + 2
1475 ! compute the grid velocity if present.
1476 ! it is taken as the average of k and k-1,
1477  voli = half/vol(i, j, k)
1478  if (addgridvelocities) then
1479  qs = (sfacek(i, j, k)+sfacek(i, j, k-1))*voli
1480  call pushcontrol1b(0)
1481  else
1482  call pushcontrol1b(1)
1483  end if
1484 ! compute the normal velocity, where the normal direction
1485 ! is taken as the average of faces k and k-1.
1486  xa = (sk(i, j, k, 1)+sk(i, j, k-1, 1))*voli
1487  ya = (sk(i, j, k, 2)+sk(i, j, k-1, 2))*voli
1488  za = (sk(i, j, k, 3)+sk(i, j, k-1, 3))*voli
1489  uu = xa*w(i, j, k, ivx) + ya*w(i, j, k, ivy) + za*w(i, j, k, ivz) &
1490 & - qs
1491 ! this term has unit: velocity/length
1492 ! determine the situation we are having here, i.e. positive
1493 ! or negative normal velocity.
1494  if (uu .gt. zero) then
1495  uud = 0.0_8
1496 !$bwd-of ii-loop
1497  do 140 ii=1,nadv
1498 ! set the value of jj such that it corresponds to the
1499 ! turbulent entry in w.
1500  jj = ii + offset
1501 ! check whether a first or a second order discretization
1502 ! must be used.
1503  if (secondord) then
1504 ! second order; store the three differences for the
1505 ! discretization of the derivative in k-direction.
1506  dwtm1 = w(i, j, k-1, jj) - w(i, j, k-2, jj)
1507  dwt = w(i, j, k, jj) - w(i, j, k-1, jj)
1508  dwtp1 = w(i, j, k+1, jj) - w(i, j, k, jj)
1509 ! construct the derivative in this cell center. this
1510 ! is the first order upwind derivative with two
1511 ! nonlinear corrections.
1512  dwtk = dwt
1513  if (dwt*dwtp1 .gt. zero) then
1514  if (dwt .ge. 0.) then
1515  abs0 = dwt
1516  else
1517  abs0 = -dwt
1518  end if
1519  if (dwtp1 .ge. 0.) then
1520  abs12 = dwtp1
1521  else
1522  abs12 = -dwtp1
1523  end if
1524  if (abs0 .lt. abs12) then
1525  dwtk = dwtk + half*dwt
1526  call pushcontrol2b(0)
1527  else
1528  dwtk = dwtk + half*dwtp1
1529  call pushcontrol2b(1)
1530  end if
1531  else
1532  call pushcontrol2b(2)
1533  end if
1534  if (dwt*dwtm1 .gt. zero) then
1535  if (dwt .ge. 0.) then
1536  abs1 = dwt
1537  else
1538  abs1 = -dwt
1539  end if
1540  if (dwtm1 .ge. 0.) then
1541  abs13 = dwtm1
1542  else
1543  abs13 = -dwtm1
1544  end if
1545  if (abs1 .lt. abs13) then
1546  dwtk = dwtk - half*dwt
1547  call pushcontrol2b(0)
1548  else
1549  dwtk = dwtk - half*dwtm1
1550  call pushcontrol2b(1)
1551  end if
1552  else
1553  call pushcontrol2b(2)
1554  end if
1555  else
1556 ! 1st order upwind scheme.
1557  dwtk = w(i, j, k, jj) - w(i, j, k-1, jj)
1558  call pushcontrol2b(3)
1559  end if
1560  uud = uud - dwtk*scratchd(i, j, k, idvt+ii-1)
1561  dwtkd = -(uu*scratchd(i, j, k, idvt+ii-1))
1562  call popcontrol2b(branch)
1563  if (branch .lt. 2) then
1564  if (branch .eq. 0) then
1565  dwtd = -(half*dwtkd)
1566  dwtm1d = 0.0_8
1567  else
1568  dwtm1d = -(half*dwtkd)
1569  dwtd = 0.0_8
1570  end if
1571  else if (branch .eq. 2) then
1572  dwtd = 0.0_8
1573  dwtm1d = 0.0_8
1574  else
1575  wd(i, j, k, jj) = wd(i, j, k, jj) + dwtkd
1576  wd(i, j, k-1, jj) = wd(i, j, k-1, jj) - dwtkd
1577  goto 140
1578  end if
1579  call popcontrol2b(branch)
1580  if (branch .eq. 0) then
1581  dwtd = dwtd + half*dwtkd
1582  dwtp1d = 0.0_8
1583  else if (branch .eq. 1) then
1584  dwtp1d = half*dwtkd
1585  else
1586  dwtp1d = 0.0_8
1587  end if
1588  dwtd = dwtd + dwtkd
1589  wd(i, j, k+1, jj) = wd(i, j, k+1, jj) + dwtp1d
1590  wd(i, j, k, jj) = wd(i, j, k, jj) + dwtd - dwtp1d
1591  wd(i, j, k-1, jj) = wd(i, j, k-1, jj) + dwtm1d - dwtd
1592  wd(i, j, k-2, jj) = wd(i, j, k-2, jj) - dwtm1d
1593  140 continue
1594  else
1595  uud = 0.0_8
1596 !$bwd-of ii-loop
1597  do 150 ii=1,nadv
1598 ! set the value of jj such that it corresponds to the
1599 ! turbulent entry in w.
1600  jj = ii + offset
1601 ! check whether a first or a second order discretization
1602 ! must be used.
1603  if (secondord) then
1604 ! store the three differences for the discretization of
1605 ! the derivative in k-direction.
1606  dwtm1 = w(i, j, k, jj) - w(i, j, k-1, jj)
1607  dwt = w(i, j, k+1, jj) - w(i, j, k, jj)
1608  dwtp1 = w(i, j, k+2, jj) - w(i, j, k+1, jj)
1609 ! construct the derivative in this cell center. this is
1610 ! the first order upwind derivative with two nonlinear
1611 ! corrections.
1612  dwtk = dwt
1613  if (dwt*dwtp1 .gt. zero) then
1614  if (dwt .ge. 0.) then
1615  abs2 = dwt
1616  else
1617  abs2 = -dwt
1618  end if
1619  if (dwtp1 .ge. 0.) then
1620  abs14 = dwtp1
1621  else
1622  abs14 = -dwtp1
1623  end if
1624  if (abs2 .lt. abs14) then
1625  dwtk = dwtk - half*dwt
1626  call pushcontrol2b(0)
1627  else
1628  dwtk = dwtk - half*dwtp1
1629  call pushcontrol2b(1)
1630  end if
1631  else
1632  call pushcontrol2b(2)
1633  end if
1634  if (dwt*dwtm1 .gt. zero) then
1635  if (dwt .ge. 0.) then
1636  abs3 = dwt
1637  else
1638  abs3 = -dwt
1639  end if
1640  if (dwtm1 .ge. 0.) then
1641  abs15 = dwtm1
1642  else
1643  abs15 = -dwtm1
1644  end if
1645  if (abs3 .lt. abs15) then
1646  dwtk = dwtk + half*dwt
1647  call pushcontrol2b(0)
1648  else
1649  dwtk = dwtk + half*dwtm1
1650  call pushcontrol2b(1)
1651  end if
1652  else
1653  call pushcontrol2b(2)
1654  end if
1655  else
1656 ! 1st order upwind scheme.
1657  dwtk = w(i, j, k+1, jj) - w(i, j, k, jj)
1658  call pushcontrol2b(3)
1659  end if
1660  uud = uud - dwtk*scratchd(i, j, k, idvt+ii-1)
1661  dwtkd = -(uu*scratchd(i, j, k, idvt+ii-1))
1662  call popcontrol2b(branch)
1663  if (branch .lt. 2) then
1664  if (branch .eq. 0) then
1665  dwtd = half*dwtkd
1666  dwtm1d = 0.0_8
1667  else
1668  dwtm1d = half*dwtkd
1669  dwtd = 0.0_8
1670  end if
1671  else if (branch .eq. 2) then
1672  dwtd = 0.0_8
1673  dwtm1d = 0.0_8
1674  else
1675  wd(i, j, k+1, jj) = wd(i, j, k+1, jj) + dwtkd
1676  wd(i, j, k, jj) = wd(i, j, k, jj) - dwtkd
1677  goto 150
1678  end if
1679  call popcontrol2b(branch)
1680  if (branch .eq. 0) then
1681  dwtd = dwtd - half*dwtkd
1682  dwtp1d = 0.0_8
1683  else if (branch .eq. 1) then
1684  dwtp1d = -(half*dwtkd)
1685  else
1686  dwtp1d = 0.0_8
1687  end if
1688  dwtd = dwtd + dwtkd
1689  wd(i, j, k+2, jj) = wd(i, j, k+2, jj) + dwtp1d
1690  wd(i, j, k+1, jj) = wd(i, j, k+1, jj) + dwtd - dwtp1d
1691  wd(i, j, k, jj) = wd(i, j, k, jj) + dwtm1d - dwtd
1692  wd(i, j, k-1, jj) = wd(i, j, k-1, jj) - dwtm1d
1693  150 continue
1694  end if
1695  xad = w(i, j, k, ivx)*uud
1696  wd(i, j, k, ivx) = wd(i, j, k, ivx) + xa*uud
1697  yad = w(i, j, k, ivy)*uud
1698  wd(i, j, k, ivy) = wd(i, j, k, ivy) + ya*uud
1699  zad = w(i, j, k, ivz)*uud
1700  wd(i, j, k, ivz) = wd(i, j, k, ivz) + za*uud
1701  qsd = qsd - uud
1702  skd(i, j, k, 3) = skd(i, j, k, 3) + voli*zad
1703  skd(i, j, k-1, 3) = skd(i, j, k-1, 3) + voli*zad
1704  volid = (sk(i, j, k, 3)+sk(i, j, k-1, 3))*zad + (sk(i, j, k, 2)+sk&
1705 & (i, j, k-1, 2))*yad + (sk(i, j, k, 1)+sk(i, j, k-1, 1))*xad
1706  skd(i, j, k, 2) = skd(i, j, k, 2) + voli*yad
1707  skd(i, j, k-1, 2) = skd(i, j, k-1, 2) + voli*yad
1708  skd(i, j, k, 1) = skd(i, j, k, 1) + voli*xad
1709  skd(i, j, k-1, 1) = skd(i, j, k-1, 1) + voli*xad
1710  call popcontrol1b(branch)
1711  if (branch .eq. 0) then
1712  sfacekd(i, j, k) = sfacekd(i, j, k) + voli*qsd
1713  sfacekd(i, j, k-1) = sfacekd(i, j, k-1) + voli*qsd
1714  volid = volid + (sfacek(i, j, k)+sfacek(i, j, k-1))*qsd
1715  qsd = 0.0_8
1716  end if
1717  vold(i, j, k) = vold(i, j, k) - half*volid/vol(i, j, k)**2
1718  end do
1719  end subroutine turbadvection_b
1720 
1721  subroutine turbadvection(madv, nadv, offset, qq)
1722 !
1723 ! turbadvection discretizes the advection part of the turbulent
1724 ! transport equations. as the advection part is the same for all
1725 ! models, this generic routine can be used. both the
1726 ! discretization and the central jacobian are computed in this
1727 ! subroutine. the former can either be 1st or 2nd order
1728 ! accurate; the latter is always based on the 1st order upwind
1729 ! discretization. when the discretization must be second order
1730 ! accurate, the fully upwind (kappa = -1) scheme in combination
1731 ! with the minmod limiter is used.
1732 ! only nadv equations are treated, while the actual system has
1733 ! size madv. the reason is that some equations for some
1734 ! turbulence equations do not have an advection part, e.g. the
1735 ! f equation in the v2-f model. the argument offset indicates
1736 ! the offset in the w vector where this subsystem starts. as a
1737 ! consequence it is assumed that the indices of the current
1738 ! subsystem are contiguous, e.g. if a 2*2 system is solved the
1739 ! last index in w is offset+1 and offset+2 respectively.
1740 !
1741  use constants
1742  use blockpointers, only : nx, ny, nz, il, jl, kl, vol, sfacei, &
1745  use inputdiscretization, only : orderturb
1746  use iteration, only : groundlevel
1747  use turbmod, only : secondord
1748  implicit none
1749 !
1750 ! subroutine arguments.
1751 !
1752  integer(kind=inttype), intent(in) :: nadv, madv, offset
1753  real(kind=realtype), dimension(2:il, 2:jl, 2:kl, madv, madv), &
1754 & intent(inout) :: qq
1755 !
1756 ! local variables.
1757 !
1758  integer(kind=inttype) :: i, j, k, ii, jj, kk, iii
1759  real(kind=realtype) :: qs, voli, xa, ya, za
1760  real(kind=realtype) :: uu, dwt, dwtm1, dwtp1, dwti, dwtj, dwtk
1761  real(kind=realtype), dimension(madv) :: impl
1762  intrinsic mod
1763  intrinsic abs
1764  real(kind=realtype) :: abs0
1765  real(kind=realtype) :: abs1
1766  real(kind=realtype) :: abs2
1767  real(kind=realtype) :: abs3
1768  real(kind=realtype) :: abs4
1769  real(kind=realtype) :: abs5
1770  real(kind=realtype) :: abs6
1771  real(kind=realtype) :: abs7
1772  real(kind=realtype) :: abs8
1773  real(kind=realtype) :: abs9
1774  real(kind=realtype) :: abs10
1775  real(kind=realtype) :: abs11
1776  real(kind=realtype) :: abs12
1777  real(kind=realtype) :: abs13
1778  real(kind=realtype) :: abs14
1779  real(kind=realtype) :: abs15
1780  real(kind=realtype) :: abs16
1781  real(kind=realtype) :: abs17
1782  real(kind=realtype) :: abs18
1783  real(kind=realtype) :: abs19
1784  real(kind=realtype) :: abs20
1785  real(kind=realtype) :: abs21
1786  real(kind=realtype) :: abs22
1787  real(kind=realtype) :: abs23
1788 ! determine whether or not a second order discretization for the
1789 ! advective terms must be used.
1790  secondord = .false.
1791  if (groundlevel .eq. 1_inttype .and. orderturb .eq. secondorder) &
1792 & secondord = .true.
1793 !$ad checkpoint-start
1794 ! initialize the grid velocity to zero. this value will be used
1795 ! if the block is not moving.
1796  qs = zero
1797 !$ad ii-loop
1798 !
1799 ! upwind discretization of the convective term in k (zeta)
1800 ! direction. either the 1st order upwind or the second order
1801 ! fully upwind interpolation scheme, kappa = -1, is used in
1802 ! combination with the minmod limiter.
1803 ! the possible grid velocity must be taken into account.
1804 !
1805  do iii=0,nx*ny*nz-1
1806  i = mod(iii, nx) + 2
1807  j = mod(iii/nx, ny) + 2
1808  k = iii/(nx*ny) + 2
1809 ! compute the grid velocity if present.
1810 ! it is taken as the average of k and k-1,
1811  voli = half/vol(i, j, k)
1812  if (addgridvelocities) qs = (sfacek(i, j, k)+sfacek(i, j, k-1))*&
1813 & voli
1814 ! compute the normal velocity, where the normal direction
1815 ! is taken as the average of faces k and k-1.
1816  xa = (sk(i, j, k, 1)+sk(i, j, k-1, 1))*voli
1817  ya = (sk(i, j, k, 2)+sk(i, j, k-1, 2))*voli
1818  za = (sk(i, j, k, 3)+sk(i, j, k-1, 3))*voli
1819  uu = xa*w(i, j, k, ivx) + ya*w(i, j, k, ivy) + za*w(i, j, k, ivz) &
1820 & - qs
1821 ! this term has unit: velocity/length
1822 ! determine the situation we are having here, i.e. positive
1823 ! or negative normal velocity.
1824  if (uu .gt. zero) then
1825 !$ad ii-loop
1826 ! velocity has a component in positive k-direction.
1827 ! loop over the number of advection equations.
1828  do ii=1,nadv
1829 ! set the value of jj such that it corresponds to the
1830 ! turbulent entry in w.
1831  jj = ii + offset
1832 ! check whether a first or a second order discretization
1833 ! must be used.
1834  if (secondord) then
1835 ! second order; store the three differences for the
1836 ! discretization of the derivative in k-direction.
1837  dwtm1 = w(i, j, k-1, jj) - w(i, j, k-2, jj)
1838  dwt = w(i, j, k, jj) - w(i, j, k-1, jj)
1839  dwtp1 = w(i, j, k+1, jj) - w(i, j, k, jj)
1840 ! construct the derivative in this cell center. this
1841 ! is the first order upwind derivative with two
1842 ! nonlinear corrections.
1843  dwtk = dwt
1844  if (dwt*dwtp1 .gt. zero) then
1845  if (dwt .ge. 0.) then
1846  abs0 = dwt
1847  else
1848  abs0 = -dwt
1849  end if
1850  if (dwtp1 .ge. 0.) then
1851  abs12 = dwtp1
1852  else
1853  abs12 = -dwtp1
1854  end if
1855  if (abs0 .lt. abs12) then
1856  dwtk = dwtk + half*dwt
1857  else
1858  dwtk = dwtk + half*dwtp1
1859  end if
1860  end if
1861  if (dwt*dwtm1 .gt. zero) then
1862  if (dwt .ge. 0.) then
1863  abs1 = dwt
1864  else
1865  abs1 = -dwt
1866  end if
1867  if (dwtm1 .ge. 0.) then
1868  abs13 = dwtm1
1869  else
1870  abs13 = -dwtm1
1871  end if
1872  if (abs1 .lt. abs13) then
1873  dwtk = dwtk - half*dwt
1874  else
1875  dwtk = dwtk - half*dwtm1
1876  end if
1877  end if
1878  else
1879 ! 1st order upwind scheme.
1880  dwtk = w(i, j, k, jj) - w(i, j, k-1, jj)
1881  end if
1882 ! update the residual. the convective term must be
1883 ! substracted, because it appears on the other side of
1884 ! the equation as the source and viscous terms.
1885 ! uu*dwtk = (v.dot.face_normal)*delta(nutilde)/delta(x)
1886  scratch(i, j, k, idvt+ii-1) = scratch(i, j, k, idvt+ii-1) - uu&
1887 & *dwtk
1888  end do
1889  else
1890 !$ad ii-loop
1891 ! velocity has a component in negative k-direction.
1892 ! loop over the number of advection equations
1893  do ii=1,nadv
1894 ! set the value of jj such that it corresponds to the
1895 ! turbulent entry in w.
1896  jj = ii + offset
1897 ! check whether a first or a second order discretization
1898 ! must be used.
1899  if (secondord) then
1900 ! store the three differences for the discretization of
1901 ! the derivative in k-direction.
1902  dwtm1 = w(i, j, k, jj) - w(i, j, k-1, jj)
1903  dwt = w(i, j, k+1, jj) - w(i, j, k, jj)
1904  dwtp1 = w(i, j, k+2, jj) - w(i, j, k+1, jj)
1905 ! construct the derivative in this cell center. this is
1906 ! the first order upwind derivative with two nonlinear
1907 ! corrections.
1908  dwtk = dwt
1909  if (dwt*dwtp1 .gt. zero) then
1910  if (dwt .ge. 0.) then
1911  abs2 = dwt
1912  else
1913  abs2 = -dwt
1914  end if
1915  if (dwtp1 .ge. 0.) then
1916  abs14 = dwtp1
1917  else
1918  abs14 = -dwtp1
1919  end if
1920  if (abs2 .lt. abs14) then
1921  dwtk = dwtk - half*dwt
1922  else
1923  dwtk = dwtk - half*dwtp1
1924  end if
1925  end if
1926  if (dwt*dwtm1 .gt. zero) then
1927  if (dwt .ge. 0.) then
1928  abs3 = dwt
1929  else
1930  abs3 = -dwt
1931  end if
1932  if (dwtm1 .ge. 0.) then
1933  abs15 = dwtm1
1934  else
1935  abs15 = -dwtm1
1936  end if
1937  if (abs3 .lt. abs15) then
1938  dwtk = dwtk + half*dwt
1939  else
1940  dwtk = dwtk + half*dwtm1
1941  end if
1942  end if
1943  else
1944 ! 1st order upwind scheme.
1945  dwtk = w(i, j, k+1, jj) - w(i, j, k, jj)
1946  end if
1947 ! update the residual. the convective term must be
1948 ! substracted, because it appears on the other side
1949 ! of the equation as the source and viscous terms.
1950  scratch(i, j, k, idvt+ii-1) = scratch(i, j, k, idvt+ii-1) - uu&
1951 & *dwtk
1952 ! update the central jacobian. first the term which is
1953 ! always present, i.e. -uu.
1954  end do
1955  end if
1956  end do
1957 !$ad checkpoint-end
1958 !
1959 ! upwind discretization of the convective term in j (eta)
1960 ! direction. either the 1st order upwind or the second order
1961 ! fully upwind interpolation scheme, kappa = -1, is used in
1962 ! combination with the minmod limiter.
1963 ! the possible grid velocity must be taken into account.
1964 !
1965  continue
1966 !$ad checkpoint-start
1967  qs = zero
1968 !$ad ii-loop
1969  do iii=0,nx*ny*nz-1
1970  i = mod(iii, nx) + 2
1971  j = mod(iii/nx, ny) + 2
1972  k = iii/(nx*ny) + 2
1973 ! compute the grid velocity if present.
1974 ! it is taken as the average of j and j-1,
1975  voli = half/vol(i, j, k)
1976  if (addgridvelocities) qs = (sfacej(i, j, k)+sfacej(i, j-1, k))*&
1977 & voli
1978 ! compute the normal velocity, where the normal direction
1979 ! is taken as the average of faces j and j-1.
1980  xa = (sj(i, j, k, 1)+sj(i, j-1, k, 1))*voli
1981  ya = (sj(i, j, k, 2)+sj(i, j-1, k, 2))*voli
1982  za = (sj(i, j, k, 3)+sj(i, j-1, k, 3))*voli
1983  uu = xa*w(i, j, k, ivx) + ya*w(i, j, k, ivy) + za*w(i, j, k, ivz) &
1984 & - qs
1985 ! determine the situation we are having here, i.e. positive
1986 ! or negative normal velocity.
1987  if (uu .gt. zero) then
1988 !$ad ii-loop
1989 ! velocity has a component in positive j-direction.
1990 ! loop over the number of advection equations.
1991  do ii=1,nadv
1992 ! set the value of jj such that it corresponds to the
1993 ! turbulent entry in w.
1994  jj = ii + offset
1995 ! check whether a first or a second order discretization
1996 ! must be used.
1997  if (secondord) then
1998 ! second order; store the three differences for the
1999 ! discretization of the derivative in j-direction.
2000  dwtm1 = w(i, j-1, k, jj) - w(i, j-2, k, jj)
2001  dwt = w(i, j, k, jj) - w(i, j-1, k, jj)
2002  dwtp1 = w(i, j+1, k, jj) - w(i, j, k, jj)
2003 ! construct the derivative in this cell center. this is
2004 ! the first order upwind derivative with two nonlinear
2005 ! corrections.
2006  dwtj = dwt
2007  if (dwt*dwtp1 .gt. zero) then
2008  if (dwt .ge. 0.) then
2009  abs4 = dwt
2010  else
2011  abs4 = -dwt
2012  end if
2013  if (dwtp1 .ge. 0.) then
2014  abs16 = dwtp1
2015  else
2016  abs16 = -dwtp1
2017  end if
2018  if (abs4 .lt. abs16) then
2019  dwtj = dwtj + half*dwt
2020  else
2021  dwtj = dwtj + half*dwtp1
2022  end if
2023  end if
2024  if (dwt*dwtm1 .gt. zero) then
2025  if (dwt .ge. 0.) then
2026  abs5 = dwt
2027  else
2028  abs5 = -dwt
2029  end if
2030  if (dwtm1 .ge. 0.) then
2031  abs17 = dwtm1
2032  else
2033  abs17 = -dwtm1
2034  end if
2035  if (abs5 .lt. abs17) then
2036  dwtj = dwtj - half*dwt
2037  else
2038  dwtj = dwtj - half*dwtm1
2039  end if
2040  end if
2041  else
2042 ! 1st order upwind scheme.
2043  dwtj = w(i, j, k, jj) - w(i, j-1, k, jj)
2044  end if
2045 ! update the residual. the convective term must be
2046 ! substracted, because it appears on the other side of
2047 ! the equation as the source and viscous terms.
2048  scratch(i, j, k, idvt+ii-1) = scratch(i, j, k, idvt+ii-1) - uu&
2049 & *dwtj
2050 ! update the central jacobian. first the term which is
2051 ! always present, i.e. uu.
2052  end do
2053  else
2054 !$ad ii-loop
2055 ! velocity has a component in negative j-direction.
2056 ! loop over the number of advection equations.
2057  do ii=1,nadv
2058 ! set the value of jj such that it corresponds to the
2059 ! turbulent entry in w.
2060  jj = ii + offset
2061 ! check whether a first or a second order discretization
2062 ! must be used.
2063  if (secondord) then
2064 ! store the three differences for the discretization of
2065 ! the derivative in j-direction.
2066  dwtm1 = w(i, j, k, jj) - w(i, j-1, k, jj)
2067  dwt = w(i, j+1, k, jj) - w(i, j, k, jj)
2068  dwtp1 = w(i, j+2, k, jj) - w(i, j+1, k, jj)
2069 ! construct the derivative in this cell center. this is
2070 ! the first order upwind derivative with two nonlinear
2071 ! corrections.
2072  dwtj = dwt
2073  if (dwt*dwtp1 .gt. zero) then
2074  if (dwt .ge. 0.) then
2075  abs6 = dwt
2076  else
2077  abs6 = -dwt
2078  end if
2079  if (dwtp1 .ge. 0.) then
2080  abs18 = dwtp1
2081  else
2082  abs18 = -dwtp1
2083  end if
2084  if (abs6 .lt. abs18) then
2085  dwtj = dwtj - half*dwt
2086  else
2087  dwtj = dwtj - half*dwtp1
2088  end if
2089  end if
2090  if (dwt*dwtm1 .gt. zero) then
2091  if (dwt .ge. 0.) then
2092  abs7 = dwt
2093  else
2094  abs7 = -dwt
2095  end if
2096  if (dwtm1 .ge. 0.) then
2097  abs19 = dwtm1
2098  else
2099  abs19 = -dwtm1
2100  end if
2101  if (abs7 .lt. abs19) then
2102  dwtj = dwtj + half*dwt
2103  else
2104  dwtj = dwtj + half*dwtm1
2105  end if
2106  end if
2107  else
2108 ! 1st order upwind scheme.
2109  dwtj = w(i, j+1, k, jj) - w(i, j, k, jj)
2110  end if
2111 ! update the residual. the convective term must be
2112 ! substracted, because it appears on the other side
2113 ! of the equation as the source and viscous terms.
2114  scratch(i, j, k, idvt+ii-1) = scratch(i, j, k, idvt+ii-1) - uu&
2115 & *dwtj
2116 ! update the central jacobian. first the term which is
2117 ! always present, i.e. -uu.
2118  end do
2119  end if
2120  end do
2121 !$ad checkpoint-end
2122 !
2123 ! upwind discretization of the convective term in i (xi)
2124 ! direction. either the 1st order upwind or the second order
2125 ! fully upwind interpolation scheme, kappa = -1, is used in
2126 ! combination with the minmod limiter.
2127 ! the possible grid velocity must be taken into account.
2128 !
2129  continue
2130 !$ad checkpoint-start
2131  qs = zero
2132 !$ad ii-loop
2133  do iii=0,nx*ny*nz-1
2134  i = mod(iii, nx) + 2
2135  j = mod(iii/nx, ny) + 2
2136  k = iii/(nx*ny) + 2
2137 ! compute the grid velocity if present.
2138 ! it is taken as the average of i and i-1,
2139  voli = half/vol(i, j, k)
2140  if (addgridvelocities) qs = (sfacei(i, j, k)+sfacei(i-1, j, k))*&
2141 & voli
2142 ! compute the normal velocity, where the normal direction
2143 ! is taken as the average of faces i and i-1.
2144  xa = (si(i, j, k, 1)+si(i-1, j, k, 1))*voli
2145  ya = (si(i, j, k, 2)+si(i-1, j, k, 2))*voli
2146  za = (si(i, j, k, 3)+si(i-1, j, k, 3))*voli
2147  uu = xa*w(i, j, k, ivx) + ya*w(i, j, k, ivy) + za*w(i, j, k, ivz) &
2148 & - qs
2149 ! determine the situation we are having here, i.e. positive
2150 ! or negative normal velocity.
2151  if (uu .gt. zero) then
2152 !$ad ii-loop
2153 ! velocity has a component in positive i-direction.
2154 ! loop over the number of advection equations.
2155  do ii=1,nadv
2156 ! set the value of jj such that it corresponds to the
2157 ! turbulent entry in w.
2158  jj = ii + offset
2159 ! check whether a first or a second order discretization
2160 ! must be used.
2161  if (secondord) then
2162 ! second order; store the three differences for the
2163 ! discretization of the derivative in i-direction.
2164  dwtm1 = w(i-1, j, k, jj) - w(i-2, j, k, jj)
2165  dwt = w(i, j, k, jj) - w(i-1, j, k, jj)
2166  dwtp1 = w(i+1, j, k, jj) - w(i, j, k, jj)
2167 ! construct the derivative in this cell center. this is
2168 ! the first order upwind derivative with two nonlinear
2169 ! corrections.
2170  dwti = dwt
2171  if (dwt*dwtp1 .gt. zero) then
2172  if (dwt .ge. 0.) then
2173  abs8 = dwt
2174  else
2175  abs8 = -dwt
2176  end if
2177  if (dwtp1 .ge. 0.) then
2178  abs20 = dwtp1
2179  else
2180  abs20 = -dwtp1
2181  end if
2182  if (abs8 .lt. abs20) then
2183  dwti = dwti + half*dwt
2184  else
2185  dwti = dwti + half*dwtp1
2186  end if
2187  end if
2188  if (dwt*dwtm1 .gt. zero) then
2189  if (dwt .ge. 0.) then
2190  abs9 = dwt
2191  else
2192  abs9 = -dwt
2193  end if
2194  if (dwtm1 .ge. 0.) then
2195  abs21 = dwtm1
2196  else
2197  abs21 = -dwtm1
2198  end if
2199  if (abs9 .lt. abs21) then
2200  dwti = dwti - half*dwt
2201  else
2202  dwti = dwti - half*dwtm1
2203  end if
2204  end if
2205  else
2206 ! 1st order upwind scheme.
2207  dwti = w(i, j, k, jj) - w(i-1, j, k, jj)
2208  end if
2209 ! update the residual. the convective term must be
2210 ! substracted, because it appears on the other side of
2211 ! the equation as the source and viscous terms.
2212  scratch(i, j, k, idvt+ii-1) = scratch(i, j, k, idvt+ii-1) - uu&
2213 & *dwti
2214 ! update the central jacobian. first the term which is
2215 ! always present, i.e. uu.
2216  end do
2217  else
2218 !$ad ii-loop
2219 ! velocity has a component in negative i-direction.
2220 ! loop over the number of advection equations.
2221  do ii=1,nadv
2222 ! set the value of jj such that it corresponds to the
2223 ! turbulent entry in w.
2224  jj = ii + offset
2225 ! check whether a first or a second order discretization
2226 ! must be used.
2227  if (secondord) then
2228 ! second order; store the three differences for the
2229 ! discretization of the derivative in i-direction.
2230  dwtm1 = w(i, j, k, jj) - w(i-1, j, k, jj)
2231  dwt = w(i+1, j, k, jj) - w(i, j, k, jj)
2232  dwtp1 = w(i+2, j, k, jj) - w(i+1, j, k, jj)
2233 ! construct the derivative in this cell center. this is
2234 ! the first order upwind derivative with two nonlinear
2235 ! corrections.
2236  dwti = dwt
2237  if (dwt*dwtp1 .gt. zero) then
2238  if (dwt .ge. 0.) then
2239  abs10 = dwt
2240  else
2241  abs10 = -dwt
2242  end if
2243  if (dwtp1 .ge. 0.) then
2244  abs22 = dwtp1
2245  else
2246  abs22 = -dwtp1
2247  end if
2248  if (abs10 .lt. abs22) then
2249  dwti = dwti - half*dwt
2250  else
2251  dwti = dwti - half*dwtp1
2252  end if
2253  end if
2254  if (dwt*dwtm1 .gt. zero) then
2255  if (dwt .ge. 0.) then
2256  abs11 = dwt
2257  else
2258  abs11 = -dwt
2259  end if
2260  if (dwtm1 .ge. 0.) then
2261  abs23 = dwtm1
2262  else
2263  abs23 = -dwtm1
2264  end if
2265  if (abs11 .lt. abs23) then
2266  dwti = dwti + half*dwt
2267  else
2268  dwti = dwti + half*dwtm1
2269  end if
2270  end if
2271  else
2272 ! 1st order upwind scheme.
2273  dwti = w(i+1, j, k, jj) - w(i, j, k, jj)
2274  end if
2275 ! update the residual. the convective term must be
2276 ! substracted, because it appears on the other side
2277 ! of the equation as the source and viscous terms.
2278  scratch(i, j, k, idvt+ii-1) = scratch(i, j, k, idvt+ii-1) - uu&
2279 & *dwti
2280 ! update the central jacobian. first the term which is
2281 ! always present, i.e. -uu.
2282  end do
2283  end if
2284  end do
2285 !$ad checkpoint-end
2286 
2287  end subroutine turbadvection
2288 ! ----------------------------------------------------------------------
2289 ! |
2290 ! no tapenade routine below this line |
2291 ! |
2292 ! ----------------------------------------------------------------------
2293 
2294 end module turbutils_b
2295 
real(kind=realtype), dimension(:, :, :, :), pointer bmtk2
real(kind=realtype), dimension(:, :, :), pointer sfacek
logical addgridvelocities
integer(kind=inttype) jl
real(kind=realtype), dimension(:, :, :, :), pointer sjd
real(kind=realtype), dimension(:, :, :, :), pointer bmti1
real(kind=realtype), dimension(:, :, :, :), pointer wd
real(kind=realtype), dimension(:, :, :), pointer vold
real(kind=realtype), dimension(:, :, :, :), pointer bmtj1
integer(kind=inttype) nx
real(kind=realtype), dimension(:, :, :, :), pointer bmti2
integer(kind=inttype) ny
integer(kind=inttype) ie
real(kind=realtype), dimension(:, :, :, :), pointer w
real(kind=realtype), dimension(:, :, :, :), pointer scratch
real(kind=realtype), dimension(:, :, :), pointer sfacei
real(kind=realtype), dimension(:, :, :), pointer d2wall
real(kind=realtype), dimension(:, :, :), pointer revd
real(kind=realtype), dimension(:, :, :, :), pointer skd
real(kind=realtype), dimension(:, :, :), pointer sfacejd
real(kind=realtype), dimension(:, :, :), pointer rlv
real(kind=realtype), dimension(:, :, :, :), pointer si
real(kind=realtype), dimension(:, :, :, :), pointer sid
real(kind=realtype), dimension(:, :, :, :), pointer sj
integer(kind=inttype) sectionid
real(kind=realtype), dimension(:, :, :, :), pointer scratchd
real(kind=realtype), dimension(:, :, :), pointer rev
real(kind=realtype), dimension(:, :, :, :), pointer bmtj2
real(kind=realtype), dimension(:, :, :, :), pointer dw
real(kind=realtype), dimension(:, :, :, :), pointer sk
real(kind=realtype), dimension(:, :, :), pointer rlvd
real(kind=realtype), dimension(:, :, :), pointer vol
real(kind=realtype), dimension(:, :, :), pointer sfacej
integer(kind=inttype) nz
integer(kind=inttype) je
real(kind=realtype), dimension(:, :, :), pointer sfacekd
integer(kind=inttype) ke
real(kind=realtype), dimension(:, :, :), pointer sfaceid
real(kind=realtype), dimension(:, :, :, :), pointer bmtk1
real(kind=realtype), dimension(:, :, :, :, :), pointer wold
integer(kind=inttype) kl
integer(kind=inttype) il
integer(kind=inttype), parameter spalartallmarasedwards
Definition: constants.F90:128
integer(kind=inttype), parameter spalartallmaras
Definition: constants.F90:128
real(kind=realtype), parameter zero
Definition: constants.F90:71
real(kind=realtype), parameter three
Definition: constants.F90:74
integer, parameter idvt
Definition: constants.F90:51
integer, parameter ivort
Definition: constants.F90:53
real(kind=realtype), parameter four
Definition: constants.F90:75
real(kind=realtype), parameter third
Definition: constants.F90:81
integer, parameter itu2
Definition: constants.F90:42
real(kind=realtype), parameter thresholdreal
Definition: constants.F90:101
integer, parameter itu1
Definition: constants.F90:40
integer, parameter irho
Definition: constants.F90:34
integer, parameter ivx
Definition: constants.F90:35
integer, parameter iprod
Definition: constants.F90:55
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
real(kind=realtype), parameter fourth
Definition: constants.F90:82
integer(kind=inttype), parameter secondorder
Definition: constants.F90:142
integer, parameter ivy
Definition: constants.F90:36
real(kind=realtype) timeref
integer(kind=inttype) orderturb
Definition: inputParam.F90:73
integer(kind=inttype) equationmode
Definition: inputParam.F90:583
integer(kind=inttype) turbmodel
Definition: inputParam.F90:584
integer(kind=inttype) ntimeintervalsspectral
Definition: inputParam.F90:645
real(kind=realtype) deltat
Definition: inputParam.F90:733
integer(kind=inttype) timeintegrationscheme
Definition: inputParam.F90:719
integer(kind=inttype) noldlevels
Definition: iteration.f90:79
integer(kind=inttype) currentlevel
Definition: iteration.f90:18
integer(kind=inttype) groundlevel
Definition: iteration.f90:18
real(kind=realtype), dimension(:), allocatable coeftime
Definition: iteration.f90:80
real(kind=realtype), parameter rssta1
Definition: paramTurb.F90:41
real(kind=realtype), parameter rsacv1
Definition: paramTurb.F90:17
type(sectiontype), dimension(:), allocatable sections
Definition: section.f90:46
real(kind=realtype), dimension(:, :, :), pointer prod
Definition: turbMod.F90:35
logical secondord
Definition: turbMod.F90:15
subroutine prodkatolaunder()
Definition: turbUtils_b.f90:9
subroutine computeeddyviscosity_b(includehalos)
subroutine prodsmag2()
subroutine turbadvection(madv, nadv, offset, qq)
subroutine turbadvection_b(madv, nadv, offset, qq)
subroutine computeeddyviscosity(includehalos)
subroutine ssteddyviscosity(ibeg, iend, jbeg, jend, kbeg, kend)
subroutine saeddyviscosity_b(ibeg, iend, jbeg, jend, kbeg, kend)
subroutine prodwmag2()
subroutine unsteadyturbterm(madv, nadv, offset, qq)
subroutine saeddyviscosity(ibeg, iend, jbeg, jend, kbeg, kend)
subroutine sanuknowneddyratio_b(eddyratio, nulam, nulamd, sanuknowneddyratiod)
real(kind=realtype) function sanuknowneddyratio(eddyratio, nulam)
subroutine kweddyviscosity(ibeg, iend, jbeg, jend, kbeg, kend)