ADflow  v1.0
ADflow is a finite volume RANS solver tailored for gradient-based aerodynamic design optimization.
sa_b.f90
Go to the documentation of this file.
1 ! generated by tapenade (inria, ecuador team)
2 ! tapenade 3.16 (develop) - 22 aug 2023 15:51
3 !
4 ! this module contains the source code related to the sa turbulence
5 ! model. it is slightly more modularized than the original which makes
6 ! performing reverse mode ad simplier.
7 module sa_b
8  use constants
9  implicit none
10  real(kind=realtype) :: cv13, kar2inv, cw36, cb3inv
11  real(kind=realtype), dimension(:, :, :), allocatable :: qq
12  real(kind=realtype), dimension(:, :, :), pointer :: ddw, ww, ddvt
13  real(kind=realtype), dimension(:, :), pointer :: rrlv
14  real(kind=realtype), dimension(:, :), pointer :: dd2wall
15 
16 contains
17 ! differentiation of sasource in reverse (adjoint) mode (with options noisize i4 dr8 r8):
18 ! gradient of useful results: timeref *w *rlv *scratch *vol
19 ! *si *sj *sk
20 ! with respect to varying inputs: timeref *w *rlv *scratch *vol
21 ! *d2wall *si *sj *sk
22 ! rw status of diff variables: timeref:incr *w:incr *rlv:incr
23 ! *scratch:in-out *vol:incr *d2wall:out *si:incr
24 ! *sj:incr *sk:incr
25 ! plus diff mem management of: w:in rlv:in scratch:in vol:in
26 ! d2wall:in si:in sj:in sk:in
27  subroutine sasource_b()
28 !
29 ! source terms.
30 ! determine the source term and its derivative w.r.t. nutilde
31 ! for all internal cells of the block.
32 ! remember that the sa field variable nutilde = w(i,j,k,itu1)
33  use blockpointers
34  use constants
35  use paramturb
36  use section
37  use inputphysics
38  use inputdiscretization, only : approxsa
39  use flowvarrefstate
40  implicit none
41 ! local parameters
42  real(kind=realtype), parameter :: f23=two*third
43 ! local variables.
44  integer(kind=inttype) :: i, j, k, nn, ii
45  real(kind=realtype) :: fv1, fv2, ft2
46  real(kind=realtype) :: fv1d, fv2d, ft2d
47  real(kind=realtype) :: ss, sst, nu, dist2inv, chi, chi2, chi3
48  real(kind=realtype) :: ssd, sstd, nud, dist2invd, chid, chi2d, chi3d
49  real(kind=realtype) :: rr, gg, gg6, termfw, fwsa, term1, term2
50  real(kind=realtype) :: rrd, ggd, gg6d, termfwd, fwsad, term1d, &
51 & term2d
52  real(kind=realtype) :: dfv1, dfv2, dft2, drr, dgg, dfw
53  real(kind=realtype) :: uux, uuy, uuz, vvx, vvy, vvz, wwx, wwy, wwz
54  real(kind=realtype) :: uuxd, uuyd, uuzd, vvxd, vvyd, vvzd, wwxd, &
55 & wwyd, wwzd
56  real(kind=realtype) :: div2, fact, sxx, syy, szz, sxy, sxz, syz
57  real(kind=realtype) :: div2d, factd, sxxd, syyd, szzd, sxyd, sxzd, &
58 & syzd
59  real(kind=realtype) :: vortx, vorty, vortz
60  real(kind=realtype) :: vortxd, vortyd, vortzd
61  real(kind=realtype) :: omegax, omegay, omegaz
62  real(kind=realtype) :: omegaxd, omegayd, omegazd
63  real(kind=realtype) :: strainmag2, strainprod, vortprod
64  real(kind=realtype) :: strainmag2d, strainprodd, vortprodd
65  real(kind=realtype), parameter :: xminn=1.e-10_realtype
66  intrinsic mod
67  intrinsic sqrt
68  intrinsic exp
69  intrinsic min
70  intrinsic max
71  real(kind=realtype) :: y1
72  real(kind=realtype) :: y1d
73  real(kind=realtype) :: min1
74  real(kind=realtype) :: min1d
75  real(kind=realtype) :: temp
76  real(kind=realtype) :: tempd
77  real(kind=realtype) :: temp0
78  real(kind=realtype) :: tempd0
79  integer :: branch
80 ! set model constants
81  cv13 = rsacv1**3
82  kar2inv = one/rsak**2
83  cw36 = rsacw3**6
84 ! determine the non-dimensional wheel speed of this block.
85  omegax = timeref*sections(sectionid)%rotrate(1)
86  omegay = timeref*sections(sectionid)%rotrate(2)
87  omegaz = timeref*sections(sectionid)%rotrate(3)
88 ! create switches to production term depending on the variable that
89 ! should be used
90  if (turbprod .eq. katolaunder) then
91  stop
92  else
93  if (associated(d2walld)) d2walld = 0.0_8
94  omegaxd = 0.0_8
95  omegayd = 0.0_8
96  omegazd = 0.0_8
97  strainmag2d = 0.0_8
98  ssd = 0.0_8
99 !$bwd-of ii-loop
100  do ii=0,nx*ny*nz-1
101  i = mod(ii, nx) + 2
102  j = mod(ii/nx, ny) + 2
103  k = ii/(nx*ny) + 2
104 ! compute the gradient of u in the cell center. use is made
105 ! of the fact that the surrounding normals sum up to zero,
106 ! such that the cell i,j,k does not give a contribution.
107 ! the gradient is scaled by the factor 2*vol.
108  uux = w(i+1, j, k, ivx)*si(i, j, k, 1) - w(i-1, j, k, ivx)*si(i-&
109 & 1, j, k, 1) + w(i, j+1, k, ivx)*sj(i, j, k, 1) - w(i, j-1, k, &
110 & ivx)*sj(i, j-1, k, 1) + w(i, j, k+1, ivx)*sk(i, j, k, 1) - w(i&
111 & , j, k-1, ivx)*sk(i, j, k-1, 1)
112  uuy = w(i+1, j, k, ivx)*si(i, j, k, 2) - w(i-1, j, k, ivx)*si(i-&
113 & 1, j, k, 2) + w(i, j+1, k, ivx)*sj(i, j, k, 2) - w(i, j-1, k, &
114 & ivx)*sj(i, j-1, k, 2) + w(i, j, k+1, ivx)*sk(i, j, k, 2) - w(i&
115 & , j, k-1, ivx)*sk(i, j, k-1, 2)
116  uuz = w(i+1, j, k, ivx)*si(i, j, k, 3) - w(i-1, j, k, ivx)*si(i-&
117 & 1, j, k, 3) + w(i, j+1, k, ivx)*sj(i, j, k, 3) - w(i, j-1, k, &
118 & ivx)*sj(i, j-1, k, 3) + w(i, j, k+1, ivx)*sk(i, j, k, 3) - w(i&
119 & , j, k-1, ivx)*sk(i, j, k-1, 3)
120 ! idem for the gradient of v.
121  vvx = w(i+1, j, k, ivy)*si(i, j, k, 1) - w(i-1, j, k, ivy)*si(i-&
122 & 1, j, k, 1) + w(i, j+1, k, ivy)*sj(i, j, k, 1) - w(i, j-1, k, &
123 & ivy)*sj(i, j-1, k, 1) + w(i, j, k+1, ivy)*sk(i, j, k, 1) - w(i&
124 & , j, k-1, ivy)*sk(i, j, k-1, 1)
125  vvy = w(i+1, j, k, ivy)*si(i, j, k, 2) - w(i-1, j, k, ivy)*si(i-&
126 & 1, j, k, 2) + w(i, j+1, k, ivy)*sj(i, j, k, 2) - w(i, j-1, k, &
127 & ivy)*sj(i, j-1, k, 2) + w(i, j, k+1, ivy)*sk(i, j, k, 2) - w(i&
128 & , j, k-1, ivy)*sk(i, j, k-1, 2)
129  vvz = w(i+1, j, k, ivy)*si(i, j, k, 3) - w(i-1, j, k, ivy)*si(i-&
130 & 1, j, k, 3) + w(i, j+1, k, ivy)*sj(i, j, k, 3) - w(i, j-1, k, &
131 & ivy)*sj(i, j-1, k, 3) + w(i, j, k+1, ivy)*sk(i, j, k, 3) - w(i&
132 & , j, k-1, ivy)*sk(i, j, k-1, 3)
133 ! and for the gradient of w.
134  wwx = w(i+1, j, k, ivz)*si(i, j, k, 1) - w(i-1, j, k, ivz)*si(i-&
135 & 1, j, k, 1) + w(i, j+1, k, ivz)*sj(i, j, k, 1) - w(i, j-1, k, &
136 & ivz)*sj(i, j-1, k, 1) + w(i, j, k+1, ivz)*sk(i, j, k, 1) - w(i&
137 & , j, k-1, ivz)*sk(i, j, k-1, 1)
138  wwy = w(i+1, j, k, ivz)*si(i, j, k, 2) - w(i-1, j, k, ivz)*si(i-&
139 & 1, j, k, 2) + w(i, j+1, k, ivz)*sj(i, j, k, 2) - w(i, j-1, k, &
140 & ivz)*sj(i, j-1, k, 2) + w(i, j, k+1, ivz)*sk(i, j, k, 2) - w(i&
141 & , j, k-1, ivz)*sk(i, j, k-1, 2)
142  wwz = w(i+1, j, k, ivz)*si(i, j, k, 3) - w(i-1, j, k, ivz)*si(i-&
143 & 1, j, k, 3) + w(i, j+1, k, ivz)*sj(i, j, k, 3) - w(i, j-1, k, &
144 & ivz)*sj(i, j-1, k, 3) + w(i, j, k+1, ivz)*sk(i, j, k, 3) - w(i&
145 & , j, k-1, ivz)*sk(i, j, k-1, 3)
146 ! compute the components of the stress tensor.
147 ! the combination of the current scaling of the velocity
148 ! gradients (2*vol) and the definition of the stress tensor,
149 ! leads to the factor 1/(4*vol).
150  fact = fourth/vol(i, j, k)
151  if (turbprod .eq. strain) then
152  sxx = two*fact*uux
153  syy = two*fact*vvy
154  szz = two*fact*wwz
155  sxy = fact*(uuy+vvx)
156  sxz = fact*(uuz+wwx)
157  syz = fact*(vvz+wwy)
158 ! compute 2/3 * divergence of velocity squared
159  div2 = f23*(sxx+syy+szz)**2
160 ! compute strain production term
161  strainmag2 = two*(sxy**2+sxz**2+syz**2) + sxx**2 + syy**2 + &
162 & szz**2
163  strainprod = two*strainmag2 - div2
164  ss = sqrt(strainprod)
165  call pushcontrol2b(0)
166  else if (turbprod .eq. vorticity) then
167 ! compute the three components of the vorticity vector.
168 ! substract the part coming from the rotating frame.
169  vortx = two*fact*(wwy-vvz) - two*omegax
170  vorty = two*fact*(uuz-wwx) - two*omegay
171  vortz = two*fact*(vvx-uuy) - two*omegaz
172 ! compute the vorticity production term
173  vortprod = vortx**2 + vorty**2 + vortz**2
174 ! first take the square root of the production term to
175 ! obtain the correct production term for spalart-allmaras.
176 ! we do this to avoid if statements.
177  ss = sqrt(vortprod)
178  call pushcontrol2b(1)
179  else
180  call pushcontrol2b(2)
181  end if
182 ! compute the laminar kinematic viscosity, the inverse of
183 ! wall distance squared, the ratio chi (ratio of nutilde
184 ! and nu) and the functions fv1 and fv2. the latter corrects
185 ! the production term near a viscous wall.
186  nu = rlv(i, j, k)/w(i, j, k, irho)
187  dist2inv = one/d2wall(i, j, k)**2
188  chi = w(i, j, k, itu1)/nu
189  chi2 = chi*chi
190  chi3 = chi*chi2
191  fv1 = chi3/(chi3+cv13)
192  fv2 = one - chi/(one+chi*fv1)
193 ! the function ft2, which is designed to keep a laminar
194 ! solution laminar. when running in fully turbulent mode
195 ! this function should be set to 0.0.
196  if (useft2sa) then
197  ft2 = rsact3*exp(-(rsact4*chi2))
198  call pushcontrol1b(0)
199  else
200  ft2 = zero
201  call pushcontrol1b(1)
202  end if
203 ! correct the production term to account for the influence
204 ! of the wall.
205  sst = ss + w(i, j, k, itu1)*fv2*kar2inv*dist2inv
206 ! add rotation term (userotationsa defined in inputparams.f90)
207  if (userotationsa) then
208  y1 = sqrt(two*strainmag2)
209  if (zero .gt. y1) then
210  min1 = y1
211  call pushcontrol1b(0)
212  else
213  min1 = zero
214  call pushcontrol1b(1)
215  end if
216  sst = sst + rsacrot*min1
217  call pushcontrol1b(1)
218  else
219  call pushcontrol1b(0)
220  end if
221  if (sst .lt. xminn) then
222  sst = xminn
223  call pushcontrol1b(0)
224  else
225  call pushcontrol1b(1)
226  sst = sst
227  end if
228 ! compute the function fw. the argument rr is cut off at 10
229 ! to avoid numerical problems. this is ok, because the
230 ! asymptotical value of fw is then already reached.
231  rr = w(i, j, k, itu1)*kar2inv*dist2inv/sst
232  if (rr .gt. 10.0_realtype) then
233  rr = 10.0_realtype
234  call pushcontrol1b(0)
235  else
236  call pushcontrol1b(1)
237  rr = rr
238  end if
239  gg = rr + rsacw2*(rr**6-rr)
240  gg6 = gg**6
241  termfw = ((one+cw36)/(gg6+cw36))**sixth
242  fwsa = gg*termfw
243 ! compute the source term; some terms are saved for the
244 ! linearization. the source term is stored in dvt.
245  if (approxsa) then
246  call pushcontrol1b(0)
247  term1 = zero
248  else
249  term1 = rsacb1*(one-ft2)*ss
250  call pushcontrol1b(1)
251  end if
252  term2 = dist2inv*(kar2inv*rsacb1*((one-ft2)*fv2+ft2)-rsacw1*fwsa&
253 & )
254  temp = w(i, j, k, itu1)
255  tempd0 = w(i, j, k, itu1)*scratchd(i, j, k, idvt)
256  wd(i, j, k, itu1) = wd(i, j, k, itu1) + (term1+term2*temp)*&
257 & scratchd(i, j, k, idvt) + term2*tempd0
258  scratchd(i, j, k, idvt) = 0.0_8
259  term1d = tempd0
260  term2d = temp*tempd0
261  dist2invd = (kar2inv*rsacb1*((one-ft2)*fv2+ft2)-rsacw1*fwsa)*&
262 & term2d
263  tempd0 = kar2inv*rsacb1*dist2inv*term2d
264  fwsad = -(rsacw1*dist2inv*term2d)
265  ft2d = (1.0-fv2)*tempd0
266  fv2d = (one-ft2)*tempd0
267  call popcontrol1b(branch)
268  if (branch .ne. 0) then
269  ft2d = ft2d - ss*rsacb1*term1d
270  ssd = ssd + (one-ft2)*rsacb1*term1d
271  end if
272  termfwd = gg*fwsad
273  temp0 = (one+cw36)/(cw36+gg6)
274  if (temp0 .le. 0.0_8 .and. (sixth .eq. 0.0_8 .or. sixth .ne. int&
275 & (sixth))) then
276  gg6d = 0.0_8
277  else
278  gg6d = -(temp0*sixth*temp0**(sixth-1)*termfwd/(cw36+gg6))
279  end if
280  ggd = termfw*fwsad + 6*gg**5*gg6d
281  rrd = (6*rr**5*rsacw2-rsacw2+1.0)*ggd
282  call popcontrol1b(branch)
283  if (branch .eq. 0) rrd = 0.0_8
284  wd(i, j, k, itu1) = wd(i, j, k, itu1) + dist2inv*kar2inv*rrd/sst
285  tempd0 = w(i, j, k, itu1)*kar2inv*rrd/sst
286  dist2invd = dist2invd + tempd0
287  sstd = -(dist2inv*tempd0/sst)
288  call popcontrol1b(branch)
289  if (branch .eq. 0) sstd = 0.0_8
290  call popcontrol1b(branch)
291  if (branch .ne. 0) then
292  min1d = rsacrot*sstd
293  call popcontrol1b(branch)
294  if (branch .eq. 0) then
295  y1d = min1d
296  else
297  y1d = 0.0_8
298  end if
299  if (.not.two*strainmag2 .eq. 0.0_8) strainmag2d = strainmag2d &
300 & + two*y1d/(2.0*sqrt(two*strainmag2))
301  end if
302  ssd = ssd + sstd
303  wd(i, j, k, itu1) = wd(i, j, k, itu1) + fv2*dist2inv*kar2inv*&
304 & sstd
305  tempd0 = w(i, j, k, itu1)*kar2inv*sstd
306  fv2d = fv2d + dist2inv*tempd0
307  dist2invd = dist2invd + fv2*tempd0
308  call popcontrol1b(branch)
309  if (branch .eq. 0) then
310  chi2d = -(rsact4*exp(-(rsact4*chi2))*rsact3*ft2d)
311  else
312  chi2d = 0.0_8
313  end if
314  tempd = -(fv2d/(one+chi*fv1))
315  chid = tempd
316  tempd0 = -(chi*tempd/(one+chi*fv1))
317  fv1d = chi*tempd0
318  tempd = fv1d/(cv13+chi3)
319  chi3d = (1.0-chi3/(cv13+chi3))*tempd
320  chi2d = chi2d + chi*chi3d
321  chid = chid + fv1*tempd0 + chi2*chi3d + 2*chi*chi2d
322  wd(i, j, k, itu1) = wd(i, j, k, itu1) + chid/nu
323  nud = -(w(i, j, k, itu1)*chid/nu**2)
324  temp = d2wall(i, j, k)
325  d2walld(i, j, k) = d2walld(i, j, k) - 2*one*dist2invd/temp**3
326  temp = w(i, j, k, irho)
327  rlvd(i, j, k) = rlvd(i, j, k) + nud/temp
328  wd(i, j, k, irho) = wd(i, j, k, irho) - rlv(i, j, k)*nud/temp**2
329  call popcontrol2b(branch)
330  if (branch .eq. 0) then
331  if (strainprod .eq. 0.0_8) then
332  strainprodd = 0.0_8
333  else
334  strainprodd = ssd/(2.0*sqrt(strainprod))
335  end if
336  strainmag2d = strainmag2d + two*strainprodd
337  div2d = -strainprodd
338  tempd = two*strainmag2d
339  sxyd = 2*sxy*tempd
340  sxzd = 2*sxz*tempd
341  syzd = 2*syz*tempd
342  tempd = 2*(sxx+syy+szz)*f23*div2d
343  sxxd = 2*sxx*strainmag2d + tempd
344  syyd = 2*syy*strainmag2d + tempd
345  szzd = 2*szz*strainmag2d + tempd
346  factd = (vvz+wwy)*syzd + (uuz+wwx)*sxzd + (uuy+vvx)*sxyd + wwz&
347 & *two*szzd + vvy*two*syyd + uux*two*sxxd
348  vvzd = fact*syzd
349  wwyd = fact*syzd
350  uuzd = fact*sxzd
351  wwxd = fact*sxzd
352  uuyd = fact*sxyd
353  vvxd = fact*sxyd
354  wwzd = fact*two*szzd
355  vvyd = fact*two*syyd
356  uuxd = fact*two*sxxd
357  strainmag2d = 0.0_8
358  ssd = 0.0_8
359  else
360  if (branch .eq. 1) then
361  if (vortprod .eq. 0.0_8) then
362  vortprodd = 0.0_8
363  else
364  vortprodd = ssd/(2.0*sqrt(vortprod))
365  end if
366  vortxd = 2*vortx*vortprodd
367  vortyd = 2*vorty*vortprodd
368  vortzd = 2*vortz*vortprodd
369  tempd = two*vortzd
370  omegazd = omegazd - two*vortzd
371  factd = (vvx-uuy)*tempd
372  vvxd = fact*tempd
373  uuyd = -(fact*tempd)
374  tempd = two*vortyd
375  omegayd = omegayd - two*vortyd
376  factd = factd + (uuz-wwx)*tempd
377  uuzd = fact*tempd
378  wwxd = -(fact*tempd)
379  tempd = two*vortxd
380  omegaxd = omegaxd - two*vortxd
381  factd = factd + (wwy-vvz)*tempd
382  wwyd = fact*tempd
383  vvzd = -(fact*tempd)
384  ssd = 0.0_8
385  else
386  wwxd = 0.0_8
387  wwyd = 0.0_8
388  vvxd = 0.0_8
389  vvzd = 0.0_8
390  factd = 0.0_8
391  uuyd = 0.0_8
392  uuzd = 0.0_8
393  end if
394  wwzd = 0.0_8
395  vvyd = 0.0_8
396  uuxd = 0.0_8
397  end if
398  wd(i, j, k-1, ivz) = wd(i, j, k-1, ivz) - sk(i, j, k-1, 3)*wwzd &
399 & - sk(i, j, k-1, 2)*wwyd - sk(i, j, k-1, 1)*wwxd
400  wd(i, j-1, k, ivz) = wd(i, j-1, k, ivz) - sj(i, j-1, k, 3)*wwzd &
401 & - sj(i, j-1, k, 2)*wwyd - sj(i, j-1, k, 1)*wwxd
402  wd(i, j, k+1, ivz) = wd(i, j, k+1, ivz) + sk(i, j, k, 3)*wwzd + &
403 & sk(i, j, k, 2)*wwyd + sk(i, j, k, 1)*wwxd
404  wd(i, j+1, k, ivz) = wd(i, j+1, k, ivz) + sj(i, j, k, 3)*wwzd + &
405 & sj(i, j, k, 2)*wwyd + sj(i, j, k, 1)*wwxd
406  wd(i-1, j, k, ivz) = wd(i-1, j, k, ivz) - si(i-1, j, k, 3)*wwzd &
407 & - si(i-1, j, k, 2)*wwyd - si(i-1, j, k, 1)*wwxd
408  vold(i, j, k) = vold(i, j, k) - fourth*factd/vol(i, j, k)**2
409  wd(i+1, j, k, ivz) = wd(i+1, j, k, ivz) + si(i, j, k, 3)*wwzd + &
410 & si(i, j, k, 2)*wwyd + si(i, j, k, 1)*wwxd
411  sid(i, j, k, 3) = sid(i, j, k, 3) + w(i+1, j, k, ivz)*wwzd
412  sid(i-1, j, k, 3) = sid(i-1, j, k, 3) - w(i-1, j, k, ivz)*wwzd
413  sjd(i, j, k, 3) = sjd(i, j, k, 3) + w(i, j+1, k, ivz)*wwzd
414  skd(i, j, k, 3) = skd(i, j, k, 3) + w(i, j, k+1, ivz)*wwzd
415  sjd(i, j-1, k, 3) = sjd(i, j-1, k, 3) - w(i, j-1, k, ivz)*wwzd
416  skd(i, j, k-1, 3) = skd(i, j, k-1, 3) - w(i, j, k-1, ivz)*wwzd
417  sid(i, j, k, 2) = sid(i, j, k, 2) + w(i+1, j, k, ivz)*wwyd
418  sid(i-1, j, k, 2) = sid(i-1, j, k, 2) - w(i-1, j, k, ivz)*wwyd
419  sjd(i, j, k, 2) = sjd(i, j, k, 2) + w(i, j+1, k, ivz)*wwyd
420  skd(i, j, k, 2) = skd(i, j, k, 2) + w(i, j, k+1, ivz)*wwyd
421  sjd(i, j-1, k, 2) = sjd(i, j-1, k, 2) - w(i, j-1, k, ivz)*wwyd
422  skd(i, j, k-1, 2) = skd(i, j, k-1, 2) - w(i, j, k-1, ivz)*wwyd
423  sid(i, j, k, 1) = sid(i, j, k, 1) + w(i+1, j, k, ivz)*wwxd
424  sid(i-1, j, k, 1) = sid(i-1, j, k, 1) - w(i-1, j, k, ivz)*wwxd
425  sjd(i, j, k, 1) = sjd(i, j, k, 1) + w(i, j+1, k, ivz)*wwxd
426  skd(i, j, k, 1) = skd(i, j, k, 1) + w(i, j, k+1, ivz)*wwxd
427  sjd(i, j-1, k, 1) = sjd(i, j-1, k, 1) - w(i, j-1, k, ivz)*wwxd
428  skd(i, j, k-1, 1) = skd(i, j, k-1, 1) - w(i, j, k-1, ivz)*wwxd
429  sid(i, j, k, 3) = sid(i, j, k, 3) + w(i+1, j, k, ivy)*vvzd
430  sid(i-1, j, k, 3) = sid(i-1, j, k, 3) - w(i-1, j, k, ivy)*vvzd
431  sjd(i, j, k, 3) = sjd(i, j, k, 3) + w(i, j+1, k, ivy)*vvzd
432  skd(i, j, k, 3) = skd(i, j, k, 3) + w(i, j, k+1, ivy)*vvzd
433  sjd(i, j-1, k, 3) = sjd(i, j-1, k, 3) - w(i, j-1, k, ivy)*vvzd
434  wd(i, j, k-1, ivy) = wd(i, j, k-1, ivy) - sk(i, j, k-1, 3)*vvzd &
435 & - sk(i, j, k-1, 2)*vvyd - sk(i, j, k-1, 1)*vvxd
436  wd(i, j-1, k, ivy) = wd(i, j-1, k, ivy) - sj(i, j-1, k, 3)*vvzd &
437 & - sj(i, j-1, k, 2)*vvyd - sj(i, j-1, k, 1)*vvxd
438  wd(i, j, k+1, ivy) = wd(i, j, k+1, ivy) + sk(i, j, k, 3)*vvzd + &
439 & sk(i, j, k, 2)*vvyd + sk(i, j, k, 1)*vvxd
440  wd(i, j+1, k, ivy) = wd(i, j+1, k, ivy) + sj(i, j, k, 3)*vvzd + &
441 & sj(i, j, k, 2)*vvyd + sj(i, j, k, 1)*vvxd
442  wd(i-1, j, k, ivy) = wd(i-1, j, k, ivy) - si(i-1, j, k, 3)*vvzd &
443 & - si(i-1, j, k, 2)*vvyd - si(i-1, j, k, 1)*vvxd
444  wd(i+1, j, k, ivy) = wd(i+1, j, k, ivy) + si(i, j, k, 3)*vvzd + &
445 & si(i, j, k, 2)*vvyd + si(i, j, k, 1)*vvxd
446  skd(i, j, k-1, 3) = skd(i, j, k-1, 3) - w(i, j, k-1, ivy)*vvzd
447  sid(i, j, k, 2) = sid(i, j, k, 2) + w(i+1, j, k, ivy)*vvyd
448  sid(i-1, j, k, 2) = sid(i-1, j, k, 2) - w(i-1, j, k, ivy)*vvyd
449  sjd(i, j, k, 2) = sjd(i, j, k, 2) + w(i, j+1, k, ivy)*vvyd
450  skd(i, j, k, 2) = skd(i, j, k, 2) + w(i, j, k+1, ivy)*vvyd
451  sjd(i, j-1, k, 2) = sjd(i, j-1, k, 2) - w(i, j-1, k, ivy)*vvyd
452  skd(i, j, k-1, 2) = skd(i, j, k-1, 2) - w(i, j, k-1, ivy)*vvyd
453  sid(i, j, k, 1) = sid(i, j, k, 1) + w(i+1, j, k, ivy)*vvxd
454  sid(i-1, j, k, 1) = sid(i-1, j, k, 1) - w(i-1, j, k, ivy)*vvxd
455  sjd(i, j, k, 1) = sjd(i, j, k, 1) + w(i, j+1, k, ivy)*vvxd
456  skd(i, j, k, 1) = skd(i, j, k, 1) + w(i, j, k+1, ivy)*vvxd
457  sjd(i, j-1, k, 1) = sjd(i, j-1, k, 1) - w(i, j-1, k, ivy)*vvxd
458  skd(i, j, k-1, 1) = skd(i, j, k-1, 1) - w(i, j, k-1, ivy)*vvxd
459  sid(i, j, k, 3) = sid(i, j, k, 3) + w(i+1, j, k, ivx)*uuzd
460  sid(i-1, j, k, 3) = sid(i-1, j, k, 3) - w(i-1, j, k, ivx)*uuzd
461  sjd(i, j, k, 3) = sjd(i, j, k, 3) + w(i, j+1, k, ivx)*uuzd
462  skd(i, j, k, 3) = skd(i, j, k, 3) + w(i, j, k+1, ivx)*uuzd
463  sjd(i, j-1, k, 3) = sjd(i, j-1, k, 3) - w(i, j-1, k, ivx)*uuzd
464  wd(i, j, k-1, ivx) = wd(i, j, k-1, ivx) - sk(i, j, k-1, 3)*uuzd &
465 & - sk(i, j, k-1, 2)*uuyd - sk(i, j, k-1, 1)*uuxd
466  wd(i, j-1, k, ivx) = wd(i, j-1, k, ivx) - sj(i, j-1, k, 3)*uuzd &
467 & - sj(i, j-1, k, 2)*uuyd - sj(i, j-1, k, 1)*uuxd
468  wd(i, j, k+1, ivx) = wd(i, j, k+1, ivx) + sk(i, j, k, 3)*uuzd + &
469 & sk(i, j, k, 2)*uuyd + sk(i, j, k, 1)*uuxd
470  wd(i, j+1, k, ivx) = wd(i, j+1, k, ivx) + sj(i, j, k, 3)*uuzd + &
471 & sj(i, j, k, 2)*uuyd + sj(i, j, k, 1)*uuxd
472  wd(i-1, j, k, ivx) = wd(i-1, j, k, ivx) - si(i-1, j, k, 3)*uuzd &
473 & - si(i-1, j, k, 2)*uuyd - si(i-1, j, k, 1)*uuxd
474  wd(i+1, j, k, ivx) = wd(i+1, j, k, ivx) + si(i, j, k, 3)*uuzd + &
475 & si(i, j, k, 2)*uuyd + si(i, j, k, 1)*uuxd
476  skd(i, j, k-1, 3) = skd(i, j, k-1, 3) - w(i, j, k-1, ivx)*uuzd
477  sid(i, j, k, 2) = sid(i, j, k, 2) + w(i+1, j, k, ivx)*uuyd
478  sid(i-1, j, k, 2) = sid(i-1, j, k, 2) - w(i-1, j, k, ivx)*uuyd
479  sjd(i, j, k, 2) = sjd(i, j, k, 2) + w(i, j+1, k, ivx)*uuyd
480  skd(i, j, k, 2) = skd(i, j, k, 2) + w(i, j, k+1, ivx)*uuyd
481  sjd(i, j-1, k, 2) = sjd(i, j-1, k, 2) - w(i, j-1, k, ivx)*uuyd
482  skd(i, j, k-1, 2) = skd(i, j, k-1, 2) - w(i, j, k-1, ivx)*uuyd
483  sid(i, j, k, 1) = sid(i, j, k, 1) + w(i+1, j, k, ivx)*uuxd
484  sid(i-1, j, k, 1) = sid(i-1, j, k, 1) - w(i-1, j, k, ivx)*uuxd
485  sjd(i, j, k, 1) = sjd(i, j, k, 1) + w(i, j+1, k, ivx)*uuxd
486  skd(i, j, k, 1) = skd(i, j, k, 1) + w(i, j, k+1, ivx)*uuxd
487  sjd(i, j-1, k, 1) = sjd(i, j-1, k, 1) - w(i, j-1, k, ivx)*uuxd
488  skd(i, j, k-1, 1) = skd(i, j, k-1, 1) - w(i, j, k-1, ivx)*uuxd
489  end do
490  timerefd = timerefd + sections(sectionid)%rotrate(3)*omegazd + &
491 & sections(sectionid)%rotrate(2)*omegayd + sections(sectionid)%&
492 & rotrate(1)*omegaxd
493  end if
494  end subroutine sasource_b
495 
496  subroutine sasource()
497 !
498 ! source terms.
499 ! determine the source term and its derivative w.r.t. nutilde
500 ! for all internal cells of the block.
501 ! remember that the sa field variable nutilde = w(i,j,k,itu1)
502  use blockpointers
503  use constants
504  use paramturb
505  use section
506  use inputphysics
507  use inputdiscretization, only : approxsa
508  use flowvarrefstate
509  implicit none
510 ! local parameters
511  real(kind=realtype), parameter :: f23=two*third
512 ! local variables.
513  integer(kind=inttype) :: i, j, k, nn, ii
514  real(kind=realtype) :: fv1, fv2, ft2
515  real(kind=realtype) :: ss, sst, nu, dist2inv, chi, chi2, chi3
516  real(kind=realtype) :: rr, gg, gg6, termfw, fwsa, term1, term2
517  real(kind=realtype) :: dfv1, dfv2, dft2, drr, dgg, dfw
518  real(kind=realtype) :: uux, uuy, uuz, vvx, vvy, vvz, wwx, wwy, wwz
519  real(kind=realtype) :: div2, fact, sxx, syy, szz, sxy, sxz, syz
520  real(kind=realtype) :: vortx, vorty, vortz
521  real(kind=realtype) :: omegax, omegay, omegaz
522  real(kind=realtype) :: strainmag2, strainprod, vortprod
523  real(kind=realtype), parameter :: xminn=1.e-10_realtype
524  intrinsic mod
525  intrinsic sqrt
526  intrinsic exp
527  intrinsic min
528  intrinsic max
529  real(kind=realtype) :: y1
530  real(kind=realtype) :: min1
531 ! set model constants
532  cv13 = rsacv1**3
533  kar2inv = one/rsak**2
534  cw36 = rsacw3**6
535  cb3inv = one/rsacb3
536 ! determine the non-dimensional wheel speed of this block.
537  omegax = timeref*sections(sectionid)%rotrate(1)
538  omegay = timeref*sections(sectionid)%rotrate(2)
539  omegaz = timeref*sections(sectionid)%rotrate(3)
540 ! create switches to production term depending on the variable that
541 ! should be used
542  if (turbprod .eq. katolaunder) then
543  print*, 'katolaunder production term not supported for sa'
544  stop
545  else
546 !$ad ii-loop
547  do ii=0,nx*ny*nz-1
548  i = mod(ii, nx) + 2
549  j = mod(ii/nx, ny) + 2
550  k = ii/(nx*ny) + 2
551 ! compute the gradient of u in the cell center. use is made
552 ! of the fact that the surrounding normals sum up to zero,
553 ! such that the cell i,j,k does not give a contribution.
554 ! the gradient is scaled by the factor 2*vol.
555  uux = w(i+1, j, k, ivx)*si(i, j, k, 1) - w(i-1, j, k, ivx)*si(i-&
556 & 1, j, k, 1) + w(i, j+1, k, ivx)*sj(i, j, k, 1) - w(i, j-1, k, &
557 & ivx)*sj(i, j-1, k, 1) + w(i, j, k+1, ivx)*sk(i, j, k, 1) - w(i&
558 & , j, k-1, ivx)*sk(i, j, k-1, 1)
559  uuy = w(i+1, j, k, ivx)*si(i, j, k, 2) - w(i-1, j, k, ivx)*si(i-&
560 & 1, j, k, 2) + w(i, j+1, k, ivx)*sj(i, j, k, 2) - w(i, j-1, k, &
561 & ivx)*sj(i, j-1, k, 2) + w(i, j, k+1, ivx)*sk(i, j, k, 2) - w(i&
562 & , j, k-1, ivx)*sk(i, j, k-1, 2)
563  uuz = w(i+1, j, k, ivx)*si(i, j, k, 3) - w(i-1, j, k, ivx)*si(i-&
564 & 1, j, k, 3) + w(i, j+1, k, ivx)*sj(i, j, k, 3) - w(i, j-1, k, &
565 & ivx)*sj(i, j-1, k, 3) + w(i, j, k+1, ivx)*sk(i, j, k, 3) - w(i&
566 & , j, k-1, ivx)*sk(i, j, k-1, 3)
567 ! idem for the gradient of v.
568  vvx = w(i+1, j, k, ivy)*si(i, j, k, 1) - w(i-1, j, k, ivy)*si(i-&
569 & 1, j, k, 1) + w(i, j+1, k, ivy)*sj(i, j, k, 1) - w(i, j-1, k, &
570 & ivy)*sj(i, j-1, k, 1) + w(i, j, k+1, ivy)*sk(i, j, k, 1) - w(i&
571 & , j, k-1, ivy)*sk(i, j, k-1, 1)
572  vvy = w(i+1, j, k, ivy)*si(i, j, k, 2) - w(i-1, j, k, ivy)*si(i-&
573 & 1, j, k, 2) + w(i, j+1, k, ivy)*sj(i, j, k, 2) - w(i, j-1, k, &
574 & ivy)*sj(i, j-1, k, 2) + w(i, j, k+1, ivy)*sk(i, j, k, 2) - w(i&
575 & , j, k-1, ivy)*sk(i, j, k-1, 2)
576  vvz = w(i+1, j, k, ivy)*si(i, j, k, 3) - w(i-1, j, k, ivy)*si(i-&
577 & 1, j, k, 3) + w(i, j+1, k, ivy)*sj(i, j, k, 3) - w(i, j-1, k, &
578 & ivy)*sj(i, j-1, k, 3) + w(i, j, k+1, ivy)*sk(i, j, k, 3) - w(i&
579 & , j, k-1, ivy)*sk(i, j, k-1, 3)
580 ! and for the gradient of w.
581  wwx = w(i+1, j, k, ivz)*si(i, j, k, 1) - w(i-1, j, k, ivz)*si(i-&
582 & 1, j, k, 1) + w(i, j+1, k, ivz)*sj(i, j, k, 1) - w(i, j-1, k, &
583 & ivz)*sj(i, j-1, k, 1) + w(i, j, k+1, ivz)*sk(i, j, k, 1) - w(i&
584 & , j, k-1, ivz)*sk(i, j, k-1, 1)
585  wwy = w(i+1, j, k, ivz)*si(i, j, k, 2) - w(i-1, j, k, ivz)*si(i-&
586 & 1, j, k, 2) + w(i, j+1, k, ivz)*sj(i, j, k, 2) - w(i, j-1, k, &
587 & ivz)*sj(i, j-1, k, 2) + w(i, j, k+1, ivz)*sk(i, j, k, 2) - w(i&
588 & , j, k-1, ivz)*sk(i, j, k-1, 2)
589  wwz = w(i+1, j, k, ivz)*si(i, j, k, 3) - w(i-1, j, k, ivz)*si(i-&
590 & 1, j, k, 3) + w(i, j+1, k, ivz)*sj(i, j, k, 3) - w(i, j-1, k, &
591 & ivz)*sj(i, j-1, k, 3) + w(i, j, k+1, ivz)*sk(i, j, k, 3) - w(i&
592 & , j, k-1, ivz)*sk(i, j, k-1, 3)
593 ! compute the components of the stress tensor.
594 ! the combination of the current scaling of the velocity
595 ! gradients (2*vol) and the definition of the stress tensor,
596 ! leads to the factor 1/(4*vol).
597  fact = fourth/vol(i, j, k)
598  if (turbprod .eq. strain) then
599  sxx = two*fact*uux
600  syy = two*fact*vvy
601  szz = two*fact*wwz
602  sxy = fact*(uuy+vvx)
603  sxz = fact*(uuz+wwx)
604  syz = fact*(vvz+wwy)
605 ! compute 2/3 * divergence of velocity squared
606  div2 = f23*(sxx+syy+szz)**2
607 ! compute strain production term
608  strainmag2 = two*(sxy**2+sxz**2+syz**2) + sxx**2 + syy**2 + &
609 & szz**2
610  strainprod = two*strainmag2 - div2
611  ss = sqrt(strainprod)
612  else if (turbprod .eq. vorticity) then
613 ! compute the three components of the vorticity vector.
614 ! substract the part coming from the rotating frame.
615  vortx = two*fact*(wwy-vvz) - two*omegax
616  vorty = two*fact*(uuz-wwx) - two*omegay
617  vortz = two*fact*(vvx-uuy) - two*omegaz
618 ! compute the vorticity production term
619  vortprod = vortx**2 + vorty**2 + vortz**2
620 ! first take the square root of the production term to
621 ! obtain the correct production term for spalart-allmaras.
622 ! we do this to avoid if statements.
623  ss = sqrt(vortprod)
624  end if
625 ! compute the laminar kinematic viscosity, the inverse of
626 ! wall distance squared, the ratio chi (ratio of nutilde
627 ! and nu) and the functions fv1 and fv2. the latter corrects
628 ! the production term near a viscous wall.
629  nu = rlv(i, j, k)/w(i, j, k, irho)
630  dist2inv = one/d2wall(i, j, k)**2
631  chi = w(i, j, k, itu1)/nu
632  chi2 = chi*chi
633  chi3 = chi*chi2
634  fv1 = chi3/(chi3+cv13)
635  fv2 = one - chi/(one+chi*fv1)
636 ! the function ft2, which is designed to keep a laminar
637 ! solution laminar. when running in fully turbulent mode
638 ! this function should be set to 0.0.
639  if (useft2sa) then
640  ft2 = rsact3*exp(-(rsact4*chi2))
641  else
642  ft2 = zero
643  end if
644 ! correct the production term to account for the influence
645 ! of the wall.
646  sst = ss + w(i, j, k, itu1)*fv2*kar2inv*dist2inv
647 ! add rotation term (userotationsa defined in inputparams.f90)
648  if (userotationsa) then
649  y1 = sqrt(two*strainmag2)
650  if (zero .gt. y1) then
651  min1 = y1
652  else
653  min1 = zero
654  end if
655  sst = sst + rsacrot*min1
656  end if
657  if (sst .lt. xminn) then
658  sst = xminn
659  else
660  sst = sst
661  end if
662 ! compute the function fw. the argument rr is cut off at 10
663 ! to avoid numerical problems. this is ok, because the
664 ! asymptotical value of fw is then already reached.
665  rr = w(i, j, k, itu1)*kar2inv*dist2inv/sst
666  if (rr .gt. 10.0_realtype) then
667  rr = 10.0_realtype
668  else
669  rr = rr
670  end if
671  gg = rr + rsacw2*(rr**6-rr)
672  gg6 = gg**6
673  termfw = ((one+cw36)/(gg6+cw36))**sixth
674  fwsa = gg*termfw
675 ! compute the source term; some terms are saved for the
676 ! linearization. the source term is stored in dvt.
677  if (approxsa) then
678  term1 = zero
679  else
680  term1 = rsacb1*(one-ft2)*ss
681  end if
682  term2 = dist2inv*(kar2inv*rsacb1*((one-ft2)*fv2+ft2)-rsacw1*fwsa&
683 & )
684  scratch(i, j, k, idvt) = (term1+term2*w(i, j, k, itu1))*w(i, j, &
685 & k, itu1)
686  end do
687  end if
688  end subroutine sasource
689 
690 ! differentiation of saviscous in reverse (adjoint) mode (with options noisize i4 dr8 r8):
691 ! gradient of useful results: *w *rlv *scratch *vol *si *sj
692 ! *sk
693 ! with respect to varying inputs: *w *rlv *scratch *vol *si *sj
694 ! *sk
695 ! rw status of diff variables: *w:incr *rlv:incr *scratch:in-out
696 ! *vol:incr *si:incr *sj:incr *sk:incr
697 ! plus diff mem management of: w:in rlv:in scratch:in vol:in
698 ! si:in sj:in sk:in
699  subroutine saviscous_b()
700 !
701 ! viscous term.
702 ! determine the viscous contribution to the residual
703 ! for all internal cells of the block.
704  use blockpointers
705  use paramturb
706  implicit none
707 ! local variables.
708  integer(kind=inttype) :: i, j, k, nn, ii
709  real(kind=realtype) :: nu
710  real(kind=realtype) :: nud
711  real(kind=realtype) :: fv1, fv2, ft2
712  real(kind=realtype) :: voli, volmi, volpi, xm, ym, zm, xp, yp, zp
713  real(kind=realtype) :: volid, volmid, volpid, xmd, ymd, zmd, xpd, &
714 & ypd, zpd
715  real(kind=realtype) :: xa, ya, za, ttm, ttp, cnud, cam, cap
716  real(kind=realtype) :: xad, yad, zad, ttmd, ttpd, cnudd, camd, capd
717  real(kind=realtype) :: nutm, nutp, num, nup, cdm, cdp
718  real(kind=realtype) :: nutmd, nutpd, numd, nupd, cdmd, cdpd
719  real(kind=realtype) :: c1m, c1p, c10, b1, c1, d1, qs
720  real(kind=realtype) :: c1md, c1pd, c10d
721  intrinsic mod
722  intrinsic max
723  real(kind=realtype) :: temp
724  real(kind=realtype) :: tempd
725  real(kind=realtype) :: temp0
726  real(kind=realtype) :: tempd0
727  integer :: branch
728 ! set model constants
729  cb3inv = one/rsacb3
730 !$bwd-of ii-loop
731  do ii=0,nx*ny*nz-1
732  i = mod(ii, nx) + 2
733  j = mod(ii/nx, ny) + 2
734  k = ii/(nx*ny) + 2
735 ! compute the metrics in xi-direction, i.e. along the
736 ! line i = constant.
737  voli = one/vol(i, j, k)
738  volmi = two/(vol(i, j, k)+vol(i-1, j, k))
739  volpi = two/(vol(i, j, k)+vol(i+1, j, k))
740  xm = si(i-1, j, k, 1)*volmi
741  ym = si(i-1, j, k, 2)*volmi
742  zm = si(i-1, j, k, 3)*volmi
743  xp = si(i, j, k, 1)*volpi
744  yp = si(i, j, k, 2)*volpi
745  zp = si(i, j, k, 3)*volpi
746  xa = half*(si(i, j, k, 1)+si(i-1, j, k, 1))*voli
747  ya = half*(si(i, j, k, 2)+si(i-1, j, k, 2))*voli
748  za = half*(si(i, j, k, 3)+si(i-1, j, k, 3))*voli
749  ttm = xm*xa + ym*ya + zm*za
750  ttp = xp*xa + yp*ya + zp*za
751 ! computation of the viscous terms in xi-direction; note
752 ! that cross-derivatives are neglected, i.e. the mesh is
753 ! assumed to be orthogonal.
754 ! furthermore, the grad(nu)**2 has been rewritten as
755 ! div(nu grad(nu)) - nu div(grad nu) to enhance stability.
756 ! the second derivative in xi-direction is constructed as
757 ! the central difference of the first order derivatives, i.e.
758 ! d^2/dxi^2 = d/dxi (d/dxi i+1/2 - d/dxi i-1/2).
759 ! in this way the metric can be taken into account.
760 ! compute the diffusion coefficients multiplying the nodes
761 ! i+1, i and i-1 in the second derivative. make sure that
762 ! these coefficients are nonnegative.
763  cnud = -(rsacb2*w(i, j, k, itu1)*cb3inv)
764  cam = ttm*cnud
765  cap = ttp*cnud
766  nutm = half*(w(i-1, j, k, itu1)+w(i, j, k, itu1))
767  nutp = half*(w(i+1, j, k, itu1)+w(i, j, k, itu1))
768  nu = rlv(i, j, k)/w(i, j, k, irho)
769  num = half*(rlv(i-1, j, k)/w(i-1, j, k, irho)+nu)
770  nup = half*(rlv(i+1, j, k)/w(i+1, j, k, irho)+nu)
771  cdm = (num+(one+rsacb2)*nutm)*ttm*cb3inv
772  cdp = (nup+(one+rsacb2)*nutp)*ttp*cb3inv
773  if (cdm + cam .lt. zero) then
774  c1m = zero
775  call pushcontrol1b(0)
776  else
777  c1m = cdm + cam
778  call pushcontrol1b(1)
779  end if
780  if (cdp + cap .lt. zero) then
781  c1p = zero
782  call pushcontrol1b(0)
783  else
784  c1p = cdp + cap
785  call pushcontrol1b(1)
786  end if
787  c10 = c1m + c1p
788 ! update the residual for this cell and store the possible
789 ! coefficients for the matrix in b1, c1 and d1.
790  c10d = -(w(i, j, k, itu1)*scratchd(i, j, k, idvt))
791  c1md = w(i-1, j, k, itu1)*scratchd(i, j, k, idvt) + c10d
792  wd(i-1, j, k, itu1) = wd(i-1, j, k, itu1) + c1m*scratchd(i, j, k, &
793 & idvt)
794  c1pd = w(i+1, j, k, itu1)*scratchd(i, j, k, idvt) + c10d
795  wd(i+1, j, k, itu1) = wd(i+1, j, k, itu1) + c1p*scratchd(i, j, k, &
796 & idvt)
797  wd(i, j, k, itu1) = wd(i, j, k, itu1) - c10*scratchd(i, j, k, idvt&
798 & )
799  call popcontrol1b(branch)
800  if (branch .eq. 0) then
801  cdpd = 0.0_8
802  capd = 0.0_8
803  else
804  cdpd = c1pd
805  capd = c1pd
806  end if
807  call popcontrol1b(branch)
808  if (branch .eq. 0) then
809  cdmd = 0.0_8
810  camd = 0.0_8
811  else
812  cdmd = c1md
813  camd = c1md
814  end if
815  cnudd = ttp*capd + ttm*camd
816  tempd0 = cb3inv*cdpd
817  nupd = ttp*tempd0
818  nutpd = (one+rsacb2)*ttp*tempd0
819  ttpd = (nup+(one+rsacb2)*nutp)*tempd0 + cnud*capd
820  tempd0 = cb3inv*cdmd
821  numd = ttm*tempd0
822  nutmd = (one+rsacb2)*ttm*tempd0
823  ttmd = (num+(one+rsacb2)*nutm)*tempd0 + cnud*camd
824  temp0 = w(i+1, j, k, irho)
825  tempd = half*nupd/temp0
826  nud = half*nupd + half*numd
827  rlvd(i+1, j, k) = rlvd(i+1, j, k) + tempd
828  wd(i+1, j, k, irho) = wd(i+1, j, k, irho) - rlv(i+1, j, k)*tempd/&
829 & temp0
830  temp0 = w(i-1, j, k, irho)
831  tempd = half*numd/temp0
832  rlvd(i-1, j, k) = rlvd(i-1, j, k) + tempd
833  wd(i-1, j, k, irho) = wd(i-1, j, k, irho) - rlv(i-1, j, k)*tempd/&
834 & temp0
835  temp0 = w(i, j, k, irho)
836  rlvd(i, j, k) = rlvd(i, j, k) + nud/temp0
837  wd(i, j, k, irho) = wd(i, j, k, irho) - rlv(i, j, k)*nud/temp0**2
838  wd(i+1, j, k, itu1) = wd(i+1, j, k, itu1) + half*nutpd
839  wd(i, j, k, itu1) = wd(i, j, k, itu1) + half*nutpd + half*nutmd - &
840 & rsacb2*cb3inv*cnudd
841  wd(i-1, j, k, itu1) = wd(i-1, j, k, itu1) + half*nutmd
842  xpd = xa*ttpd
843  xad = xp*ttpd + xm*ttmd
844  ypd = ya*ttpd
845  yad = yp*ttpd + ym*ttmd
846  zpd = za*ttpd
847  zad = zp*ttpd + zm*ttmd
848  xmd = xa*ttmd
849  ymd = ya*ttmd
850  zmd = za*ttmd
851  tempd0 = half*zad
852  sid(i, j, k, 3) = sid(i, j, k, 3) + voli*tempd0
853  sid(i-1, j, k, 3) = sid(i-1, j, k, 3) + voli*tempd0
854  volid = (si(i, j, k, 3)+si(i-1, j, k, 3))*tempd0
855  tempd0 = half*yad
856  sid(i, j, k, 2) = sid(i, j, k, 2) + voli*tempd0
857  sid(i-1, j, k, 2) = sid(i-1, j, k, 2) + voli*tempd0
858  volid = volid + (si(i, j, k, 2)+si(i-1, j, k, 2))*tempd0
859  tempd0 = half*xad
860  sid(i, j, k, 1) = sid(i, j, k, 1) + voli*tempd0
861  sid(i-1, j, k, 1) = sid(i-1, j, k, 1) + voli*tempd0
862  volid = volid + (si(i, j, k, 1)+si(i-1, j, k, 1))*tempd0
863  sid(i, j, k, 3) = sid(i, j, k, 3) + volpi*zpd
864  volpid = si(i, j, k, 3)*zpd + si(i, j, k, 2)*ypd + si(i, j, k, 1)*&
865 & xpd
866  sid(i, j, k, 2) = sid(i, j, k, 2) + volpi*ypd
867  sid(i, j, k, 1) = sid(i, j, k, 1) + volpi*xpd
868  sid(i-1, j, k, 3) = sid(i-1, j, k, 3) + volmi*zmd
869  volmid = si(i-1, j, k, 3)*zmd + si(i-1, j, k, 2)*ymd + si(i-1, j, &
870 & k, 1)*xmd
871  sid(i-1, j, k, 2) = sid(i-1, j, k, 2) + volmi*ymd
872  sid(i-1, j, k, 1) = sid(i-1, j, k, 1) + volmi*xmd
873  temp0 = vol(i, j, k) + vol(i+1, j, k)
874  tempd0 = -(two*volpid/temp0**2)
875  vold(i, j, k) = vold(i, j, k) + tempd0
876  vold(i+1, j, k) = vold(i+1, j, k) + tempd0
877  temp0 = vol(i, j, k) + vol(i-1, j, k)
878  tempd0 = -(two*volmid/temp0**2)
879  vold(i-1, j, k) = vold(i-1, j, k) + tempd0
880  vold(i, j, k) = vold(i, j, k) + tempd0 - one*volid/vol(i, j, k)**2
881  end do
882 !$bwd-of ii-loop
883  do ii=0,nx*ny*nz-1
884  i = mod(ii, nx) + 2
885  j = mod(ii/nx, ny) + 2
886  k = ii/(nx*ny) + 2
887 ! compute the metrics in eta-direction, i.e. along the
888 ! line j = constant.
889  voli = one/vol(i, j, k)
890  volmi = two/(vol(i, j, k)+vol(i, j-1, k))
891  volpi = two/(vol(i, j, k)+vol(i, j+1, k))
892  xm = sj(i, j-1, k, 1)*volmi
893  ym = sj(i, j-1, k, 2)*volmi
894  zm = sj(i, j-1, k, 3)*volmi
895  xp = sj(i, j, k, 1)*volpi
896  yp = sj(i, j, k, 2)*volpi
897  zp = sj(i, j, k, 3)*volpi
898  xa = half*(sj(i, j, k, 1)+sj(i, j-1, k, 1))*voli
899  ya = half*(sj(i, j, k, 2)+sj(i, j-1, k, 2))*voli
900  za = half*(sj(i, j, k, 3)+sj(i, j-1, k, 3))*voli
901  ttm = xm*xa + ym*ya + zm*za
902  ttp = xp*xa + yp*ya + zp*za
903 ! computation of the viscous terms in eta-direction; note
904 ! that cross-derivatives are neglected, i.e. the mesh is
905 ! assumed to be orthogonal.
906 ! furthermore, the grad(nu)**2 has been rewritten as
907 ! div(nu grad(nu)) - nu div(grad nu) to enhance stability.
908 ! the second derivative in eta-direction is constructed as
909 ! the central difference of the first order derivatives, i.e.
910 ! d^2/deta^2 = d/deta (d/deta j+1/2 - d/deta j-1/2).
911 ! in this way the metric can be taken into account.
912 ! compute the diffusion coefficients multiplying the nodes
913 ! j+1, j and j-1 in the second derivative. make sure that
914 ! these coefficients are nonnegative.
915  cnud = -(rsacb2*w(i, j, k, itu1)*cb3inv)
916  cam = ttm*cnud
917  cap = ttp*cnud
918  nutm = half*(w(i, j-1, k, itu1)+w(i, j, k, itu1))
919  nutp = half*(w(i, j+1, k, itu1)+w(i, j, k, itu1))
920  nu = rlv(i, j, k)/w(i, j, k, irho)
921  num = half*(rlv(i, j-1, k)/w(i, j-1, k, irho)+nu)
922  nup = half*(rlv(i, j+1, k)/w(i, j+1, k, irho)+nu)
923  cdm = (num+(one+rsacb2)*nutm)*ttm*cb3inv
924  cdp = (nup+(one+rsacb2)*nutp)*ttp*cb3inv
925  if (cdm + cam .lt. zero) then
926  c1m = zero
927  call pushcontrol1b(0)
928  else
929  c1m = cdm + cam
930  call pushcontrol1b(1)
931  end if
932  if (cdp + cap .lt. zero) then
933  c1p = zero
934  call pushcontrol1b(0)
935  else
936  c1p = cdp + cap
937  call pushcontrol1b(1)
938  end if
939  c10 = c1m + c1p
940 ! update the residual for this cell and store the possible
941 ! coefficients for the matrix in b1, c1 and d1.
942  c10d = -(w(i, j, k, itu1)*scratchd(i, j, k, idvt))
943  c1md = w(i, j-1, k, itu1)*scratchd(i, j, k, idvt) + c10d
944  wd(i, j-1, k, itu1) = wd(i, j-1, k, itu1) + c1m*scratchd(i, j, k, &
945 & idvt)
946  c1pd = w(i, j+1, k, itu1)*scratchd(i, j, k, idvt) + c10d
947  wd(i, j+1, k, itu1) = wd(i, j+1, k, itu1) + c1p*scratchd(i, j, k, &
948 & idvt)
949  wd(i, j, k, itu1) = wd(i, j, k, itu1) - c10*scratchd(i, j, k, idvt&
950 & )
951  call popcontrol1b(branch)
952  if (branch .eq. 0) then
953  cdpd = 0.0_8
954  capd = 0.0_8
955  else
956  cdpd = c1pd
957  capd = c1pd
958  end if
959  call popcontrol1b(branch)
960  if (branch .eq. 0) then
961  cdmd = 0.0_8
962  camd = 0.0_8
963  else
964  cdmd = c1md
965  camd = c1md
966  end if
967  cnudd = ttp*capd + ttm*camd
968  tempd0 = cb3inv*cdpd
969  nupd = ttp*tempd0
970  nutpd = (one+rsacb2)*ttp*tempd0
971  ttpd = (nup+(one+rsacb2)*nutp)*tempd0 + cnud*capd
972  tempd0 = cb3inv*cdmd
973  numd = ttm*tempd0
974  nutmd = (one+rsacb2)*ttm*tempd0
975  ttmd = (num+(one+rsacb2)*nutm)*tempd0 + cnud*camd
976  temp0 = w(i, j+1, k, irho)
977  tempd = half*nupd/temp0
978  nud = half*nupd + half*numd
979  rlvd(i, j+1, k) = rlvd(i, j+1, k) + tempd
980  wd(i, j+1, k, irho) = wd(i, j+1, k, irho) - rlv(i, j+1, k)*tempd/&
981 & temp0
982  temp0 = w(i, j-1, k, irho)
983  tempd = half*numd/temp0
984  rlvd(i, j-1, k) = rlvd(i, j-1, k) + tempd
985  wd(i, j-1, k, irho) = wd(i, j-1, k, irho) - rlv(i, j-1, k)*tempd/&
986 & temp0
987  temp0 = w(i, j, k, irho)
988  rlvd(i, j, k) = rlvd(i, j, k) + nud/temp0
989  wd(i, j, k, irho) = wd(i, j, k, irho) - rlv(i, j, k)*nud/temp0**2
990  wd(i, j+1, k, itu1) = wd(i, j+1, k, itu1) + half*nutpd
991  wd(i, j, k, itu1) = wd(i, j, k, itu1) + half*nutpd + half*nutmd - &
992 & rsacb2*cb3inv*cnudd
993  wd(i, j-1, k, itu1) = wd(i, j-1, k, itu1) + half*nutmd
994  xpd = xa*ttpd
995  xad = xp*ttpd + xm*ttmd
996  ypd = ya*ttpd
997  yad = yp*ttpd + ym*ttmd
998  zpd = za*ttpd
999  zad = zp*ttpd + zm*ttmd
1000  xmd = xa*ttmd
1001  ymd = ya*ttmd
1002  zmd = za*ttmd
1003  tempd0 = half*zad
1004  sjd(i, j, k, 3) = sjd(i, j, k, 3) + voli*tempd0
1005  sjd(i, j-1, k, 3) = sjd(i, j-1, k, 3) + voli*tempd0
1006  volid = (sj(i, j, k, 3)+sj(i, j-1, k, 3))*tempd0
1007  tempd0 = half*yad
1008  sjd(i, j, k, 2) = sjd(i, j, k, 2) + voli*tempd0
1009  sjd(i, j-1, k, 2) = sjd(i, j-1, k, 2) + voli*tempd0
1010  volid = volid + (sj(i, j, k, 2)+sj(i, j-1, k, 2))*tempd0
1011  tempd0 = half*xad
1012  sjd(i, j, k, 1) = sjd(i, j, k, 1) + voli*tempd0
1013  sjd(i, j-1, k, 1) = sjd(i, j-1, k, 1) + voli*tempd0
1014  volid = volid + (sj(i, j, k, 1)+sj(i, j-1, k, 1))*tempd0
1015  sjd(i, j, k, 3) = sjd(i, j, k, 3) + volpi*zpd
1016  volpid = sj(i, j, k, 3)*zpd + sj(i, j, k, 2)*ypd + sj(i, j, k, 1)*&
1017 & xpd
1018  sjd(i, j, k, 2) = sjd(i, j, k, 2) + volpi*ypd
1019  sjd(i, j, k, 1) = sjd(i, j, k, 1) + volpi*xpd
1020  sjd(i, j-1, k, 3) = sjd(i, j-1, k, 3) + volmi*zmd
1021  volmid = sj(i, j-1, k, 3)*zmd + sj(i, j-1, k, 2)*ymd + sj(i, j-1, &
1022 & k, 1)*xmd
1023  sjd(i, j-1, k, 2) = sjd(i, j-1, k, 2) + volmi*ymd
1024  sjd(i, j-1, k, 1) = sjd(i, j-1, k, 1) + volmi*xmd
1025  temp0 = vol(i, j, k) + vol(i, j+1, k)
1026  tempd0 = -(two*volpid/temp0**2)
1027  vold(i, j, k) = vold(i, j, k) + tempd0
1028  vold(i, j+1, k) = vold(i, j+1, k) + tempd0
1029  temp0 = vol(i, j, k) + vol(i, j-1, k)
1030  tempd0 = -(two*volmid/temp0**2)
1031  vold(i, j-1, k) = vold(i, j-1, k) + tempd0
1032  vold(i, j, k) = vold(i, j, k) + tempd0 - one*volid/vol(i, j, k)**2
1033  end do
1034 !$bwd-of ii-loop
1035  do ii=0,nx*ny*nz-1
1036  i = mod(ii, nx) + 2
1037  j = mod(ii/nx, ny) + 2
1038  k = ii/(nx*ny) + 2
1039 ! compute the metrics in zeta-direction, i.e. along the
1040 ! line k = constant.
1041  voli = one/vol(i, j, k)
1042  volmi = two/(vol(i, j, k)+vol(i, j, k-1))
1043  volpi = two/(vol(i, j, k)+vol(i, j, k+1))
1044  xm = sk(i, j, k-1, 1)*volmi
1045  ym = sk(i, j, k-1, 2)*volmi
1046  zm = sk(i, j, k-1, 3)*volmi
1047  xp = sk(i, j, k, 1)*volpi
1048  yp = sk(i, j, k, 2)*volpi
1049  zp = sk(i, j, k, 3)*volpi
1050  xa = half*(sk(i, j, k, 1)+sk(i, j, k-1, 1))*voli
1051  ya = half*(sk(i, j, k, 2)+sk(i, j, k-1, 2))*voli
1052  za = half*(sk(i, j, k, 3)+sk(i, j, k-1, 3))*voli
1053  ttm = xm*xa + ym*ya + zm*za
1054  ttp = xp*xa + yp*ya + zp*za
1055 ! ttm and ttp ~ 1/deltax^2
1056 ! computation of the viscous terms in zeta-direction; note
1057 ! that cross-derivatives are neglected, i.e. the mesh is
1058 ! assumed to be orthogonal.
1059 ! furthermore, the grad(nu)**2 has been rewritten as
1060 ! div(nu grad(nu)) - nu div(grad nu) to enhance stability.
1061 ! the second derivative in zeta-direction is constructed as
1062 ! the central difference of the first order derivatives, i.e.
1063 ! d^2/dzeta^2 = d/dzeta (d/dzeta k+1/2 - d/dzeta k-1/2).
1064 ! in this way the metric can be taken into account.
1065 ! compute the diffusion coefficients multiplying the nodes
1066 ! k+1, k and k-1 in the second derivative. make sure that
1067 ! these coefficients are nonnegative.
1068  cnud = -(rsacb2*w(i, j, k, itu1)*cb3inv)
1069  cam = ttm*cnud
1070  cap = ttp*cnud
1071 ! compute nutilde at the faces
1072  nutm = half*(w(i, j, k-1, itu1)+w(i, j, k, itu1))
1073  nutp = half*(w(i, j, k+1, itu1)+w(i, j, k, itu1))
1074 ! compute nu at the faces
1075  nu = rlv(i, j, k)/w(i, j, k, irho)
1076  num = half*(rlv(i, j, k-1)/w(i, j, k-1, irho)+nu)
1077  nup = half*(rlv(i, j, k+1)/w(i, j, k+1, irho)+nu)
1078  cdm = (num+(one+rsacb2)*nutm)*ttm*cb3inv
1079  cdp = (nup+(one+rsacb2)*nutp)*ttp*cb3inv
1080  if (cdm + cam .lt. zero) then
1081  c1m = zero
1082  call pushcontrol1b(0)
1083  else
1084  c1m = cdm + cam
1085  call pushcontrol1b(1)
1086  end if
1087  if (cdp + cap .lt. zero) then
1088  c1p = zero
1089  call pushcontrol1b(0)
1090  else
1091  c1p = cdp + cap
1092  call pushcontrol1b(1)
1093  end if
1094  c10 = c1m + c1p
1095 ! update the residual for this cell and store the possible
1096 ! coefficients for the matrix in b1, c1 and d1.
1097  c10d = -(w(i, j, k, itu1)*scratchd(i, j, k, idvt))
1098  c1md = w(i, j, k-1, itu1)*scratchd(i, j, k, idvt) + c10d
1099  wd(i, j, k-1, itu1) = wd(i, j, k-1, itu1) + c1m*scratchd(i, j, k, &
1100 & idvt)
1101  c1pd = w(i, j, k+1, itu1)*scratchd(i, j, k, idvt) + c10d
1102  wd(i, j, k+1, itu1) = wd(i, j, k+1, itu1) + c1p*scratchd(i, j, k, &
1103 & idvt)
1104  wd(i, j, k, itu1) = wd(i, j, k, itu1) - c10*scratchd(i, j, k, idvt&
1105 & )
1106  call popcontrol1b(branch)
1107  if (branch .eq. 0) then
1108  cdpd = 0.0_8
1109  capd = 0.0_8
1110  else
1111  cdpd = c1pd
1112  capd = c1pd
1113  end if
1114  call popcontrol1b(branch)
1115  if (branch .eq. 0) then
1116  cdmd = 0.0_8
1117  camd = 0.0_8
1118  else
1119  cdmd = c1md
1120  camd = c1md
1121  end if
1122  cnudd = ttp*capd + ttm*camd
1123  tempd0 = cb3inv*cdpd
1124  nupd = ttp*tempd0
1125  nutpd = (one+rsacb2)*ttp*tempd0
1126  ttpd = (nup+(one+rsacb2)*nutp)*tempd0 + cnud*capd
1127  tempd0 = cb3inv*cdmd
1128  numd = ttm*tempd0
1129  nutmd = (one+rsacb2)*ttm*tempd0
1130  ttmd = (num+(one+rsacb2)*nutm)*tempd0 + cnud*camd
1131  temp0 = w(i, j, k+1, irho)
1132  tempd = half*nupd/temp0
1133  nud = half*nupd + half*numd
1134  rlvd(i, j, k+1) = rlvd(i, j, k+1) + tempd
1135  wd(i, j, k+1, irho) = wd(i, j, k+1, irho) - rlv(i, j, k+1)*tempd/&
1136 & temp0
1137  temp = w(i, j, k-1, irho)
1138  tempd0 = half*numd/temp
1139  rlvd(i, j, k-1) = rlvd(i, j, k-1) + tempd0
1140  wd(i, j, k-1, irho) = wd(i, j, k-1, irho) - rlv(i, j, k-1)*tempd0/&
1141 & temp
1142  temp = w(i, j, k, irho)
1143  rlvd(i, j, k) = rlvd(i, j, k) + nud/temp
1144  wd(i, j, k, irho) = wd(i, j, k, irho) - rlv(i, j, k)*nud/temp**2
1145  wd(i, j, k+1, itu1) = wd(i, j, k+1, itu1) + half*nutpd
1146  wd(i, j, k, itu1) = wd(i, j, k, itu1) + half*nutpd + half*nutmd - &
1147 & rsacb2*cb3inv*cnudd
1148  wd(i, j, k-1, itu1) = wd(i, j, k-1, itu1) + half*nutmd
1149  xpd = xa*ttpd
1150  xad = xp*ttpd + xm*ttmd
1151  ypd = ya*ttpd
1152  yad = yp*ttpd + ym*ttmd
1153  zpd = za*ttpd
1154  zad = zp*ttpd + zm*ttmd
1155  xmd = xa*ttmd
1156  ymd = ya*ttmd
1157  zmd = za*ttmd
1158  tempd = half*zad
1159  skd(i, j, k, 3) = skd(i, j, k, 3) + voli*tempd
1160  skd(i, j, k-1, 3) = skd(i, j, k-1, 3) + voli*tempd
1161  volid = (sk(i, j, k, 3)+sk(i, j, k-1, 3))*tempd
1162  tempd = half*yad
1163  skd(i, j, k, 2) = skd(i, j, k, 2) + voli*tempd
1164  skd(i, j, k-1, 2) = skd(i, j, k-1, 2) + voli*tempd
1165  volid = volid + (sk(i, j, k, 2)+sk(i, j, k-1, 2))*tempd
1166  tempd = half*xad
1167  skd(i, j, k, 1) = skd(i, j, k, 1) + voli*tempd
1168  skd(i, j, k-1, 1) = skd(i, j, k-1, 1) + voli*tempd
1169  volid = volid + (sk(i, j, k, 1)+sk(i, j, k-1, 1))*tempd
1170  skd(i, j, k, 3) = skd(i, j, k, 3) + volpi*zpd
1171  volpid = sk(i, j, k, 3)*zpd + sk(i, j, k, 2)*ypd + sk(i, j, k, 1)*&
1172 & xpd
1173  skd(i, j, k, 2) = skd(i, j, k, 2) + volpi*ypd
1174  skd(i, j, k, 1) = skd(i, j, k, 1) + volpi*xpd
1175  skd(i, j, k-1, 3) = skd(i, j, k-1, 3) + volmi*zmd
1176  volmid = sk(i, j, k-1, 3)*zmd + sk(i, j, k-1, 2)*ymd + sk(i, j, k-&
1177 & 1, 1)*xmd
1178  skd(i, j, k-1, 2) = skd(i, j, k-1, 2) + volmi*ymd
1179  skd(i, j, k-1, 1) = skd(i, j, k-1, 1) + volmi*xmd
1180  temp = vol(i, j, k) + vol(i, j, k+1)
1181  tempd = -(two*volpid/temp**2)
1182  vold(i, j, k) = vold(i, j, k) + tempd
1183  vold(i, j, k+1) = vold(i, j, k+1) + tempd
1184  temp = vol(i, j, k) + vol(i, j, k-1)
1185  tempd = -(two*volmid/temp**2)
1186  vold(i, j, k-1) = vold(i, j, k-1) + tempd
1187  vold(i, j, k) = vold(i, j, k) + tempd - one*volid/vol(i, j, k)**2
1188  end do
1189  end subroutine saviscous_b
1190 
1191  subroutine saviscous()
1192 !
1193 ! viscous term.
1194 ! determine the viscous contribution to the residual
1195 ! for all internal cells of the block.
1196  use blockpointers
1197  use paramturb
1198  implicit none
1199 ! local variables.
1200  integer(kind=inttype) :: i, j, k, nn, ii
1201  real(kind=realtype) :: nu
1202  real(kind=realtype) :: fv1, fv2, ft2
1203  real(kind=realtype) :: voli, volmi, volpi, xm, ym, zm, xp, yp, zp
1204  real(kind=realtype) :: xa, ya, za, ttm, ttp, cnud, cam, cap
1205  real(kind=realtype) :: nutm, nutp, num, nup, cdm, cdp
1206  real(kind=realtype) :: c1m, c1p, c10, b1, c1, d1, qs
1207  intrinsic mod
1208  intrinsic max
1209 ! set model constants
1210  cv13 = rsacv1**3
1211  kar2inv = one/rsak**2
1212  cw36 = rsacw3**6
1213  cb3inv = one/rsacb3
1214 !$ad ii-loop
1215 !
1216 ! viscous terms in k-direction.
1217 !
1218  do ii=0,nx*ny*nz-1
1219  i = mod(ii, nx) + 2
1220  j = mod(ii/nx, ny) + 2
1221  k = ii/(nx*ny) + 2
1222 ! compute the metrics in zeta-direction, i.e. along the
1223 ! line k = constant.
1224  voli = one/vol(i, j, k)
1225  volmi = two/(vol(i, j, k)+vol(i, j, k-1))
1226  volpi = two/(vol(i, j, k)+vol(i, j, k+1))
1227  xm = sk(i, j, k-1, 1)*volmi
1228  ym = sk(i, j, k-1, 2)*volmi
1229  zm = sk(i, j, k-1, 3)*volmi
1230  xp = sk(i, j, k, 1)*volpi
1231  yp = sk(i, j, k, 2)*volpi
1232  zp = sk(i, j, k, 3)*volpi
1233  xa = half*(sk(i, j, k, 1)+sk(i, j, k-1, 1))*voli
1234  ya = half*(sk(i, j, k, 2)+sk(i, j, k-1, 2))*voli
1235  za = half*(sk(i, j, k, 3)+sk(i, j, k-1, 3))*voli
1236  ttm = xm*xa + ym*ya + zm*za
1237  ttp = xp*xa + yp*ya + zp*za
1238 ! ttm and ttp ~ 1/deltax^2
1239 ! computation of the viscous terms in zeta-direction; note
1240 ! that cross-derivatives are neglected, i.e. the mesh is
1241 ! assumed to be orthogonal.
1242 ! furthermore, the grad(nu)**2 has been rewritten as
1243 ! div(nu grad(nu)) - nu div(grad nu) to enhance stability.
1244 ! the second derivative in zeta-direction is constructed as
1245 ! the central difference of the first order derivatives, i.e.
1246 ! d^2/dzeta^2 = d/dzeta (d/dzeta k+1/2 - d/dzeta k-1/2).
1247 ! in this way the metric can be taken into account.
1248 ! compute the diffusion coefficients multiplying the nodes
1249 ! k+1, k and k-1 in the second derivative. make sure that
1250 ! these coefficients are nonnegative.
1251  cnud = -(rsacb2*w(i, j, k, itu1)*cb3inv)
1252  cam = ttm*cnud
1253  cap = ttp*cnud
1254 ! compute nutilde at the faces
1255  nutm = half*(w(i, j, k-1, itu1)+w(i, j, k, itu1))
1256  nutp = half*(w(i, j, k+1, itu1)+w(i, j, k, itu1))
1257 ! compute nu at the faces
1258  nu = rlv(i, j, k)/w(i, j, k, irho)
1259  num = half*(rlv(i, j, k-1)/w(i, j, k-1, irho)+nu)
1260  nup = half*(rlv(i, j, k+1)/w(i, j, k+1, irho)+nu)
1261  cdm = (num+(one+rsacb2)*nutm)*ttm*cb3inv
1262  cdp = (nup+(one+rsacb2)*nutp)*ttp*cb3inv
1263  if (cdm + cam .lt. zero) then
1264  c1m = zero
1265  else
1266  c1m = cdm + cam
1267  end if
1268  if (cdp + cap .lt. zero) then
1269  c1p = zero
1270  else
1271  c1p = cdp + cap
1272  end if
1273  c10 = c1m + c1p
1274 ! update the residual for this cell and store the possible
1275 ! coefficients for the matrix in b1, c1 and d1.
1276  scratch(i, j, k, idvt) = scratch(i, j, k, idvt) + c1m*w(i, j, k-1&
1277 & , itu1) - c10*w(i, j, k, itu1) + c1p*w(i, j, k+1, itu1)
1278  end do
1279 !$ad ii-loop
1280 !
1281 ! viscous terms in j-direction.
1282 !
1283  do ii=0,nx*ny*nz-1
1284  i = mod(ii, nx) + 2
1285  j = mod(ii/nx, ny) + 2
1286  k = ii/(nx*ny) + 2
1287 ! compute the metrics in eta-direction, i.e. along the
1288 ! line j = constant.
1289  voli = one/vol(i, j, k)
1290  volmi = two/(vol(i, j, k)+vol(i, j-1, k))
1291  volpi = two/(vol(i, j, k)+vol(i, j+1, k))
1292  xm = sj(i, j-1, k, 1)*volmi
1293  ym = sj(i, j-1, k, 2)*volmi
1294  zm = sj(i, j-1, k, 3)*volmi
1295  xp = sj(i, j, k, 1)*volpi
1296  yp = sj(i, j, k, 2)*volpi
1297  zp = sj(i, j, k, 3)*volpi
1298  xa = half*(sj(i, j, k, 1)+sj(i, j-1, k, 1))*voli
1299  ya = half*(sj(i, j, k, 2)+sj(i, j-1, k, 2))*voli
1300  za = half*(sj(i, j, k, 3)+sj(i, j-1, k, 3))*voli
1301  ttm = xm*xa + ym*ya + zm*za
1302  ttp = xp*xa + yp*ya + zp*za
1303 ! computation of the viscous terms in eta-direction; note
1304 ! that cross-derivatives are neglected, i.e. the mesh is
1305 ! assumed to be orthogonal.
1306 ! furthermore, the grad(nu)**2 has been rewritten as
1307 ! div(nu grad(nu)) - nu div(grad nu) to enhance stability.
1308 ! the second derivative in eta-direction is constructed as
1309 ! the central difference of the first order derivatives, i.e.
1310 ! d^2/deta^2 = d/deta (d/deta j+1/2 - d/deta j-1/2).
1311 ! in this way the metric can be taken into account.
1312 ! compute the diffusion coefficients multiplying the nodes
1313 ! j+1, j and j-1 in the second derivative. make sure that
1314 ! these coefficients are nonnegative.
1315  cnud = -(rsacb2*w(i, j, k, itu1)*cb3inv)
1316  cam = ttm*cnud
1317  cap = ttp*cnud
1318  nutm = half*(w(i, j-1, k, itu1)+w(i, j, k, itu1))
1319  nutp = half*(w(i, j+1, k, itu1)+w(i, j, k, itu1))
1320  nu = rlv(i, j, k)/w(i, j, k, irho)
1321  num = half*(rlv(i, j-1, k)/w(i, j-1, k, irho)+nu)
1322  nup = half*(rlv(i, j+1, k)/w(i, j+1, k, irho)+nu)
1323  cdm = (num+(one+rsacb2)*nutm)*ttm*cb3inv
1324  cdp = (nup+(one+rsacb2)*nutp)*ttp*cb3inv
1325  if (cdm + cam .lt. zero) then
1326  c1m = zero
1327  else
1328  c1m = cdm + cam
1329  end if
1330  if (cdp + cap .lt. zero) then
1331  c1p = zero
1332  else
1333  c1p = cdp + cap
1334  end if
1335  c10 = c1m + c1p
1336 ! update the residual for this cell and store the possible
1337 ! coefficients for the matrix in b1, c1 and d1.
1338  scratch(i, j, k, idvt) = scratch(i, j, k, idvt) + c1m*w(i, j-1, k&
1339 & , itu1) - c10*w(i, j, k, itu1) + c1p*w(i, j+1, k, itu1)
1340  end do
1341 !$ad ii-loop
1342 !
1343 ! viscous terms in i-direction.
1344 !
1345  do ii=0,nx*ny*nz-1
1346  i = mod(ii, nx) + 2
1347  j = mod(ii/nx, ny) + 2
1348  k = ii/(nx*ny) + 2
1349 ! compute the metrics in xi-direction, i.e. along the
1350 ! line i = constant.
1351  voli = one/vol(i, j, k)
1352  volmi = two/(vol(i, j, k)+vol(i-1, j, k))
1353  volpi = two/(vol(i, j, k)+vol(i+1, j, k))
1354  xm = si(i-1, j, k, 1)*volmi
1355  ym = si(i-1, j, k, 2)*volmi
1356  zm = si(i-1, j, k, 3)*volmi
1357  xp = si(i, j, k, 1)*volpi
1358  yp = si(i, j, k, 2)*volpi
1359  zp = si(i, j, k, 3)*volpi
1360  xa = half*(si(i, j, k, 1)+si(i-1, j, k, 1))*voli
1361  ya = half*(si(i, j, k, 2)+si(i-1, j, k, 2))*voli
1362  za = half*(si(i, j, k, 3)+si(i-1, j, k, 3))*voli
1363  ttm = xm*xa + ym*ya + zm*za
1364  ttp = xp*xa + yp*ya + zp*za
1365 ! computation of the viscous terms in xi-direction; note
1366 ! that cross-derivatives are neglected, i.e. the mesh is
1367 ! assumed to be orthogonal.
1368 ! furthermore, the grad(nu)**2 has been rewritten as
1369 ! div(nu grad(nu)) - nu div(grad nu) to enhance stability.
1370 ! the second derivative in xi-direction is constructed as
1371 ! the central difference of the first order derivatives, i.e.
1372 ! d^2/dxi^2 = d/dxi (d/dxi i+1/2 - d/dxi i-1/2).
1373 ! in this way the metric can be taken into account.
1374 ! compute the diffusion coefficients multiplying the nodes
1375 ! i+1, i and i-1 in the second derivative. make sure that
1376 ! these coefficients are nonnegative.
1377  cnud = -(rsacb2*w(i, j, k, itu1)*cb3inv)
1378  cam = ttm*cnud
1379  cap = ttp*cnud
1380  nutm = half*(w(i-1, j, k, itu1)+w(i, j, k, itu1))
1381  nutp = half*(w(i+1, j, k, itu1)+w(i, j, k, itu1))
1382  nu = rlv(i, j, k)/w(i, j, k, irho)
1383  num = half*(rlv(i-1, j, k)/w(i-1, j, k, irho)+nu)
1384  nup = half*(rlv(i+1, j, k)/w(i+1, j, k, irho)+nu)
1385  cdm = (num+(one+rsacb2)*nutm)*ttm*cb3inv
1386  cdp = (nup+(one+rsacb2)*nutp)*ttp*cb3inv
1387  if (cdm + cam .lt. zero) then
1388  c1m = zero
1389  else
1390  c1m = cdm + cam
1391  end if
1392  if (cdp + cap .lt. zero) then
1393  c1p = zero
1394  else
1395  c1p = cdp + cap
1396  end if
1397  c10 = c1m + c1p
1398 ! update the residual for this cell and store the possible
1399 ! coefficients for the matrix in b1, c1 and d1.
1400  scratch(i, j, k, idvt) = scratch(i, j, k, idvt) + c1m*w(i-1, j, k&
1401 & , itu1) - c10*w(i, j, k, itu1) + c1p*w(i+1, j, k, itu1)
1402  end do
1403  end subroutine saviscous
1404 
1405 ! differentiation of saresscale in reverse (adjoint) mode (with options noisize i4 dr8 r8):
1406 ! gradient of useful results: *dw
1407 ! with respect to varying inputs: *dw *scratch
1408 ! rw status of diff variables: *dw:in-out *scratch:out
1409 ! plus diff mem management of: dw:in scratch:in
1410  subroutine saresscale_b()
1411 !
1412 ! multiply the residual by the volume and store this in dw; this
1413 ! * is done for monitoring reasons only. the multiplication with the
1414 ! * volume is present to be consistent with the flow residuals; also
1415 ! the negative value is taken, again to be consistent with the
1416 ! * flow equations. also multiply by iblank so that no updates occur
1417 ! in holes or the overset boundary.
1418  use blockpointers
1419  implicit none
1420 ! local variables
1421  integer(kind=inttype) :: i, j, k, ii
1422  real(kind=realtype) :: rblank
1423  intrinsic mod
1424  intrinsic real
1425  intrinsic max
1426  real(realtype) :: x1
1427  if (associated(scratchd)) scratchd = 0.0_8
1428 !$bwd-of ii-loop
1429  do ii=0,nx*ny*nz-1
1430  i = mod(ii, nx) + 2
1431  j = mod(ii/nx, ny) + 2
1432  k = ii/(nx*ny) + 2
1433  x1 = real(iblank(i, j, k), realtype)
1434  if (x1 .lt. zero) then
1435  rblank = zero
1436  else
1437  rblank = x1
1438  end if
1439  scratchd(i, j, k, idvt) = scratchd(i, j, k, idvt) - volref(i, j, k&
1440 & )*rblank*dwd(i, j, k, itu1)
1441  dwd(i, j, k, itu1) = 0.0_8
1442  end do
1443  end subroutine saresscale_b
1444 
1445  subroutine saresscale()
1446 !
1447 ! multiply the residual by the volume and store this in dw; this
1448 ! * is done for monitoring reasons only. the multiplication with the
1449 ! * volume is present to be consistent with the flow residuals; also
1450 ! the negative value is taken, again to be consistent with the
1451 ! * flow equations. also multiply by iblank so that no updates occur
1452 ! in holes or the overset boundary.
1453  use blockpointers
1454  implicit none
1455 ! local variables
1456  integer(kind=inttype) :: i, j, k, ii
1457  real(kind=realtype) :: rblank
1458  intrinsic mod
1459  intrinsic real
1460  intrinsic max
1461  real(realtype) :: x1
1462 !$ad ii-loop
1463  do ii=0,nx*ny*nz-1
1464  i = mod(ii, nx) + 2
1465  j = mod(ii/nx, ny) + 2
1466  k = ii/(nx*ny) + 2
1467  x1 = real(iblank(i, j, k), realtype)
1468  if (x1 .lt. zero) then
1469  rblank = zero
1470  else
1471  rblank = x1
1472  end if
1473  dw(i, j, k, itu1) = -(volref(i, j, k)*scratch(i, j, k, idvt)*&
1474 & rblank)
1475  end do
1476  end subroutine saresscale
1477 
1478 end module sa_b
1479 
real(kind=realtype), dimension(:, :, :, :), pointer sjd
real(kind=realtype), dimension(:, :, :, :), pointer wd
real(kind=realtype), dimension(:, :, :), pointer vold
integer(kind=inttype) nx
integer(kind=inttype) ny
real(kind=realtype), dimension(:, :, :, :), pointer w
real(kind=realtype), dimension(:, :, :, :), pointer scratch
real(kind=realtype), dimension(:, :, :), pointer d2wall
integer(kind=inttype), dimension(:, :, :), pointer iblank
real(kind=realtype), dimension(:, :, :, :), pointer skd
real(kind=realtype), dimension(:, :, :), pointer rlv
real(kind=realtype), dimension(:, :, :, :), pointer si
real(kind=realtype), dimension(:, :, :, :), pointer sid
real(kind=realtype), dimension(:, :, :), pointer volref
real(kind=realtype), dimension(:, :, :, :), pointer sj
integer(kind=inttype) sectionid
real(kind=realtype), dimension(:, :, :, :), pointer scratchd
real(kind=realtype), dimension(:, :, :, :), pointer dw
real(kind=realtype), dimension(:, :, :, :), pointer sk
real(kind=realtype), dimension(:, :, :), pointer rlvd
real(kind=realtype), dimension(:, :, :), pointer vol
integer(kind=inttype) nz
real(kind=realtype), dimension(:, :, :), pointer d2walld
real(kind=realtype), dimension(:, :, :, :), pointer dwd
integer(kind=inttype), parameter strain
Definition: constants.F90:137
real(kind=realtype), parameter zero
Definition: constants.F90:71
integer, parameter idvt
Definition: constants.F90:51
real(kind=realtype), parameter third
Definition: constants.F90:81
integer, parameter itu1
Definition: constants.F90:40
integer, parameter irho
Definition: constants.F90:34
integer(kind=inttype), parameter vorticity
Definition: constants.F90:137
integer, parameter ivx
Definition: constants.F90:35
real(kind=realtype), parameter one
Definition: constants.F90:72
real(kind=realtype), parameter half
Definition: constants.F90:80
integer(kind=inttype), parameter katolaunder
Definition: constants.F90:137
integer, parameter ivz
Definition: constants.F90:37
real(kind=realtype), parameter two
Definition: constants.F90:73
real(kind=realtype), parameter fourth
Definition: constants.F90:82
integer, parameter ivy
Definition: constants.F90:36
real(kind=realtype), parameter sixth
Definition: constants.F90:83
real(kind=realtype) timeref
real(kind=realtype) timerefd
logical useft2sa
Definition: inputParam.F90:587
integer(kind=inttype) turbprod
Definition: inputParam.F90:584
logical userotationsa
Definition: inputParam.F90:587
real(kind=realtype), parameter rsacw1
Definition: paramTurb.F90:18
real(kind=realtype), parameter rsak
Definition: paramTurb.F90:13
real(kind=realtype), parameter rsact4
Definition: paramTurb.F90:25
real(kind=realtype), parameter rsacrot
Definition: paramTurb.F90:26
real(kind=realtype), parameter rsacb2
Definition: paramTurb.F90:15
real(kind=realtype), parameter rsact3
Definition: paramTurb.F90:24
real(kind=realtype), parameter rsacw3
Definition: paramTurb.F90:21
real(kind=realtype), parameter rsacw2
Definition: paramTurb.F90:20
real(kind=realtype), parameter rsacv1
Definition: paramTurb.F90:17
real(kind=realtype), parameter rsacb3
Definition: paramTurb.F90:16
real(kind=realtype), parameter rsacb1
Definition: paramTurb.F90:14
Definition: sa_b.f90:7
real(kind=realtype), dimension(:, :, :), pointer ddw
Definition: sa_b.f90:12
real(kind=realtype) cv13
Definition: sa_b.f90:10
real(kind=realtype) cb3inv
Definition: sa_b.f90:10
real(kind=realtype), dimension(:, :, :), pointer ddvt
Definition: sa_b.f90:12
real(kind=realtype), dimension(:, :), pointer rrlv
Definition: sa_b.f90:13
real(kind=realtype) cw36
Definition: sa_b.f90:10
real(kind=realtype), dimension(:, :, :), allocatable qq
Definition: sa_b.f90:11
real(kind=realtype) kar2inv
Definition: sa_b.f90:10
subroutine sasource()
Definition: sa_b.f90:497
real(kind=realtype), dimension(:, :), pointer dd2wall
Definition: sa_b.f90:14
subroutine saviscous()
Definition: sa_b.f90:1192
subroutine saresscale()
Definition: sa_b.f90:1446
subroutine saviscous_b()
Definition: sa_b.f90:700
subroutine saresscale_b()
Definition: sa_b.f90:1411
real(kind=realtype), dimension(:, :, :), pointer ww
Definition: sa_b.f90:12
subroutine sasource_b()
Definition: sa_b.f90:28
type(sectiontype), dimension(:), allocatable sections
Definition: section.f90:46
Definition: SST.F90:1