ADflow  v1.0
ADflow is a finite volume RANS solver tailored for gradient-based aerodynamic design optimization.
turbUtils_fast_b.f90
Go to the documentation of this file.
1 ! generated by tapenade (inria, ecuador team)
2 ! tapenade 3.16 (develop) - 22 aug 2023 15:51
3 !
5  implicit none
6 
7 contains
8  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, &
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, &
122 & sk, vol, sectionid, scratch
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, &
215 & sk, vol, sectionid, scratch
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  function sanuknowneddyratio(eddyratio, nulam)
282 !
283 ! sanuknowneddyratio computes the spalart-allmaras transport
284 ! variable nu for the given eddy viscosity ratio.
285 !
286  use constants
287  use paramturb
288  implicit none
289 !
290 ! function type.
291 !
292  real(kind=realtype) :: sanuknowneddyratio
293 !
294 ! function arguments.
295 !
296  real(kind=realtype), intent(in) :: eddyratio, nulam
297 !
298 ! local variables.
299 !
300  real(kind=realtype) :: cv13, chi, chi2, chi3, chi4, f, df, dchi
301  intrinsic abs
302  real(kind=realtype) :: abs0
303 ! take care of the exceptional cases.
304  if (eddyratio .le. zero) then
306  return
307  else
308 ! set the value of cv1^3, which is the constant appearing in the
309 ! sa function fv1 to compute the eddy viscosity
310  cv13 = rsacv1**3
311 ! determine the value of chi, which is given by the quartic
312 ! polynomial chi^4 - ratio*(chi^3 + cv1^3) = 0.
313 ! first determine the start value, depending on the eddyratio.
314  if (eddyratio .lt. 1.e-4_realtype) then
315  chi = 0.5_realtype
316  else if (eddyratio .lt. 1.0_realtype) then
317  chi = 5.0_realtype
318  else if (eddyratio .lt. 10.0_realtype) then
319  chi = 10.0_realtype
320  else
321  chi = eddyratio
322  end if
323 ! the actual newton algorithm.
324  do
325 ! compute the function value and the derivative.
326  chi2 = chi*chi
327  chi3 = chi*chi2
328  chi4 = chi*chi3
329  f = chi4 - eddyratio*(chi3+cv13)
330  df = four*chi3 - three*eddyratio*chi2
331 ! compute the negative update and the new value of chi.
332  dchi = f/df
333  chi = chi - dchi
334  if (dchi/chi .ge. 0.) then
335  abs0 = dchi/chi
336  else
337  abs0 = -(dchi/chi)
338  end if
339 ! condition to exit the loop.
340  if (abs0 .le. thresholdreal) then
341 ! chi is the ratio of the spalart allmaras transport variable and
342 ! the laminar viscosity. so multiply chi with the laminar viscosity
343 ! to obtain the correct value.
344  sanuknowneddyratio = nulam*chi
345  goto 100
346  end if
347  end do
348  end if
349  100 continue
350  end function sanuknowneddyratio
351 
352  subroutine unsteadyturbterm(madv, nadv, offset, qq)
353 !
354 ! unsteadyturbterm discretizes the time derivative of the
355 ! turbulence transport equations and add it to the residual.
356 ! as the time derivative is the same for all turbulence models,
357 ! this generic routine can be used; both the discretization of
358 ! the time derivative and its contribution to the central
359 ! jacobian are computed by this routine.
360 ! only nadv equations are treated, while the actual system has
361 ! size madv. the reason is that some equations for some
362 ! turbulence equations do not have a time derivative, e.g. the
363 ! f equation in the v2-f model. the argument offset indicates
364 ! the offset in the w vector where this subsystem starts. as a
365 ! consequence it is assumed that the indices of the current
366 ! subsystem are contiguous, e.g. if a 2*2 system is solved the
367 ! last index in w is offset+1 and offset+2 respectively.
368 !
369  use blockpointers
370  use flowvarrefstate
371  use inputphysics
373  use inputunsteady
374  use iteration
375  use section
376  use turbmod
377  implicit none
378 !
379 ! subroutine arguments.
380 !
381  integer(kind=inttype), intent(in) :: madv, nadv, offset
382  real(kind=realtype), dimension(2:il, 2:jl, 2:kl, madv, madv), &
383 & intent(inout) :: qq
384 !
385 ! local variables.
386 !
387  integer(kind=inttype) :: i, j, k, ii, jj, nn
388  real(kind=realtype) :: oneoverdt, tmp
389 ! determine the equation mode.
390  select case (equationmode)
391  case (steady)
392 ! steady computation. no time derivative present.
393  return
394 !===============================================================
395  case (unsteady)
396 ! the time deritvative term depends on the integration
397 ! scheme used.
398  select case (timeintegrationscheme)
399  case (bdf)
400 ! backward difference formula is used as time
401 ! integration scheme.
402 ! store the inverse of the physical nondimensional
403 ! time step a bit easier.
404  oneoverdt = timeref/deltat
405 ! loop over the number of turbulent transport equations.
406 nadvloopunsteady:do ii=1,nadv
407 ! store the index of the current turbulent variable in jj.
408  jj = ii + offset
409 ! loop over the owned cells of this block to compute the
410 ! time derivative.
411  do k=2,kl
412  do j=2,jl
413  do i=2,il
414 ! initialize tmp to the value of the current
415 ! level multiplied by the corresponding coefficient
416 ! in the time integration scheme.
417  tmp = coeftime(0)*w(i, j, k, jj)
418 ! loop over the old time levels and add the
419 ! corresponding contribution to tmp.
420  do nn=1,noldlevels
421  tmp = tmp + coeftime(nn)*wold(nn, i, j, k, jj)
422  end do
423 ! update the residual. note that in the turbulent
424 ! routines the residual is defined with an opposite
425 ! sign compared to the residual of the flow equations.
426 ! therefore the time derivative must be substracted
427 ! from dvt.
428  scratch(i, j, k, idvt+ii-1) = scratch(i, j, k, idvt+ii-1&
429 & ) - oneoverdt*tmp
430 ! update the central jacobian.
431  qq(i, j, k, ii, ii) = qq(i, j, k, ii, ii) + coeftime(0)*&
432 & oneoverdt
433  end do
434  end do
435  end do
436  end do nadvloopunsteady
437  case (explicitrk)
438 !===========================================================
439 ! explicit time integration scheme. the time derivative
440 ! is handled differently.
441  return
442  end select
443 !===============================================================
444  case (timespectral)
445 ! time spectral method.
446 ! loop over the number of turbulent transport equations.
447 nadvloopspectral:do ii=1,nadv
448 ! store the index of the current turbulent variable in jj.
449  jj = ii + offset
450 ! the time derivative has been computed earlier in
451 ! unsteadyturbspectral and stored in entry jj of scratch.
452 ! substract this value for all owned cells. it must be
453 ! substracted, because in the turbulent routines the
454 ! residual is defined with an opposite sign compared to
455 ! the residual of the flow equations.
456 ! also add a term to the diagonal matrix, which corresponds
457 ! to to the contribution of the highest frequency. this is
458 ! equivalent to an explicit treatment of the time derivative
459 ! and may need to be changed.
461 & timeperiod
462  do k=2,kl
463  do j=2,jl
464  do i=2,il
465  scratch(i, j, k, idvt+ii-1) = scratch(i, j, k, idvt+ii-1) &
466 & - dw(i, j, k, jj)
467  qq(i, j, k, ii, ii) = qq(i, j, k, ii, ii) + tmp
468  end do
469  end do
470  end do
471  end do nadvloopspectral
472  end select
473  end subroutine unsteadyturbterm
474 
475  subroutine computeeddyviscosity(includehalos)
476 !
477 ! computeeddyviscosity computes the eddy viscosity in the
478 ! owned cell centers of the given block. it is assumed that the
479 ! pointes already point to the correct block before entering
480 ! this subroutine.
481 !
482  use constants
483  use flowvarrefstate
484  use inputphysics
485  use iteration
486  use blockpointers
487  implicit none
488 ! input parameter
489  logical, intent(in) :: includehalos
490 !
491 ! local variables.
492 !
493  logical :: returnimmediately
494  integer(kind=inttype) :: ibeg, iend, jbeg, jend, kbeg, kend
495 ! check if an immediate return can be made.
496  if (eddymodel) then
497  if (currentlevel .le. groundlevel) then
498  returnimmediately = .false.
499  else
500  returnimmediately = .true.
501  end if
502  else
503  returnimmediately = .true.
504  end if
505  if (returnimmediately) then
506  return
507  else
508 ! determine the turbulence model and call the appropriate
509 ! routine to compute the eddy viscosity.
510  if (includehalos) then
511  ibeg = 1
512  iend = ie
513  jbeg = 1
514  jend = je
515  kbeg = 1
516  kend = ke
517  else
518  ibeg = 2
519  iend = il
520  jbeg = 2
521  jend = jl
522  kbeg = 2
523  kend = kl
524  end if
525  select case (turbmodel)
527  call saeddyviscosity(ibeg, iend, jbeg, jend, kbeg, kend)
528  end select
529  end if
530  end subroutine computeeddyviscosity
531 
532 ! differentiation of saeddyviscosity in reverse (adjoint) mode (with options noisize i4 dr8 r8):
533 ! gradient of useful results: *rev *w *rlv
534 ! with respect to varying inputs: *rev *w *rlv
535 ! rw status of diff variables: *rev:in-out *w:incr *rlv:incr
536 ! plus diff mem management of: rev:in w:in rlv:in
537  subroutine saeddyviscosity_fast_b(ibeg, iend, jbeg, jend, kbeg, kend)
538 !
539 ! saeddyviscosity computes the eddy-viscosity according to the
540 ! spalart-allmaras model for the block given in blockpointers.
541 ! this routine for both the original version as well as the
542 ! modified version according to edwards.
543 !
544  use constants
545  use blockpointers
546  use constants
547  use paramturb
548  implicit none
549 ! input variables
550  integer(kind=inttype) :: ibeg, iend, jbeg, jend, kbeg, kend
551 !
552 ! local variables.
553 !
554  integer(kind=inttype) :: i, j, k, ii, isize, jsize, ksize
555  real(kind=realtype) :: chi, chi3, fv1, rnusa, cv13
556  real(kind=realtype) :: chid, chi3d, fv1d, rnusad
557  intrinsic mod
558  real(kind=realtype) :: tempd
559 ! store the cv1^3; cv1 is a constant of the spalart-allmaras model.
560  cv13 = rsacv1**3
561 ! loop over the cells of this block and compute the eddy viscosity.
562 ! do not include halo's.
563  isize = iend - ibeg + 1
564  jsize = jend - jbeg + 1
565  ksize = kend - kbeg + 1
566 !$bwd-of ii-loop
567  do ii=0,isize*jsize*ksize-1
568  i = mod(ii, isize) + ibeg
569  j = mod(ii/isize, jsize) + jbeg
570  k = ii/(isize*jsize) + kbeg
571  rnusa = w(i, j, k, itu1)*w(i, j, k, irho)
572  chi = rnusa/rlv(i, j, k)
573  chi3 = chi**3
574  fv1 = chi3/(chi3+cv13)
575  fv1d = rnusa*revd(i, j, k)
576  tempd = fv1d/(cv13+chi3)
577  chi3d = (1.0-chi3/(cv13+chi3))*tempd
578  chid = 3*chi**2*chi3d
579  tempd = chid/rlv(i, j, k)
580  rnusad = fv1*revd(i, j, k) + tempd
581  revd(i, j, k) = 0.0_8
582  rlvd(i, j, k) = rlvd(i, j, k) - rnusa*tempd/rlv(i, j, k)
583  wd(i, j, k, itu1) = wd(i, j, k, itu1) + w(i, j, k, irho)*rnusad
584  wd(i, j, k, irho) = wd(i, j, k, irho) + w(i, j, k, itu1)*rnusad
585  end do
586  end subroutine saeddyviscosity_fast_b
587 
588  subroutine saeddyviscosity(ibeg, iend, jbeg, jend, kbeg, kend)
589 !
590 ! saeddyviscosity computes the eddy-viscosity according to the
591 ! spalart-allmaras model for the block given in blockpointers.
592 ! this routine for both the original version as well as the
593 ! modified version according to edwards.
594 !
595  use constants
596  use blockpointers
597  use constants
598  use paramturb
599  implicit none
600 ! input variables
601  integer(kind=inttype) :: ibeg, iend, jbeg, jend, kbeg, kend
602 !
603 ! local variables.
604 !
605  integer(kind=inttype) :: i, j, k, ii, isize, jsize, ksize
606  real(kind=realtype) :: chi, chi3, fv1, rnusa, cv13
607  intrinsic mod
608 ! store the cv1^3; cv1 is a constant of the spalart-allmaras model.
609  cv13 = rsacv1**3
610 ! loop over the cells of this block and compute the eddy viscosity.
611 ! do not include halo's.
612  isize = iend - ibeg + 1
613  jsize = jend - jbeg + 1
614  ksize = kend - kbeg + 1
615 !$ad ii-loop
616  do ii=0,isize*jsize*ksize-1
617  i = mod(ii, isize) + ibeg
618  j = mod(ii/isize, jsize) + jbeg
619  k = ii/(isize*jsize) + kbeg
620  rnusa = w(i, j, k, itu1)*w(i, j, k, irho)
621  chi = rnusa/rlv(i, j, k)
622  chi3 = chi**3
623  fv1 = chi3/(chi3+cv13)
624  rev(i, j, k) = fv1*rnusa
625  end do
626  end subroutine saeddyviscosity
627 
628  subroutine kweddyviscosity(ibeg, iend, jbeg, jend, kbeg, kend)
629 !
630 ! kweddyviscosity computes the eddy viscosity according to the
631 ! k-omega models (both the original wilcox as well as the
632 ! modified version) for the block given in blockpointers.
633 !
634  use constants
635  use blockpointers
636  implicit none
637 ! input variables
638  integer(kind=inttype) :: ibeg, iend, jbeg, jend, kbeg, kend
639 !
640 ! local variables.
641 !
642  integer(kind=inttype) :: i, j, k, ii, isize, jsize, ksize
643  intrinsic mod
644  intrinsic abs
645  real(kind=realtype) :: x1
646 ! loop over the cells of this block and compute the eddy viscosity.
647 ! do not include halo's.
648  isize = iend - ibeg + 1
649  jsize = jend - jbeg + 1
650  ksize = kend - kbeg + 1
651 !$ad ii-loop
652  do ii=0,isize*jsize*ksize-1
653  i = mod(ii, isize) + ibeg
654  j = mod(ii/isize, jsize) + jbeg
655  k = ii/(isize*jsize) + kbeg
656  x1 = w(i, j, k, irho)*w(i, j, k, itu1)/w(i, j, k, itu2)
657  if (x1 .ge. 0.) then
658  rev(i, j, k) = x1
659  else
660  rev(i, j, k) = -x1
661  end if
662  end do
663  end subroutine kweddyviscosity
664 
665  subroutine ssteddyviscosity(ibeg, iend, jbeg, jend, kbeg, kend)
666 !
667 ! ssteddyviscosity computes the eddy viscosity according to
668 ! menter's sst variant of the k-omega turbulence model for the
669 ! block given in blockpointers.
670 !
671  use constants
672  use blockpointers
673  use paramturb
674  use turbmod
675  implicit none
676 ! input variables
677  integer(kind=inttype) :: ibeg, iend, jbeg, jend, kbeg, kend
678 !
679 ! local variables.
680 !
681  integer(kind=inttype) :: i, j, k, ii, isize, jsize, ksize
682  real(kind=realtype) :: t1, t2, arg2, f2, vortmag
683  intrinsic mod
684  intrinsic sqrt
685  intrinsic max
686  intrinsic tanh
687  real(kind=realtype) :: max1
688 ! compute the vorticity squared in the cell centers. the reason
689 ! for computing the vorticity squared is that a routine exists
690 ! for it; for the actual eddy viscosity computation the vorticity
691 ! itself is needed.
692  call prodwmag2()
693 ! loop over the cells of this block and compute the eddy viscosity.
694 ! do not include halo's.
695  isize = iend - ibeg + 1
696  jsize = jend - jbeg + 1
697  ksize = kend - kbeg + 1
698 !$ad ii-loop
699  do ii=0,isize*jsize*ksize-1
700  i = mod(ii, isize) + ibeg
701  j = mod(ii/isize, jsize) + jbeg
702  k = ii/(isize*jsize) + kbeg
703 ! compute the value of the function f2, which occurs in the
704 ! eddy-viscosity computation.
705  t1 = two*sqrt(w(i, j, k, itu1))/(0.09_realtype*w(i, j, k, itu2)*&
706 & d2wall(i, j, k))
707  t2 = 500.0_realtype*rlv(i, j, k)/(w(i, j, k, irho)*w(i, j, k, itu2&
708 & )*d2wall(i, j, k)**2)
709  if (t1 .lt. t2) then
710  arg2 = t2
711  else
712  arg2 = t1
713  end if
714  f2 = tanh(arg2**2)
715 ! and compute the eddy viscosity.
716  vortmag = sqrt(scratch(i, j, k, iprod))
717  if (rssta1*w(i, j, k, itu2) .lt. f2*vortmag) then
718  max1 = f2*vortmag
719  else
720  max1 = rssta1*w(i, j, k, itu2)
721  end if
722  rev(i, j, k) = w(i, j, k, irho)*rssta1*w(i, j, k, itu1)/max1
723  end do
724  end subroutine ssteddyviscosity
725 
726 ! differentiation of turbadvection in reverse (adjoint) mode (with options noisize i4 dr8 r8):
727 ! gradient of useful results: *w *scratch
728 ! with respect to varying inputs: *w *scratch
729 ! rw status of diff variables: *w:incr *scratch:in-out
730 ! plus diff mem management of: w:in scratch:in
731  subroutine turbadvection_fast_b(madv, nadv, offset, qq)
732 !
733 ! turbadvection discretizes the advection part of the turbulent
734 ! transport equations. as the advection part is the same for all
735 ! models, this generic routine can be used. both the
736 ! discretization and the central jacobian are computed in this
737 ! subroutine. the former can either be 1st or 2nd order
738 ! accurate; the latter is always based on the 1st order upwind
739 ! discretization. when the discretization must be second order
740 ! accurate, the fully upwind (kappa = -1) scheme in combination
741 ! with the minmod limiter is used.
742 ! only nadv equations are treated, while the actual system has
743 ! size madv. the reason is that some equations for some
744 ! turbulence equations do not have an advection part, e.g. the
745 ! f equation in the v2-f model. the argument offset indicates
746 ! the offset in the w vector where this subsystem starts. as a
747 ! consequence it is assumed that the indices of the current
748 ! subsystem are contiguous, e.g. if a 2*2 system is solved the
749 ! last index in w is offset+1 and offset+2 respectively.
750 !
751  use constants
752  use blockpointers, only : nx, ny, nz, il, jl, kl, vol, sfacei&
755  use inputdiscretization, only : orderturb
756  use iteration, only : groundlevel
757  use turbmod, only : secondord
758  implicit none
759 !
760 ! subroutine arguments.
761 !
762  integer(kind=inttype), intent(in) :: nadv, madv, offset
763  real(kind=realtype), dimension(2:il, 2:jl, 2:kl, madv, madv), &
764 & intent(inout) :: qq
765 !
766 ! local variables.
767 !
768  integer(kind=inttype) :: i, j, k, ii, jj, kk, iii
769  real(kind=realtype) :: qs, voli, xa, ya, za
770  real(kind=realtype) :: uu, dwt, dwtm1, dwtp1, dwti, dwtj, dwtk
771  real(kind=realtype) :: uud, dwtd, dwtm1d, dwtp1d, dwtid, dwtjd, &
772 & dwtkd
773  real(kind=realtype), dimension(madv) :: impl
774  intrinsic mod
775  intrinsic abs
776  real(kind=realtype) :: abs0
777  real(kind=realtype) :: abs1
778  real(kind=realtype) :: abs2
779  real(kind=realtype) :: abs3
780  real(kind=realtype) :: abs4
781  real(kind=realtype) :: abs5
782  real(kind=realtype) :: abs6
783  real(kind=realtype) :: abs7
784  real(kind=realtype) :: abs8
785  real(kind=realtype) :: abs9
786  real(kind=realtype) :: abs10
787  real(kind=realtype) :: abs11
788  real(kind=realtype) :: abs12
789  real(kind=realtype) :: abs13
790  real(kind=realtype) :: abs14
791  real(kind=realtype) :: abs15
792  real(kind=realtype) :: abs16
793  real(kind=realtype) :: abs17
794  real(kind=realtype) :: abs18
795  real(kind=realtype) :: abs19
796  real(kind=realtype) :: abs20
797  real(kind=realtype) :: abs21
798  real(kind=realtype) :: abs22
799  real(kind=realtype) :: abs23
800  integer :: branch
801 ! determine whether or not a second order discretization for the
802 ! advective terms must be used.
803  secondord = .false.
804  if (groundlevel .eq. 1_inttype .and. orderturb .eq. secondorder) &
805 & secondord = .true.
806  qs = zero
807 !$bwd-of ii-loop
808  do iii=0,nx*ny*nz-1
809  i = mod(iii, nx) + 2
810  j = mod(iii/nx, ny) + 2
811  k = iii/(nx*ny) + 2
812 ! compute the grid velocity if present.
813 ! it is taken as the average of i and i-1,
814  voli = half/vol(i, j, k)
815  if (addgridvelocities) qs = (sfacei(i, j, k)+sfacei(i-1, j, k))*&
816 & voli
817 ! compute the normal velocity, where the normal direction
818 ! is taken as the average of faces i and i-1.
819  xa = (si(i, j, k, 1)+si(i-1, j, k, 1))*voli
820  ya = (si(i, j, k, 2)+si(i-1, j, k, 2))*voli
821  za = (si(i, j, k, 3)+si(i-1, j, k, 3))*voli
822  uu = xa*w(i, j, k, ivx) + ya*w(i, j, k, ivy) + za*w(i, j, k, ivz) &
823 & - qs
824 ! determine the situation we are having here, i.e. positive
825 ! or negative normal velocity.
826  if (uu .gt. zero) then
827  uud = 0.0_8
828 !$bwd-of ii-loop
829  do 100 ii=1,nadv
830 ! set the value of jj such that it corresponds to the
831 ! turbulent entry in w.
832  jj = ii + offset
833 ! check whether a first or a second order discretization
834 ! must be used.
835  if (secondord) then
836 ! second order; store the three differences for the
837 ! discretization of the derivative in i-direction.
838  dwtm1 = w(i-1, j, k, jj) - w(i-2, j, k, jj)
839  dwt = w(i, j, k, jj) - w(i-1, j, k, jj)
840  dwtp1 = w(i+1, j, k, jj) - w(i, j, k, jj)
841 ! construct the derivative in this cell center. this is
842 ! the first order upwind derivative with two nonlinear
843 ! corrections.
844  dwti = dwt
845  if (dwt*dwtp1 .gt. zero) then
846  if (dwt .ge. 0.) then
847  abs8 = dwt
848  else
849  abs8 = -dwt
850  end if
851  if (dwtp1 .ge. 0.) then
852  abs20 = dwtp1
853  else
854  abs20 = -dwtp1
855  end if
856  if (abs8 .lt. abs20) then
857  dwti = dwti + half*dwt
858  call pushcontrol2b(0)
859  else
860  dwti = dwti + half*dwtp1
861  call pushcontrol2b(1)
862  end if
863  else
864  call pushcontrol2b(2)
865  end if
866  if (dwt*dwtm1 .gt. zero) then
867  if (dwt .ge. 0.) then
868  abs9 = dwt
869  else
870  abs9 = -dwt
871  end if
872  if (dwtm1 .ge. 0.) then
873  abs21 = dwtm1
874  else
875  abs21 = -dwtm1
876  end if
877  if (abs9 .lt. abs21) then
878  dwti = dwti - half*dwt
879  call pushcontrol2b(0)
880  else
881  dwti = dwti - half*dwtm1
882  call pushcontrol2b(1)
883  end if
884  else
885  call pushcontrol2b(2)
886  end if
887  else
888 ! 1st order upwind scheme.
889  dwti = w(i, j, k, jj) - w(i-1, j, k, jj)
890  call pushcontrol2b(3)
891  end if
892  uud = uud - dwti*scratchd(i, j, k, idvt+ii-1)
893  dwtid = -(uu*scratchd(i, j, k, idvt+ii-1))
894  call popcontrol2b(branch)
895  if (branch .lt. 2) then
896  if (branch .eq. 0) then
897  dwtd = -(half*dwtid)
898  dwtm1d = 0.0_8
899  else
900  dwtm1d = -(half*dwtid)
901  dwtd = 0.0_8
902  end if
903  else if (branch .eq. 2) then
904  dwtd = 0.0_8
905  dwtm1d = 0.0_8
906  else
907  wd(i, j, k, jj) = wd(i, j, k, jj) + dwtid
908  wd(i-1, j, k, jj) = wd(i-1, j, k, jj) - dwtid
909  goto 100
910  end if
911  call popcontrol2b(branch)
912  if (branch .eq. 0) then
913  dwtd = dwtd + half*dwtid
914  dwtp1d = 0.0_8
915  else if (branch .eq. 1) then
916  dwtp1d = half*dwtid
917  else
918  dwtp1d = 0.0_8
919  end if
920  dwtd = dwtd + dwtid
921  wd(i+1, j, k, jj) = wd(i+1, j, k, jj) + dwtp1d
922  wd(i, j, k, jj) = wd(i, j, k, jj) + dwtd - dwtp1d
923  wd(i-1, j, k, jj) = wd(i-1, j, k, jj) + dwtm1d - dwtd
924  wd(i-2, j, k, jj) = wd(i-2, j, k, jj) - dwtm1d
925  100 continue
926  else
927  uud = 0.0_8
928 !$bwd-of ii-loop
929  do 110 ii=1,nadv
930 ! set the value of jj such that it corresponds to the
931 ! turbulent entry in w.
932  jj = ii + offset
933 ! check whether a first or a second order discretization
934 ! must be used.
935  if (secondord) then
936 ! second order; store the three differences for the
937 ! discretization of the derivative in i-direction.
938  dwtm1 = w(i, j, k, jj) - w(i-1, j, k, jj)
939  dwt = w(i+1, j, k, jj) - w(i, j, k, jj)
940  dwtp1 = w(i+2, j, k, jj) - w(i+1, j, k, jj)
941 ! construct the derivative in this cell center. this is
942 ! the first order upwind derivative with two nonlinear
943 ! corrections.
944  dwti = dwt
945  if (dwt*dwtp1 .gt. zero) then
946  if (dwt .ge. 0.) then
947  abs10 = dwt
948  else
949  abs10 = -dwt
950  end if
951  if (dwtp1 .ge. 0.) then
952  abs22 = dwtp1
953  else
954  abs22 = -dwtp1
955  end if
956  if (abs10 .lt. abs22) then
957  dwti = dwti - half*dwt
958  call pushcontrol2b(0)
959  else
960  dwti = dwti - half*dwtp1
961  call pushcontrol2b(1)
962  end if
963  else
964  call pushcontrol2b(2)
965  end if
966  if (dwt*dwtm1 .gt. zero) then
967  if (dwt .ge. 0.) then
968  abs11 = dwt
969  else
970  abs11 = -dwt
971  end if
972  if (dwtm1 .ge. 0.) then
973  abs23 = dwtm1
974  else
975  abs23 = -dwtm1
976  end if
977  if (abs11 .lt. abs23) then
978  dwti = dwti + half*dwt
979  call pushcontrol2b(0)
980  else
981  dwti = dwti + half*dwtm1
982  call pushcontrol2b(1)
983  end if
984  else
985  call pushcontrol2b(2)
986  end if
987  else
988 ! 1st order upwind scheme.
989  dwti = w(i+1, j, k, jj) - w(i, j, k, jj)
990  call pushcontrol2b(3)
991  end if
992  uud = uud - dwti*scratchd(i, j, k, idvt+ii-1)
993  dwtid = -(uu*scratchd(i, j, k, idvt+ii-1))
994  call popcontrol2b(branch)
995  if (branch .lt. 2) then
996  if (branch .eq. 0) then
997  dwtd = half*dwtid
998  dwtm1d = 0.0_8
999  else
1000  dwtm1d = half*dwtid
1001  dwtd = 0.0_8
1002  end if
1003  else if (branch .eq. 2) then
1004  dwtd = 0.0_8
1005  dwtm1d = 0.0_8
1006  else
1007  wd(i+1, j, k, jj) = wd(i+1, j, k, jj) + dwtid
1008  wd(i, j, k, jj) = wd(i, j, k, jj) - dwtid
1009  goto 110
1010  end if
1011  call popcontrol2b(branch)
1012  if (branch .eq. 0) then
1013  dwtd = dwtd - half*dwtid
1014  dwtp1d = 0.0_8
1015  else if (branch .eq. 1) then
1016  dwtp1d = -(half*dwtid)
1017  else
1018  dwtp1d = 0.0_8
1019  end if
1020  dwtd = dwtd + dwtid
1021  wd(i+2, j, k, jj) = wd(i+2, j, k, jj) + dwtp1d
1022  wd(i+1, j, k, jj) = wd(i+1, j, k, jj) + dwtd - dwtp1d
1023  wd(i, j, k, jj) = wd(i, j, k, jj) + dwtm1d - dwtd
1024  wd(i-1, j, k, jj) = wd(i-1, j, k, jj) - dwtm1d
1025  110 continue
1026  end if
1027  wd(i, j, k, ivx) = wd(i, j, k, ivx) + xa*uud
1028  wd(i, j, k, ivy) = wd(i, j, k, ivy) + ya*uud
1029  wd(i, j, k, ivz) = wd(i, j, k, ivz) + za*uud
1030  end do
1031  qs = zero
1032 !$bwd-of ii-loop
1033  do iii=0,nx*ny*nz-1
1034  i = mod(iii, nx) + 2
1035  j = mod(iii/nx, ny) + 2
1036  k = iii/(nx*ny) + 2
1037 ! compute the grid velocity if present.
1038 ! it is taken as the average of j and j-1,
1039  voli = half/vol(i, j, k)
1040  if (addgridvelocities) qs = (sfacej(i, j, k)+sfacej(i, j-1, k))*&
1041 & voli
1042 ! compute the normal velocity, where the normal direction
1043 ! is taken as the average of faces j and j-1.
1044  xa = (sj(i, j, k, 1)+sj(i, j-1, k, 1))*voli
1045  ya = (sj(i, j, k, 2)+sj(i, j-1, k, 2))*voli
1046  za = (sj(i, j, k, 3)+sj(i, j-1, k, 3))*voli
1047  uu = xa*w(i, j, k, ivx) + ya*w(i, j, k, ivy) + za*w(i, j, k, ivz) &
1048 & - qs
1049 ! determine the situation we are having here, i.e. positive
1050 ! or negative normal velocity.
1051  if (uu .gt. zero) then
1052  uud = 0.0_8
1053 !$bwd-of ii-loop
1054  do 120 ii=1,nadv
1055 ! set the value of jj such that it corresponds to the
1056 ! turbulent entry in w.
1057  jj = ii + offset
1058 ! check whether a first or a second order discretization
1059 ! must be used.
1060  if (secondord) then
1061 ! second order; store the three differences for the
1062 ! discretization of the derivative in j-direction.
1063  dwtm1 = w(i, j-1, k, jj) - w(i, j-2, k, jj)
1064  dwt = w(i, j, k, jj) - w(i, j-1, k, jj)
1065  dwtp1 = w(i, j+1, k, jj) - w(i, j, k, jj)
1066 ! construct the derivative in this cell center. this is
1067 ! the first order upwind derivative with two nonlinear
1068 ! corrections.
1069  dwtj = dwt
1070  if (dwt*dwtp1 .gt. zero) then
1071  if (dwt .ge. 0.) then
1072  abs4 = dwt
1073  else
1074  abs4 = -dwt
1075  end if
1076  if (dwtp1 .ge. 0.) then
1077  abs16 = dwtp1
1078  else
1079  abs16 = -dwtp1
1080  end if
1081  if (abs4 .lt. abs16) then
1082  dwtj = dwtj + half*dwt
1083  call pushcontrol2b(0)
1084  else
1085  dwtj = dwtj + half*dwtp1
1086  call pushcontrol2b(1)
1087  end if
1088  else
1089  call pushcontrol2b(2)
1090  end if
1091  if (dwt*dwtm1 .gt. zero) then
1092  if (dwt .ge. 0.) then
1093  abs5 = dwt
1094  else
1095  abs5 = -dwt
1096  end if
1097  if (dwtm1 .ge. 0.) then
1098  abs17 = dwtm1
1099  else
1100  abs17 = -dwtm1
1101  end if
1102  if (abs5 .lt. abs17) then
1103  dwtj = dwtj - half*dwt
1104  call pushcontrol2b(0)
1105  else
1106  dwtj = dwtj - half*dwtm1
1107  call pushcontrol2b(1)
1108  end if
1109  else
1110  call pushcontrol2b(2)
1111  end if
1112  else
1113 ! 1st order upwind scheme.
1114  dwtj = w(i, j, k, jj) - w(i, j-1, k, jj)
1115  call pushcontrol2b(3)
1116  end if
1117  uud = uud - dwtj*scratchd(i, j, k, idvt+ii-1)
1118  dwtjd = -(uu*scratchd(i, j, k, idvt+ii-1))
1119  call popcontrol2b(branch)
1120  if (branch .lt. 2) then
1121  if (branch .eq. 0) then
1122  dwtd = -(half*dwtjd)
1123  dwtm1d = 0.0_8
1124  else
1125  dwtm1d = -(half*dwtjd)
1126  dwtd = 0.0_8
1127  end if
1128  else if (branch .eq. 2) then
1129  dwtd = 0.0_8
1130  dwtm1d = 0.0_8
1131  else
1132  wd(i, j, k, jj) = wd(i, j, k, jj) + dwtjd
1133  wd(i, j-1, k, jj) = wd(i, j-1, k, jj) - dwtjd
1134  goto 120
1135  end if
1136  call popcontrol2b(branch)
1137  if (branch .eq. 0) then
1138  dwtd = dwtd + half*dwtjd
1139  dwtp1d = 0.0_8
1140  else if (branch .eq. 1) then
1141  dwtp1d = half*dwtjd
1142  else
1143  dwtp1d = 0.0_8
1144  end if
1145  dwtd = dwtd + dwtjd
1146  wd(i, j+1, k, jj) = wd(i, j+1, k, jj) + dwtp1d
1147  wd(i, j, k, jj) = wd(i, j, k, jj) + dwtd - dwtp1d
1148  wd(i, j-1, k, jj) = wd(i, j-1, k, jj) + dwtm1d - dwtd
1149  wd(i, j-2, k, jj) = wd(i, j-2, k, jj) - dwtm1d
1150  120 continue
1151  else
1152  uud = 0.0_8
1153 !$bwd-of ii-loop
1154  do 130 ii=1,nadv
1155 ! set the value of jj such that it corresponds to the
1156 ! turbulent entry in w.
1157  jj = ii + offset
1158 ! check whether a first or a second order discretization
1159 ! must be used.
1160  if (secondord) then
1161 ! store the three differences for the discretization of
1162 ! the derivative in j-direction.
1163  dwtm1 = w(i, j, k, jj) - w(i, j-1, k, jj)
1164  dwt = w(i, j+1, k, jj) - w(i, j, k, jj)
1165  dwtp1 = w(i, j+2, k, jj) - w(i, j+1, k, jj)
1166 ! construct the derivative in this cell center. this is
1167 ! the first order upwind derivative with two nonlinear
1168 ! corrections.
1169  dwtj = dwt
1170  if (dwt*dwtp1 .gt. zero) then
1171  if (dwt .ge. 0.) then
1172  abs6 = dwt
1173  else
1174  abs6 = -dwt
1175  end if
1176  if (dwtp1 .ge. 0.) then
1177  abs18 = dwtp1
1178  else
1179  abs18 = -dwtp1
1180  end if
1181  if (abs6 .lt. abs18) then
1182  dwtj = dwtj - half*dwt
1183  call pushcontrol2b(0)
1184  else
1185  dwtj = dwtj - half*dwtp1
1186  call pushcontrol2b(1)
1187  end if
1188  else
1189  call pushcontrol2b(2)
1190  end if
1191  if (dwt*dwtm1 .gt. zero) then
1192  if (dwt .ge. 0.) then
1193  abs7 = dwt
1194  else
1195  abs7 = -dwt
1196  end if
1197  if (dwtm1 .ge. 0.) then
1198  abs19 = dwtm1
1199  else
1200  abs19 = -dwtm1
1201  end if
1202  if (abs7 .lt. abs19) then
1203  dwtj = dwtj + half*dwt
1204  call pushcontrol2b(0)
1205  else
1206  dwtj = dwtj + half*dwtm1
1207  call pushcontrol2b(1)
1208  end if
1209  else
1210  call pushcontrol2b(2)
1211  end if
1212  else
1213 ! 1st order upwind scheme.
1214  dwtj = w(i, j+1, k, jj) - w(i, j, k, jj)
1215  call pushcontrol2b(3)
1216  end if
1217  uud = uud - dwtj*scratchd(i, j, k, idvt+ii-1)
1218  dwtjd = -(uu*scratchd(i, j, k, idvt+ii-1))
1219  call popcontrol2b(branch)
1220  if (branch .lt. 2) then
1221  if (branch .eq. 0) then
1222  dwtd = half*dwtjd
1223  dwtm1d = 0.0_8
1224  else
1225  dwtm1d = half*dwtjd
1226  dwtd = 0.0_8
1227  end if
1228  else if (branch .eq. 2) then
1229  dwtd = 0.0_8
1230  dwtm1d = 0.0_8
1231  else
1232  wd(i, j+1, k, jj) = wd(i, j+1, k, jj) + dwtjd
1233  wd(i, j, k, jj) = wd(i, j, k, jj) - dwtjd
1234  goto 130
1235  end if
1236  call popcontrol2b(branch)
1237  if (branch .eq. 0) then
1238  dwtd = dwtd - half*dwtjd
1239  dwtp1d = 0.0_8
1240  else if (branch .eq. 1) then
1241  dwtp1d = -(half*dwtjd)
1242  else
1243  dwtp1d = 0.0_8
1244  end if
1245  dwtd = dwtd + dwtjd
1246  wd(i, j+2, k, jj) = wd(i, j+2, k, jj) + dwtp1d
1247  wd(i, j+1, k, jj) = wd(i, j+1, k, jj) + dwtd - dwtp1d
1248  wd(i, j, k, jj) = wd(i, j, k, jj) + dwtm1d - dwtd
1249  wd(i, j-1, k, jj) = wd(i, j-1, k, jj) - dwtm1d
1250  130 continue
1251  end if
1252  wd(i, j, k, ivx) = wd(i, j, k, ivx) + xa*uud
1253  wd(i, j, k, ivy) = wd(i, j, k, ivy) + ya*uud
1254  wd(i, j, k, ivz) = wd(i, j, k, ivz) + za*uud
1255  end do
1256 ! initialize the grid velocity to zero. this value will be used
1257 ! if the block is not moving.
1258  qs = zero
1259 !$bwd-of ii-loop
1260  do iii=0,nx*ny*nz-1
1261  i = mod(iii, nx) + 2
1262  j = mod(iii/nx, ny) + 2
1263  k = iii/(nx*ny) + 2
1264 ! compute the grid velocity if present.
1265 ! it is taken as the average of k and k-1,
1266  voli = half/vol(i, j, k)
1267  if (addgridvelocities) qs = (sfacek(i, j, k)+sfacek(i, j, k-1))*&
1268 & voli
1269 ! compute the normal velocity, where the normal direction
1270 ! is taken as the average of faces k and k-1.
1271  xa = (sk(i, j, k, 1)+sk(i, j, k-1, 1))*voli
1272  ya = (sk(i, j, k, 2)+sk(i, j, k-1, 2))*voli
1273  za = (sk(i, j, k, 3)+sk(i, j, k-1, 3))*voli
1274  uu = xa*w(i, j, k, ivx) + ya*w(i, j, k, ivy) + za*w(i, j, k, ivz) &
1275 & - qs
1276 ! this term has unit: velocity/length
1277 ! determine the situation we are having here, i.e. positive
1278 ! or negative normal velocity.
1279  if (uu .gt. zero) then
1280  uud = 0.0_8
1281 !$bwd-of ii-loop
1282  do 140 ii=1,nadv
1283 ! set the value of jj such that it corresponds to the
1284 ! turbulent entry in w.
1285  jj = ii + offset
1286 ! check whether a first or a second order discretization
1287 ! must be used.
1288  if (secondord) then
1289 ! second order; store the three differences for the
1290 ! discretization of the derivative in k-direction.
1291  dwtm1 = w(i, j, k-1, jj) - w(i, j, k-2, jj)
1292  dwt = w(i, j, k, jj) - w(i, j, k-1, jj)
1293  dwtp1 = w(i, j, k+1, jj) - w(i, j, k, jj)
1294 ! construct the derivative in this cell center. this
1295 ! is the first order upwind derivative with two
1296 ! nonlinear corrections.
1297  dwtk = dwt
1298  if (dwt*dwtp1 .gt. zero) then
1299  if (dwt .ge. 0.) then
1300  abs0 = dwt
1301  else
1302  abs0 = -dwt
1303  end if
1304  if (dwtp1 .ge. 0.) then
1305  abs12 = dwtp1
1306  else
1307  abs12 = -dwtp1
1308  end if
1309  if (abs0 .lt. abs12) then
1310  dwtk = dwtk + half*dwt
1311  call pushcontrol2b(0)
1312  else
1313  dwtk = dwtk + half*dwtp1
1314  call pushcontrol2b(1)
1315  end if
1316  else
1317  call pushcontrol2b(2)
1318  end if
1319  if (dwt*dwtm1 .gt. zero) then
1320  if (dwt .ge. 0.) then
1321  abs1 = dwt
1322  else
1323  abs1 = -dwt
1324  end if
1325  if (dwtm1 .ge. 0.) then
1326  abs13 = dwtm1
1327  else
1328  abs13 = -dwtm1
1329  end if
1330  if (abs1 .lt. abs13) then
1331  dwtk = dwtk - half*dwt
1332  call pushcontrol2b(0)
1333  else
1334  dwtk = dwtk - half*dwtm1
1335  call pushcontrol2b(1)
1336  end if
1337  else
1338  call pushcontrol2b(2)
1339  end if
1340  else
1341 ! 1st order upwind scheme.
1342  dwtk = w(i, j, k, jj) - w(i, j, k-1, jj)
1343  call pushcontrol2b(3)
1344  end if
1345  uud = uud - dwtk*scratchd(i, j, k, idvt+ii-1)
1346  dwtkd = -(uu*scratchd(i, j, k, idvt+ii-1))
1347  call popcontrol2b(branch)
1348  if (branch .lt. 2) then
1349  if (branch .eq. 0) then
1350  dwtd = -(half*dwtkd)
1351  dwtm1d = 0.0_8
1352  else
1353  dwtm1d = -(half*dwtkd)
1354  dwtd = 0.0_8
1355  end if
1356  else if (branch .eq. 2) then
1357  dwtd = 0.0_8
1358  dwtm1d = 0.0_8
1359  else
1360  wd(i, j, k, jj) = wd(i, j, k, jj) + dwtkd
1361  wd(i, j, k-1, jj) = wd(i, j, k-1, jj) - dwtkd
1362  goto 140
1363  end if
1364  call popcontrol2b(branch)
1365  if (branch .eq. 0) then
1366  dwtd = dwtd + half*dwtkd
1367  dwtp1d = 0.0_8
1368  else if (branch .eq. 1) then
1369  dwtp1d = half*dwtkd
1370  else
1371  dwtp1d = 0.0_8
1372  end if
1373  dwtd = dwtd + dwtkd
1374  wd(i, j, k+1, jj) = wd(i, j, k+1, jj) + dwtp1d
1375  wd(i, j, k, jj) = wd(i, j, k, jj) + dwtd - dwtp1d
1376  wd(i, j, k-1, jj) = wd(i, j, k-1, jj) + dwtm1d - dwtd
1377  wd(i, j, k-2, jj) = wd(i, j, k-2, jj) - dwtm1d
1378  140 continue
1379  else
1380  uud = 0.0_8
1381 !$bwd-of ii-loop
1382  do 150 ii=1,nadv
1383 ! set the value of jj such that it corresponds to the
1384 ! turbulent entry in w.
1385  jj = ii + offset
1386 ! check whether a first or a second order discretization
1387 ! must be used.
1388  if (secondord) then
1389 ! store the three differences for the discretization of
1390 ! the derivative in k-direction.
1391  dwtm1 = w(i, j, k, jj) - w(i, j, k-1, jj)
1392  dwt = w(i, j, k+1, jj) - w(i, j, k, jj)
1393  dwtp1 = w(i, j, k+2, jj) - w(i, j, k+1, jj)
1394 ! construct the derivative in this cell center. this is
1395 ! the first order upwind derivative with two nonlinear
1396 ! corrections.
1397  dwtk = dwt
1398  if (dwt*dwtp1 .gt. zero) then
1399  if (dwt .ge. 0.) then
1400  abs2 = dwt
1401  else
1402  abs2 = -dwt
1403  end if
1404  if (dwtp1 .ge. 0.) then
1405  abs14 = dwtp1
1406  else
1407  abs14 = -dwtp1
1408  end if
1409  if (abs2 .lt. abs14) then
1410  dwtk = dwtk - half*dwt
1411  call pushcontrol2b(0)
1412  else
1413  dwtk = dwtk - half*dwtp1
1414  call pushcontrol2b(1)
1415  end if
1416  else
1417  call pushcontrol2b(2)
1418  end if
1419  if (dwt*dwtm1 .gt. zero) then
1420  if (dwt .ge. 0.) then
1421  abs3 = dwt
1422  else
1423  abs3 = -dwt
1424  end if
1425  if (dwtm1 .ge. 0.) then
1426  abs15 = dwtm1
1427  else
1428  abs15 = -dwtm1
1429  end if
1430  if (abs3 .lt. abs15) then
1431  dwtk = dwtk + half*dwt
1432  call pushcontrol2b(0)
1433  else
1434  dwtk = dwtk + half*dwtm1
1435  call pushcontrol2b(1)
1436  end if
1437  else
1438  call pushcontrol2b(2)
1439  end if
1440  else
1441 ! 1st order upwind scheme.
1442  dwtk = w(i, j, k+1, jj) - w(i, j, k, jj)
1443  call pushcontrol2b(3)
1444  end if
1445  uud = uud - dwtk*scratchd(i, j, k, idvt+ii-1)
1446  dwtkd = -(uu*scratchd(i, j, k, idvt+ii-1))
1447  call popcontrol2b(branch)
1448  if (branch .lt. 2) then
1449  if (branch .eq. 0) then
1450  dwtd = half*dwtkd
1451  dwtm1d = 0.0_8
1452  else
1453  dwtm1d = half*dwtkd
1454  dwtd = 0.0_8
1455  end if
1456  else if (branch .eq. 2) then
1457  dwtd = 0.0_8
1458  dwtm1d = 0.0_8
1459  else
1460  wd(i, j, k+1, jj) = wd(i, j, k+1, jj) + dwtkd
1461  wd(i, j, k, jj) = wd(i, j, k, jj) - dwtkd
1462  goto 150
1463  end if
1464  call popcontrol2b(branch)
1465  if (branch .eq. 0) then
1466  dwtd = dwtd - half*dwtkd
1467  dwtp1d = 0.0_8
1468  else if (branch .eq. 1) then
1469  dwtp1d = -(half*dwtkd)
1470  else
1471  dwtp1d = 0.0_8
1472  end if
1473  dwtd = dwtd + dwtkd
1474  wd(i, j, k+2, jj) = wd(i, j, k+2, jj) + dwtp1d
1475  wd(i, j, k+1, jj) = wd(i, j, k+1, jj) + dwtd - dwtp1d
1476  wd(i, j, k, jj) = wd(i, j, k, jj) + dwtm1d - dwtd
1477  wd(i, j, k-1, jj) = wd(i, j, k-1, jj) - dwtm1d
1478  150 continue
1479  end if
1480  wd(i, j, k, ivx) = wd(i, j, k, ivx) + xa*uud
1481  wd(i, j, k, ivy) = wd(i, j, k, ivy) + ya*uud
1482  wd(i, j, k, ivz) = wd(i, j, k, ivz) + za*uud
1483  end do
1484  end subroutine turbadvection_fast_b
1485 
1486  subroutine turbadvection(madv, nadv, offset, qq)
1487 !
1488 ! turbadvection discretizes the advection part of the turbulent
1489 ! transport equations. as the advection part is the same for all
1490 ! models, this generic routine can be used. both the
1491 ! discretization and the central jacobian are computed in this
1492 ! subroutine. the former can either be 1st or 2nd order
1493 ! accurate; the latter is always based on the 1st order upwind
1494 ! discretization. when the discretization must be second order
1495 ! accurate, the fully upwind (kappa = -1) scheme in combination
1496 ! with the minmod limiter is used.
1497 ! only nadv equations are treated, while the actual system has
1498 ! size madv. the reason is that some equations for some
1499 ! turbulence equations do not have an advection part, e.g. the
1500 ! f equation in the v2-f model. the argument offset indicates
1501 ! the offset in the w vector where this subsystem starts. as a
1502 ! consequence it is assumed that the indices of the current
1503 ! subsystem are contiguous, e.g. if a 2*2 system is solved the
1504 ! last index in w is offset+1 and offset+2 respectively.
1505 !
1506  use constants
1507  use blockpointers, only : nx, ny, nz, il, jl, kl, vol, sfacei&
1510  use inputdiscretization, only : orderturb
1511  use iteration, only : groundlevel
1512  use turbmod, only : secondord
1513  implicit none
1514 !
1515 ! subroutine arguments.
1516 !
1517  integer(kind=inttype), intent(in) :: nadv, madv, offset
1518  real(kind=realtype), dimension(2:il, 2:jl, 2:kl, madv, madv), &
1519 & intent(inout) :: qq
1520 !
1521 ! local variables.
1522 !
1523  integer(kind=inttype) :: i, j, k, ii, jj, kk, iii
1524  real(kind=realtype) :: qs, voli, xa, ya, za
1525  real(kind=realtype) :: uu, dwt, dwtm1, dwtp1, dwti, dwtj, dwtk
1526  real(kind=realtype), dimension(madv) :: impl
1527  intrinsic mod
1528  intrinsic abs
1529  real(kind=realtype) :: abs0
1530  real(kind=realtype) :: abs1
1531  real(kind=realtype) :: abs2
1532  real(kind=realtype) :: abs3
1533  real(kind=realtype) :: abs4
1534  real(kind=realtype) :: abs5
1535  real(kind=realtype) :: abs6
1536  real(kind=realtype) :: abs7
1537  real(kind=realtype) :: abs8
1538  real(kind=realtype) :: abs9
1539  real(kind=realtype) :: abs10
1540  real(kind=realtype) :: abs11
1541  real(kind=realtype) :: abs12
1542  real(kind=realtype) :: abs13
1543  real(kind=realtype) :: abs14
1544  real(kind=realtype) :: abs15
1545  real(kind=realtype) :: abs16
1546  real(kind=realtype) :: abs17
1547  real(kind=realtype) :: abs18
1548  real(kind=realtype) :: abs19
1549  real(kind=realtype) :: abs20
1550  real(kind=realtype) :: abs21
1551  real(kind=realtype) :: abs22
1552  real(kind=realtype) :: abs23
1553 ! determine whether or not a second order discretization for the
1554 ! advective terms must be used.
1555  secondord = .false.
1556  if (groundlevel .eq. 1_inttype .and. orderturb .eq. secondorder) &
1557 & secondord = .true.
1558 !$ad checkpoint-start
1559 ! initialize the grid velocity to zero. this value will be used
1560 ! if the block is not moving.
1561  qs = zero
1562 !$ad ii-loop
1563 !
1564 ! upwind discretization of the convective term in k (zeta)
1565 ! direction. either the 1st order upwind or the second order
1566 ! fully upwind interpolation scheme, kappa = -1, is used in
1567 ! combination with the minmod limiter.
1568 ! the possible grid velocity must be taken into account.
1569 !
1570  do iii=0,nx*ny*nz-1
1571  i = mod(iii, nx) + 2
1572  j = mod(iii/nx, ny) + 2
1573  k = iii/(nx*ny) + 2
1574 ! compute the grid velocity if present.
1575 ! it is taken as the average of k and k-1,
1576  voli = half/vol(i, j, k)
1577  if (addgridvelocities) qs = (sfacek(i, j, k)+sfacek(i, j, k-1))*&
1578 & voli
1579 ! compute the normal velocity, where the normal direction
1580 ! is taken as the average of faces k and k-1.
1581  xa = (sk(i, j, k, 1)+sk(i, j, k-1, 1))*voli
1582  ya = (sk(i, j, k, 2)+sk(i, j, k-1, 2))*voli
1583  za = (sk(i, j, k, 3)+sk(i, j, k-1, 3))*voli
1584  uu = xa*w(i, j, k, ivx) + ya*w(i, j, k, ivy) + za*w(i, j, k, ivz) &
1585 & - qs
1586 ! this term has unit: velocity/length
1587 ! determine the situation we are having here, i.e. positive
1588 ! or negative normal velocity.
1589  if (uu .gt. zero) then
1590 !$ad ii-loop
1591 ! velocity has a component in positive k-direction.
1592 ! loop over the number of advection equations.
1593  do ii=1,nadv
1594 ! set the value of jj such that it corresponds to the
1595 ! turbulent entry in w.
1596  jj = ii + offset
1597 ! check whether a first or a second order discretization
1598 ! must be used.
1599  if (secondord) then
1600 ! second order; store the three differences for the
1601 ! discretization of the derivative in k-direction.
1602  dwtm1 = w(i, j, k-1, jj) - w(i, j, k-2, jj)
1603  dwt = w(i, j, k, jj) - w(i, j, k-1, jj)
1604  dwtp1 = w(i, j, k+1, jj) - w(i, j, k, jj)
1605 ! construct the derivative in this cell center. this
1606 ! is the first order upwind derivative with two
1607 ! nonlinear corrections.
1608  dwtk = dwt
1609  if (dwt*dwtp1 .gt. zero) then
1610  if (dwt .ge. 0.) then
1611  abs0 = dwt
1612  else
1613  abs0 = -dwt
1614  end if
1615  if (dwtp1 .ge. 0.) then
1616  abs12 = dwtp1
1617  else
1618  abs12 = -dwtp1
1619  end if
1620  if (abs0 .lt. abs12) then
1621  dwtk = dwtk + half*dwt
1622  else
1623  dwtk = dwtk + half*dwtp1
1624  end if
1625  end if
1626  if (dwt*dwtm1 .gt. zero) then
1627  if (dwt .ge. 0.) then
1628  abs1 = dwt
1629  else
1630  abs1 = -dwt
1631  end if
1632  if (dwtm1 .ge. 0.) then
1633  abs13 = dwtm1
1634  else
1635  abs13 = -dwtm1
1636  end if
1637  if (abs1 .lt. abs13) then
1638  dwtk = dwtk - half*dwt
1639  else
1640  dwtk = dwtk - half*dwtm1
1641  end if
1642  end if
1643  else
1644 ! 1st order upwind scheme.
1645  dwtk = w(i, j, k, jj) - w(i, j, k-1, jj)
1646  end if
1647 ! update the residual. the convective term must be
1648 ! substracted, because it appears on the other side of
1649 ! the equation as the source and viscous terms.
1650 ! uu*dwtk = (v.dot.face_normal)*delta(nutilde)/delta(x)
1651  scratch(i, j, k, idvt+ii-1) = scratch(i, j, k, idvt+ii-1) - uu&
1652 & *dwtk
1653  end do
1654  else
1655 !$ad ii-loop
1656 ! velocity has a component in negative k-direction.
1657 ! loop over the number of advection equations
1658  do ii=1,nadv
1659 ! set the value of jj such that it corresponds to the
1660 ! turbulent entry in w.
1661  jj = ii + offset
1662 ! check whether a first or a second order discretization
1663 ! must be used.
1664  if (secondord) then
1665 ! store the three differences for the discretization of
1666 ! the derivative in k-direction.
1667  dwtm1 = w(i, j, k, jj) - w(i, j, k-1, jj)
1668  dwt = w(i, j, k+1, jj) - w(i, j, k, jj)
1669  dwtp1 = w(i, j, k+2, jj) - w(i, j, k+1, jj)
1670 ! construct the derivative in this cell center. this is
1671 ! the first order upwind derivative with two nonlinear
1672 ! corrections.
1673  dwtk = dwt
1674  if (dwt*dwtp1 .gt. zero) then
1675  if (dwt .ge. 0.) then
1676  abs2 = dwt
1677  else
1678  abs2 = -dwt
1679  end if
1680  if (dwtp1 .ge. 0.) then
1681  abs14 = dwtp1
1682  else
1683  abs14 = -dwtp1
1684  end if
1685  if (abs2 .lt. abs14) then
1686  dwtk = dwtk - half*dwt
1687  else
1688  dwtk = dwtk - half*dwtp1
1689  end if
1690  end if
1691  if (dwt*dwtm1 .gt. zero) then
1692  if (dwt .ge. 0.) then
1693  abs3 = dwt
1694  else
1695  abs3 = -dwt
1696  end if
1697  if (dwtm1 .ge. 0.) then
1698  abs15 = dwtm1
1699  else
1700  abs15 = -dwtm1
1701  end if
1702  if (abs3 .lt. abs15) then
1703  dwtk = dwtk + half*dwt
1704  else
1705  dwtk = dwtk + half*dwtm1
1706  end if
1707  end if
1708  else
1709 ! 1st order upwind scheme.
1710  dwtk = w(i, j, k+1, jj) - w(i, j, k, jj)
1711  end if
1712 ! update the residual. the convective term must be
1713 ! substracted, because it appears on the other side
1714 ! of the equation as the source and viscous terms.
1715  scratch(i, j, k, idvt+ii-1) = scratch(i, j, k, idvt+ii-1) - uu&
1716 & *dwtk
1717 ! update the central jacobian. first the term which is
1718 ! always present, i.e. -uu.
1719  end do
1720  end if
1721  end do
1722 !$ad checkpoint-end
1723 !
1724 ! upwind discretization of the convective term in j (eta)
1725 ! direction. either the 1st order upwind or the second order
1726 ! fully upwind interpolation scheme, kappa = -1, is used in
1727 ! combination with the minmod limiter.
1728 ! the possible grid velocity must be taken into account.
1729 !
1730  continue
1731 !$ad checkpoint-start
1732  qs = zero
1733 !$ad ii-loop
1734  do iii=0,nx*ny*nz-1
1735  i = mod(iii, nx) + 2
1736  j = mod(iii/nx, ny) + 2
1737  k = iii/(nx*ny) + 2
1738 ! compute the grid velocity if present.
1739 ! it is taken as the average of j and j-1,
1740  voli = half/vol(i, j, k)
1741  if (addgridvelocities) qs = (sfacej(i, j, k)+sfacej(i, j-1, k))*&
1742 & voli
1743 ! compute the normal velocity, where the normal direction
1744 ! is taken as the average of faces j and j-1.
1745  xa = (sj(i, j, k, 1)+sj(i, j-1, k, 1))*voli
1746  ya = (sj(i, j, k, 2)+sj(i, j-1, k, 2))*voli
1747  za = (sj(i, j, k, 3)+sj(i, j-1, k, 3))*voli
1748  uu = xa*w(i, j, k, ivx) + ya*w(i, j, k, ivy) + za*w(i, j, k, ivz) &
1749 & - qs
1750 ! determine the situation we are having here, i.e. positive
1751 ! or negative normal velocity.
1752  if (uu .gt. zero) then
1753 !$ad ii-loop
1754 ! velocity has a component in positive j-direction.
1755 ! loop over the number of advection equations.
1756  do ii=1,nadv
1757 ! set the value of jj such that it corresponds to the
1758 ! turbulent entry in w.
1759  jj = ii + offset
1760 ! check whether a first or a second order discretization
1761 ! must be used.
1762  if (secondord) then
1763 ! second order; store the three differences for the
1764 ! discretization of the derivative in j-direction.
1765  dwtm1 = w(i, j-1, k, jj) - w(i, j-2, k, jj)
1766  dwt = w(i, j, k, jj) - w(i, j-1, k, jj)
1767  dwtp1 = w(i, j+1, k, jj) - w(i, j, k, jj)
1768 ! construct the derivative in this cell center. this is
1769 ! the first order upwind derivative with two nonlinear
1770 ! corrections.
1771  dwtj = dwt
1772  if (dwt*dwtp1 .gt. zero) then
1773  if (dwt .ge. 0.) then
1774  abs4 = dwt
1775  else
1776  abs4 = -dwt
1777  end if
1778  if (dwtp1 .ge. 0.) then
1779  abs16 = dwtp1
1780  else
1781  abs16 = -dwtp1
1782  end if
1783  if (abs4 .lt. abs16) then
1784  dwtj = dwtj + half*dwt
1785  else
1786  dwtj = dwtj + half*dwtp1
1787  end if
1788  end if
1789  if (dwt*dwtm1 .gt. zero) then
1790  if (dwt .ge. 0.) then
1791  abs5 = dwt
1792  else
1793  abs5 = -dwt
1794  end if
1795  if (dwtm1 .ge. 0.) then
1796  abs17 = dwtm1
1797  else
1798  abs17 = -dwtm1
1799  end if
1800  if (abs5 .lt. abs17) then
1801  dwtj = dwtj - half*dwt
1802  else
1803  dwtj = dwtj - half*dwtm1
1804  end if
1805  end if
1806  else
1807 ! 1st order upwind scheme.
1808  dwtj = w(i, j, k, jj) - w(i, j-1, k, jj)
1809  end if
1810 ! update the residual. the convective term must be
1811 ! substracted, because it appears on the other side of
1812 ! the equation as the source and viscous terms.
1813  scratch(i, j, k, idvt+ii-1) = scratch(i, j, k, idvt+ii-1) - uu&
1814 & *dwtj
1815 ! update the central jacobian. first the term which is
1816 ! always present, i.e. uu.
1817  end do
1818  else
1819 !$ad ii-loop
1820 ! velocity has a component in negative j-direction.
1821 ! loop over the number of advection equations.
1822  do ii=1,nadv
1823 ! set the value of jj such that it corresponds to the
1824 ! turbulent entry in w.
1825  jj = ii + offset
1826 ! check whether a first or a second order discretization
1827 ! must be used.
1828  if (secondord) then
1829 ! store the three differences for the discretization of
1830 ! the derivative in j-direction.
1831  dwtm1 = w(i, j, k, jj) - w(i, j-1, k, jj)
1832  dwt = w(i, j+1, k, jj) - w(i, j, k, jj)
1833  dwtp1 = w(i, j+2, k, jj) - w(i, j+1, k, jj)
1834 ! construct the derivative in this cell center. this is
1835 ! the first order upwind derivative with two nonlinear
1836 ! corrections.
1837  dwtj = dwt
1838  if (dwt*dwtp1 .gt. zero) then
1839  if (dwt .ge. 0.) then
1840  abs6 = dwt
1841  else
1842  abs6 = -dwt
1843  end if
1844  if (dwtp1 .ge. 0.) then
1845  abs18 = dwtp1
1846  else
1847  abs18 = -dwtp1
1848  end if
1849  if (abs6 .lt. abs18) then
1850  dwtj = dwtj - half*dwt
1851  else
1852  dwtj = dwtj - half*dwtp1
1853  end if
1854  end if
1855  if (dwt*dwtm1 .gt. zero) then
1856  if (dwt .ge. 0.) then
1857  abs7 = dwt
1858  else
1859  abs7 = -dwt
1860  end if
1861  if (dwtm1 .ge. 0.) then
1862  abs19 = dwtm1
1863  else
1864  abs19 = -dwtm1
1865  end if
1866  if (abs7 .lt. abs19) then
1867  dwtj = dwtj + half*dwt
1868  else
1869  dwtj = dwtj + half*dwtm1
1870  end if
1871  end if
1872  else
1873 ! 1st order upwind scheme.
1874  dwtj = w(i, j+1, k, jj) - w(i, j, k, jj)
1875  end if
1876 ! update the residual. the convective term must be
1877 ! substracted, because it appears on the other side
1878 ! of the equation as the source and viscous terms.
1879  scratch(i, j, k, idvt+ii-1) = scratch(i, j, k, idvt+ii-1) - uu&
1880 & *dwtj
1881 ! update the central jacobian. first the term which is
1882 ! always present, i.e. -uu.
1883  end do
1884  end if
1885  end do
1886 !$ad checkpoint-end
1887 !
1888 ! upwind discretization of the convective term in i (xi)
1889 ! direction. either the 1st order upwind or the second order
1890 ! fully upwind interpolation scheme, kappa = -1, is used in
1891 ! combination with the minmod limiter.
1892 ! the possible grid velocity must be taken into account.
1893 !
1894  continue
1895 !$ad checkpoint-start
1896  qs = zero
1897 !$ad ii-loop
1898  do iii=0,nx*ny*nz-1
1899  i = mod(iii, nx) + 2
1900  j = mod(iii/nx, ny) + 2
1901  k = iii/(nx*ny) + 2
1902 ! compute the grid velocity if present.
1903 ! it is taken as the average of i and i-1,
1904  voli = half/vol(i, j, k)
1905  if (addgridvelocities) qs = (sfacei(i, j, k)+sfacei(i-1, j, k))*&
1906 & voli
1907 ! compute the normal velocity, where the normal direction
1908 ! is taken as the average of faces i and i-1.
1909  xa = (si(i, j, k, 1)+si(i-1, j, k, 1))*voli
1910  ya = (si(i, j, k, 2)+si(i-1, j, k, 2))*voli
1911  za = (si(i, j, k, 3)+si(i-1, j, k, 3))*voli
1912  uu = xa*w(i, j, k, ivx) + ya*w(i, j, k, ivy) + za*w(i, j, k, ivz) &
1913 & - qs
1914 ! determine the situation we are having here, i.e. positive
1915 ! or negative normal velocity.
1916  if (uu .gt. zero) then
1917 !$ad ii-loop
1918 ! velocity has a component in positive i-direction.
1919 ! loop over the number of advection equations.
1920  do ii=1,nadv
1921 ! set the value of jj such that it corresponds to the
1922 ! turbulent entry in w.
1923  jj = ii + offset
1924 ! check whether a first or a second order discretization
1925 ! must be used.
1926  if (secondord) then
1927 ! second order; store the three differences for the
1928 ! discretization of the derivative in i-direction.
1929  dwtm1 = w(i-1, j, k, jj) - w(i-2, j, k, jj)
1930  dwt = w(i, j, k, jj) - w(i-1, j, k, jj)
1931  dwtp1 = w(i+1, j, k, jj) - w(i, j, k, jj)
1932 ! construct the derivative in this cell center. this is
1933 ! the first order upwind derivative with two nonlinear
1934 ! corrections.
1935  dwti = dwt
1936  if (dwt*dwtp1 .gt. zero) then
1937  if (dwt .ge. 0.) then
1938  abs8 = dwt
1939  else
1940  abs8 = -dwt
1941  end if
1942  if (dwtp1 .ge. 0.) then
1943  abs20 = dwtp1
1944  else
1945  abs20 = -dwtp1
1946  end if
1947  if (abs8 .lt. abs20) then
1948  dwti = dwti + half*dwt
1949  else
1950  dwti = dwti + half*dwtp1
1951  end if
1952  end if
1953  if (dwt*dwtm1 .gt. zero) then
1954  if (dwt .ge. 0.) then
1955  abs9 = dwt
1956  else
1957  abs9 = -dwt
1958  end if
1959  if (dwtm1 .ge. 0.) then
1960  abs21 = dwtm1
1961  else
1962  abs21 = -dwtm1
1963  end if
1964  if (abs9 .lt. abs21) then
1965  dwti = dwti - half*dwt
1966  else
1967  dwti = dwti - half*dwtm1
1968  end if
1969  end if
1970  else
1971 ! 1st order upwind scheme.
1972  dwti = w(i, j, k, jj) - w(i-1, j, k, jj)
1973  end if
1974 ! update the residual. the convective term must be
1975 ! substracted, because it appears on the other side of
1976 ! the equation as the source and viscous terms.
1977  scratch(i, j, k, idvt+ii-1) = scratch(i, j, k, idvt+ii-1) - uu&
1978 & *dwti
1979 ! update the central jacobian. first the term which is
1980 ! always present, i.e. uu.
1981  end do
1982  else
1983 !$ad ii-loop
1984 ! velocity has a component in negative i-direction.
1985 ! loop over the number of advection equations.
1986  do ii=1,nadv
1987 ! set the value of jj such that it corresponds to the
1988 ! turbulent entry in w.
1989  jj = ii + offset
1990 ! check whether a first or a second order discretization
1991 ! must be used.
1992  if (secondord) then
1993 ! second order; store the three differences for the
1994 ! discretization of the derivative in i-direction.
1995  dwtm1 = w(i, j, k, jj) - w(i-1, j, k, jj)
1996  dwt = w(i+1, j, k, jj) - w(i, j, k, jj)
1997  dwtp1 = w(i+2, j, k, jj) - w(i+1, j, k, jj)
1998 ! construct the derivative in this cell center. this is
1999 ! the first order upwind derivative with two nonlinear
2000 ! corrections.
2001  dwti = dwt
2002  if (dwt*dwtp1 .gt. zero) then
2003  if (dwt .ge. 0.) then
2004  abs10 = dwt
2005  else
2006  abs10 = -dwt
2007  end if
2008  if (dwtp1 .ge. 0.) then
2009  abs22 = dwtp1
2010  else
2011  abs22 = -dwtp1
2012  end if
2013  if (abs10 .lt. abs22) then
2014  dwti = dwti - half*dwt
2015  else
2016  dwti = dwti - half*dwtp1
2017  end if
2018  end if
2019  if (dwt*dwtm1 .gt. zero) then
2020  if (dwt .ge. 0.) then
2021  abs11 = dwt
2022  else
2023  abs11 = -dwt
2024  end if
2025  if (dwtm1 .ge. 0.) then
2026  abs23 = dwtm1
2027  else
2028  abs23 = -dwtm1
2029  end if
2030  if (abs11 .lt. abs23) then
2031  dwti = dwti + half*dwt
2032  else
2033  dwti = dwti + half*dwtm1
2034  end if
2035  end if
2036  else
2037 ! 1st order upwind scheme.
2038  dwti = w(i+1, j, k, jj) - w(i, j, k, jj)
2039  end if
2040 ! update the residual. the convective term must be
2041 ! substracted, because it appears on the other side
2042 ! of the equation as the source and viscous terms.
2043  scratch(i, j, k, idvt+ii-1) = scratch(i, j, k, idvt+ii-1) - uu&
2044 & *dwti
2045 ! update the central jacobian. first the term which is
2046 ! always present, i.e. -uu.
2047  end do
2048  end if
2049  end do
2050 !$ad checkpoint-end
2051 
2052  end subroutine turbadvection
2053 ! ----------------------------------------------------------------------
2054 ! |
2055 ! no tapenade routine below this line |
2056 ! |
2057 ! ----------------------------------------------------------------------
2058 
2059 end module turbutils_fast_b
2060 
real(kind=realtype), dimension(:, :, :, :), pointer bmtk2
real(kind=realtype), dimension(:, :, :), pointer sfacek
logical addgridvelocities
integer(kind=inttype) jl
real(kind=realtype), dimension(:, :, :, :), pointer bmti1
real(kind=realtype), dimension(:, :, :, :), pointer wd
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 rlv
real(kind=realtype), dimension(:, :, :, :), pointer si
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
integer(kind=inttype) ke
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 saeddyviscosity(ibeg, iend, jbeg, jend, kbeg, kend)
subroutine prodkatolaunder()
subroutine unsteadyturbterm(madv, nadv, offset, qq)
subroutine kweddyviscosity(ibeg, iend, jbeg, jend, kbeg, kend)
subroutine saeddyviscosity_fast_b(ibeg, iend, jbeg, jend, kbeg, kend)
subroutine turbadvection_fast_b(madv, nadv, offset, qq)
subroutine turbadvection(madv, nadv, offset, qq)
real(kind=realtype) function sanuknowneddyratio(eddyratio, nulam)
subroutine prodwmag2()
subroutine computeeddyviscosity(includehalos)
subroutine ssteddyviscosity(ibeg, iend, jbeg, jend, kbeg, kend)
subroutine prodsmag2()