1 subroutine pppma4 ( rangfa, nbfast,
5 > posini, xyzfac, tabaux,
6 > ulsort, langue, codret )
7 c ______________________________________________________________________
11 c Outil de Maillage Adaptatif par Raffinement et Deraffinement d'EDF R&D
13 c Version originale enregistree le 18 juin 1996 sous le numero 96036
14 c aupres des huissiers de justice Simart et Lavoir a Clamart
15 c Version 11.2 enregistree le 13 fevrier 2015 sous le numero 2015/014
16 c aupres des huissiers de justice
17 c Lavoir, Silinski & Cherqui-Abrahmi a Clamart
19 c HOMARD est une marque deposee d'Electricite de France
25 c ______________________________________________________________________
27 c Post-Processeur - Preparation du MAillage - phase 4
29 c ______________________________________________________________________
31 c On place la rangfa-ieme face par rapport aux autres
32 c ______________________________________________________________________
34 c . nom . e/s . taille . description .
35 c .____________________________________________________________________.
36 c . rangfa . e . 1 . rang dans la liste initiale de la face a .
38 c . nbfast . es . 1 . nombre de faces deja classees .
39 c . nbtrvi . e . 1 . nombre triangles visualisables .
40 c . nbquvi . e . 1 . nombre de quadrangles visualisables .
41 c . nntrvi . e .10nbtrvi. 1 : niveau du triangle a afficher .
42 c . . . . 2 : numero HOMARD du triangle .
43 c . . . . 3, 4, 5 : numeros des noeuds p1 .
44 c . . . . 6 : famille du triangle .
45 c . . . . 7, 8, 9 : numeros des noeuds p2 .
46 c . . . . 10 : numero du noeud interne .
47 c . nnquvi . e .12nbquvi. 1 : niveau du quadrangle a afficher .
48 c . . . . 2 : numero HOMARD du quadrangle .
49 c . . . . 3, 4, 5, 6 : numeros des noeuds p1 .
50 c . . . . 7 : famille du quadrangle .
51 c . . . . 8, 9, 10, 11 : numeros des noeuds p2 .
52 c . . . . 12 : numero du noeud interne .
53 c . coopro . e . sdim* . coordonnees projetees de : .
54 c . . .nbnot+12. le triedre : -8:O ; -9:I ; -10:J ; -11:K .
55 c . . . . la fenetre de zoom : de -7 a 0 en 3D ou .
56 c . . . . de -3 a 0 en 2D .
57 c . . . . les noeuds de 1 a nbnoto .
58 c . posini . aux . nbquvi . tableau auxiliaire de renumerotation des .
59 c . . .+nbtrvi . faces en fonction de l'affichage .
60 c . xyzfac . e .nbtrvi+ . coordonnees des noeuds des faces .
62 c . tabaux . e/s . nbquvi . tabaux(i) = 1 : la face i est stockee .
63 c . . .+nbtrvi . tabaux(i) = 0 : la face i n'est pas stockee.
64 c . ulsort . e . 1 . unite logique de la sortie generale .
65 c . langue . e . 1 . langue des messages .
66 c . . . . 1 : francais, 2 : anglais .
67 c . codret . s . 1 . code de retour des modules .
68 c . . . . 0 : pas de probleme .
69 c ._____________________________________________________________________
72 c 0. declarations et dimensionnement
75 c 0.1. ==> generalites
81 parameter ( nompro = 'PPPMA4' )
93 integer rangfa, nbfast
94 integer nbtrvi, nbquvi
95 integer nntrvi(10,nbtrvi)
96 integer nnquvi(12,nbquvi)
97 integer posini(nbtrvi+nbquvi)
98 integer tabaux(nbtrvi+nbquvi)
100 double precision coopro(sdim,-11:nbnoto)
101 double precision xyzfac(nbtrvi+nbquvi,9)
103 integer ulsort, langue, codret
105 c 0.4. ==> variables locales
107 integer indpos, lerang
108 integer numfac, rangqu
109 integer nufast, rgfast, rgqust
110 integer nbnfac, nbnfst
114 double precision daux
115 double precision dzmini
116 double precision xminfa, xmaxfa
117 double precision yminfa, ymaxfa
118 double precision zvuefa, zvuefs
119 double precision v1(3), v2(3), v3(3), v4(3)
120 double precision w1(3), w2(3), w3(3), w4(3), wn(2)
126 parameter ( nbmess = 10 )
127 character*80 texte(nblang,nbmess)
129 c 0.5. ==> initialisations
130 c_______________________________________________________________________
138 #ifdef _DEBUG_HOMARD_
139 write (ulsort,texte(langue,1)) 'Entree', nompro
143 #ifdef _DEBUG_HOMARD_
144 cgn write (ulsort,1795) '. nbtrvi', nbtrvi, 'nbquvi', nbquvi
145 write (ulsort,1795) '. rangfa', rangfa, 'nbfast', nbfast
152 1794 format(3(a,' =',f12.5,' , '))
153 1795 format(3(a,' =',i5,' , '))
154 1796 format(a,6f12.5)
155 1797 format(i5,' *',6f12.5)
157 c 1.2. ==> Caracteristiques
159 if ( rangfa.gt.nbtrvi ) then
160 rangqu = rangfa - nbtrvi
162 if ( rangfa.le.nbtrvi ) then
163 numfac = nntrvi(2,rangfa)
165 numfac = -nnquvi(2,rangqu)
168 c 1.3. ==> A priori, on va mettre la face devant toutes les autres
173 c 2. On commence par s'assurer que la face a classer n'est pas
174 c parallele a l'axe de vision. Si c'est le cas, on la range dans la
175 c place la plus eloignee car l'ordre d'affichage n'a pas
176 c d'importance : on ne verra qu'une tranche !
179 daux = sqrt( abs(xyzfac(rangfa,7))**2
180 > + abs(xyzfac(rangfa,8))**2
181 > + abs(xyzfac(rangfa,9))**2 )
182 if ( abs(xyzfac(rangfa,9))/daux.le.dzmini ) then
183 cgn write(*,*)'rang',rangfa,', face',numfac
184 cgn write(*,1794)'Nx',xyzfac(rangfa,7),'Ny',xyzfac(rangfa,8),
185 cgn > 'Nz',xyzfac(rangfa,9)
186 cgn write(*,1794)'norme',daux,
187 cgn > 'Nz/norme',abs(xyzfac(rangfa,9))/daux
188 cgn write(*,*)'La face a classer est parallele a la vision'
195 c 3. Suite des caracteristiques
200 xminfa = xyzfac(rangfa,1)
201 xmaxfa = xyzfac(rangfa,2)
202 yminfa = xyzfac(rangfa,3)
203 ymaxfa = xyzfac(rangfa,4)
206 cgn if ( numfac.eq.-25 .or. numfac.eq.-21 ) then
210 write(*,*)'*************************************************'
211 write(*,*)'Examen de la face',numfac,' (rangfa =', rangfa,')'
213 if ( glop.ne.0 ) then
214 write(*,*)'....... Face a classer',numfac,' ==> noeuds :'
215 if ( rangfa.le.nbtrvi ) then
216 jaux = nntrvi(3,rangfa)
217 write(*,1797) jaux, (coopro(iaux,jaux),iaux=1,3)
218 jaux = nntrvi(4,rangfa)
219 write(*,1797) jaux, (coopro(iaux,jaux),iaux=1,3)
220 jaux = nntrvi(5,rangfa)
221 write(*,1797) jaux, (coopro(iaux,jaux),iaux=1,3)
223 jaux = nnquvi(3,rangqu)
224 write(*,1797) jaux, (coopro(iaux,jaux),iaux=1,3)
225 jaux = nnquvi(4,rangqu)
226 write(*,1797) jaux, (coopro(iaux,jaux),iaux=1,3)
227 jaux = nnquvi(5,rangqu)
228 write(*,1797) jaux, (coopro(iaux,jaux),iaux=1,3)
229 jaux = nnquvi(6,rangqu)
230 write(*,1797) jaux, (coopro(iaux,jaux),iaux=1,3)
232 write(*,1796)'normale',(xyzfac(rangfa,iaux),iaux=7,9)
236 c 4. On parcourt toutes les faces deja stockees
237 c posini(indpos) est la position de la indpos-eme face stockee,
238 c dans la suite generale des faces a visualiser.
239 c . Si posini(indpos) est inferieur a nbtrvi, c'est que la face
240 c stockee est un triangle. Son indice dans les triangles a tracer
241 c est posini(indpos).
242 c . Si posini(indpos) est superieur a nbtrvi, c'est un quadrangle
243 c dont l'indice dans les quadrangles est posini(indpos)-nbtrvi
244 c Attention a ne pas comparer une face a elle-meme ! Cela peut
245 c arriver quand on fait une seconde passe pour replacer une face
246 c qui n'avait aucun point commun avec les autres.
249 do 40 , indpos = 1 , nbfast
251 c 4.1. ==> caracteristique de la face stockee
253 rgfast = posini(indpos)
255 if ( rgfast.eq.rangfa ) then
256 if ( glop.ne.0 ) then
257 write(*,*)'Ne pas tester une face par rapport a elle-meme'
261 if ( rgfast.le.nbtrvi ) then
262 nufast = nntrvi(2,rgfast)
264 rgqust = rgfast - nbtrvi
265 nufast = -nnquvi(2,rgqust)
268 cgn if ( nufast.eq.2098 ) then
271 if ( glop.ne.0 .or. glop1.ne.0 ) then
272 write(*,*)'.... Face stockee', nufast,', (rang',rgfast,')'
275 c 4.2. ==> On commence par s'assurer que la face stockee n'est pas
276 c parallele a l'axe de vision. Si c'est le cas, leur ordre
277 c de trace relatif n'a aucune importance. On passe donc a la
278 c face stockee suivante.
280 daux = sqrt( abs(xyzfac(rgfast,7))**2
281 > + abs(xyzfac(rgfast,8))**2
282 > + abs(xyzfac(rgfast,9))**2 )
283 if ( abs(xyzfac(rgfast,9))/daux.le.dzmini ) then
284 if ( glop.ne.0 .or. glop1.ne.0 ) then
285 write(*,1794)'Nx',xyzfac(rgfast,7),'Ny',xyzfac(rgfast,8),
286 > 'Nz',xyzfac(rgfast,9)
287 write(*,1794)'norme',daux,
288 > 'Nz/norme',abs(xyzfac(rgfast,9))/daux
289 write(*,*)'La face stockee est parallele a la vision'
294 c 4.3. ==> Si le quadrangle enveloppe de la face stockee n'a pas de
295 c recouvrement avec la face a classer, leur ordre de trace
296 c relatif n'a aucune importance. On passe donc a la face
299 if ( xyzfac(rgfast,1).ge.xmaxfa ) then
300 cgn write(*,*) '==> xyzfac > xmaxfa'
303 if ( xyzfac(rgfast,2).le.xminfa ) then
304 cgn write(*,*) '==> xyzfac < xminfa'
307 if ( xyzfac(rgfast,3).ge.ymaxfa ) then
308 cgn write(*,*) '==> xyzfac > ymaxfa'
311 if ( xyzfac(rgfast,4).le.yminfa ) then
312 cgn write(*,*) '==> xyzfac < yminfa'
316 c 4.4. ==> Les deux quadrangles enveloppes des faces se recouvrent,
317 c mais pas forcement les faces.
318 c On cherche a savoir si les deux faces partagent une
319 c surface non vide. C'est de la methode arlequin ;=)
320 c On va chercher si un point interne a la face stockee est
321 c strictement interne a la face a classer.
322 c Si on en trouve un, on calculera ses distances.
324 if ( glop.ne.0 .or. glop1.ne.0 ) then
325 write(*,*)'....... Point commun aux deux faces ?'
328 c 4.4.1. ==> Transfert des coordonnees des noeuds de la face a classer
329 c Remarque : on ne le fait qu'une fois
332 if ( rangfa.le.nbtrvi ) then
333 v1(1) = coopro(1,nntrvi(3,rangfa))
334 v1(2) = coopro(2,nntrvi(3,rangfa))
335 v2(1) = coopro(1,nntrvi(4,rangfa))
336 v2(2) = coopro(2,nntrvi(4,rangfa))
337 v3(1) = coopro(1,nntrvi(5,rangfa))
338 v3(2) = coopro(2,nntrvi(5,rangfa))
341 v1(1) = coopro(1,nnquvi(3,rangqu))
342 v1(2) = coopro(2,nnquvi(3,rangqu))
343 v2(1) = coopro(1,nnquvi(4,rangqu))
344 v2(2) = coopro(2,nnquvi(4,rangqu))
345 v3(1) = coopro(1,nnquvi(5,rangqu))
346 v3(2) = coopro(2,nnquvi(5,rangqu))
347 v4(1) = coopro(1,nnquvi(6,rangqu))
348 v4(2) = coopro(2,nnquvi(6,rangqu))
354 c 4.4.2. ==> Transfert des coordonnees des noeuds de la face stockee
356 if ( rgfast.le.nbtrvi ) then
357 w1(1) = coopro(1,nntrvi(3,rgfast))
358 w1(2) = coopro(2,nntrvi(3,rgfast))
359 w2(1) = coopro(1,nntrvi(4,rgfast))
360 w2(2) = coopro(2,nntrvi(4,rgfast))
361 w3(1) = coopro(1,nntrvi(5,rgfast))
362 w3(2) = coopro(2,nntrvi(5,rgfast))
365 w1(1) = coopro(1,nnquvi(3,rgqust))
366 w1(2) = coopro(2,nnquvi(3,rgqust))
367 w2(1) = coopro(1,nnquvi(4,rgqust))
368 w2(2) = coopro(2,nnquvi(4,rgqust))
369 w3(1) = coopro(1,nnquvi(5,rgqust))
370 w3(2) = coopro(2,nnquvi(5,rgqust))
371 w4(1) = coopro(1,nnquvi(6,rgqust))
372 w4(2) = coopro(2,nnquvi(6,rgqust))
375 if ( glop1.ne.0 ) then
376 write(*,*)'....... Noeuds de la face stockee'
377 if ( rgfast.le.nbtrvi ) then
378 write(*,1797) nntrvi(3,rgfast), (w1(iaux),iaux=1,2)
379 write(*,1797) nntrvi(4,rgfast), (w2(iaux),iaux=1,2)
380 write(*,1797) nntrvi(5,rgfast), (w3(iaux),iaux=1,2)
382 write(*,1797) nnquvi(3,rgqust), (w1(iaux),iaux=1,2)
383 write(*,1797) nnquvi(4,rgqust), (w2(iaux),iaux=1,2)
384 write(*,1797) nnquvi(5,rgqust), (w3(iaux),iaux=1,2)
385 write(*,1797) nnquvi(6,rgqust), (w4(iaux),iaux=1,2)
387 write(*,1796)'normale',(xyzfac(rgfast,iaux),iaux=7,9)
390 c 4.4.3. ==> Un point de la face a classer est-il dans la face stockee ?
392 #ifdef _DEBUG_HOMARD_
393 write (ulsort,texte(langue,3)) 'PPPMA5', nompro
395 call pppma5 ( dedans, wn,
396 > nbnfst, w1, w2, w3, w4,
397 > nbnfac, v1, v2, v3, v4,
398 > ulsort, langue, codret )
401 if ( glop.ne.0 .or. glop1.ne.0 ) then
402 write(*,*)'..... Un point de',numfac,' est dans', nufast
403 write(*,*)'..... modif pour',numfac,', rang', rangfa
409 c 4.4.4. ==> Un point de la face stockee est-il dans la face a classer ?
411 if ( codret.eq.0 ) then
413 #ifdef _DEBUG_HOMARD_
414 write (ulsort,texte(langue,3)) 'PPPMA5', nompro
416 call pppma5 ( dedans, wn,
417 > nbnfac, v1, v2, v3, v4,
418 > nbnfst, w1, w2, w3, w4,
419 > ulsort, langue, codret )
422 if ( glop.ne.0 .or. glop1.ne.0 ) then
423 write(*,*)'..... Un point de', nufast,' est dans',numfac
424 write(*,*)'..... modif pour',numfac,'(rangfa =', rangfa,')'
432 c 4.4.5. ==> Sortie prematuree
434 if ( codret.ne.0 ) then
438 c 4.4.5. ==> Si on arrive ici c'est qu'on a n'a pas reussi a mettre
439 c un point dans la zone commune aux 2 faces.
440 c On passe a la suite
442 if ( glop.ne.0 .or. glop1.ne.0 ) then
443 write(*,*) 'Impossible de trier les faces',numfac,' et',nufast
445 c if ( glop1.ne.0 ) then
450 c 4.4.7. ==> Test des profondeurs du point vis-a-vis des 2 faces
454 c 4.4.7.1. ==> Face a classer
456 if ( rangfa.le.nbtrvi ) then
457 zvuefa = coopro(3,nntrvi(3,rangfa))
459 zvuefa = coopro(3,nnquvi(3,rangqu))
462 > - ( (wn(1)-v1(1))*xyzfac(rangfa,7)
463 > + (wn(2)-v1(2))*xyzfac(rangfa,8) ) / xyzfac(rangfa,9)
465 c 4.4.7.2. ==> Face stokee
467 if ( rgfast.le.nbtrvi ) then
468 zvuefs = coopro(3,nntrvi(3,rgfast))
470 zvuefs = coopro(3,nnquvi(3,rgqust))
473 > - ( (wn(1)-w1(1))*xyzfac(rgfast,7)
474 > + (wn(2)-w1(2))*xyzfac(rgfast,8) ) / xyzfac(rgfast,9)
476 cgn if ( glop.ne.0 ) then
477 cgn write(*,1796)'... point commun', wn
478 cgn write(*,*)'....... zvuefs = ',zvuefs
479 cgn write(*,*)'....... zvuefa = ',zvuefa
482 c 4.4.7.3. ==> Comparaison :
483 c Si la face a classer est derriere la face a stocker,
484 c il faut l'inserer a cet endroit, sinon, on ne fait rien
486 if ( zvuefa.le.zvuefs ) then
489 if ( glop.ne.0 ) then
490 write(*,*)'La face',numfac,'est derriere la face', nufast
494 #ifdef _DEBUG_HOMARD_
496 if ( glop.ne.0 ) then
497 write(*,*)'La face',nufast,'est derriere la face', numfac
505 if ( tabaux(rangfa).eq.0 ) then
506 if ( glop.ne.0 ) then
507 write(*,*) 'Impossible de placer la face',numfac
513 c 5. On insere la face a la position lerang
518 if ( glop.ne.0 ) then
519 write(*,*) '==> On insere la face',numfac,' en', lerang
523 do 51 , indpos = nbfast , lerang+1, -1
524 cgn write(ulsort,*)'indpos =',indpos
525 posini(indpos) = posini(indpos-1)
527 posini(lerang) = rangfa
529 if ( glop.ne.0 ) then
530 do 501 , iaux = 1 , nbfast
531 if ( posini(iaux).le.nbtrvi ) then
532 jaux = nntrvi(2,posini(iaux))
534 jaux = -nnquvi(2,posini(iaux)-nbtrvi)
536 write (*,*) iaux,posini(iaux),'-eme face :',jaux
542 if ( glop.ne.0 ) then
543 if ( posini(1).le.nbtrvi ) then
544 iaux = nntrvi(2,posini(1))
546 iaux = -nnquvi(2,posini(1)-nbtrvi)
548 write(*,*)'Face la plus eloignee :', iaux
549 if ( posini(nbfast).le.nbtrvi ) then
550 iaux = nntrvi(2,posini(nbfast))
552 iaux = -nnquvi(2,posini(nbfast)-nbtrvi)
554 write(*,*)'Face la plus proche :', iaux
562 if ( codret.ne.0 ) then
566 write (ulsort,texte(langue,1)) 'Sortie', nompro
567 write (ulsort,texte(langue,2)) codret
571 #ifdef _DEBUG_HOMARD_
572 write (ulsort,texte(langue,1)) 'Sortie', nompro