40
41
42
43
44
45
46
47
48
49
50
51
52
53
54! - loop over
the nodes of each element
55
56
57
58
59
60
61 use element_mod , only :nixs,nixq,nixtg
62
63
64
65#include "implicit_f.inc"
66
67
68
69 INTEGER, INTENT(IN) :: NPARG,NGROUP,NUMELS,NUMELQ,NUMELTG,NUMNOD,NSURF,N2D
70 INTEGER, INTENT(IN) :: LEADING_DIMENSION
71 INTEGER, INTENT(IN) :: NB_BOX_LIMIT
72 INTEGER, INTENT(IN) :: NB_CELL_X,,NB_CELL_Z
73 INTEGER, DIMENSION(NPARG,NGROUP), INTENT(IN) :: IPARG
74 INTEGER, DIMENSION(NIXS,NUMELS),INTENT(IN), TARGET :: IXS
75 INTEGER, DIMENSION(NIXQ,NUMELQ),INTENT(IN), TARGET :: IXQ
76 INTEGER, DIMENSION(NIXTG,NUMELTG),INTENT(IN), TARGET :: IXTG
77 INTEGER, DIMENSION(NUMNOD), INTENT(INOUT) :: NODAL_PHASE
78 INTEGER, DIMENSION(NUMNOD), INTENT(INOUT) :: CLOSEST_NODE_ID
79 INTEGER, DIMENSION(3,NUMNOD), INTENT(IN) :: CELL_POSITION
80 INTEGER, DIMENSION(NB_CELL_X,NB_CELL_Y,NB_CELL_Z), INTENT(INOUT) :: CELL
81 my_real,
DIMENSION(3,NUMNOD),
INTENT(IN) :: x
82 INTEGER, INTENT(IN) :: ID_SURFACE
83 INTEGER, DIMENSION(NSEG,4), INTENT(IN) :: SURFACE_NODES
84 INTEGER, INTENT(IN) :: NNOD2SURF,NSEG_USED
85 INTEGER, DIMENSION(NUMNOD+1), INTENT(IN) :: KNOD2SURF
86 INTEGER, DIMENSION(NNOD2SURF,NUMNOD), INTENT(IN) :: INOD2SURF
87 my_real,
DIMENSION(3,NUMNOD),
INTENT(IN) :: nod_normal
88 INTEGER, DIMENSION(NSEG_USED), INTENT(IN) :: SEGTOSURF
89 INTEGER, INTENT(IN) :: NSEG
90 INTEGER, DIMENSION(NSEG), INTENT(IN) :: SURF_ELTYP
91 INTEGER, DIMENSION(NSURF), INTENT(IN) :: SWIFTSURF
92
93
94
95 LOGICAL :: BOOL,CONDITION
96 INTEGER :: I,J,NG
97 INTEGER :: MTN,NEL,NFT,ITY,ISOLNOD,INIVOL
98 INTEGER :: ,NODE_NUMBER,FIRST,SURF_NODE_NUMBER,NODE_ID,CLOSEST_NODE
99 INTEGER, DIMENSION(:,:), POINTER :: IXP
100 INTEGER, DIMENSION(:), ALLOCATABLE :: TAG_ARRAY,SURF_NODE_LIST
101
102 INTEGER :: IX,IY,IZ,NEXT_NODE
103 INTEGER :: MY_PHASE,OLD_PHASE
104 INTEGER :: UNKNOWN_CELL_INDEX,LAST_UNKNOWN_CELL,CURRENT_UNKNOWN_CELL
105 INTEGER, DIMENSION(8,3) :: POSITION_SAVE
107
108 INTEGER :: info
109
110 INTEGER, DIMENSION(:), ALLOCATABLE :: KEY1,KEY2,ID_LIST
111 my_real,
DIMENSION(:),
ALLOCATABLE :: x_tmp
113 my_real,
DIMENSION(:,:),
ALLOCATABLE :: local_x
114 INTEGER, DIMENSION(:), ALLOCATABLE:: LIST_NODE
115 INTEGERDIMENSION(32)
116integer, target :: nothing(1,1)
117
118 ALLOCATE( tag_array(numnod) )
119 ALLOCATE( surf_node_list(numnod) )
120 ALLOCATE( list_node(numnod) )
121 tag_array(1:numnod) = 0
122 surf_node_number = 0
123
124
125
126
127
128 DO j=1,4
129 DO i=1,nseg
130 node_id = surface_nodes(i,j)
131 IF(tag_array(node_id) == 0) THEN
132 tag_array(node_id) = 1
133 surf_node_number = surf_node_number + 1
134 surf_node_list(surf_node_number) = node_id
135 ENDIF
136 ENDDO
137 ENDDO
138
139 ALLOCATE( x_tmp(surf_node_number) )
140 ALLOCATE( key2(surf_node_number) )
141 DO i=1,surf_node_number
142 x_tmp(i) = x(leading_dimension,surf_node_list(i))
143 key2(i) = i
144 ENDDO
145
146
147 CALL myqsort(surf_node_number,x_tmp,key2,info)
148 DEALLOCATE( x_tmp )
149
150
151 tag_array(1:numnod) = 0
152 next_node = 0
153 ALLOCATE( local_x(3,8) )
154
155
156
157 DO ng=1,ngroup
158 mtn = iparg(1,ng)
159 nel = iparg(2,ng)
160 nft = iparg(3,ng)
161 ity = iparg(5,ng)
162 isolnod = iparg(28,ng)
163 inivol = iparg(53,ng)
164 IF(inivol <= 0) cycle
165 IF(mtn /= 51 .AND. mtn /= 151) cycle
166 IF(n2d == 0 .AND. ity /= 1)THEN
167 cycle
168 ELSEIF(n2d > 0 .AND. ity /= 7 .AND. ity /= 2)THEN
169 cycle
170 ENDIF
171
172
173 IF(ity == 1) THEN
174 first = 1
175 node_number = 8
176 ixp => ixs(1:node_number+1,nft+1:nft+nel)
177 ELSEIF(ity == 2) THEN
178 first = 2
179 node_number = 4
180 ixp => ixq(1:node_number+1,nft+1:nft+nel)
181 ELSEIF(ity == 7) THEN
182 first = 2
183 node_number = 3
184 ixp => ixtg(1:node_number+1,nft+1:nft+nel)
185 ELSE
186 first = -huge(first)
187 node_number = -huge(node_number)
188 ixp => nothing
189 ENDIF
190
191
192
193
194 DO j=1,nel
195 old_phase = 0
196 my_phase = 0
197 bool = .false.
198 condition = .true.
199 i = 1
200 unknown_cell_index = 0
201 position_save(1:node_number,1:3) = 0
202 last_unknown_cell = 0
203
204
205
206 DO WHILE (condition)
207 node_id = ixp(1+i,j)
208 ix = cell_position(1,node_id)
209 iy = cell_position(2,node_id)
210 iz = cell_position(3,node_id)
211 ! ---------------
212
213 IF(cell(ix,iy,iz)==2) THEN
214 bool = .true.
215 condition = .false.
216
217
218 ELSEIF(cell(ix,iy,iz) == 1 .OR. cell(ix,iy,iz) == -1) THEN
219 old_phase = my_phase
220 my_phase = cell(ix,iy,iz)
221
222
223 ELSEIF(cell(ix,iy,iz) == 0) THEN
224 current_unknown_cell = ix + 1000 * iy + 1000**2 * iz
225 IF(last_unknown_cell /= current_unknown_cell) THEN
226 unknown_cell_index = unknown_cell_index + 1
227 position_save(unknown_cell_index,1) = ix
228 position_save(unknown_cell_index,2) = iy
229 position_save(unknown_cell_index,3) = iz
230 last_unknown_cell = current_unknown_cell
231 id_node_save(unknown_cell_index) = node_id
232 ENDIF
233 ENDIF
234
235 i = i + 1
236 IF( i > node_number ) condition = .false.
237 ENDDO
238
239
240
241
242 IF(bool) THEN
243
244
245 DO i=1,node_number
246 node_id = ixp(1+i,j)
247 IF(tag_array(node_id) == 0) THEN
248 tag_array(node_id) = 1
249 next_node = next_node + 1
250 list_node(next_node) = node_id
251 ENDIF
252 ENDDO
253 ELSE
254
255
256
257
258
259
260
261 IF(my_phase /= 0) THEN
262 DO i=1,node_number
263 node_id = ixp(1+i,j)
264 nodal_phase(node_id) = my_phase
265 ENDDO
266 DO i=1,unknown_cell_index
267 ix = position_save(i,1)
268 iy = position_save(i,2)
269 iz = position_save(i,3)
270 cell(ix,iy,iz) = my_phase
271 ENDDO
272
273
274 ELSE
275
276
277 ALLOCATE( id_list(unknown_cell_index) )
278 ALLOCATE( key1(unknown_cell_index) )
279 DO i=1,unknown_cell_index
280 ix = position_save(i,1)
281 iy = position_save(i,2)
282 iz = position_save(i,3)
283 node_id = id_node_save(i)
284 local_x(1,i) = x(1,node_id)
285 local_x(2,i) = x(2,node_id)
286 local_x(3,i) = x(3,node_id)
287 key1(i) = i
288 ENDDO
289 eps = 1d-6
290 CALL find_closest_node(leading_dimension,unknown_cell_index,surf_node_number,numnod,
291 . local_x,x,eps,
292 . key1,key2,surf_node_list,id_list)
293
294
295
296
297 DO i=1,unknown_cell_index
298 inod = id_list(i)
299 xn(1:3) = local_x(1:3,i)
300 dist = zero
301 CALL in_out_side( inod,inod2surf,knod2surf,nnod2surf,x,
302 . xn,dist,nseg,surf_eltyp,nod_normal,
303 . surface_nodes,swiftsurf,id_surface,segtosurf )
304 ix = position_save(i,1)
305 iy = position_save(i,2)
306 iz = position_save(i,3)
307 my_phase = int(dist)
308 cell(ix,iy,iz) = my_phase
309 ENDDO
310
311
312
313 DO i=1,node_number
314 node_id = ixp(1+i,j)
315 ix = cell_position(1,node_id)
316 iy = cell_position(2,node_id)
317 iz = cell_position(3,node_id)
318 my_phase = cell(ix,iy,iz)
319 nodal_phase(node_id) = my_phase
320 ENDDO
321
322
323 DO i=1,unknown_cell_index
324 ix = position_save(i,1)
325 iy = position_save(i,2)
326 iz = position_save(i,3)
328 ENDDO
329
330 DEALLOCATE( id_list )
331 DEALLOCATE( key1 )
332 ENDIF
333
334 ENDIF
335 ENDDO
336
337 ENDDO
338
339
340 DEALLOCATE( local_x )
341
342
343
344
345
346 ALLOCATE( local_x(3,next_node) )
347 ALLOCATE( id_list(next_node) )
348 ALLOCATE( key1(next_node) )
349
350 DO i=1,next_node
351 node_id = list_node(i)
352 local_x(1:3,i) = x(1:3,node_id)
353 key1(i) = i
354 ENDDO
355
356 eps = 1d-6
357
358
360 . local_x,x,eps,
361 . key1,key2,surf_node_list,id_list)
362
363
364
365
366 DO i=1,next_node
367 closest_node = id_list(i)
368 node_id = list_node(i)
369 xn(1:3) = local_x(1:3,i)
370 dist = zero
371 CALL in_out_side( closest_node,inod2surf,knod2surf,nnod2surf,x,
372 . xn,dist,nseg,surf_eltyp,nod_normal,
373 . surface_nodes,swiftsurf,id_surface,segtosurf )
374 my_phase = int(dist)
375 nodal_phase(node_id) = my_phase
376 closest_node_id(node_id) = closest_node
377 ENDDO
378
379
380
381
382 DEALLOCATE( key2 )
383 DEALLOCATE( tag_array )
384 DEALLOCATE( surf_node_list )
385 DEALLOCATE( list_node )
386 DEALLOCATE( local_x )
387
388 RETURN
end diagonal values have been computed in the(sparse) matrix id.SOL
subroutine find_closest_node(leading_direction, n1, n2, n3, x1, x2, eps, key1, key2, id_x2, id_list)
subroutine in_out_side(inod, inod2surf, knod2surf, nnod2surf, x, xn, dist, nseg, surf_eltyp, nod_normal, surf_nodes, swiftsurf, idsurf, segtosurf)
subroutine myqsort(n, a, perm, error)
subroutine phase_propagation(ix, iy, iz, nb_cell_x, nb_cell_y, nb_cell_z, nb_box_limit, cell)