ADflow  v1.0
ADflow is a finite volume RANS solver tailored for gradient-based aerodynamic design optimization.
wallDistance_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 !
5  use constants, only : inttype, realtype
7  implicit none
8  save
9 
10 contains
11 ! differentiation of updatewalldistancesquickly in forward (tangent) mode (with options i4 dr8 r8):
12 ! variations of useful results: *d2wall
13 ! with respect to varying inputs: *x *d2wall *xsurf
14 ! rw status of diff variables: *x:in *d2wall:in-out *xsurf:in
15 ! plus diff mem management of: x:in d2wall:in xsurf:in
16  subroutine updatewalldistancesquickly_d(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 sqrt
34  real(kind=realtype) :: arg1
35  real(kind=realtype) :: arg1d
36  real(kind=realtype) :: temp
37  xcd = 0.0_8
38  do k=2,kl
39  do j=2,jl
40  do i=2,il
41  if (flowdoms(nn, level, sps)%surfnodeindices(1, i, j, k) .eq. &
42 & 0) then
43 ! this node is too far away and has no
44 ! association. set the distance to a large constant.
45  d2walld(i, j, k) = 0.0_8
46  d2wall(i, j, k) = large
47  else
48 ! extract elemid and u-v position for the association of
49 ! this cell:
50  ind = flowdoms(nn, level, sps)%surfnodeindices(:, i, j, k)
51  u = flowdoms(nn, level, sps)%uv(1, i, j, k)
52  v = flowdoms(nn, level, sps)%uv(2, i, j, k)
53 ! now we have the 4 corners, use bi-linear shape
54 ! functions o to get target: (ccw ordering remember!)
55  temp = (one-u)*(one-v)
56  xpd(:) = temp*xsurfd(3*(ind(1)-1)+1:3*ind(1)) + u*(one-v)*&
57 & xsurfd(3*(ind(2)-1)+1:3*ind(2)) + u*v*xsurfd(3*(ind(3)-1)+&
58 & 1:3*ind(3)) + (one-u)*v*xsurfd(3*(ind(4)-1)+1:3*ind(4))
59  xp(:) = temp*xsurf(3*(ind(1)-1)+1:3*ind(1)) + u*(one-v)*&
60 & xsurf(3*(ind(2)-1)+1:3*ind(2)) + u*v*xsurf(3*(ind(3)-1)+1:&
61 & 3*ind(3)) + (one-u)*v*xsurf(3*(ind(4)-1)+1:3*ind(4))
62 ! get the cell center
63  xcd(1) = eighth*(xd(i-1, j-1, k-1, 1)+xd(i, j-1, k-1, 1)+xd(&
64 & i-1, j, k-1, 1)+xd(i, j, k-1, 1)+xd(i-1, j-1, k, 1)+xd(i, &
65 & j-1, k, 1)+xd(i-1, j, k, 1)+xd(i, j, k, 1))
66  xc(1) = eighth*(x(i-1, j-1, k-1, 1)+x(i, j-1, k-1, 1)+x(i-1&
67 & , j, k-1, 1)+x(i, j, k-1, 1)+x(i-1, j-1, k, 1)+x(i, j-1, k&
68 & , 1)+x(i-1, j, k, 1)+x(i, j, k, 1))
69  xcd(2) = eighth*(xd(i-1, j-1, k-1, 2)+xd(i, j-1, k-1, 2)+xd(&
70 & i-1, j, k-1, 2)+xd(i, j, k-1, 2)+xd(i-1, j-1, k, 2)+xd(i, &
71 & j-1, k, 2)+xd(i-1, j, k, 2)+xd(i, j, k, 2))
72  xc(2) = eighth*(x(i-1, j-1, k-1, 2)+x(i, j-1, k-1, 2)+x(i-1&
73 & , j, k-1, 2)+x(i, j, k-1, 2)+x(i-1, j-1, k, 2)+x(i, j-1, k&
74 & , 2)+x(i-1, j, k, 2)+x(i, j, k, 2))
75  xcd(3) = eighth*(xd(i-1, j-1, k-1, 3)+xd(i, j-1, k-1, 3)+xd(&
76 & i-1, j, k-1, 3)+xd(i, j, k-1, 3)+xd(i-1, j-1, k, 3)+xd(i, &
77 & j-1, k, 3)+xd(i-1, j, k, 3)+xd(i, j, k, 3))
78  xc(3) = eighth*(x(i-1, j-1, k-1, 3)+x(i, j-1, k-1, 3)+x(i-1&
79 & , j, k-1, 3)+x(i, j, k-1, 3)+x(i-1, j-1, k, 3)+x(i, j-1, k&
80 & , 3)+x(i-1, j, k, 3)+x(i, j, k, 3))
81 ! now we have the two points...just take the norm of the
82 ! distance between them
83  arg1d = 2*(xc(1)-xp(1))*(xcd(1)-xpd(1)) + 2*(xc(2)-xp(2))*(&
84 & xcd(2)-xpd(2)) + 2*(xc(3)-xp(3))*(xcd(3)-xpd(3))
85  arg1 = (xc(1)-xp(1))**2 + (xc(2)-xp(2))**2 + (xc(3)-xp(3))**&
86 & 2
87  temp = sqrt(arg1)
88  if (arg1 .eq. 0.0_8) then
89  d2walld(i, j, k) = 0.0_8
90  else
91  d2walld(i, j, k) = arg1d/(2.0*temp)
92  end if
93  d2wall(i, j, k) = temp
94  end if
95  end do
96  end do
97  end do
98  end subroutine updatewalldistancesquickly_d
99 
100  subroutine updatewalldistancesquickly(nn, level, sps)
101 ! this is the actual update routine that uses xsurf. it is done on
102 ! block-level-sps basis. this is the used to update the wall
103 ! distance. most importantly, this routine is included in the
104 ! reverse mode ad routines, but not the forward mode. since it is
105 ! done on a per-block basis, it is assumed that the required block
106 ! pointers are already set.
107  use constants
108  use blockpointers, only : nx, ny, nz, il, jl, kl, x, flowdoms, &
109 & d2wall
110  implicit none
111 ! subroutine arguments
112  integer(kind=inttype) :: nn, level, sps
113 ! local variables
114  integer(kind=inttype) :: i, j, k, ii, ind(4)
115  real(kind=realtype) :: xp(3), xc(3), u, v
116  intrinsic sqrt
117  real(kind=realtype) :: arg1
118  do k=2,kl
119  do j=2,jl
120  do i=2,il
121  if (flowdoms(nn, level, sps)%surfnodeindices(1, i, j, k) .eq. &
122 & 0) then
123 ! this node is too far away and has no
124 ! association. set the distance to a large constant.
125  d2wall(i, j, k) = large
126  else
127 ! extract elemid and u-v position for the association of
128 ! this cell:
129  ind = flowdoms(nn, level, sps)%surfnodeindices(:, i, j, k)
130  u = flowdoms(nn, level, sps)%uv(1, i, j, k)
131  v = flowdoms(nn, level, sps)%uv(2, i, j, k)
132 ! now we have the 4 corners, use bi-linear shape
133 ! functions o to get target: (ccw ordering remember!)
134  xp(:) = (one-u)*(one-v)*xsurf(3*(ind(1)-1)+1:3*ind(1)) + u*(&
135 & one-v)*xsurf(3*(ind(2)-1)+1:3*ind(2)) + u*v*xsurf(3*(ind(3&
136 & )-1)+1:3*ind(3)) + (one-u)*v*xsurf(3*(ind(4)-1)+1:3*ind(4)&
137 & )
138 ! get the cell center
139  xc(1) = eighth*(x(i-1, j-1, k-1, 1)+x(i, j-1, k-1, 1)+x(i-1&
140 & , j, k-1, 1)+x(i, j, k-1, 1)+x(i-1, j-1, k, 1)+x(i, j-1, k&
141 & , 1)+x(i-1, j, k, 1)+x(i, j, k, 1))
142  xc(2) = eighth*(x(i-1, j-1, k-1, 2)+x(i, j-1, k-1, 2)+x(i-1&
143 & , j, k-1, 2)+x(i, j, k-1, 2)+x(i-1, j-1, k, 2)+x(i, j-1, k&
144 & , 2)+x(i-1, j, k, 2)+x(i, j, k, 2))
145  xc(3) = eighth*(x(i-1, j-1, k-1, 3)+x(i, j-1, k-1, 3)+x(i-1&
146 & , j, k-1, 3)+x(i, j, k-1, 3)+x(i-1, j-1, k, 3)+x(i, j-1, k&
147 & , 3)+x(i-1, j, k, 3)+x(i, j, k, 3))
148 ! now we have the two points...just take the norm of the
149 ! distance between them
150  arg1 = (xc(1)-xp(1))**2 + (xc(2)-xp(2))**2 + (xc(3)-xp(3))**&
151 & 2
152  d2wall(i, j, k) = sqrt(arg1)
153  end if
154  end do
155  end do
156  end do
157  end subroutine updatewalldistancesquickly
158 ! ----------------------------------------------------------------------
159 ! |
160 ! no tapenade routine below this line |
161 ! |
162 ! ----------------------------------------------------------------------
163 
164 end module walldistance_d
165 
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_d(nn, level, sps)
real(kind=realtype), dimension(:), pointer xsurf
real(kind=realtype), dimension(:), pointer xsurfd