ADflow  v1.0
ADflow is a finite volume RANS solver tailored for gradient-based aerodynamic design optimization.
overset.F90
Go to the documentation of this file.
1 module oversetdata
2 
3  use constants
4  use adtdata, only: adttype
5  use block, only: fringetype
6  use kdtree2_module, only: kdtree2
7 #ifndef USE_TAPENADE
8 #include <petsc/finclude/petsc.h>
9  use petsc
10  implicit none
11 
12 #endif
13  ! Helper dataType for communicated overset grid points. This data
14  ! structure mirrros the blockType structure in block.F90, but only
15  ! contains minimum amount of information required for computing
16  ! overset connectivities.
17 
18  ! Store the coordinates from a block that will need to be searched.
19 
20  ! A simple generic sparse matrix storage container for storing the
21  ! (sparse) overlap structure of an overset mesh
22  type csrmatrix
23  integer(kind=intType) :: nrow, ncol, nnz, nnzlocal
24  integer(kind=intType), dimension(:), pointer :: colind, rowptr
25  real(kind=realtype), dimension(:), pointer :: data
26  integer(Kind=intType), dimension(:), pointer :: assignedproc
27 
28  ! Flag if this matrix is allocated
29  logical :: allocated = .false.
30 
31  end type csrmatrix
32 
33  ! This derived type contains sufficient information to perfom ADT
34  ! donor searches.
36 
37  ! Sizes for the block
38  integer(kind=intType) :: il, jl, kl
39 
40  ! Cluster this block belongs to
41  integer(kind=intType) :: cluster
42 
43  ! This is the cell volume of the donor
44  real(kind=realtype), dimension(:, :), pointer :: qualdonor
45 
46  ! Connectivity for the ADT
47  integer(kind=intType), dimension(:, :), pointer :: hexaconn
48 
49  ! Coordinates for the ADT
50  real(kind=realtype), dimension(:, :), pointer :: xadt
51 
52  ! Copy of global cell
53  integer(kind=intType), dimension(:, :, :), pointer :: globalcell
54 
55  ! Whether or not a cell is "near" a wall
56  integer(kind=intType), dimension(:, :, :), pointer :: nearwall
57 
58  ! Whether or not a cell is not possible to be a donor. Ie. a forceRecv
59  integer(kind=intType), dimension(:, :, :), pointer :: invaliddonor
60 
61  ! Minimum volume for this block
62  real(kind=realtype) :: minvol
63 
64  ! The ADT for this block
65  type(adttype) :: adt
66 
67  ! The processor for this block
68  integer(kind=intType) :: proc
69 
70  ! And the local block index
71  integer(kind=intType) :: block
72 
73  ! Buffer space for sending/receiving the block
74  real(kind=realtype), dimension(:), allocatable :: rbuffer
75  integer(kind=intType), dimension(:), allocatable :: ibuffer
76 
77  ! Flag if this block got allocated
78  logical :: allocated = .false.
79 
80  ! Flag if the real/int Buffers are ready after receiving info
81  logical :: realbufferready = .false.
82  logical :: intbufferready = .false.
83 
84  end type oversetblock
85 
87 
88  ! The processor where this set of fringes came from
89  integer(kind=intType) :: proc
90 
91  ! The block number of these fringes on processor 'proc'
92  integer(kind=intType) :: block
93 
94  ! Sizes
95  integer(kind=intType) :: il, jl, kl, nx, ny, nz
96 
97  ! Cluster this set of fringes belongs to
98  integer(kind=intType) :: cluster
99 
100  ! Buffer space for sending/receiving the fringes
101  real(kind=realtype), dimension(:), allocatable :: rbuffer
102  integer(kind=intType), dimension(:), allocatable :: ibuffer
103 
104  ! These are the coordinates of the points we are searching for
105  real(kind=realtype), dimension(:, :), allocatable :: x
106 
107  ! These are the coordinate of its wall surface pt if applicable
108  real(kind=realtype), dimension(:, :), allocatable :: xseed
109 
110  ! These are the indices of the wall surfaces
111  integer(kind=intType), dimension(:), allocatable :: wallind
112 
113  ! Flag specifying if this cell is next to a wall or not. 1 for
114  ! next to wall, 0 otherwise.
115  integer(kind=intType), dimension(:), allocatable :: iswall
116 
117  ! This is where we will store all the potential donors that have
118  ! been found for this set of fringes
119  integer(kind=intType) :: ndonor = 0
120  integer(kind=intType), dimension(:, :), pointer :: fringeintbuffer => null()
121  real(kind=realtype), dimension(:, :), pointer :: fringerealbuffer => null()
122 
123  ! Flag if this set of fringes got allocated
124  logical :: allocated = .false.
125 
126  ! Flag if the real/int Buffers are ready after receiving info
127  logical :: realbufferready = .false.
128  logical :: intbufferready = .false.
129 
130  ! The number of actual fringes that need to communicated.
131  integer(kind=intType) :: fringereturnsize = 0
132 
133  end type oversetfringe
134 
136 
137  ! Sizes
138  integer(kind=intType) :: il, jl, kl
139  integer(kind=intType) :: nnodes = 0
140  integer(kind=intType) :: ncells = 0
141  integer(kind=intType) :: maxcells = 0
142  integer(kind=intType) :: cluster = 0
143 
144  ! Buffer space for sending/receiving the fringes
145  real(kind=realtype), dimension(:), allocatable :: rbuffer
146  integer(kind=intType), dimension(:), allocatable :: ibuffer
147 
148  ! Surface nodes used to build the tree:
149  real(kind=realtype), dimension(:, :), pointer :: x => null()
150 
151  ! Only primal mesh cell centers for dual mesh. Only allocated as
152  ! needed.
153  real(kind=realtype), dimension(:, :), pointer :: xprimalcen => null()
154 
155  ! Surface nonal used for determining if point is "underneath" the
156  ! surface.
157  real(kind=realtype), dimension(:, :), pointer :: norm => null()
158 
159  ! Local estimate of surface error
160  real(kind=realtype), dimension(:), pointer :: delta => null()
161 
162  ! Connectivity for the surface
163  integer(kind=intType), dimension(:, :), pointer :: conn => null()
164 
165  ! ind: Global node index for nodes
166  integer(kind=intType), dimension(:), pointer :: ind => null()
167 
168  ! indPrimal: Global node index. Only temporarly used to store
169  ! index for strictly primal cells on dual mesh.
170  integer(kind=intType), dimension(:), pointer :: indprimal => null()
171 
172  ! indCell: Global cell index for wall cells
173  integer(kind=intType), dimension(:), pointer :: indcell
174 
175  ! Blanking values for Nodes
176  integer(kind=intType), dimension(:), allocatable :: iblank
177  integer(kind=intType), dimension(:), allocatable :: cellptr
178 
179  ! Node to element array
180  integer(kind=intType), dimension(:, :), allocatable :: nte
181 
182  ! The ADT for this block's wall(s)
183  type(adttype) :: adt
184 
185  ! This KDTree for this block's wall
186  type(kdtree2), pointer :: tree
187 
188  ! Flag if the real/int Buffers are ready after receiving info
189  logical :: realbufferready = .false.
190  logical :: intbufferready = .false.
191 
192  ! Flag if this wall got allocated
193  logical :: allocated = .false.
194 
195  end type oversetwall
196 
198  ! This is a generic type defining a string list. It may be used
199  ! as both a "parent" or a "child".
200 
201  ! Sizes
202  integer(kind=intType) :: nnodes, nelems
203 
204  ! My String's index
205  integer(kind=intType) :: myid
206 
207  ! Whether or no this string is periodic
208  logical :: isperiodic = .false.
209 
210  ! Whether or no this string is a pocket
211  logical :: ispocket = .false.
212 
213  ! --------------------------------------------------------------------
214  ! Node Data: The actual physical node locations, unit surface normal,
215  ! perpNormal and mesh size. x is from index 1:3, normal from 4:6,
216  ! perpNormal form 7:9 and h is index 10. This pointer gets allocated.
217  real(kind=realtype), dimension(:, :), pointer :: nodedata => null()
218 
219  ! Pointer for physical node location. Points to nodeData
220  real(kind=realtype), dimension(:, :), pointer :: x => null()
221 
222  ! Pointer for nodal unit normal. Points to nodeData
223  real(kind=realtype), dimension(:, :), pointer :: norm => null()
224 
225  ! Pointer for nodal unit perpendicual in-plane normal. Points to nodeData
226  real(kind=realtype), dimension(:, :), pointer :: perpnorm => null()
227 
228  ! Pointer for nodal element size. Points to nodeData
229  real(kind=realtype), dimension(:), pointer :: h => null()
230 
231  ! --------------------------------------------------------------------
232  ! Integer Node Data: This stores the global node index (into
233  ! xVec), the cluster ID of the node, and the family ID of the node
234  integer(kind=intType), dimension(:, :), pointer :: intnodedata => null()
235 
236  ! The orignal nodal index. Size nNodes. Pointer into intNodeData
237  integer(kind=intType), dimension(:), pointer :: ind => null()
238 
239  ! The cluster the node came from. Pointer into intNodeData
240  integer(kind=intType), dimension(:), pointer :: cluster => null()
241 
242  ! The family the node came from. Pointer into intNodeData
243  integer(kind=intType), dimension(:), pointer :: family => null()
244  ! --------------------------------------------------------------------
245 
246  ! The connectivity of the nodes forming 1D bar elements. Size (2, nElems)
247  integer(kind=intType), dimension(:, :), pointer :: conn => null()
248 
249  ! The index of my node numbers on my parent
250  integer(kind=intType), dimension(:), pointer :: pnodes => null()
251 
252  ! The index of my elements numbers on my parent
253  integer(kind=intType), dimension(:), pointer :: pelems => null()
254 
255  ! The string ID and index of my nodes on a split substing
256  integer(kind=intType), dimension(:, :), pointer :: cnodes => null()
257 
258  ! The cloest string ID of each node *AND* the node index on the
259  ! other string. Size (2, nNodes)
260  integer(kind=intType), dimension(:, :), pointer :: otherid => null()
261 
262  ! The inverse of the connectivity node to elem array. Size (5,
263  ! nNodes). First index is the number of elements, other 4 entries
264  ! are the up to 4 possible element neighbours.
265  integer(kind=intType), dimension(:, :), pointer :: nte => null()
266 
267  ! Two buffer used for storing element indices while creating
268  ! chains. Size (2, nElem)
269  integer(kind=intType), dimension(:, :), pointer :: substr => null()
270 
271  ! The sizes of the two substrings
272  integer(kind=intType), dimension(2) :: nsubstr
273 
274  ! A array to keep track of the number of elements
275  ! "consumed" during chain searches or during zipping.
276  integer(kind=intType), dimension(:), pointer :: elemused => null()
277 
278  ! Array to keep track of nodes used to contruct string pairs for
279  ! crossZipping.
280  integer(kind=intType), dimension(:), pointer :: xzipnodeused => null()
281 
282  ! The KD tree for this string for performing fast seaches.
283  !type(tree_master_record), pointer :: tree
284  type(kdtree2), pointer :: tree => null()
285 
286  ! Pointer to the parent string
287  type(oversetstring), pointer :: p => null()
288 
289  ! Pointer for next string for a linked list
290  type(oversetstring), pointer :: next => null()
291 
292  ! List of all all directed edges.
293  type(oversetedge), pointer, dimension(:) :: edges => null()
294 
295  ! nEdges: The number of new edges added due to triangles.
296  integer(kind=intTYpe) :: nedges
297 
298  ! List of all computed triangles
299  integer(kind=intType), dimension(:, :), pointer :: tris => null()
300 
301  ! Number of trianges
302  integer(kind=intType) :: ntris
303 
304  ! surfCellID(1:nTris)
305  ! Global cellID of the primal cell containing the triangle centroid
306  integer(kind=intType), dimension(:), pointer :: surfcellid
307 
308  end type oversetstring
309 
311  ! Simple data structure representing a directed edge from n1->n2
312  integer(kind=intType) :: n1, n2
313  end type oversetedge
314 
315  interface operator(<=)
316  module procedure lessequaledgetype
317  end interface operator(<=)
318 
319  interface operator(<)
320  module procedure lessedgetype
321  end interface operator(<)
322 
324  ! Simple data structure representing a directed edge from n1->n2
325  ! Similar to oversetEdge, but introduced to do different type
326  ! of sort on edges
327  integer(kind=intType) :: n1, n2
328  end type pocketedge
329 
330  interface operator(<=)
331  module procedure lessequalpocketedgen2
332  end interface operator(<=)
333 
334  interface operator(<)
335  module procedure lesspocketedgen2
336  end interface operator(<)
337 
338  interface operator(==)
339  module procedure equalpocketedgen2
340  end interface operator(==)
341 
343 
344  ! Data required for zipper mesh surface integer for a particular BCGroup
345  integer(kind=intType), dimension(:, :), allocatable :: conn
346  integer(kind=intType), dimension(:), allocatable :: fam, indices
347  logical :: allocated = .false.
348 #ifndef USE_TAPENADE
349  vecscatter :: scatter
350  vec :: localval
351 #endif
352  end type zippermesh
353 
354  ! This is the flattened list of the fringes next to the wall that we
355  ! have actually found donors for.
356  ! tmpFringePtr is only used if we need to realloc.
357  type(fringetype), dimension(:), pointer :: localwallfringes, wallfringes, tmpfringeptr
358  integer(kind=intType) :: nlocalwallfringe, nwallfringe
359 
360  ! These are the master overlap matrices
361  type(csrmatrix), dimension(:, :), allocatable, target :: overlapmatrix
362 
363  ! Some additional helper stuff
364  integer(kind=intType), dimension(:), allocatable :: ndomproc, cumdomproc
365  integer(kind=intType) :: ndomtotal
366  integer(kind=intType) :: nclusters
367  integer(kind=intType), dimension(:), allocatable :: clusters
368  real(kind=realtype), dimension(:), allocatable :: clusterareas
369  real(kind=realtype), dimension(:), allocatable :: clustermarchdist
370  type(oversetwall), dimension(:), allocatable, target :: clusterwalls
371 
372  ! Flag specifying if overset is present in mesh
373  logical :: oversetpresent
374 
375  ! Zipper meshes
376  type(zippermesh), dimension(nFamExchange), target :: zippermeshes
377 
378  ! Static arrays for doing timings
379  real(kind=realtype), dimension(iTotal) :: tstart
380  real(kind=realtype), dimension(iTotal) :: oversettimes
381 
382 contains
383  ! ==============================
384  ! Operator overloading functions
385  ! ==============================
386  logical function lessequaledgetype(e1, e2)
387  !
388  ! lessEqualEdgeType returns .True. if e1<=e2 and .False. otherwise.
389  ! Compared on the directed edge node indices n1 and n2.
390  ! First compare wrt averaged node indices data. If same averaged
391  ! node data, then compare wrt increasing or decreasing node indices.
392 
393  implicit none
394 
395  ! Input
396  type(oversetedge), intent(in) :: e1, e2
397 
398  ! Local variables
399  integer(kind=intType) :: nsum1, nsum2, ndiff1, ndiff2
400 
401  ! Compare the averaged (or just sum of) node indices values.
402  ! Positive sign for increasing order of node indices.
403  nsum1 = e1%n1 + e1%n2
404  nsum2 = e2%n1 + e2%n2
405  ndiff1 = e1%n2 - e1%n1
406  ndiff2 = e2%n2 - e2%n1
407 
408  ! Compare based on averaged node indices values
409  if (abs(nsum1) < abs(nsum2)) then
410  lessequaledgetype = .true.
411  return
412  else if (abs(nsum1) > abs(nsum2)) then
413  lessequaledgetype = .false.
414  return
415  end if
416 
417  if (abs(nsum1) /= abs(nsum2)) &
418  stop ' *** Error in lessEqualEdgeType ***'
419 
420  ! Compare based on edge nodes difference
421  if (abs(ndiff1) < abs(ndiff2)) then
422  lessequaledgetype = .true.
423  return
424  else if (abs(ndiff1) > abs(ndiff2)) then
425  lessequaledgetype = .false.
426  return
427  end if
428 
429  ! here abs(ndiff1) == abs(ndiff2) and
430  ! abs(nsum1)== abs(nsum2), so same edge
431  if (ndiff1 < ndiff2) then
432  lessequaledgetype = .true.
433  return
434  else if (ndiff1 > ndiff2) then
435  lessequaledgetype = .false.
436  return
437  end if
438 
439  ! here ndiff1 == ndiff2, hence .True.
440 
441  lessequaledgetype = .true.
442 
443  end function lessequaledgetype
444 
445  ! ---------------------------------
446  logical function lessedgetype(e1, e2)
447  !
448  ! lessEdgeType returns .True. if e1<e2 and .False. otherwise.
449  ! Compared on the directed edge node indices n1 and n2.
450  ! First compare wrt averaged node indices data. If same averaged
451  ! node data, then compare wrt increasing or decreasing node indices.
452 
453  implicit none
454 
455  ! Input
456  type(oversetedge), intent(in) :: e1, e2
457 
458  ! Local variables
459  integer(kind=intType) :: nsum1, nsum2, ndiff1, ndiff2
460 
461  ! Compare the averaged (or just sum of) node indices values.
462  ! Positive sign for increasing order of node indices.
463  nsum1 = e1%n1 + e1%n2
464  nsum2 = e2%n1 + e2%n2
465  ndiff1 = e1%n2 - e1%n1
466  ndiff2 = e2%n2 - e2%n1
467 
468  ! Compare based on averaged node indices values
469  if (abs(nsum1) < abs(nsum2)) then
470  lessedgetype = .true.
471  return
472  else if (abs(nsum1) > abs(nsum2)) then
473  lessedgetype = .false.
474  return
475  end if
476 
477  if (abs(nsum1) /= abs(nsum2)) &
478  stop ' *** Error in lessEdgeType ***'
479 
480  ! Compare based on edge nodes difference
481  if (abs(ndiff1) < abs(ndiff2)) then
482  lessedgetype = .true.
483  return
484  else if (abs(ndiff1) > abs(ndiff2)) then
485  lessedgetype = .false.
486  return
487  end if
488 
489  ! here abs(ndiff1) == abs(ndiff2) and
490  ! abs(nsum1)== abs(nsum2), so same edge
491  if (ndiff1 < ndiff2) then
492  lessedgetype = .true.
493  return
494  else if (ndiff1 > ndiff2) then
495  lessedgetype = .false.
496  return
497  end if
498 
499  ! here ndiff1 == ndiff2, hence .False.
500 
501  lessedgetype = .false.
502 
503  end function lessedgetype
504 
505  logical function lessequalpocketedgen2(e1, e2)
506  !
507  ! lessEqualPocketEdgeN2 returns .True. if e1%n2<=e2%n2 and .False.
508  ! otherwise. Compared on the directed edge node indices n1 and n2.
509 
510  implicit none
511 
512  ! Input
513  type(pocketedge), intent(in) :: e1, e2
514 
515  if (e1%n2 < e2%n2) then
516  lessequalpocketedgen2 = .true.
517  return
518  else if (e1%n2 > e2%n2) then
519  lessequalpocketedgen2 = .false.
520  return
521  end if
522 
523  ! Here e1%n2==e2%n2, so edges are equal, hence .True.
524  lessequalpocketedgen2 = .true.
525 
526  end function lessequalpocketedgen2
527 
528  logical function lesspocketedgen2(e1, e2)
529  !
530  ! lessPocketEdgeN2 returns .True. if e1%N2<e2%N2 and .False.
531  ! otherwise. Compared on the directed edge node indices n1 and n2.
532 
533  implicit none
534 
535  ! Input
536  type(pocketedge), intent(in) :: e1, e2
537 
538  if (e1%N2 < e2%N2) then
539  lesspocketedgen2 = .true.
540  return
541  else if (e1%N2 > e2%N2) then
542  lesspocketedgen2 = .false.
543  return
544  end if
545 
546  ! Here e1%N2==e2%n2, so edges are equal, hence .False.
547  lesspocketedgen2 = .false.
548 
549  end function lesspocketedgen2
550 
551  logical function equalpocketedgen2(e1, e2)
552  !
553  ! EqualPocketEdgeN2 returns .True. if e1%N2==e2%N2 and .False.
554  ! otherwise. Compared on the directed edge node indices n1 and n2.
555 
556  implicit none
557 
558  ! Input
559  type(pocketedge), intent(in) :: e1, e2
560 
561  if (e1%N2 == e2%N2) then
562  equalpocketedgen2 = .true.
563  return
564  else
565  equalpocketedgen2 = .false.
566  return
567  end if
568 
569  end function equalpocketedgen2
570 end module oversetdata
Definition: block.F90:1
real(kind=realtype), dimension(:), allocatable clusterareas
Definition: overset.F90:368
real(kind=realtype), dimension(itotal) oversettimes
Definition: overset.F90:380
logical function lessequalpocketedgen2(e1, e2)
Definition: overset.F90:506
integer(kind=inttype), dimension(:), allocatable ndomproc
Definition: overset.F90:364
logical function equalpocketedgen2(e1, e2)
Definition: overset.F90:552
integer(kind=inttype) nclusters
Definition: overset.F90:366
type(zippermesh), dimension(nfamexchange), target zippermeshes
Definition: overset.F90:376
type(fringetype), dimension(:), pointer localwallfringes
Definition: overset.F90:357
integer(kind=inttype) nwallfringe
Definition: overset.F90:358
type(fringetype), dimension(:), pointer wallfringes
Definition: overset.F90:357
logical function lesspocketedgen2(e1, e2)
Definition: overset.F90:529
integer(kind=inttype) nlocalwallfringe
Definition: overset.F90:358
integer(kind=inttype) ndomtotal
Definition: overset.F90:365
type(fringetype), dimension(:), pointer tmpfringeptr
Definition: overset.F90:357
type(oversetwall), dimension(:), allocatable, target clusterwalls
Definition: overset.F90:370
logical function lessequaledgetype(e1, e2)
Definition: overset.F90:387
real(kind=realtype), dimension(itotal) tstart
Definition: overset.F90:379
integer(kind=inttype), dimension(:), allocatable cumdomproc
Definition: overset.F90:364
logical function lessedgetype(e1, e2)
Definition: overset.F90:447
integer(kind=inttype), dimension(:), allocatable clusters
Definition: overset.F90:367
real(kind=realtype), dimension(:), allocatable clustermarchdist
Definition: overset.F90:369
logical oversetpresent
Definition: overset.F90:373
type(csrmatrix), dimension(:, :), allocatable, target overlapmatrix
Definition: overset.F90:361