Salome HOME
Homard executable
[modules/homard.git] / src / tool / Utilitaire / utnc01.F
1       subroutine utnc01 ( nbanci, nbgemx,
2      >                    coonoe,
3      >                    somare, merare,
4      >                    aretri,
5      >                    povoso, voisom,
6      >                    ngenar,
7      >                    ulsort, langue, codret )
8 c ______________________________________________________________________
9 c
10 c                             H O M A R D
11 c
12 c Outil de Maillage Adaptatif par Raffinement et Deraffinement d'EDF R&D
13 c
14 c Version originale enregistree le 18 juin 1996 sous le numero 96036
15 c aupres des huissiers de justice Simart et Lavoir a Clamart
16 c Version 11.2 enregistree le 13 fevrier 2015 sous le numero 2015/014
17 c aupres des huissiers de justice
18 c Lavoir, Silinski & Cherqui-Abrahmi a Clamart
19 c
20 c    HOMARD est une marque deposee d'Electricite de France
21 c
22 c Copyright EDF 1996
23 c Copyright EDF 1998
24 c Copyright EDF 2002
25 c Copyright EDF 2020
26 c ______________________________________________________________________
27 c
28 c    UTilitaire - Non Conformite - phase 01
29 c    --           -   -                  --
30 c    Reperage des non conformites : on repere les aretes par des
31 c    filiations "adoptives" en notant negativement les numeros d'arete
32 c ______________________________________________________________________
33 c .        .     .        .                                            .
34 c .  nom   . e/s . taille .           description                      .
35 c .____________________________________________________________________.
36 c . nbanci .   s .    1   . nombre d'aretes de non conformite initiale .
37 c .        .     .        . egal au nombre d'aretes recouvrant 2 autres.
38 c . nbgemx .   s .    1   . nombre maximal de generations sous une     .
39 c .        .     .        . arete                                      .
40 c . coonoe . e   . nbnoto . coordonnees des noeuds                     .
41 c .        .     . * sdim .                                            .
42 c . somare . e   .2*nbarto. numeros des extremites d'arete             .
43 c . merare . es  . nbarto . mere des aretes                            .
44 c . aretri . e   .nbtrto*3. numeros des 3 aretes des triangles         .
45 c . povoso . e   .0:nbnoto. pointeur des voisins par sommet            .
46 c . voisom . e   . nvosom . elements 1d, 2d ou 3d voisins par sommet   .
47 c . ngenar .  s  . nbarto . nombre de generations au-dessus des aretes .
48 c . ulsort . e   .   1    . numero d'unite logique de la liste standard.
49 c . langue . e   .    1   . langue des messages                        .
50 c .        .     .        . 1 : francais, 2 : anglais                  .
51 c . codret . es  .    1   . code de retour des modules                 .
52 c .        .     .        . 0 : pas de probleme                        .
53 c .        .     .        . 3 : probleme                               .
54 c ______________________________________________________________________
55 c
56 c====
57 c 0. declarations et dimensionnement
58 c====
59 c
60 c 0.1. ==> generalites
61 c
62       implicit none
63       save
64 c
65       character*6 nompro
66       parameter ( nompro = 'UTNC01' )
67 c
68 #include "nblang.h"
69 c
70 c 0.2. ==> communs
71 c
72 #include "envex1.h"
73 c
74 #include "nombno.h"
75 #include "nombar.h"
76 #include "nombtr.h"
77 #include "envca1.h"
78 #include "precis.h"
79 #include "ope1a3.h"
80 #include "impr02.h"
81 c
82 c 0.3. ==> arguments
83 c
84       integer nbanci, nbgemx
85       integer somare(2,nbarto), merare(nbarto)
86       integer aretri(nbtrto,3)
87       integer povoso(0:nbnoto), voisom(*)
88       integer ngenar(nbarto)
89 c
90       double precision coonoe(nbnoto,sdim)
91 c
92       integer ulsort, langue, codret
93 c
94 c 0.4. ==> variables locales
95 c
96       integer iaux, jaux, kaux
97       integer poind2, poinf2, point2
98       integer poind3, poinf3, point3
99       integer aret1, aretmi, aretmo, aretma
100       integer sonnnn, sopppp, soqqqq
101       integer somdep, somarr
102       integer somde3, somar3
103       integer larete(3), lenoeu(3,3)
104 #ifdef _DEBUG_HOMARD_
105       integer glop
106 #endif
107 c
108       double precision daux(3), vect(3,3)
109 c
110       integer nbmess
111       parameter ( nbmess = 10 )
112       character*80 texte(nblang,nbmess)
113 c
114 c 0.5. ==> initialisations
115 c ______________________________________________________________________
116 c
117 c====
118 c 1. preliminaires
119 c====
120 c
121 c 1.1. ==> messages
122 c
123 #include "impr01.h"
124 c
125 #ifdef _DEBUG_HOMARD_
126       write (ulsort,texte(langue,1)) 'Entree', nompro
127       call dmflsh (iaux)
128 #endif
129 c
130       texte(1,4) =
131      > '(''Nombre de paires de '',a,'' non-conformes :'',i10))'
132       texte(1,5) =
133      > '(''Nombre maximal de generations de '',a,'' :'',i10))'
134       texte(1,6) = '(/,''Examen du '',a,i10)'
135       texte(1,7) = '(a,1x,a,i10,'', de'',i10,'' a'',i10)'
136       texte(1,8) = '(a,3('' '',a,'' :'',i10))'
137       texte(1,10) =
138      > '(''Nombre de '',a,'' de generation'',i10,'' :'',i10)'
139 c
140       texte(2,4) =
141      > '(''Number of non-conformal situations for '',a,'':'',i10))'
142       texte(2,5) =
143      > '(''Maximal number of generations for '',a,'':'',i10))'
144       texte(2,6) = '(/,''Examination of '',a,'' #'',i10)'
145       texte(2,7) = '(a,1x,a,'' #'',i10,'', from'',i10,'' to'',i10)'
146       texte(2,8) = '(a,3('' '',a,'' :'',i10))'
147       texte(2,10) =
148      > '(''Number of '',a,'' from generation #'',i10,'' :'',i10)'
149 c
150       codret = 0
151       nbanci = 0
152 c
153 c====
154 c 2. On cherche tous les triplets d'aretes (aret1,larete(2),larete(3))
155 c    qui sont concourrantes.
156 c    Si elles definissent un triangle, on ne fait rien.
157 c    Sinon, on repere laquelle chapeaute les 2 autres : ce sera la
158 c    non conformite.
159 c====
160 c
161 c 2.1. ==> initialisations
162 c
163       do 21 , aret1 = 1 , nbarto
164         merare(aret1) = 0
165         ngenar(aret1) = 0
166    21 continue
167 c
168 c 2.2. ==> traitement
169 c
170       do 2 , aret1 = 1 , nbarto
171 c
172         if ( codret.eq.0 ) then
173 c
174         sonnnn = somare(1,aret1)
175         sopppp = somare(2,aret1)
176 #ifdef _DEBUG_HOMARD_
177           if ( aret1.eq.10)then
178             glop = 1
179            else
180             glop = 0
181            endif
182           if ( glop.gt.0)then
183       write (ulsort,texte(langue,6)) mess14(langue,1,1), aret1
184       write (ulsort,texte(langue,8)) ' ', 'de', sonnnn, 'a', sopppp
185 cgn      write (ulsort,texte(langue,4)) mess14(langue,3,1), nbanci
186             endif
187 #endif
188 c
189 c 2.2.1. ==> pour chacune des autres aretes contenant 'sonnnn'
190 c
191         poind2 = povoso(sonnnn-1) + 1
192         poinf2 = povoso(sonnnn)
193         do 22 , point2 = poind2, poinf2
194 c
195           if ( aret1.ne.voisom(point2) ) then
196 c
197             larete(2) = voisom(point2)
198 c
199 c           les deux sommets de cette arete : P et Q
200 c
201             somdep = somare(1,larete(2))
202             somarr = somare(2,larete(2))
203 #ifdef _DEBUG_HOMARD_
204           if ( glop.gt.0)then
205       write (ulsort,texte(langue,7)) '...', mess14(langue,1,1),
206      >                               larete(2), somdep, somarr
207             endif
208 #endif
209 c
210 c           celui des sommets qui n'est pas sommet de 'aret1'
211 c
212             if ( somdep.eq.sonnnn ) then
213               soqqqq = somarr
214             else
215               soqqqq = somdep
216             endif
217 c
218 #ifdef _DEBUG_HOMARD_
219           if ( glop.gt.0)then
220       write (ulsort,texte(langue,8)) '   ', 'N', sonnnn, 'P', sopppp,
221      >                               'Q', soqqqq
222             endif
223 #endif
224 c
225 c           existe-t-il une arete joignant P et Q ?
226 c
227             poind3 = povoso(sopppp-1) + 1
228             poinf3 = povoso(sopppp)
229             do 221 , point3 = poind3, poinf3
230 c
231               larete(3) = voisom(point3)
232 c
233 c          les deux sommets de cette arete
234 c
235               somde3 = somare(1,larete(3))
236               somar3 = somare(2,larete(3))
237 #ifdef _DEBUG_HOMARD_
238           if ( glop.gt.0)then
239       write (ulsort,texte(langue,7)) '.....', mess14(langue,1,1),
240      >                               larete(3), somde3, somar3
241             endif
242 #endif
243 c
244               if ( somde3.eq.soqqqq .or. somar3.eq.soqqqq ) then
245 c
246               if ( ngenar(aret1).eq.0 .and.
247      >             ngenar(larete(2)).eq.0 .and.
248      >             ngenar(larete(3)).eq.0 ) then
249 c
250                 larete(1) = aret1
251 #ifdef _DEBUG_HOMARD_
252           if ( glop.gt.0)then
253       write (ulsort,texte(langue,7)) '====>', mess14(langue,1,1),
254      >                               larete(3), somde3, somar3
255       write (ulsort,texte(langue,8)) '   ', 'A1', larete(1),
256      >                               'A2', larete(2), 'A3', larete(3)
257             endif
258 #endif
259 c
260 c               existe-t-il un triangle defini par ces 3 aretes ?
261 c
262                 if ( nbtrto.ne.0 ) then
263 c
264 cgn      print *,'A1', larete(1),' A2', larete(2), ' A3', larete(3)
265                   aretmi = min(larete(1), larete(2), larete(3))
266                   aretma = max(larete(1), larete(2), larete(3))
267                   if ( larete(1).ne.aretmi .and.
268      >                 larete(1).ne.aretma ) then
269                     aretmo = larete(1)
270                   elseif ( larete(2).ne.aretmi .and.
271      >                     larete(2).ne.aretma ) then
272                     aretmo = larete(2)
273                   else
274                     aretmo = larete(3)
275                   endif
276 #ifdef _DEBUG_HOMARD_
277           if ( glop.gt.0)then
278             write (ulsort,*)'aretmi/mo/ma',aretmi, aretmo, aretma
279           endif
280 #endif
281                   do 2211 , iaux = 1, nbtrto
282 cgn      print *,aretri(iaux,1),aretri(iaux,2),aretri(iaux,3)
283                     if ( min(aretri(iaux,1),
284      >                       aretri(iaux,2),
285      >                       aretri(iaux,3)).eq.aretmi ) then
286 #ifdef _DEBUG_HOMARD_
287           if ( glop.gt.0)then
288             write (ulsort,*)'triangle ',iaux,' :',
289      >                     aretri(iaux,1),aretri(iaux,2),aretri(iaux,3)
290           endif
291 #endif
292                       if ( max(aretri(iaux,1),
293      >                         aretri(iaux,2),
294      >                         aretri(iaux,3)).eq.aretma ) then
295                         if ( aretri(iaux,1).eq.aretmo .or.
296      >                       aretri(iaux,2).eq.aretmo .or.
297      >                       aretri(iaux,3).eq.aretmo ) then
298 cgn      print *,'c''est un vrai triangle'
299                            goto 22
300                         endif
301                       endif
302                     endif
303  2211             continue
304 c
305                 endif
306 c
307 c               recherche des dependances de ces 3 aretes
308 c               on cherche quel est l'alignement des noeuds
309 c
310 c               l'arete 1 va de N a P
311 c               l'arete 2 est entre N et Q
312 c               l'arete 3 est entre Q et P
313 c               l'arete i va de lenoeu(1,i) a lenoeu(2,i)
314 c
315                 lenoeu(1,1) = sonnnn
316                 lenoeu(2,1) = sopppp
317                 lenoeu(3,1) = soqqqq
318 c
319                 lenoeu(1,2) = min(sonnnn,soqqqq)
320                 lenoeu(2,2) = max(sonnnn,soqqqq)
321                 lenoeu(3,2) = sopppp
322 c
323                 lenoeu(1,3) = min(sopppp,soqqqq)
324                 lenoeu(2,3) = max(sopppp,soqqqq)
325                 lenoeu(3,3) = sonnnn
326 c
327                 do 2212 , iaux = 1, 3
328 cgn      print *,larete(iaux),lenoeu(1,iaux),lenoeu(2,iaux),lenoeu(3,iaux)
329                   do 2213 , jaux = 1, sdim
330                     vect(iaux,jaux) = coonoe(lenoeu(2,iaux),jaux)
331      >                              - coonoe(lenoeu(1,iaux),jaux)
332  2213             continue
333 cgn         print *,vect(iaux,1),vect(iaux,2),vect(iaux,3)
334  2212           continue
335 c
336 c       on verifie que les 3 points sont alignes :
337 c
338 c                A--------C---------------------B
339 c       attention : contrairement a ce que nous pensions au depart,
340 c                   on peut tres bien avoir des situations avec 3 aretes
341 c                   concourrantes sans qu'elles ne forment un triangle
342 c                   au sens de face HOMARD.
343 c                   Exemple :
344 c
345 c                            A
346 c                          . . .
347 c                         .  .  .
348 c                        .   .   .
349 c                       .    .    .
350 c                      .    .R.    .
351 c                     .   .     .   .
352 c                    .  .         .  .
353 c                   . .             . .
354 c                  B...................C
355 c
356 c                Si des tetraedres sont batis sur les faces ACR, CRB et
357 c               BRA, le triangle ABC n'existe pas
358 c
359                 if ( sdim.eq.2 ) then
360 c
361                   daux(1) =
362      >   ( vect(1,1) * vect(2,2) ) - ( vect(1,2) * vect(2,1) )
363 cgn                  print *,daux(1)
364                   if ( daux(1).gt.epsima ) then
365 #ifdef _DEBUG_HOMARD_
366                   write(ulsort,*) 'bizarrerie : daux(1) =',daux(1)
367                   write(ulsort,*) 'arete 1 =',sonnnn,' => ', sopppp
368                   write(ulsort,*) 'arete 2 =',sopppp,' => ', soqqqq
369                   write(ulsort,*) 'arete 3 =',soqqqq,' => ', sonnnn
370 #endif
371                     goto 22
372                   endif
373 c
374                 else
375 c
376                   daux(1) =
377      >   ( vect(1,2) * vect(2,3) ) - ( vect(1,3) * vect(2,2) )
378                   daux(2) =
379      >   ( vect(1,3) * vect(2,1) ) - ( vect(1,1) * vect(2,3) )
380                   daux(3) =
381      >   ( vect(1,1) * vect(2,2) ) - ( vect(1,2) * vect(2,1) )
382 c
383                   daux(1) = abs(daux(1)) + abs(daux(2)) + abs(daux(3))
384 cgn                  print *,daux(1)
385                   if ( daux(1).gt.epsima ) then
386 #ifdef _DEBUG_HOMARD_
387                   write(ulsort,*) 'bizarrerie : daux(1) =',daux(1)
388                   write(ulsort,6661) aret1,lenoeu(1,1), lenoeu(2,1)
389                   write(ulsort,6661) larete(2),lenoeu(1,2), lenoeu(2,2)
390                   write(ulsort,6661) larete(3),lenoeu(1,3), lenoeu(2,3)
391                   write(ulsort,6662) sonnnn,
392      >coonoe(sonnnn,1),coonoe(sonnnn,2),coonoe(sonnnn,3)
393                   write(ulsort,6662) sopppp,
394      >coonoe(sopppp,1),coonoe(sopppp,2),coonoe(sopppp,3)
395                   write(ulsort,6662) soqqqq,
396      >coonoe(soqqqq,1),coonoe(soqqqq,2),coonoe(soqqqq,3)
397                   write(ulsort,6663) sonnnn,soqqqq,
398      >coonoe(soqqqq,1)-coonoe(sonnnn,1),
399      >coonoe(soqqqq,2)-coonoe(sonnnn,2),
400      >coonoe(soqqqq,3)-coonoe(sonnnn,3)
401                   write(ulsort,6663) sopppp,soqqqq,
402      >coonoe(soqqqq,1)-coonoe(sopppp,1),
403      >coonoe(soqqqq,2)-coonoe(sopppp,2),
404      >coonoe(soqqqq,3)-coonoe(sopppp,3)
405                   write(ulsort,6664)
406      >(coonoe(soqqqq,1)-coonoe(sopppp,1))/
407      >(coonoe(soqqqq,1)-coonoe(sonnnn,1)),
408      >(coonoe(soqqqq,2)-coonoe(sopppp,2))/
409      >(coonoe(soqqqq,2)-coonoe(sonnnn,2)),
410      >(coonoe(soqqqq,3)-coonoe(sopppp,3))/
411      >(coonoe(soqqqq,3)-coonoe(sonnnn,3))
412  6661 format('arete',i10,' de',i10,' a',i10)
413  6662 format('noeud',i10,' :',3(g15.8,1x))
414  6663 format('de',i10,' a',i10,' :',3(g15.8,1x))
415  6664 format('rapport :',3(g15.8,1x))
416 #endif
417                     goto 22
418                   endif
419 c
420                 endif
421 c
422 c  Calcul du produit scalaire entre le 3�me noeud et les 2 extremites
423 c  de chaque arete iaux :
424 c                           arete iaux
425 c                A--------C---------------------B
426 c
427 c     CA*CB = CA * CB * cos(CA,CB) = - CA * CB < 0
428 c     AB*AC = AB * AC * cos(AB,AC) = + AB * AC > 0
429 c     BC*BA = BC * BA * cos(BC,BA) = + BC * BA > 0
430 c
431                 do 2214 , iaux = 1, 3
432 c
433                   daux(iaux) = 0.d0
434                   do 2215 , jaux = 1, sdim
435                     daux(iaux) = daux(iaux) +
436      >   ( coonoe(lenoeu(1,iaux),jaux) - coonoe(lenoeu(3,iaux),jaux) ) *
437      >   ( coonoe(lenoeu(2,iaux),jaux) - coonoe(lenoeu(3,iaux),jaux) )
438  2215             continue
439 cgn                  print *,'daux(',iaux,') =',daux(iaux)
440 c
441 c  On repere celui qui est negatif (il y en a forcement un !)
442 c  On connait alors l'arete qui recouvre les deux autres : c'est iaux
443 c  Les deux autres sont obtenues par pemutation circulaire de iaux
444 c  On declare que :
445 c     - les deux "petites" aretes ont la grande comme mere adoptive
446 c       cela servira dans la suite de la conversion
447 c     - la "grande" arete a une fille ; il suffit de mettre un numero
448 c       positif strictement car c'est utilise uniquement ici pour ne
449 c       pas faire plusieurs fois la meme chose (cf test au debut de
450 c       la boucle 221). On choisit de mettre 1.
451 c
452                   if ( daux(iaux).lt.epsima ) then
453                     jaux = per1a3(-1,iaux)
454                     kaux = per1a3( 1,iaux)
455 cgn      if ( aret1.eq.15931)then
456 cgn      print *,larete(iaux),larete(jaux),larete(kaux)
457 cgn      write (ulsort,texte(langue,6)) mess14(langue,1,1), 16334
458 cgn      write (ulsort,texte(langue,8)) ' ', 'de', somare(1,16334),
459 cgn     > 'a', somare(2,16334)
460 cgn      endif
461                     merare(larete(jaux)) = -larete(iaux)
462                     merare(larete(kaux)) = -larete(iaux)
463                     ngenar(larete(iaux)) = 1
464 cgn                    ngenar(larete(iaux)) =
465 cgn     >                       - max(larete(jaux),larete(kaux))
466                     nbanci = nbanci + 1
467                     goto 22
468                   endif
469 c
470  2214           continue
471 c
472 c probleme si on arrive ici ...
473 c
474                 codret = codret + 1
475 c
476               endif
477 c
478               endif
479 c
480   221       continue
481 c
482           endif
483 c
484    22   continue
485 c
486       endif
487 #ifdef _DEBUG_HOMARD_
488 cgn          if ( aret1.eq.15931)then
489       write (ulsort,texte(langue,4)) mess14(langue,3,1), nbanci
490 cgn            endif
491 #endif
492 c
493     2 continue
494 c
495 c====
496 c 3. Determination du nombre de generations au-dessus de chaque arete
497 c
498 c      x---------------------------0---------------------------x
499 c      x-------------1-------------x-------------1-------------x
500 c      x------2------x------2------x------2------x------2------x
501 c                                  x---3--x---3--x
502 c
503 c    On part d'une arete quelconque. On compte le nombre d'aretes
504 c    au-dessus d'elle dans l'ascendance.
505 c====
506 c
507       if ( codret.eq.0 ) then
508 c
509       do 31 , iaux = 1 , nbarto
510 c
511         jaux = iaux
512         kaux = 0
513   310   continue
514 cgn        write (ulsort,texte(langue,6)) mess14(langue,1,1), jaux
515         if ( merare(jaux).ne.0 ) then
516           jaux = -merare(jaux)
517           kaux = kaux + 1
518           goto 310
519         endif
520 c
521         ngenar(iaux) = kaux
522 c
523    31 continue
524 c
525       nbgemx = ngenar(1)
526       do 32 , iaux = 2 , nbarto
527         nbgemx = max(nbgemx,ngenar(iaux))
528    32 continue
529 c
530       endif
531 c
532 cgn       write (ulsort,*)'ngenar : ',ngenar
533 cgn       write (ulsort,*)'merare : ',merare
534 cgn       print *,'ngenar(190) : ',ngenar(190)
535 cgn       print *,'merare(190) : ',merare(190)
536 c
537 #ifdef _DEBUG_HOMARD_
538 c
539 c 3.3. ==> impression du nombre d'aretes par generation
540 c
541         kaux = 0
542 c
543   330 continue
544 c
545         if ( codret.eq.0 ) then
546 c
547         jaux = 0
548         do 33 , iaux = 1 , nbarto
549 c
550           if ( ngenar(iaux).eq.kaux ) then
551             jaux = jaux + 1
552           endif
553 c
554    33 continue
555 c
556         if ( jaux.ne.0 ) then
557           write (ulsort,texte(langue,10)) mess14(langue,3,1),
558      >                                    kaux, jaux
559           kaux = kaux + 1
560           goto 330
561         endif
562 c
563         endif
564 #endif
565 c
566 c====
567 c 4. la fin
568 c====
569 c
570 #ifdef _DEBUG_HOMARD_
571       write (ulsort,texte(langue,4)) mess14(langue,3,1), nbanci
572       write (ulsort,texte(langue,5)) mess14(langue,3,1), nbgemx
573 #endif
574 c
575       if ( codret.ne.0 ) then
576 c
577 #include "envex2.h"
578 c
579       write (ulsort,texte(langue,1)) 'Sortie', nompro
580       write (ulsort,texte(langue,2)) codret
581 c
582       endif
583 c
584 #ifdef _DEBUG_HOMARD_
585       write (ulsort,texte(langue,1)) 'Sortie', nompro
586       call dmflsh (iaux)
587 #endif
588 c
589       end