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