ADflow  v1.0
ADflow is a finite volume RANS solver tailored for gradient-based aerodynamic design optimization.
oversetUtilities_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  implicit none
6 
7 contains
8 ! differentiation of fractoweights in forward (tangent) mode (with options i4 dr8 r8):
9 ! variations of useful results: weights
10 ! with respect to varying inputs: frac
11 ! rw status of diff variables: weights:out frac:in
12 ! --------------------------------------------------
13 ! tapenade routine below this point
14 ! --------------------------------------------------
15  subroutine fractoweights_d(frac, fracd, weights, weightsd)
16  use constants
17  implicit none
18  real(kind=realtype), dimension(3), intent(in) :: frac
19  real(kind=realtype), dimension(3), intent(in) :: fracd
20  real(kind=realtype), dimension(8), intent(out) :: weights
21  real(kind=realtype), dimension(8), intent(out) :: weightsd
22  real(kind=realtype) :: temp
23  weightsd = 0.0_8
24  temp = (one-frac(1))*(one-frac(2))
25  weightsd(1) = (one-frac(3))*(-((one-frac(2))*fracd(1))-(one-frac(1))&
26 & *fracd(2)) - temp*fracd(3)
27  weights(1) = temp*(one-frac(3))
28  temp = frac(1)*(one-frac(2))
29  weightsd(2) = (one-frac(3))*((one-frac(2))*fracd(1)-frac(1)*fracd(2)&
30 & ) - temp*fracd(3)
31  weights(2) = temp*(one-frac(3))
32  temp = (one-frac(1))*frac(2)
33  weightsd(3) = (one-frac(3))*((one-frac(1))*fracd(2)-frac(2)*fracd(1)&
34 & ) - temp*fracd(3)
35  weights(3) = temp*(one-frac(3))
36  weightsd(4) = (one-frac(3))*(frac(2)*fracd(1)+frac(1)*fracd(2)) - &
37 & frac(1)*frac(2)*fracd(3)
38  weights(4) = frac(1)*frac(2)*(one-frac(3))
39  temp = (one-frac(1))*frac(3)
40  weightsd(5) = (one-frac(2))*((one-frac(1))*fracd(3)-frac(3)*fracd(1)&
41 & ) - temp*fracd(2)
42  weights(5) = temp*(one-frac(2))
43  weightsd(6) = (one-frac(2))*(frac(3)*fracd(1)+frac(1)*fracd(3)) - &
44 & frac(1)*frac(3)*fracd(2)
45  weights(6) = frac(1)*(one-frac(2))*frac(3)
46  weightsd(7) = (one-frac(1))*(frac(3)*fracd(2)+frac(2)*fracd(3)) - &
47 & frac(2)*frac(3)*fracd(1)
48  weights(7) = (one-frac(1))*frac(2)*frac(3)
49  weightsd(8) = frac(3)*(frac(2)*fracd(1)+frac(1)*fracd(2)) + frac(1)*&
50 & frac(2)*fracd(3)
51  weights(8) = frac(1)*frac(2)*frac(3)
52  end subroutine fractoweights_d
53 
54 ! --------------------------------------------------
55 ! tapenade routine below this point
56 ! --------------------------------------------------
57  subroutine fractoweights(frac, weights)
58  use constants
59  implicit none
60  real(kind=realtype), dimension(3), intent(in) :: frac
61  real(kind=realtype), dimension(8), intent(out) :: weights
62  weights(1) = (one-frac(1))*(one-frac(2))*(one-frac(3))
63  weights(2) = frac(1)*(one-frac(2))*(one-frac(3))
64  weights(3) = (one-frac(1))*frac(2)*(one-frac(3))
65  weights(4) = frac(1)*frac(2)*(one-frac(3))
66  weights(5) = (one-frac(1))*(one-frac(2))*frac(3)
67  weights(6) = frac(1)*(one-frac(2))*frac(3)
68  weights(7) = (one-frac(1))*frac(2)*frac(3)
69  weights(8) = frac(1)*frac(2)*frac(3)
70  end subroutine fractoweights
71 
72  subroutine fractoweights2(frac, weights)
73  use constants
74  implicit none
75  real(kind=realtype), dimension(3), intent(in) :: frac
76  real(kind=realtype), dimension(8), intent(out) :: weights
77  weights(1) = (one-frac(1))*(one-frac(2))*(one-frac(3))
78  weights(2) = frac(1)*(one-frac(2))*(one-frac(3))
79  weights(3) = frac(1)*frac(2)*(one-frac(3))
80  weights(4) = (one-frac(1))*frac(2)*(one-frac(3))
81  weights(5) = (one-frac(1))*(one-frac(2))*frac(3)
82  weights(6) = frac(1)*(one-frac(2))*frac(3)
83  weights(7) = frac(1)*frac(2)*frac(3)
84  weights(8) = (one-frac(1))*frac(2)*frac(3)
85  end subroutine fractoweights2
86 
87 ! differentiation of newtonupdate in forward (tangent) mode (with options i4 dr8 r8):
88 ! variations of useful results: frac
89 ! with respect to varying inputs: xcen blk frac
90 ! rw status of diff variables: xcen:in blk:in frac:in-out
91  subroutine newtonupdate_d(xcen, xcend, blk, blkd, frac0, frac, fracd)
92 ! this routine performs the newton update to recompute the new
93 ! "frac" (u,v,w) for the point xcen. the actual search is performed
94 ! on the the dual cell formed by the cell centers of the 3x3x3 block
95 ! of primal nodes. this routine is ad'd with tapenade in both
96 ! forward and reverse.
97  use constants
98  implicit none
99 ! input
100  real(kind=realtype), dimension(3), intent(in) :: xcen
101  real(kind=realtype), dimension(3), intent(in) :: xcend
102  real(kind=realtype), dimension(3, 3, 3, 3), intent(in) :: blk
103  real(kind=realtype), dimension(3, 3, 3, 3), intent(in) :: blkd
104  real(kind=realtype), dimension(3), intent(in) :: frac0
105 ! output
106  real(kind=realtype), dimension(3), intent(out) :: frac
107  real(kind=realtype), dimension(3), intent(out) :: fracd
108 ! working
109  real(kind=realtype), dimension(3, 8) :: xn
110  real(kind=realtype), dimension(3, 8) :: xnd
111  real(kind=realtype) :: u, v, w, uv, uw, vw, wvu, du, dv, dw
112  real(kind=realtype) :: ud, vd, wd, uvd, uwd, vwd, wvud, dud, dvd, &
113 & dwd
114  real(kind=realtype) :: a11, a12, a13, a21, a22, a23, a31, a32, a33, &
115 & val
116  real(kind=realtype) :: a11d, a12d, a13d, a21d, a22d, a23d, a31d, &
117 & a32d, a33d, vald
118  real(kind=realtype) :: f(3), x(3)
119  real(kind=realtype) :: fd(3), xd(3)
120  integer(kind=inttype), dimension(8), parameter :: indices=(/1, 2, 4&
121 & , 3, 5, 6, 8, 7/)
122  integer(kind=inttype) :: i, j, k, ii, ll
123  real(kind=realtype), parameter :: adteps=1.e-25_realtype
124  real(kind=realtype), parameter :: thresconv=1.e-10_realtype
125  intrinsic sign
126  intrinsic abs
127  intrinsic max
128  intrinsic sqrt
129  real(kind=realtype) :: x1
130  real(kind=realtype) :: x1d
131  real(kind=realtype) :: max1
132  real(kind=realtype) :: max1d
133  real(kind=realtype) :: arg1
134  real(kind=realtype) :: temp
135  real(kind=realtype) :: temp0
136  real(kind=realtype) :: temp1
137  real(kind=realtype) :: temp2
138 ! compute the cell center locations for the 8 nodes describing the
139 ! dual cell. note that this must be counter-clockwise ordering.
140  ii = 0
141  xnd = 0.0_8
142  do k=1,2
143  do j=1,2
144  do i=1,2
145  ii = ii + 1
146  xnd(:, indices(ii)) = eighth*(blkd(i, j, k, :)+blkd(i+1, j, k&
147 & , :)+blkd(i, j+1, k, :)+blkd(i+1, j+1, k, :)+blkd(i, j, k+1&
148 & , :)+blkd(i+1, j, k+1, :)+blkd(i, j+1, k+1, :)+blkd(i+1, j+1&
149 & , k+1, :))
150  xn(:, indices(ii)) = eighth*(blk(i, j, k, :)+blk(i+1, j, k, :)&
151 & +blk(i, j+1, k, :)+blk(i+1, j+1, k, :)+blk(i, j, k+1, :)+blk&
152 & (i+1, j, k+1, :)+blk(i, j+1, k+1, :)+blk(i+1, j+1, k+1, :))
153  end do
154  end do
155  end do
156 ! compute the coordinates relative to node 1.
157  do i=2,8
158  xnd(:, i) = xnd(:, i) - xnd(:, 1)
159  xn(:, i) = xn(:, i) - xn(:, 1)
160  end do
161 ! compute the location of our seach point relative to the first node.
162  xd = xcend - xnd(:, 1)
163  x = xcen - xn(:, 1)
164 ! modify the coordinates of node 3, 6, 8 and 7 such that
165 ! they correspond to the weights of the u*v, u*w, v*w and
166 ! u*v*w term in the transformation respectively.
167  xnd(1, 7) = xnd(1, 7) + xnd(1, 2) + xnd(1, 4) + xnd(1, 5) - xnd(1, 3&
168 & ) - xnd(1, 6) - xnd(1, 8)
169  xn(1, 7) = xn(1, 7) + xn(1, 2) + xn(1, 4) + xn(1, 5) - xn(1, 3) - xn&
170 & (1, 6) - xn(1, 8)
171  xnd(2, 7) = xnd(2, 7) + xnd(2, 2) + xnd(2, 4) + xnd(2, 5) - xnd(2, 3&
172 & ) - xnd(2, 6) - xnd(2, 8)
173  xn(2, 7) = xn(2, 7) + xn(2, 2) + xn(2, 4) + xn(2, 5) - xn(2, 3) - xn&
174 & (2, 6) - xn(2, 8)
175  xnd(3, 7) = xnd(3, 7) + xnd(3, 2) + xnd(3, 4) + xnd(3, 5) - xnd(3, 3&
176 & ) - xnd(3, 6) - xnd(3, 8)
177  xn(3, 7) = xn(3, 7) + xn(3, 2) + xn(3, 4) + xn(3, 5) - xn(3, 3) - xn&
178 & (3, 6) - xn(3, 8)
179  xnd(1, 3) = xnd(1, 3) - xnd(1, 2) - xnd(1, 4)
180  xn(1, 3) = xn(1, 3) - xn(1, 2) - xn(1, 4)
181  xnd(2, 3) = xnd(2, 3) - xnd(2, 2) - xnd(2, 4)
182  xn(2, 3) = xn(2, 3) - xn(2, 2) - xn(2, 4)
183  xnd(3, 3) = xnd(3, 3) - xnd(3, 2) - xnd(3, 4)
184  xn(3, 3) = xn(3, 3) - xn(3, 2) - xn(3, 4)
185  xnd(1, 6) = xnd(1, 6) - xnd(1, 2) - xnd(1, 5)
186  xn(1, 6) = xn(1, 6) - xn(1, 2) - xn(1, 5)
187  xnd(2, 6) = xnd(2, 6) - xnd(2, 2) - xnd(2, 5)
188  xn(2, 6) = xn(2, 6) - xn(2, 2) - xn(2, 5)
189  xnd(3, 6) = xnd(3, 6) - xnd(3, 2) - xnd(3, 5)
190  xn(3, 6) = xn(3, 6) - xn(3, 2) - xn(3, 5)
191  xnd(1, 8) = xnd(1, 8) - xnd(1, 4) - xnd(1, 5)
192  xn(1, 8) = xn(1, 8) - xn(1, 4) - xn(1, 5)
193  xnd(2, 8) = xnd(2, 8) - xnd(2, 4) - xnd(2, 5)
194  xn(2, 8) = xn(2, 8) - xn(2, 4) - xn(2, 5)
195  xnd(3, 8) = xnd(3, 8) - xnd(3, 4) - xnd(3, 5)
196  xn(3, 8) = xn(3, 8) - xn(3, 4) - xn(3, 5)
197 ! set the starting values of u, v and w based on our previous values
198  u = frac0(1)
199  v = frac0(2)
200  w = frac0(3)
201  fd = 0.0_8
202  ud = 0.0_8
203  vd = 0.0_8
204  wd = 0.0_8
205 ! the newton algorithm to determine the parametric
206 ! weights u, v and w for the given coordinate.
207 newtonhexa:do ll=1,15
208 ! compute the rhs.
209  uvd = v*ud + u*vd
210  uv = u*v
211  uwd = w*ud + u*wd
212  uw = u*w
213  vwd = w*vd + v*wd
214  vw = v*w
215  wvud = w*(v*ud+u*vd) + u*v*wd
216  wvu = u*v*w
217  fd(1) = u*xnd(1, 2) + xn(1, 2)*ud + v*xnd(1, 4) + xn(1, 4)*vd + w*&
218 & xnd(1, 5) + xn(1, 5)*wd + uv*xnd(1, 3) + xn(1, 3)*uvd + uw*xnd(1&
219 & , 6) + xn(1, 6)*uwd + vw*xnd(1, 8) + xn(1, 8)*vwd + wvu*xnd(1, 7&
220 & ) + xn(1, 7)*wvud - xd(1)
221  f(1) = xn(1, 2)*u + xn(1, 4)*v + xn(1, 5)*w + xn(1, 3)*uv + xn(1, &
222 & 6)*uw + xn(1, 8)*vw + xn(1, 7)*wvu - x(1)
223  fd(2) = u*xnd(2, 2) + xn(2, 2)*ud + v*xnd(2, 4) + xn(2, 4)*vd + w*&
224 & xnd(2, 5) + xn(2, 5)*wd + uv*xnd(2, 3) + xn(2, 3)*uvd + uw*xnd(2&
225 & , 6) + xn(2, 6)*uwd + vw*xnd(2, 8) + xn(2, 8)*vwd + wvu*xnd(2, 7&
226 & ) + xn(2, 7)*wvud - xd(2)
227  f(2) = xn(2, 2)*u + xn(2, 4)*v + xn(2, 5)*w + xn(2, 3)*uv + xn(2, &
228 & 6)*uw + xn(2, 8)*vw + xn(2, 7)*wvu - x(2)
229  fd(3) = u*xnd(3, 2) + xn(3, 2)*ud + v*xnd(3, 4) + xn(3, 4)*vd + w*&
230 & xnd(3, 5) + xn(3, 5)*wd + uv*xnd(3, 3) + xn(3, 3)*uvd + uw*xnd(3&
231 & , 6) + xn(3, 6)*uwd + vw*xnd(3, 8) + xn(3, 8)*vwd + wvu*xnd(3, 7&
232 & ) + xn(3, 7)*wvud - xd(3)
233  f(3) = xn(3, 2)*u + xn(3, 4)*v + xn(3, 5)*w + xn(3, 3)*uv + xn(3, &
234 & 6)*uw + xn(3, 8)*vw + xn(3, 7)*wvu - x(3)
235 ! compute the jacobian.
236  a11d = xnd(1, 2) + v*xnd(1, 3) + xn(1, 3)*vd + w*xnd(1, 6) + xn(1&
237 & , 6)*wd + vw*xnd(1, 7) + xn(1, 7)*vwd
238  a11 = xn(1, 2) + xn(1, 3)*v + xn(1, 6)*w + xn(1, 7)*vw
239  a12d = xnd(1, 4) + u*xnd(1, 3) + xn(1, 3)*ud + w*xnd(1, 8) + xn(1&
240 & , 8)*wd + uw*xnd(1, 7) + xn(1, 7)*uwd
241  a12 = xn(1, 4) + xn(1, 3)*u + xn(1, 8)*w + xn(1, 7)*uw
242  a13d = xnd(1, 5) + u*xnd(1, 6) + xn(1, 6)*ud + v*xnd(1, 8) + xn(1&
243 & , 8)*vd + uv*xnd(1, 7) + xn(1, 7)*uvd
244  a13 = xn(1, 5) + xn(1, 6)*u + xn(1, 8)*v + xn(1, 7)*uv
245  a21d = xnd(2, 2) + v*xnd(2, 3) + xn(2, 3)*vd + w*xnd(2, 6) + xn(2&
246 & , 6)*wd + vw*xnd(2, 7) + xn(2, 7)*vwd
247  a21 = xn(2, 2) + xn(2, 3)*v + xn(2, 6)*w + xn(2, 7)*vw
248  a22d = xnd(2, 4) + u*xnd(2, 3) + xn(2, 3)*ud + w*xnd(2, 8) + xn(2&
249 & , 8)*wd + uw*xnd(2, 7) + xn(2, 7)*uwd
250  a22 = xn(2, 4) + xn(2, 3)*u + xn(2, 8)*w + xn(2, 7)*uw
251  a23d = xnd(2, 5) + u*xnd(2, 6) + xn(2, 6)*ud + v*xnd(2, 8) + xn(2&
252 & , 8)*vd + uv*xnd(2, 7) + xn(2, 7)*uvd
253  a23 = xn(2, 5) + xn(2, 6)*u + xn(2, 8)*v + xn(2, 7)*uv
254  a31d = xnd(3, 2) + v*xnd(3, 3) + xn(3, 3)*vd + w*xnd(3, 6) + xn(3&
255 & , 6)*wd + vw*xnd(3, 7) + xn(3, 7)*vwd
256  a31 = xn(3, 2) + xn(3, 3)*v + xn(3, 6)*w + xn(3, 7)*vw
257  a32d = xnd(3, 4) + u*xnd(3, 3) + xn(3, 3)*ud + w*xnd(3, 8) + xn(3&
258 & , 8)*wd + uw*xnd(3, 7) + xn(3, 7)*uwd
259  a32 = xn(3, 4) + xn(3, 3)*u + xn(3, 8)*w + xn(3, 7)*uw
260  a33d = xnd(3, 5) + u*xnd(3, 6) + xn(3, 6)*ud + v*xnd(3, 8) + xn(3&
261 & , 8)*vd + uv*xnd(3, 7) + xn(3, 7)*uvd
262  a33 = xn(3, 5) + xn(3, 6)*u + xn(3, 8)*v + xn(3, 7)*uv
263 ! compute the determinant. make sure that it is not zero
264 ! and invert the value. the cut off is needed to be able
265 ! to handle exceptional cases for degenerate elements.
266  temp = a22*a33 - a32*a23
267  temp0 = a13*a32 - a12*a33
268  temp1 = a12*a23 - a13*a22
269  vald = temp*a11d + a11*(a33*a22d+a22*a33d-a23*a32d-a32*a23d) + &
270 & temp0*a21d + a21*(a32*a13d+a13*a32d-a33*a12d-a12*a33d) + temp1*&
271 & a31d + a31*(a23*a12d+a12*a23d-a22*a13d-a13*a22d)
272  val = a11*temp + a21*temp0 + a31*temp1
273  if (val .ge. 0.) then
274  x1d = vald
275  x1 = val
276  else
277  x1d = -vald
278  x1 = -val
279  end if
280  if (x1 .lt. adteps) then
281  max1 = adteps
282  max1d = 0.0_8
283  else
284  max1d = x1d
285  max1 = x1
286  end if
287  temp1 = sign(one, val)/max1
288  vald = -(temp1*max1d/max1)
289  val = temp1
290 ! compute the new values of u, v and w.
291  temp1 = a12*a23 - a13*a22
292  temp0 = a13*a32 - a12*a33
293  temp = a22*a33 - a23*a32
294  temp2 = temp*f(1) + temp0*f(2) + temp1*f(3)
295  dud = temp2*vald + val*(f(1)*(a33*a22d+a22*a33d-a32*a23d-a23*a32d)&
296 & +temp*fd(1)+f(2)*(a32*a13d+a13*a32d-a33*a12d-a12*a33d)+temp0*fd(&
297 & 2)+f(3)*(a23*a12d+a12*a23d-a22*a13d-a13*a22d)+temp1*fd(3))
298  du = val*temp2
299  temp2 = a13*a21 - a11*a23
300  temp1 = a11*a33 - a13*a31
301  temp0 = a23*a31 - a21*a33
302  temp = temp0*f(1) + temp1*f(2) + temp2*f(3)
303  dvd = temp*vald + val*(f(1)*(a31*a23d+a23*a31d-a33*a21d-a21*a33d)+&
304 & temp0*fd(1)+f(2)*(a33*a11d+a11*a33d-a31*a13d-a13*a31d)+temp1*fd(&
305 & 2)+f(3)*(a21*a13d+a13*a21d-a23*a11d-a11*a23d)+temp2*fd(3))
306  dv = val*temp
307  temp2 = a11*a22 - a12*a21
308  temp1 = a12*a31 - a11*a32
309  temp0 = a21*a32 - a22*a31
310  temp = temp0*f(1) + temp1*f(2) + temp2*f(3)
311  dwd = temp*vald + val*(f(1)*(a32*a21d+a21*a32d-a31*a22d-a22*a31d)+&
312 & temp0*fd(1)+f(2)*(a31*a12d+a12*a31d-a32*a11d-a11*a32d)+temp1*fd(&
313 & 2)+f(3)*(a22*a11d+a11*a22d-a21*a12d-a12*a21d)+temp2*fd(3))
314  dw = val*temp
315  ud = ud - dud
316  u = u - du
317  vd = vd - dvd
318  v = v - dv
319  wd = wd - dwd
320  w = w - dw
321 ! exit the loop if the update of the parametric
322 ! weights is below the threshold
323  arg1 = du*du + dv*dv + dw*dw
324  val = sqrt(arg1)
325  if (val .le. thresconv) exit
326  end do newtonhexa
327 ! we would *like* that all solutions fall inside the hexa, but we
328 ! can't be picky here since we are not changing the donors. so
329 ! whatever the u,v,w is we have to accept. even if it is greater than
330 ! 1 or less than zero, it shouldn't be by much.
331  fracd(1) = ud
332  frac(1) = u
333  fracd(2) = vd
334  frac(2) = v
335  fracd(3) = wd
336  frac(3) = w
337  end subroutine newtonupdate_d
338 
339  subroutine newtonupdate(xcen, blk, frac0, frac)
340 ! this routine performs the newton update to recompute the new
341 ! "frac" (u,v,w) for the point xcen. the actual search is performed
342 ! on the the dual cell formed by the cell centers of the 3x3x3 block
343 ! of primal nodes. this routine is ad'd with tapenade in both
344 ! forward and reverse.
345  use constants
346  implicit none
347 ! input
348  real(kind=realtype), dimension(3), intent(in) :: xcen
349  real(kind=realtype), dimension(3, 3, 3, 3), intent(in) :: blk
350  real(kind=realtype), dimension(3), intent(in) :: frac0
351 ! output
352  real(kind=realtype), dimension(3), intent(out) :: frac
353 ! working
354  real(kind=realtype), dimension(3, 8) :: xn
355  real(kind=realtype) :: u, v, w, uv, uw, vw, wvu, du, dv, dw
356  real(kind=realtype) :: a11, a12, a13, a21, a22, a23, a31, a32, a33, &
357 & val
358  real(kind=realtype) :: f(3), x(3)
359  integer(kind=inttype), dimension(8), parameter :: indices=(/1, 2, 4&
360 & , 3, 5, 6, 8, 7/)
361  integer(kind=inttype) :: i, j, k, ii, ll
362  real(kind=realtype), parameter :: adteps=1.e-25_realtype
363  real(kind=realtype), parameter :: thresconv=1.e-10_realtype
364  intrinsic sign
365  intrinsic abs
366  intrinsic max
367  intrinsic sqrt
368  real(kind=realtype) :: x1
369  real(kind=realtype) :: max1
370  real(kind=realtype) :: arg1
371 ! compute the cell center locations for the 8 nodes describing the
372 ! dual cell. note that this must be counter-clockwise ordering.
373  ii = 0
374  do k=1,2
375  do j=1,2
376  do i=1,2
377  ii = ii + 1
378  xn(:, indices(ii)) = eighth*(blk(i, j, k, :)+blk(i+1, j, k, :)&
379 & +blk(i, j+1, k, :)+blk(i+1, j+1, k, :)+blk(i, j, k+1, :)+blk&
380 & (i+1, j, k+1, :)+blk(i, j+1, k+1, :)+blk(i+1, j+1, k+1, :))
381  end do
382  end do
383  end do
384 ! compute the coordinates relative to node 1.
385  do i=2,8
386  xn(:, i) = xn(:, i) - xn(:, 1)
387  end do
388 ! compute the location of our seach point relative to the first node.
389  x = xcen - xn(:, 1)
390 ! modify the coordinates of node 3, 6, 8 and 7 such that
391 ! they correspond to the weights of the u*v, u*w, v*w and
392 ! u*v*w term in the transformation respectively.
393  xn(1, 7) = xn(1, 7) + xn(1, 2) + xn(1, 4) + xn(1, 5) - xn(1, 3) - xn&
394 & (1, 6) - xn(1, 8)
395  xn(2, 7) = xn(2, 7) + xn(2, 2) + xn(2, 4) + xn(2, 5) - xn(2, 3) - xn&
396 & (2, 6) - xn(2, 8)
397  xn(3, 7) = xn(3, 7) + xn(3, 2) + xn(3, 4) + xn(3, 5) - xn(3, 3) - xn&
398 & (3, 6) - xn(3, 8)
399  xn(1, 3) = xn(1, 3) - xn(1, 2) - xn(1, 4)
400  xn(2, 3) = xn(2, 3) - xn(2, 2) - xn(2, 4)
401  xn(3, 3) = xn(3, 3) - xn(3, 2) - xn(3, 4)
402  xn(1, 6) = xn(1, 6) - xn(1, 2) - xn(1, 5)
403  xn(2, 6) = xn(2, 6) - xn(2, 2) - xn(2, 5)
404  xn(3, 6) = xn(3, 6) - xn(3, 2) - xn(3, 5)
405  xn(1, 8) = xn(1, 8) - xn(1, 4) - xn(1, 5)
406  xn(2, 8) = xn(2, 8) - xn(2, 4) - xn(2, 5)
407  xn(3, 8) = xn(3, 8) - xn(3, 4) - xn(3, 5)
408 ! set the starting values of u, v and w based on our previous values
409  u = frac0(1)
410  v = frac0(2)
411  w = frac0(3)
412 ! the newton algorithm to determine the parametric
413 ! weights u, v and w for the given coordinate.
414 newtonhexa:do ll=1,15
415 ! compute the rhs.
416  uv = u*v
417  uw = u*w
418  vw = v*w
419  wvu = u*v*w
420  f(1) = xn(1, 2)*u + xn(1, 4)*v + xn(1, 5)*w + xn(1, 3)*uv + xn(1, &
421 & 6)*uw + xn(1, 8)*vw + xn(1, 7)*wvu - x(1)
422  f(2) = xn(2, 2)*u + xn(2, 4)*v + xn(2, 5)*w + xn(2, 3)*uv + xn(2, &
423 & 6)*uw + xn(2, 8)*vw + xn(2, 7)*wvu - x(2)
424  f(3) = xn(3, 2)*u + xn(3, 4)*v + xn(3, 5)*w + xn(3, 3)*uv + xn(3, &
425 & 6)*uw + xn(3, 8)*vw + xn(3, 7)*wvu - x(3)
426 ! compute the jacobian.
427  a11 = xn(1, 2) + xn(1, 3)*v + xn(1, 6)*w + xn(1, 7)*vw
428  a12 = xn(1, 4) + xn(1, 3)*u + xn(1, 8)*w + xn(1, 7)*uw
429  a13 = xn(1, 5) + xn(1, 6)*u + xn(1, 8)*v + xn(1, 7)*uv
430  a21 = xn(2, 2) + xn(2, 3)*v + xn(2, 6)*w + xn(2, 7)*vw
431  a22 = xn(2, 4) + xn(2, 3)*u + xn(2, 8)*w + xn(2, 7)*uw
432  a23 = xn(2, 5) + xn(2, 6)*u + xn(2, 8)*v + xn(2, 7)*uv
433  a31 = xn(3, 2) + xn(3, 3)*v + xn(3, 6)*w + xn(3, 7)*vw
434  a32 = xn(3, 4) + xn(3, 3)*u + xn(3, 8)*w + xn(3, 7)*uw
435  a33 = xn(3, 5) + xn(3, 6)*u + xn(3, 8)*v + xn(3, 7)*uv
436 ! compute the determinant. make sure that it is not zero
437 ! and invert the value. the cut off is needed to be able
438 ! to handle exceptional cases for degenerate elements.
439  val = a11*(a22*a33-a32*a23) + a21*(a13*a32-a12*a33) + a31*(a12*a23&
440 & -a13*a22)
441  if (val .ge. 0.) then
442  x1 = val
443  else
444  x1 = -val
445  end if
446  if (x1 .lt. adteps) then
447  max1 = adteps
448  else
449  max1 = x1
450  end if
451  val = sign(one, val)/max1
452 ! compute the new values of u, v and w.
453  du = val*((a22*a33-a23*a32)*f(1)+(a13*a32-a12*a33)*f(2)+(a12*a23-&
454 & a13*a22)*f(3))
455  dv = val*((a23*a31-a21*a33)*f(1)+(a11*a33-a13*a31)*f(2)+(a13*a21-&
456 & a11*a23)*f(3))
457  dw = val*((a21*a32-a22*a31)*f(1)+(a12*a31-a11*a32)*f(2)+(a11*a22-&
458 & a12*a21)*f(3))
459  u = u - du
460  v = v - dv
461  w = w - dw
462 ! exit the loop if the update of the parametric
463 ! weights is below the threshold
464  arg1 = du*du + dv*dv + dw*dw
465  val = sqrt(arg1)
466  if (val .le. thresconv) goto 100
467  end do newtonhexa
468 ! we would *like* that all solutions fall inside the hexa, but we
469 ! can't be picky here since we are not changing the donors. so
470 ! whatever the u,v,w is we have to accept. even if it is greater than
471 ! 1 or less than zero, it shouldn't be by much.
472  100 frac(1) = u
473  frac(2) = v
474  frac(3) = w
475  end subroutine newtonupdate
476 
477 end module oversetutilities_d
478 
real(kind=realtype), parameter eighth
Definition: constants.F90:84
real(kind=realtype), parameter one
Definition: constants.F90:72
subroutine newtonupdate_d(xcen, xcend, blk, blkd, frac0, frac, fracd)
subroutine newtonupdate(xcen, blk, frac0, frac)
subroutine fractoweights2(frac, weights)
subroutine fractoweights_d(frac, fracd, weights, weightsd)
subroutine fractoweights(frac, weights)