Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
READ_FRAC.f90
Go to the documentation of this file.
1 !*********************************************************************
2 !* Illinois Open Source License *
3 !* *
4 !* University of Illinois/NCSA *
5 !* Open Source License *
6 !* *
7 !* Copyright@2008, University of Illinois. All rights reserved. *
8 !* *
9 !* Developed by: *
10 !* *
11 !* Center for Simulation of Advanced Rockets *
12 !* *
13 !* University of Illinois *
14 !* *
15 !* www.csar.uiuc.edu *
16 !* *
17 !* Permission is hereby granted, free of charge, to any person *
18 !* obtaining a copy of this software and associated documentation *
19 !* files (the "Software"), to deal with the Software without *
20 !* restriction, including without limitation the rights to use, *
21 !* copy, modify, merge, publish, distribute, sublicense, and/or *
22 !* sell copies of the Software, and to permit persons to whom the *
23 !* Software is furnished to do so, subject to the following *
24 !* conditions: *
25 !* *
26 !* *
27 !* @ Redistributions of source code must retain the above copyright *
28 !* notice, this list of conditions and the following disclaimers. *
29 !* *
30 !* @ Redistributions in binary form must reproduce the above *
31 !* copyright notice, this list of conditions and the following *
32 !* disclaimers in the documentation and/or other materials *
33 !* provided with the distribution. *
34 !* *
35 !* @ Neither the names of the Center for Simulation of Advanced *
36 !* Rockets, the University of Illinois, nor the names of its *
37 !* contributors may be used to endorse or promote products derived *
38 !* from this Software without specific prior written permission. *
39 !* *
40 !* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
41 !* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES *
42 !* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND *
43 !* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR *
44 !* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
45 !* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
46 !* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
47 !* USE OR OTHER DEALINGS WITH THE SOFTWARE. *
48 !*********************************************************************
49 !* Please acknowledge The University of Illinois Center for *
50 !* Simulation of Advanced Rockets in works and publications *
51 !* resulting from this software or its derivatives. *
52 !*********************************************************************
53  SUBROUTINE read_frac
55 
56  IMPLICIT NONE
57 
58  INTEGER :: numsurfnp, & ! number of surface nodes
59  numsurfelem, & ! number of surface elements (3-node)
60  numsurfsis, & ! Number of intended sister node matches
61  numsurfsisb, & ! for the backface of the geometry
62  iteration, & ! Current iteration number
63  max_iterations, & ! Maximum number of iterations
64  scount, & ! The number of nodes communicating with
65  step ! The step value for redefining the tolerances
66 
67  INTEGER :: num_matches ! The current number of sister node matches
68  REAL*8 :: low_tol ! The low tolerance used to compare coord. values
69  REAL*8 :: hi_tol ! The high tolerance used to compare coord. values
70 
71  INTEGER :: nfront_elem ! The number of front boundary elements
72  INTEGER :: nback_elem ! The number of back boundary elements
73  INTEGER :: nboundryel ! The total number of boundary elements
74 
75  ! Data type used to hold information on the boundary elements
76  TYPE bound_elem
77  INTEGER :: id
78  INTEGER :: conn(3)
79  INTEGER :: flag
80  TYPE(bound_elem), POINTER :: next
81  END TYPE bound_elem
82 
83 
84  INTEGER :: jj ! some variable scot put in... counter
85 
86  TYPE(bound_elem), POINTER :: &
87  front_elem, & ! A list of the front boundary elements
88  back_elem, & ! A list of the back boundary elements
89  first_back_elem, &
90  first_front_elem
91 
92 ! INTEGER, ALLOCATABLE, DIMENSION(:) :: NBoundryEl
93 
94 ! ALLOCATE(NBoundryEl(1:scale))
95 ! NBoundryEl(:) = 0
96 
97 
98  ! Variable initializations
99  low_tol = 99999.00000
100  hi_tol = 100001.00000
101  max_iterations = 5
102  iteration = 1
103  step = 5
104 
105  ! Number of boundary element counters are initialized to '0'
106  nboundryel = 0
107  nfront_elem = 0
108  nback_elem = 0
109 
110  ! Number of surface sister nodes initialized to '0'
111  numsurfsis = 0
112  numsurfsisb = 0
113 
114 !---------------------------------------------------------------------------------------------------!
115 ! READ 'frac.im' SURFACE MESH DESCRIPTION FILE !
116 !---------------------------------------------------------------------------------------------------!
117  OPEN(unit = 40, file="fracSF.im", status = "OLD")
118 
119  WRITE(6,*)
120  WRITE(6,*)
121  WRITE(6,'(A,$)') "Reading 'fracSF.im' file... "
122 
123  READ(40,*) ! INFORMATION NOT NEEDED
124  READ(40,*) ! INFORMATION NOT NEEDED
125 
126  ! Reading in number of surface node points and surface elements
127  READ(40,*) numsurfnp, numsurfelem
128 
129  ! Allocating surface node array
130  ALLOCATE(surfnode(numsurfnp))
131 
132  ! Setting up L-lists for front surface and back surface nodes
133  ALLOCATE(frontsnode); first_frontsnode => frontsnode; nullify(frontsnode%next)
134  ALLOCATE(backsnode); first_backsnode => backsnode; nullify(backsnode%next)
135 
136  ! Loops through the number of surface nodes in the file
137  DO l = 1, numsurfnp
138 
139  ! Reading the surface node coordinates and marker
140  READ(40,*) surfnode(l)%coord(1:3), surfnode(l)%marker
141 
142  ! IF this node lies on the back edge...
143  IF (surfnode(l)%coord(3) .LE. minz) THEN
144 
145  ! ...THEN add this node to the back surface node L-list
146  backsnode%ID = l
147  backsnode%coord(1:3) = surfnode(l)%coord(1:3)
148  backsnode%marker = surfnode(l)%marker
149  ALLOCATE(backsnode%next); backsnode => backsnode%next; nullify(backsnode%next)
150 
151  ! Updates the counter for number of surface sister nodes (edge nodes)
152  numsurfsis = numsurfsis + 1
153 
154  ! ELSE IF this node is located on the front edge...
155  ELSE IF (surfnode(l)%coord(3) .GE. maxz) THEN
156 
157  ! ...THEN add this node to the front surface node L-list
158  frontsnode%ID = l
159  frontsnode%coord(1:3) = surfnode(l)%coord(1:3)
160  frontsnode%marker = surfnode(l)%marker
161  ALLOCATE(frontsnode%next); frontsnode => frontsnode%next; nullify(frontsnode%next)
162 
163  ! Updates the counter for number of surface sister nodes (edge nodes)
164  numsurfsisb = numsurfsisb + 1 ! These are BACK edge nodes
165  END IF
166 
167  END DO
168 
169  elemlist => firstelem ! Lists all of the surface elements
170 
171  ! Allocation of the L-lists that contain element info only for front and back boundary elements
172  ALLOCATE(front_elem); first_front_elem => front_elem; nullify(front_elem%next)
173  ALLOCATE(back_elem); first_back_elem => back_elem; nullify(back_elem%next)
174 
175 
176  ALLOCATE(surface(numsurfelem))
177 
178  ! Loop that reads in element data and searches for boundary elements
179  DO l = 1, numsurfelem
180 
181  ! Reads in the element data from the 'frac.im' file
182  READ(40,*) surface(l)%conn(1:3), surface(l)%marker, m, n
183 
184  ! Loops through all nodes. (used in searching for boundary elements)
185  DO m = 1, numsurfnp
186 
187  ! If there is a node on the front boundary... (checks node z-coordinate)
188  IF(surfnode(m)%coord(3) .GE. maxz) THEN
189 
190  ! ...THEN check to see if the current element has this node in its conn array
191  DO n = 1, 3
192 
193  ! If the element conn array contains the node in question...
194  IF (m .EQ. surface(l)%conn(n)) THEN
195 
196  ! ...THEN add this element and its information to 'front_elem' L-list
197  ! This list keeps track of only the front elements
198  front_elem%ID = l
199  front_elem%conn(1:3) = surface(l)%conn(1:3)
200  front_elem%flag = surface(l)%marker
201  ALLOCATE(front_elem%next); front_elem => front_elem%next; nullify(front_elem%next)
202 
203  ! These two variables keep count of the elements
204  nfront_elem = nfront_elem + 1 ! Keeps count of only the front boundary elements
205  nboundryel = nboundryel + 1 ! Keeps count of all boundary elements
206 
207  ! Since the element was found to be on the boundary...
208  goto 50 ! ...exit these loops and move on to the next element
209  END IF
210  END DO
211 
212  ! ELSE IF the node is on the back boundary... (checks node z-coordinate)
213  ELSE IF (surfnode(m)%coord(3) .LE. minz) THEN
214 
215  ! ...THEN check to see if the current element has this node in its conn array
216  DO n = 1, 3
217 
218  ! IF the element conn array contains the node in question...
219  IF (m .EQ. surface(l)%conn(n)) THEN
220 
221  ! THEN add this element and its information to 'back_elem' L-list
222  ! This list keeps track of only the back elements
223  back_elem%ID = l
224  back_elem%conn(1:3) = surface(l)%conn(1:3)
225  back_elem%flag = surface(l)%marker
226  ALLOCATE(back_elem%next); back_elem => back_elem%next; nullify(back_elem%next)
227 
228  ! These two variables keep count of the elements
229  nback_elem = nback_elem + 1 ! Keeps count of only the back boundary elements
230  nboundryel = nboundryel + 1 ! Keeps count of all boundary elements
231 
232  ! Since the element was found to be on the boundary...
233  goto 50 ! ...exit these loops and move on to the next element
234  END IF
235  END DO
236  END IF
237  END DO
238 
239  ! Now that it has been determined - if the element lies on the boundary...
240  ! ...we can add its information to the main element L-list
241  elemlist%ID = l
242  elemlist%conn(1:3) = surface(l)%conn(1:3)
243  elemlist%conn(4) = 0 ! since this list was used for vol. Elem... we assign '0'
244  ! to the unneeded cell in the conn array
245  elemlist%flag = surface(l)%marker
246  ALLOCATE(elemlist%next); elemlist => elemlist%next; nullify(elemlist%next)
247 
248 50 END DO
249 
250  ! We are now finished reading the 'frac.im' file
251  CLOSE(40)
252 
253 
254 !---------------------------------------------------------------------------------------------------!
255 ! RUNNING SEARCH ON SISTER NODE MATCHES !
256 !---------------------------------------------------------------------------------------------------!
257 
258  iteration = 0 ! initializes the number of iterations needed to find sister nodes
259 
260  WRITE(6,*) "DONE."
261  WRITE(6,*) "Number of back edge nodes: ", numsurfsisb
262  WRITE(6,*) "Number of front edge nodes: ", numsurfsis
263 
264  ! Just checks to see if there were the same number of nodes on both the front and back edges
265  IF (numsurfsisb .EQ. numsurfsis) THEN
266  WRITE(6,*) "...node quantities confirmed."
267  ELSE
268  ! If there wasn't a match, the program exits because nothing else can be done
269  WRITE(6,*) "There was an error in calculating the number of matching edge nodes."
270  stop
271  END IF
272 
273  scount = numsurfsis
274 100 frontsnode => first_frontsnode
275  backsnode => first_backsnode
276  iteration = iteration + 1
277  num_matches = 0
278 
279  WRITE(6,*) "Beginning search on sister nodes..."
280 
281  ! Loop through all back edge nodes
282  DO WHILE(associated(backsnode%next))
283 
284  ! Also loop through all front edge nodes
285  DO WHILE(associated(frontsnode%next))
286 
287  ! If the 'X' coord is almost identical for both nodes THEN
288  ! check the 'Y' coord value
289  IF ((backsnode%coord(1) .EQ. frontsnode%coord(1)) .OR. &
290  ((backsnode%coord(1)/frontsnode%coord(1) .GT. low_tol/100000) .AND. &
291  (backsnode%coord(1)/frontsnode%coord(1) .LT. hi_tol/100000))) THEN
292 
293  ! IF the 'Y' coord is almost identical for both nodes THEN
294  ! these nodes are sister nodes (a match is found)
295  IF((backsnode%coord(2) .EQ. frontsnode%coord(2)) .OR. &
296  ((backsnode%coord(2)/frontsnode%coord(2) .GT. low_tol/100000) .AND. &
297  (backsnode%coord(2)/frontsnode%coord(2) .LT. hi_tol/100000))) THEN
298 
299  backsnode%sister => frontsnode
300  frontsnode%sister => backsnode
301 
302  ! updates the number of sister node matches found
303  num_matches = num_matches + 1
304 
305  ENDIF
306  ENDIF
307 
308  ! proceed to the next node
309  frontsnode => frontsnode%next
310  ENDDO
311 
312  ! Once all the front nodes are cycled through, proceed to the next backsnode
313  ! and begin the search again
314  backsnode => backsnode%next
315  frontsnode => first_frontsnode
316  ENDDO
317 
318  WRITE(6,*) "Number of verified matches: ", num_matches
319  WRITE(6,*) "Number of intended matches: ", numsurfsis
320 
321 
322  WRITE(6,*) "Writing node match information to 'nodematch.dat' file..."
323 
324 
325 
326  OPEN(unit = 500, file = '2Dnodematch.dat', status = 'UNKNOWN')
327 
328  WRITE(500,'(A8,3(6X,A1,5X),5X,A9,3(6X,A1,5X))') &
329  "BACKNODE", "X", "Y", "Z", "FRONTNODE", "X", "Y", "Z"
330 
331  frontsnode => first_frontsnode
332  backsnode => first_backsnode
333 
334  DO WHILE(associated(frontsnode%next) .AND. associated(backsnode%next))
335  WRITE(500,'(I8,3F12.8,6X,I8,3F12.8)') backsnode%ID, backsnode%coord(1:3), &
336  backsnode%sister%ID, backsnode%sister%coord(1:3)
337  frontsnode => frontsnode%next
338  backsnode => backsnode%next
339  END DO
340 
341  CLOSE(500)
342 
343 
344 
345  IF (iteration .LE. max_iterations) THEN
346  IF (numsurfsis .NE. num_matches) THEN
347  WRITE(6,*) "There was a failure in matching up the desired number of nodes."
348  WRITE(6,*) "Redefining tolerances and starting iteration number ", iteration
349  low_tol = low_tol - step
350  hi_tol = hi_tol + step
351  goto 100
352  ELSE IF (numscale_np/2 .EQ. num_matches) THEN
353  WRITE(6,*) "Number of matches confirmed. Proceeding to next step."
354  ENDIF
355  ENDIF
356 
357 
358 !---------------------------------------------------------------------------------------------------!
359 ! WRITING OUTPUT FILE !
360 !---------------------------------------------------------------------------------------------------!
361 
362  OPEN(unit = 45, file = prefix(1:length(prefix))//'/fracSF.im', &
363  status = "UNKNOWN")
364  WRITE(45,*) scale, 3
365 
366  ! Loops through all processors
367  DO k = 1, scale
368 
369  WRITE(45,*) k ! Writes the current Processor Number
370 
371  ! Writes the number of surface nodes and elements (This is the same for all Processors)
372  WRITE(45,*) numsurfnp, numsurfelem
373 
374  ! Loops through all surface nodes
375  DO l = 1, numsurfnp
376  ! Writes the current node information to output file
377  WRITE(45,*) surfnode(l)%coord(1:3), surfnode(l)%marker,0
378  END DO
379 
380  ! Returns L-lists to the beginning
381  elemlist => firstelem
382  front_elem => first_front_elem
383  back_elem => first_back_elem
384 
385 
386  ! First it lists the back edge boundary elements...
387  DO WHILE(associated(back_elem%next))
388  WRITE(45,*) back_elem%conn(1:3), back_elem%flag, m, n
389  back_elem => back_elem%next
390  m = m + 1
391  END DO
392 
393  ! ...Then it lists the front edge boundary elements...
394  DO WHILE(associated(front_elem%next))
395  WRITE(45,*) front_elem%conn(1:3), front_elem%flag, m, n
396  front_elem => front_elem%next
397  m = m + 1
398  END DO
399 
400  ! Finally, we list all the internal nodes
401  DO WHILE(associated(elemlist%next))
402  WRITE(45,*) elemlist%conn(1:3), elemlist%flag, m, n
403  elemlist => elemlist%next
404  END DO
405 
406  ! Beginning translation
407  DO l = 1, numsurfnp
408  surfnode(l)%coord(3) = surfnode(l)%coord(3) + ztrans
409  END DO
410  END DO
411 
412  CLOSE(45)
413 
414  OPEN(unit = 45, file = prefix(1:length(prefix))//'/fracS.im', &
415  status = "UNKNOWN")
416  WRITE(45,*) scale, 3
417  DO i = 1, scale
418  WRITE(45,*) i ! processor id
419  WRITE(45,*) 0, 0
420  ENDDO
421 
422  CLOSE(45)
423 
424 
425  ! Starting communication information
426 !!$ DO j = 0, scale - 1
427 !!$
428 !!$ ! Writes out the current processor and total number of boundary nodes
429 !!$ IF (j .EQ. 0) THEN
430 !!$ WRITE(45,*) j, NBoundryEL ! Nfront_elem for the number of front edge elements
431 !!$
432 !!$ ! Loop through each processor again
433 !!$ DO jj = 0, scale - 1
434 !!$
435 !!$ ! IF the current proc is the first one...
436 !!$ IF(jj .EQ. 0)THEN
437 !!$
438 !!$ ! There is no communication information sent to itself
439 !!$ WRITE(45,*) 0
440 !!$
441 !!$ ! ELSE IF the current proc is the very next one in the list...
442 !!$ ELSE IF(jj .EQ. 1)THEN
443 !!$
444 !!$ ! Write the number of sister nodes communicating with
445 !!$ WRITE(45,*) numsurfsis ! Number of nodes sending
446 !!$ backsnode => first_backsnode
447 !!$
448 !!$ ! Then list all of these nodes
449 !!$ DO WHILE(associated(backsnode%next))
450 !!$ WRITE(45,*) backsnode%sister%ID
451 !!$ backsnode => backsnode%next
452 !!$ END DO
453 !!$
454 !!$ ! ELSE no other information is being sent to any other proc
455 !!$ ELSE
456 !!$ WRITE(45,*) 0
457 !!$ ENDIF
458 !!$ ENDDO
459 !!$
460 !!$
461 !!$ ! ELSE IF the current processor is somewhere in the middle...
462 !!$ ELSE IF ((j .GT. 0).AND.(j .LT. scale-1)) THEN ! middle blocks
463 !!$ ! Write the number of boundary elements
464 !!$ WRITE(45,*) j, NBoundryEL
465 !!$
466 !!$ ! Loops through all processors again
467 !!$ DO jj = 0, scale - 1
468 !!$
469 !!$ ! IF the current processor is 1 less than the other looped proc #...
470 !!$ IF(jj .EQ. j+1)THEN
471 !!$
472 !!$ WRITE(45,*) numsurfsis ! Number of nodes sending
473 !!$ backsnode => first_backsnode
474 !!$ ! Then write the list of these nodes
475 !!$ DO WHILE(associated(backsnode%next))
476 !!$ WRITE(45,*) backsnode%sister%ID
477 !!$ backsnode => backsnode%next
478 !!$ END DO
479 !!$
480 !!$ ! IF the current processor is equal to the other looped proc #...
481 !!$ ELSE IF(jj .EQ. j)THEN
482 !!$ WRITE(45,*) 0 ! Nothing is communicated with itself
483 !!$
484 !!$ ! ELSE IF the current proc is the other looped proc right after this one...
485 !!$ ELSE IF(jj .EQ. j-1)THEN
486 !!$
487 !!$ WRITE(45,*) numsurfsisb ! Number of nodes sending
488 !!$ backsnode => first_backsnode
489 !!$ ! Then write the list of these nodes
490 !!$ DO WHILE(associated(backsnode%next))
491 !!$ WRITE(45,*) backsnode%ID
492 !!$ backsnode => backsnode%next
493 !!$ END DO
494 !!$
495 !!$ ! Else write '0' for the communication information
496 !!$ ELSE
497 !!$ WRITE(45,*) 0
498 !!$ ENDIF
499 !!$ END DO
500 !!$
501 !!$ ! Else if the current processor is the last proc...
502 !!$ ELSE IF (j .EQ. scale-1) THEN
503 !!$ ! Write the number of boundary elements
504 !!$ WRITE(45,*) j, NBoundryEL ! Nback_elem for just the back edge element total
505 !!$
506 !!$ ! Loops through all processors again
507 !!$ DO jj = 0, scale - 1
508 !!$
509 !!$ ! IF the current processor is 1 less than the other looped proc #...
510 !!$ IF(jj .EQ. scale-2)THEN
511 !!$
512 !!$ WRITE(45,*) scount ! Number of nodes sending
513 !!$ backsnode => first_backsnode
514 !!$ ! Then write the list of these nodes
515 !!$ DO WHILE(associated(backsnode%next))
516 !!$ WRITE(45,*) backsnode%ID
517 !!$ backsnode => backsnode%next
518 !!$ END DO
519 !!$ ! Else write '0' for the communication information
520 !!$ ELSE
521 !!$ WRITE(45,*) 0
522 !!$ ENDIF
523 !!$ ENDDO
524 !!$ END IF
525 !!$
526 !!$ ! Writes out neighboring file information
527 !!$ IF (j .EQ. 0) THEN
528 !!$ WRITE(45,*) 1 ! The number of files communicating with
529 !!$ WRITE(45,*) 1 ! The fileID the current proc. is communicating with
530 !!$
531 !!$ ELSE IF (j .EQ. scale - 1) THEN
532 !!$ WRITE(45,*) 1 ! The number of files communicating with
533 !!$ WRITE(45,*) (scale - 2) ! The fileID the current proc. is communicating with
534 !!$
535 !!$ ELSE
536 !!$ WRITE(45,*) 2 ! The number of files communicating with
537 !!$ WRITE(45,*) (j - 1), (j + 1) ! The fileID's the current proc. is communicating with
538 !!$ END IF
539 !!$ END DO
540 !!$
541  END SUBROUTINE read_frac
542 
543 
544 
545 
546 
547 
FT m(int i, int j) const
j indices k indices k
Definition: Indexing.h:6
int status() const
Obtain the status of the attribute.
Definition: Attribute.h:240
const std::string & unit() const
Obtain the unit of the attribute.
Definition: Attribute.h:200
void scale(const Real &a, Nodal_data &x)
blockLoc i
Definition: read.cpp:79
const NT & n
unsigned long id(const Leda_like_handle &x)
Definition: Handle.h:107
void next()
Go to the next element within the connectivity tables of a pane.
subroutine read_frac
Definition: READ_FRAC.f90:53