ADflow  v1.0
ADflow is a finite volume RANS solver tailored for gradient-based aerodynamic design optimization.
fringeSearch.F90
Go to the documentation of this file.
1 subroutine fringesearch(oBlock, oFringe)
2 
3  use constants
4  use block, only: fringetype
10  use adtdata, only: adtbboxtargettype
11  use adtutils, only: stack
12  use utils, only: mynorm2
14  tic, toc, windindex
15  implicit none
16 
17  type(oversetblock), intent(inout) :: oBlock
18  type(oversetfringe), intent(inout) :: oFringe
19 
20  integer(kind=intType) :: idom, jdom
21 
22  ! Working Varaibles
23  integer(kind=intType) :: nInterpol, elemID, nalloc, intInfo(3), intInfo2(3)
24  integer(kind=intType) :: i, ii, jj, kk, j, nn, myI, myJ, myK
25  integer(kind=intTYpe) :: iii, jjj, kkk, n, myind, nx, ny, nz, myindex
26  logical :: invalid, failed
27  real(kind=realtype) :: uu, vv, ww, err1, err2
28  real(kind=realtype) :: uvw(5), uvw2(5), xx(4), pt(3), xcheck(3)
29  real(kind=realtype), dimension(:, :), allocatable :: offset
30  real(kind=realtype) :: oneminusu, oneminusv, oneminusw, weight(8)
31  ! Variables we have to pass the ADT search routine
32  integer(kind=intType), dimension(:), pointer :: BB
33  type(adtbboxtargettype), dimension(:), pointer :: BB2
34  integer(kind=intType), dimension(:), pointer :: frontLeaves
35  integer(kind=intType), dimension(:), pointer :: frontLeavesNew
36  type(fringetype) :: fringe
37  ninterpol = 1 ! we get the ADT to compute the interpolated volume for us.
38 
39  ! Allocate the (pointer) memory that may be resized as necessary for
40  ! the singlePoint search routine.
41  allocate (bb(20), bb2(20), frontleaves(25), frontleavesnew(25), stack(100))
42 
43  ! Number of fringes we have:
44  n = size(ofringe%x, 2)
45 
46  ! Offset vector:
47  allocate (offset(3, n))
48  offset = zero
50  call surfacecorrection(oblock, ofringe, offset, n)
52 
53  call tic(idonorsearch)
54  ! Search the cells one at a time:
55  do i = 1, n
56 
57  ! Compute the potentailly offset point to search for.
58  xx(1:3) = ofringe%x(:, i) + offset(:, i)
59 
60  call containmenttreesearchsinglepoint(oblock%ADT, xx, intinfo, uvw, &
61  oblock%qualDonor, ninterpol, bb, frontleaves, frontleavesnew, failed)
62 
63  if (intinfo(1) >= 0) then
64  call fractoweights2(uvw(1:3), weight)
65  xcheck = zero
66  do j = 1, 8
67  xcheck = xcheck + weight(j) * oblock%xADT(:, oblock%hexaConn(j, intinfo(3)))
68  end do
69 
70  if (mynorm2(xcheck - xx(1:3)) > oversetprojtol) then
71  failed = .true.
72  end if
73  end if
74 
75  if (intinfo(1) >= 0 .and. failed) then
76  ! we "found" a point but it is garbage. Do the failsafe search
77  xx(4) = large
78  call mindistancetreesearchsinglepoint(oblock%ADT, xx, intinfo, uvw, &
79  oblock%qualDonor, ninterpol, bb2, frontleaves, frontleavesnew)
80 
81  ! Check this one:
82  call fractoweights2(uvw(1:3), weight)
83  xcheck = zero
84  do j = 1, 8
85  xcheck = xcheck + weight(j) * oblock%xADT(:, oblock%hexaConn(j, intinfo(3)))
86  end do
87 
88  ! Since this is the last line of defence, relax the tolerance a bit
89  if (mynorm2(xcheck - xx(1:3)) > 100 * oversetprojtol) then
90  ! This fringe has not found a donor
91  intinfo(1) = -1
92  else
93  ! This one has now passed.
94 
95  ! Important! uvw(4) is the distance squared for this search
96  ! not
97  uvw(4) = uvw(5)
98  end if
99 
100  end if
101 
102  elemfound: if (intinfo(1) >= 0) then
103 
104  ! Recompute the i,j,k indices on the donor
105  elemid = intinfo(3) - 1 ! Make it zero based for the modding.
106  ii = mod(elemid, oblock%il) + 1
107  jj = mod(elemid / oblock%il, oblock%jl) + 1
108  kk = elemid / (oblock%il * oblock%jl) + 1
109 
110  ! Now record the information onto the fringe
111  fringe%donorProc = oblock%proc
112  fringe%donorBlock = oblock%block
113  fringe%dIndex = windindex(ii, jj, kk, oblock%il, oblock%jl, oblock%kl)
114  fringe%donorFrac = uvw(1:3)
115  fringe%quality = uvw(4)
116 
117  ! Also save the information about where it came from,
118  ! we need this to combine everything together at the end.
119  fringe%myBlock = ofringe%block
120 
121  myi = mod((i - 1), ofringe%nx) + 2
122  myj = mod((i - 1) / ofringe%nx, ofringe%ny) + 2
123  myk = (i - 1) / (ofringe%nx * ofringe%ny) + 2
124  fringe%myIndex = windindex(myi, myj, myk, ofringe%il, ofringe%jl, ofringe%kl)
125 
126  ! Store the donor in the big flat list if it isn't invalid
127  invalid = .false.
128  do kkk = 0, 1
129  do jjj = 0, 1
130  do iii = 0, 1
131  if (oblock%invalidDonor(ii + iii, jj + jjj, kk + kkk) .ne. 0) then
132  invalid = .true.
133  end if
134  end do
135  end do
136  end do
137 
138  if (.not. invalid) then
139  call addtofringebuffer(ofringe%fringeIntBuffer, ofringe%fringeRealBuffer, &
140  ofringe%nDonor, fringe)
141  end if
142 
143  ! Save the fringe to the wallList. Note that we have to do
144  ! this *after* the actual fringeList becuase we may modify the
145  ! dI, dJ, dK here.
146 
147  if ((ofringe%isWall(i) > 0) .and. .not. (oblock%nearWall(ii, jj, kk) == 1)) then
148 
149  ! Here we have to recompute the i,j,k indices since we may
150  ! need to modify them based on the frac.
151 
152  if (uvw(1) >= half) then
153  ii = ii + 1
154  end if
155 
156  if (uvw(2) >= half) then
157  jj = jj + 1
158  end if
159 
160  if (uvw(3) >= half) then
161  kk = kk + 1
162  end if
163 
164  ! Recompute the full index for the wall.
165  fringe%dIndex = windindex(ii, jj, kk, oblock%il, oblock%jl, oblock%kl)
166 
168  end if
169  end if elemfound
170  end do
171  deallocate (offset, bb, bb2, frontleaves, frontleavesnew, stack)
172  call toc(idonorsearch)
173 end subroutine fringesearch
subroutine fringesearch(oBlock, oFringe)
Definition: fringeSearch.F90:2
subroutine containmenttreesearchsinglepoint(ADT, coor, intInfo, uvw, arrDonor, nInterpol, BB, frontLeaves, frontLeavesNew, failed)
subroutine mindistancetreesearchsinglepoint(ADT, coor, intInfo, uvw, arrDonor, nInterpol, BB, frontLeaves, frontLeavesNew)
integer(kind=inttype), dimension(:), pointer stack
Definition: adtUtils.F90:20
Definition: block.F90:1
integer(kind=inttype), parameter idonorsearch
Definition: constants.F90:336
real(kind=realtype), parameter zero
Definition: constants.F90:71
real(kind=realtype), parameter half
Definition: constants.F90:80
real(kind=realtype), parameter large
Definition: constants.F90:24
integer(kind=inttype), parameter isurfacecorrection
Definition: constants.F90:335
real(kind=realtype) oversetprojtol
Definition: inputParam.F90:884
real(kind=realtype) overlapfactor
Definition: inputParam.F90:882
type(fringetype), dimension(:), pointer localwallfringes
Definition: overset.F90:357
integer(kind=inttype) nlocalwallfringe
Definition: overset.F90:358
type(fringetype), dimension(:), pointer tmpfringeptr
Definition: overset.F90:357
subroutine addtofringelist(fringeList, n, fringe)
subroutine tic(index)
subroutine toc(index)
subroutine addtofringebuffer(intBuffer, realBuffer, n, fringe)
subroutine fractoweights2(frac, weights)
integer(kind=inttype) function windindex(i, j, k, il, jl, kl)
Definition: utils.F90:1
real(kind=realtype) function mynorm2(x)
Definition: utils.F90:1697
subroutine surfacecorrection(oBlock, oFringe, offset, n)