ADflow  v1.0
ADflow is a finite volume RANS solver tailored for gradient-based aerodynamic design optimization.
wallDistance_b.f90
Go to the documentation of this file.
1 ! generated by tapenade (inria, ecuador team)
2 ! tapenade 3.16 (develop) - 22 aug 2023 15:51
3 !
5  use constants, only : inttype, realtype
7  implicit none
8  save
9 
10 contains
11 ! differentiation of updatewalldistancesquickly in reverse (adjoint) mode (with options noisize i4 dr8 r8):
12 ! gradient of useful results: *x *d2wall *xsurf
13 ! with respect to varying inputs: *x *d2wall *xsurf
14 ! rw status of diff variables: *x:incr *d2wall:in-out *xsurf:incr
15 ! plus diff mem management of: x:in d2wall:in xsurf:in
16  subroutine updatewalldistancesquickly_b(nn, level, sps)
17 ! this is the actual update routine that uses xsurf. it is done on
18 ! block-level-sps basis. this is the used to update the wall
19 ! distance. most importantly, this routine is included in the
20 ! reverse mode ad routines, but not the forward mode. since it is
21 ! done on a per-block basis, it is assumed that the required block
22 ! pointers are already set.
23  use constants
24  use blockpointers, only : nx, ny, nz, il, jl, kl, x, xd, flowdoms,&
25 & flowdomsd, d2wall, d2walld
26  implicit none
27 ! subroutine arguments
28  integer(kind=inttype) :: nn, level, sps
29 ! local variables
30  integer(kind=inttype) :: i, j, k, ii, ind(4)
31  real(kind=realtype) :: xp(3), xc(3), u, v
32  real(kind=realtype) :: xpd(3), xcd(3)
33  intrinsic mod
34  intrinsic sqrt
35  real(kind=realtype) :: tempd
36  real(kind=realtype) :: tempd0
37  real(kind=realtype) :: tempd1
38  real(kind=realtype) :: tempd2
39  xcd = 0.0_8
40 !$bwd-of ii-loop
41  do ii=0,nx*ny*nz-1
42  i = mod(ii, nx) + 2
43  j = mod(ii/nx, ny) + 2
44  k = ii/(nx*ny) + 2
45  if (flowdoms(nn, level, sps)%surfnodeindices(1, i, j, k) .eq. 0) &
46 & then
47  d2walld(i, j, k) = 0.0_8
48  else
49 ! extract elemid and u-v position for the association of
50 ! this cell:
51  ind = flowdoms(nn, level, sps)%surfnodeindices(:, i, j, k)
52  u = flowdoms(nn, level, sps)%uv(1, i, j, k)
53  v = flowdoms(nn, level, sps)%uv(2, i, j, k)
54 ! now we have the 4 corners, use bi-linear shape
55 ! functions o to get target: (ccw ordering remember!)
56  xp(:) = (one-u)*(one-v)*xsurf(3*(ind(1)-1)+1:3*ind(1)) + u*(one-&
57 & v)*xsurf(3*(ind(2)-1)+1:3*ind(2)) + u*v*xsurf(3*(ind(3)-1)+1:3&
58 & *ind(3)) + (one-u)*v*xsurf(3*(ind(4)-1)+1:3*ind(4))
59 ! get the cell center
60  xc(1) = eighth*(x(i-1, j-1, k-1, 1)+x(i, j-1, k-1, 1)+x(i-1, j, &
61 & k-1, 1)+x(i, j, k-1, 1)+x(i-1, j-1, k, 1)+x(i, j-1, k, 1)+x(i-&
62 & 1, j, k, 1)+x(i, j, k, 1))
63  xc(2) = eighth*(x(i-1, j-1, k-1, 2)+x(i, j-1, k-1, 2)+x(i-1, j, &
64 & k-1, 2)+x(i, j, k-1, 2)+x(i-1, j-1, k, 2)+x(i, j-1, k, 2)+x(i-&
65 & 1, j, k, 2)+x(i, j, k, 2))
66  xc(3) = eighth*(x(i-1, j-1, k-1, 3)+x(i, j-1, k-1, 3)+x(i-1, j, &
67 & k-1, 3)+x(i, j, k-1, 3)+x(i-1, j-1, k, 3)+x(i, j-1, k, 3)+x(i-&
68 & 1, j, k, 3)+x(i, j, k, 3))
69 ! now we have the two points...just take the norm of the
70 ! distance between them
71  xpd = 0.0_8
72  if ((xc(1)-xp(1))**2 + (xc(2)-xp(2))**2 + (xc(3)-xp(3))**2 .eq. &
73 & 0.0_8) then
74  tempd = 0.0_8
75  else
76  tempd = d2walld(i, j, k)/(2.0*sqrt((xc(1)-xp(1))**2+(xc(2)-xp(&
77 & 2))**2+(xc(3)-xp(3))**2))
78  end if
79  d2walld(i, j, k) = 0.0_8
80  tempd0 = 2*(xc(1)-xp(1))*tempd
81  tempd1 = 2*(xc(2)-xp(2))*tempd
82  tempd2 = 2*(xc(3)-xp(3))*tempd
83  xcd(3) = xcd(3) + tempd2
84  xpd(3) = xpd(3) - tempd2
85  xcd(2) = xcd(2) + tempd1
86  xpd(2) = xpd(2) - tempd1
87  xcd(1) = xcd(1) + tempd0
88  xpd(1) = xpd(1) - tempd0
89  tempd = eighth*xcd(3)
90  xcd(3) = 0.0_8
91  xd(i-1, j-1, k-1, 3) = xd(i-1, j-1, k-1, 3) + tempd
92  xd(i, j-1, k-1, 3) = xd(i, j-1, k-1, 3) + tempd
93  xd(i-1, j, k-1, 3) = xd(i-1, j, k-1, 3) + tempd
94  xd(i, j, k-1, 3) = xd(i, j, k-1, 3) + tempd
95  xd(i-1, j-1, k, 3) = xd(i-1, j-1, k, 3) + tempd
96  xd(i, j-1, k, 3) = xd(i, j-1, k, 3) + tempd
97  xd(i-1, j, k, 3) = xd(i-1, j, k, 3) + tempd
98  xd(i, j, k, 3) = xd(i, j, k, 3) + tempd
99  tempd = eighth*xcd(2)
100  xcd(2) = 0.0_8
101  xd(i-1, j-1, k-1, 2) = xd(i-1, j-1, k-1, 2) + tempd
102  xd(i, j-1, k-1, 2) = xd(i, j-1, k-1, 2) + tempd
103  xd(i-1, j, k-1, 2) = xd(i-1, j, k-1, 2) + tempd
104  xd(i, j, k-1, 2) = xd(i, j, k-1, 2) + tempd
105  xd(i-1, j-1, k, 2) = xd(i-1, j-1, k, 2) + tempd
106  xd(i, j-1, k, 2) = xd(i, j-1, k, 2) + tempd
107  xd(i-1, j, k, 2) = xd(i-1, j, k, 2) + tempd
108  xd(i, j, k, 2) = xd(i, j, k, 2) + tempd
109  tempd = eighth*xcd(1)
110  xcd(1) = 0.0_8
111  xd(i-1, j-1, k-1, 1) = xd(i-1, j-1, k-1, 1) + tempd
112  xd(i, j-1, k-1, 1) = xd(i, j-1, k-1, 1) + tempd
113  xd(i-1, j, k-1, 1) = xd(i-1, j, k-1, 1) + tempd
114  xd(i, j, k-1, 1) = xd(i, j, k-1, 1) + tempd
115  xd(i-1, j-1, k, 1) = xd(i-1, j-1, k, 1) + tempd
116  xd(i, j-1, k, 1) = xd(i, j-1, k, 1) + tempd
117  xd(i-1, j, k, 1) = xd(i-1, j, k, 1) + tempd
118  xd(i, j, k, 1) = xd(i, j, k, 1) + tempd
119  xsurfd(3*(ind(1)-1)+1:3*ind(1)) = xsurfd(3*(ind(1)-1)+1:3*ind(1)&
120 & ) + (one-u)*(one-v)*xpd
121  xsurfd(3*(ind(2)-1)+1:3*ind(2)) = xsurfd(3*(ind(2)-1)+1:3*ind(2)&
122 & ) + u*(one-v)*xpd
123  xsurfd(3*(ind(3)-1)+1:3*ind(3)) = xsurfd(3*(ind(3)-1)+1:3*ind(3)&
124 & ) + u*v*xpd
125  xsurfd(3*(ind(4)-1)+1:3*ind(4)) = xsurfd(3*(ind(4)-1)+1:3*ind(4)&
126 & ) + (one-u)*v*xpd
127  end if
128  end do
129  end subroutine updatewalldistancesquickly_b
130 
131  subroutine updatewalldistancesquickly(nn, level, sps)
132 ! this is the actual update routine that uses xsurf. it is done on
133 ! block-level-sps basis. this is the used to update the wall
134 ! distance. most importantly, this routine is included in the
135 ! reverse mode ad routines, but not the forward mode. since it is
136 ! done on a per-block basis, it is assumed that the required block
137 ! pointers are already set.
138  use constants
139  use blockpointers, only : nx, ny, nz, il, jl, kl, x, flowdoms, &
140 & d2wall
141  implicit none
142 ! subroutine arguments
143  integer(kind=inttype) :: nn, level, sps
144 ! local variables
145  integer(kind=inttype) :: i, j, k, ii, ind(4)
146  real(kind=realtype) :: xp(3), xc(3), u, v
147  intrinsic mod
148  intrinsic sqrt
149 !$ad ii-loop
150  do ii=0,nx*ny*nz-1
151  i = mod(ii, nx) + 2
152  j = mod(ii/nx, ny) + 2
153  k = ii/(nx*ny) + 2
154  if (flowdoms(nn, level, sps)%surfnodeindices(1, i, j, k) .eq. 0) &
155 & then
156 ! this node is too far away and has no
157 ! association. set the distance to a large constant.
158  d2wall(i, j, k) = large
159  else
160 ! extract elemid and u-v position for the association of
161 ! this cell:
162  ind = flowdoms(nn, level, sps)%surfnodeindices(:, i, j, k)
163  u = flowdoms(nn, level, sps)%uv(1, i, j, k)
164  v = flowdoms(nn, level, sps)%uv(2, i, j, k)
165 ! now we have the 4 corners, use bi-linear shape
166 ! functions o to get target: (ccw ordering remember!)
167  xp(:) = (one-u)*(one-v)*xsurf(3*(ind(1)-1)+1:3*ind(1)) + u*(one-&
168 & v)*xsurf(3*(ind(2)-1)+1:3*ind(2)) + u*v*xsurf(3*(ind(3)-1)+1:3&
169 & *ind(3)) + (one-u)*v*xsurf(3*(ind(4)-1)+1:3*ind(4))
170 ! get the cell center
171  xc(1) = eighth*(x(i-1, j-1, k-1, 1)+x(i, j-1, k-1, 1)+x(i-1, j, &
172 & k-1, 1)+x(i, j, k-1, 1)+x(i-1, j-1, k, 1)+x(i, j-1, k, 1)+x(i-&
173 & 1, j, k, 1)+x(i, j, k, 1))
174  xc(2) = eighth*(x(i-1, j-1, k-1, 2)+x(i, j-1, k-1, 2)+x(i-1, j, &
175 & k-1, 2)+x(i, j, k-1, 2)+x(i-1, j-1, k, 2)+x(i, j-1, k, 2)+x(i-&
176 & 1, j, k, 2)+x(i, j, k, 2))
177  xc(3) = eighth*(x(i-1, j-1, k-1, 3)+x(i, j-1, k-1, 3)+x(i-1, j, &
178 & k-1, 3)+x(i, j, k-1, 3)+x(i-1, j-1, k, 3)+x(i, j-1, k, 3)+x(i-&
179 & 1, j, k, 3)+x(i, j, k, 3))
180 ! now we have the two points...just take the norm of the
181 ! distance between them
182  d2wall(i, j, k) = sqrt((xc(1)-xp(1))**2 + (xc(2)-xp(2))**2 + (xc&
183 & (3)-xp(3))**2)
184  end if
185  end do
186  end subroutine updatewalldistancesquickly
187 ! ----------------------------------------------------------------------
188 ! |
189 ! no tapenade routine below this line |
190 ! |
191 ! ----------------------------------------------------------------------
192 
193 end module walldistance_b
194 
integer(kind=inttype) jl
integer(kind=inttype) nx
integer(kind=inttype) ny
real(kind=realtype), dimension(:, :, :), pointer d2wall
real(kind=realtype), dimension(:, :, :, :), pointer xd
integer(kind=inttype) nz
real(kind=realtype), dimension(:, :, :, :), pointer x
real(kind=realtype), dimension(:, :, :), pointer d2walld
integer(kind=inttype) kl
integer(kind=inttype) il
real(kind=realtype), parameter eighth
Definition: constants.F90:84
real(kind=realtype), parameter one
Definition: constants.F90:72
real(kind=realtype), parameter large
Definition: constants.F90:24
subroutine updatewalldistancesquickly(nn, level, sps)
subroutine updatewalldistancesquickly_b(nn, level, sps)
real(kind=realtype), dimension(:), pointer xsurf
real(kind=realtype), dimension(:), pointer xsurfd