]> SALOME platform Git repositories - modules/homard.git/blobdiff - src/tool/Suivi_Frontiere/sfslin.F
Salome HOME
Homard executable
[modules/homard.git] / src / tool / Suivi_Frontiere / sfslin.F
diff --git a/src/tool/Suivi_Frontiere/sfslin.F b/src/tool/Suivi_Frontiere/sfslin.F
new file mode 100644 (file)
index 0000000..714d95e
--- /dev/null
@@ -0,0 +1,444 @@
+      subroutine sfslin ( lenoeu, noeud1, noeud2,
+     >                    numlig, unst2x, epsid2,
+     >                    geocoo, abscur,
+     >                    numnoe, lignoe, abscno,
+     >                    typlig, somseg, seglig,
+     >                    coop,
+     >                    ulsort, langue, codret)
+c ______________________________________________________________________
+c                             H O M A R D
+c
+c Outil de Maillage Adaptatif par Raffinement et Deraffinement d'EDF R&D
+c
+c Version originale enregistree le 18 juin 1996 sous le numero 96036
+c aupres des huissiers de justice Simart et Lavoir a Clamart
+c Version 11.2 enregistree le 13 fevrier 2015 sous le numero 2015/014
+c aupres des huissiers de justice
+c Lavoir, Silinski & Cherqui-Abrahmi a Clamart
+c
+c    HOMARD est une marque deposee d'Electricite de France
+c
+c Copyright EDF 1996
+c Copyright EDF 1998
+c Copyright EDF 2002
+c Copyright EDF 2020
+c ______________________________________________________________________
+c
+c   Suivi de Frontiere - Suivi des LIgnes - placement d'un Noeud
+c   -        -           -         --                      -
+c ______________________________________________________________________
+c .        .     .        .                                            .
+c .  nom   . e/s . taille .           description                      .
+c .____________________________________________________________________.
+c . lenoeu . e   .   1    . noeud a bouger                             .
+c . noeud1 . e   .   1    . noeud voisin 1 de lenoeu sur l'arete       .
+c . noeud2 . e   .   1    . noeud voisin 2 de lenoeu sur l'arete       .
+c . numlig . e   .   1    . numero de la ligne de la frontiere         .
+c . unst2x . e   .   1    . inverse de la taille maximale au carre     .
+c . epsid2 . e   .   1    . precision relative pour carre de distance  .
+c . geocoo . e   .sfnbso**. coordonnees des sommets de la frontiere    .
+c . abscur . e   . sfnbse . abscisse curviligne des somm des segments  .
+c . numnoe . e   . mcnvnf . liste des noeuds de calcul sur le bord     .
+c . lignoe . e   . mcnvnf . liste lignes pour ces noeuds               .
+c . abscno . e   . mcnvnf . abscisse curviligne de ces noeuds          .
+c . typlig . e   . sfnbli . type de la ligne                           .
+c .        .     .        . 0 : ligne ouverte, a 2 extremites          .
+c .        .     .        . 1 : ligne fermee                           .
+c . somseg . e   . sfnbse . liste des sommets des lignes separees par  .
+c                           des 0                                      .
+c . seglig . e   .0:sfnbli. pointeur dans le tableau somseg : les      .
+c .        .     .        . segments de la ligne i sont aux places de  .
+c .        .     .        . seglig(i-1)+1 a seglig(i)-1 inclus         .
+c . coop   . es  .  sdim  . nouvelles coordonnees de lenoeu            .
+c . ulsort . e   .   1    . numero d'unite logique de la liste standard.
+c . langue . e   .    1   . langue des messages                        .
+c .        .     .        . 1 : francais, 2 : anglais                  .
+c . codret . es  .    1   . code de retour des modules                 .
+c .        .     .        . 0 : pas de probleme                        .
+c .        .     .        . 1 : impossible de retrouver les noeuds     .
+c .        .     .        .     voisins                                .
+c .        .     .        . 2 : impossible de trouver le segment       .
+c .        .     .        .     contenant le noeud                     .
+c ______________________________________________________________________
+c
+c====
+c 0. declarations et dimensionnement
+c====
+c
+c 0.1. ==> generalites
+c
+      implicit none
+      save
+c
+      character*6 nompro
+      parameter ( nompro = 'SFSLIN' )
+c
+#include "nblang.h"
+c
+c 0.2. ==> communs
+c
+#include "envex1.h"
+#include "envca1.h"
+c
+#include "front1.h"
+#include "front2.h"
+#include "impr02.h"
+c
+c 0.3. ==> arguments
+c
+      integer lenoeu, noeud1, noeud2
+      integer numlig
+      integer numnoe(mcnvnf), lignoe(mcnvnf)
+      integer typlig(sfnbli), somseg(sfnbse), seglig(0:sfnbli)
+c
+      double precision unst2x, epsid2
+      double precision geocoo(sfnbso,sdim)
+      double precision abscur(sfnbse)
+      double precision abscno(mcnvnf)
+      double precision coop(sdim)
+c
+      integer ulsort, langue, codret
+c
+c 0.4. ==> variables locales
+c
+      integer iaux, jaux, kaux
+      integer seg, seg1, seg2
+      integer nupass, nbpass
+c
+      double precision abscnn(2), abscn1, abscn2, abscnm
+      double precision daux, lgdeb, lgfin
+      double precision cooa(3)
+      double precision cooini(3), coopst(3), dist
+c
+      integer nbmess
+      parameter ( nbmess = 10 )
+      character*80 texte(nblang,nbmess)
+c
+c 0.5. ==> initialisations
+c ______________________________________________________________________
+c
+c====
+c 1. initialisations
+c====
+c
+cgn      ulsort = lenoeu
+#include "impr01.h"
+c
+#ifdef _DEBUG_HOMARD_
+      write (ulsort,texte(langue,1)) 'Entree', nompro
+      call dmflsh (iaux)
+#endif
+c
+      texte(1,4) = '(''.. '',a,i10,'' a deplacer'')'
+      texte(1,5) = '(''... Coordonnees :'',3g17.9)'
+      texte(1,6) = '(''.. Il est entre les '',a,i10,'' et'',i10)'
+      texte(1,7) =
+     > '(''.... Abscisse curviligne du noeud'',i10,'' :'',g17.9)'
+      texte(1,8) = '(''.... Abscisse curviligne '',a,'' :'',g17.9)'
+      texte(1,9) =
+     >'(''.. Impossible de trouver le '',a,i10,'' sur la frontiere.'')'
+      texte(1,10) = '(''.. Impossible de trouver le segment associe.'')'
+c
+      texte(2,4) = '(''... '',a,'' # '',i10,'' to move'')'
+      texte(2,5) = '(''... Coordinates :'',3g17.9)'
+      texte(2,6) =
+     > '(''... It is between '',a,'' # '',i10,'' and #'',i10)'
+      texte(2,7) =
+     > '(''.... Current absciss of the node'',i10,'' :'',g17.9)'
+      texte(2,8) = '(''.... Current absciss '',a,'' :'',g17.9)'
+      texte(2,9) =
+     > '(''.. The '',a,i10,'' cannot be found on boundary.'')'
+      texte(2,10) = '(''.. The edge of boundary cannot be found.'')'
+c
+#include "impr03.h"
+c
+#ifdef _DEBUG_HOMARD_
+      write (ulsort,texte(langue,4)) mess14(langue,2,-1), lenoeu
+      write (ulsort,texte(langue,5)) (coop(iaux),iaux=1,sdim)
+      write (ulsort,texte(langue,6)) mess14(langue,3,-1),
+     >                               noeud1, noeud2
+#endif
+c
+      codret = 0
+c
+c====
+c 2. Recherche des abscisses curvilignes associes aux noeuds voisins
+c====
+#ifdef _DEBUG_HOMARD_
+      write (ulsort,90002) '2. Recherche abscisse ; codret', codret
+#endif
+c
+      do 21 , iaux = 1 , 2
+c
+        if ( codret.eq.0 ) then
+c
+        if ( iaux.eq.1 ) then
+          kaux = noeud1
+        else
+          kaux = noeud2
+        endif
+#ifdef _DEBUG_HOMARD_
+      write (ulsort,90002) '.... '//mess14(langue,2,-1), kaux
+#endif
+c
+        do 211 , jaux = 1 , mcnvnf
+c
+          if ( numnoe(jaux).eq.kaux ) then
+            if ( lignoe(jaux).eq.numlig ) then
+              daux = abs(abscno(jaux))
+#ifdef _DEBUG_HOMARD_
+      write (ulsort,texte(langue,7)) jaux, daux
+#endif
+              goto 212
+            endif
+          endif
+c
+  211   continue
+c
+        codret = 1
+c
+        endif
+c
+  212  continue
+c
+        if ( codret.eq.0 ) then
+c
+        abscnn(iaux) = daux
+c
+        endif
+c
+   21 continue
+c
+c====
+c 3. Positionnement du noeud a bouger
+c====
+#ifdef _DEBUG_HOMARD_
+      write (ulsort,90002) '3. Positionnement ; codret', codret
+#endif
+c
+c 3.1. ==> Caracteristique de la ligne
+c
+      if ( codret.eq.0 ) then
+c
+      if ( typlig(numlig).eq.0 ) then
+        nbpass = 1
+      else
+        nbpass = 2
+      endif
+c
+      seg1 = seglig(numlig-1)+1
+      seg2 = seglig(numlig  )-2
+#ifdef _DEBUG_HOMARD_
+      write (ulsort,90006) 'Pointeurs ligne', numlig,
+     >              ' de', seg1,' a ', seg2
+      write (ulsort,90012) '==> Sommets extremites de la ligne',
+     >                     numlig, somseg(seg1), somseg(seg2+1)
+      write (ulsort,90004) 'abscisse debut', abscur(seg1)
+      write (ulsort,90004) 'abscisse fin  ', abscur(seg2+1)
+      write (ulsort,90002) 'nbpass', nbpass
+#endif
+c
+      if ( nbpass.gt.0 ) then
+c
+        do 31 , iaux = 1 , sdim
+          cooini(iaux) = coop(iaux)
+   31   continue
+c
+      endif
+c
+      endif
+c
+      abscn1 = abscnn(1)
+      abscn2 = abscnn(2)
+c
+      do 30 , nupass = 1 , nbpass
+cgn        write (ulsort,*) ' '
+cgn        write (ulsort,90002) 'Passage numero', nupass
+c
+c 3.2. ==> La nouvelle abscisse curviligne
+c          . Au premier passage, on calcule entre les deux noeuds
+c          . A l'eventuel second, c'est que l'on a une extremite ; on
+c          doit tester le chemin reciproque pour les cas ou la ligne
+c          serait fermee.
+c
+        if ( codret.eq.0 ) then
+c
+c
+        if ( nupass.eq.1 ) then
+c
+          abscnm = 0.5d0 * (abscn1+abscn2)
+c
+        else
+c
+          if ( abscn2.gt.abscn1 ) then
+            lgfin = abscur(seg2+1) - abscn2
+            lgdeb = abscn1 - abscur(seg1)
+cgn      write (ulsort,90004) 'de n2 a la fin', lgfin
+cgn      write (ulsort,90004) 'du debut a n1 ', lgdeb
+          else
+            lgfin = abscur(seg2+1) - abscn1
+            lgdeb = abscn2 - abscur(seg1)
+cgn      write (ulsort,90004) 'de n1 a la fin', lgfin
+cgn      write (ulsort,90004) 'du debut a n2 ', lgdeb
+            daux = (abscn2-abscur(seg1)) - (abscur(seg2+1)-abscn1)
+          endif
+          if ( lgfin.gt.lgdeb ) then
+            abscnm = abscur(seg2+1) - 0.5d0*(lgfin-lgdeb)
+          else
+            abscnm = abscur(seg1) + 0.5d0*(lgdeb-lgfin)
+          endif
+c
+          do 32 , iaux = 1 , sdim
+            coopst(iaux) = coop(iaux)
+   32     continue
+c
+        endif
+c
+#ifdef _DEBUG_HOMARD_
+        write (ulsort,90002) mess14(langue,2,-1), lenoeu
+        write (ulsort,texte(langue,8)) 'noeud', abscnm
+#endif
+c
+        endif
+c
+c 3.3. ==> Recherche du segment
+c          Remarque : le noeud a bouger ne peut pas etre une des
+c                     extremites de la ligne car il est situe entre
+c                     noeud1 et noeud2, eux-memes sur cette ligne
+c
+      if ( codret.eq.0 ) then
+c
+      seg = 0
+c
+      do 33 , kaux = seg1 , seg2
+c
+        if ( abscnm.ge.abscur(kaux) .and.
+     >       abscnm.le.abscur(kaux+1) ) then
+c
+          seg = kaux
+#ifdef _DEBUG_HOMARD_
+          write (ulsort,90006) '.... Appartiendra au segment', seg
+          write (ulsort,texte(langue,8)) 'debut', abscur(seg)
+          write (ulsort,texte(langue,8)) 'fin  ', abscur(seg+1)
+#endif
+c
+c 3.3.2. ==> Le noeud est-il le premier point du segment ?
+c
+          daux = 0.d0
+          do 332 , iaux = 1 , sdim
+            cooa(iaux) = geocoo(somseg(kaux),iaux)
+            daux = daux + (cooa(iaux)-coop(iaux))**2
+  332     continue
+c
+c 3.3.3. ==> Si non, on doit bouger le noeud
+c            Si oui, c'est parfait : le noeud est deja sur la frontiere
+c
+          if ( daux*unst2x.gt.epsid2 ) then
+c
+c         A                          M            B
+c         x--------------------------o------------x
+c
+c         On procede par proportionnalite :
+c          AM = AB *(d(A,M)/d(A,B))
+c
+            daux = ( abscnm - abscur(kaux) ) /
+     >             ( abscur(kaux+1) - abscur(kaux) )
+c
+            do 333 , iaux = 1 , sdim
+              coop(iaux) = cooa(iaux) +
+     >                 daux * ( geocoo(somseg(kaux+1),iaux)-cooa(iaux))
+  333       continue
+#ifdef _DEBUG_HOMARD_
+      write (ulsort,texte(langue,5)) (coop(iaux),iaux=1,sdim)
+#endif
+c
+#ifdef _DEBUG_HOMARD_
+          else
+      write (ulsort,90006) '.. Le noeud est extremite du segment', kaux
+#endif
+c
+          endif
+c
+          goto 30
+c
+        endif
+c
+   33 continue
+c
+      if ( seg.eq.0 ) then
+        codret = 2
+      endif
+c
+      endif
+c
+   30 continue
+c
+c 3.4. ==> Si l'arete est sur une ligne fermee, on compare les deux
+c          solutions. L'idee est que la bonne est celle ou on va
+c          le moins loin !
+c
+      if ( codret.eq.0 ) then
+c
+      if ( nbpass.gt.0 ) then
+c
+#ifdef _DEBUG_HOMARD_
+        write (ulsort,*) ' '
+        write (ulsort,90004) 'cooini', (cooini(iaux),iaux=1,sdim)
+        write (ulsort,90004) 'coopst', (coopst(iaux),iaux=1,sdim)
+        write (ulsort,90004) 'coop  ', (coop(iaux),iaux=1,sdim)
+#endif
+c
+        dist = 0.d0
+        daux = 0.d0
+        do 341 , iaux = 1 , sdim
+          dist = dist + (cooini(iaux) - coopst(iaux))**2
+          daux = daux + (cooini(iaux) - coop(iaux))**2
+  341   continue
+#ifdef _DEBUG_HOMARD_
+        write (ulsort,90004) 'dist', dist
+        write (ulsort,90004) 'daux', daux
+#endif
+c
+        if ( dist.lt.daux ) then
+          do 342 , iaux = 1 , sdim
+            coop(iaux) = coopst(iaux)
+  342     continue
+#ifdef _DEBUG_HOMARD_
+        write (ulsort,*) 'On reprend la premiere projection :'
+        write (ulsort,90004) 'coop  ', (coop(iaux),iaux=1,sdim)
+#endif
+        endif
+c
+      endif
+c
+      endif
+c
+c====
+c 4. la fin
+c====
+c
+      if ( codret.ne.0 ) then
+c
+#include "envex2.h"
+c
+      write (ulsort,texte(langue,1)) 'Sortie', nompro
+      write (ulsort,texte(langue,2)) codret
+      write (ulsort,texte(langue,4)) mess14(langue,2,-1), lenoeu
+      write (ulsort,texte(langue,6)) mess14(langue,3,-1),
+     >                               noeud1, noeud2
+      if ( codret.eq.1 ) then
+        write (ulsort,texte(langue,9)) mess14(langue,1,-1), kaux
+      elseif ( codret.eq.2 ) then
+        write (ulsort,texte(langue,10))
+      endif
+c
+      endif
+c
+#ifdef _DEBUG_HOMARD_
+      write (ulsort,texte(langue,1)) 'Sortie', nompro
+      call dmflsh (iaux)
+#endif
+c
+cgn      ulsort=1
+c
+      end