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