frene0
C FRENE0 SOURCE CB215821 25/06/20 21:15:05 12290
C ====================================================================
C Sous-programme FRENE0 : calcul du repère de Frenet d'une ligne
C
C --------------------------
C Paramètres Entrée/Sortie :
C --------------------------
C
C E/ arc : Ligne le long de laquelle on veut calculer le repère
C
C /S repere : CHPOINT contenant les vecteurs du repère
C ====================================================================
IMPLICIT INTEGER(I-N)
IMPLICIT REAL*8(A-H,O-Z)
C --------------------------------------------------------------------
C Declarations
C --------------------------------------------------------------------
-INC PPARAM
-INC CCOPTIO
-INC SMCOORD
-INC SMELEME
-INC SMCHPOI
-INC CCREEL
character*4 les_composantes(9)
data les_composantes/'TX', 'TY', 'TZ', 'NX', 'NY', 'NZ',
$ 'BX', 'BY', 'BZ'/
integer element, premier, dernier, composante_connexe, ecart
real*8 oa(3), ob(3), oc(3),
$ norme_ab, norme_bc, norme_bin
logical est_seg2, est_seg3, est_ouvert, est_transition,
$ sont_colineaires
segment nombre_occurences(nbpts)
segment numero_du_poi1(nbpts)
segment le_premier_element(0)
segment le_dernier_element(0)
pointeur repere.mchpoi
C --------------------------------------------------------------------
C Initialisations et preparation du travail
C --------------------------------------------------------------------
poi1_de_arc = arc
if(ierr.ne.0) return
if(.not.(est_seg2.or.est_seg3)) then
endif
arc_seg2 = arc
if(est_seg3) then
if(ierr.ne.0) return
endif
C On verifie l'orientation des elements avec versen
C Pour ca on est oblige de faire des ecrobj/lirobj
C => Peut-etre faudrait-il creer un deuxieme niveau dans versen
C pour pouvoir l'appeler directement ?
call versen
if(ierr.ne.0) return
C On verifie que le contour est simple
C (un noeud appartient a au plus deux elements)
C On fait comme dans ligmai.eso
segini nombre_occurences
maxel = 0
nombre_de_seg2 = arc_seg2.num(/2)
do element=1,nombre_de_seg2
do noeud_du_seg=1,2
enddo
enddo
segsup nombre_occurences
C Initialisation du segment mpoval
nombre_noeuds = poi1_de_arc.num(/2)
n = nombre_noeuds
nombre_composantes = idim**2
nc = nombre_composantes
segini mpoval
C Initialisation et remplissage de numero_du_poi1 (numerotation globale/locale)
segini numero_du_poi1
do i=1,nombre_noeuds
numero_du_poi1(poi1_de_arc.num(1, i)) = i
enddo
segdes poi1_de_arc
C On compte le nombre de composantes connexes et on stocke
C les premier et dernier elements de chacune
segini le_premier_element, le_dernier_element
le_premier_element(**) = 1
do element=1,(nombre_de_seg2 - 1)
noeud_1 = arc_seg2.num(2, element)
noeud_2 = arc_seg2.num(1, element + 1)
est_transition = noeud_1.ne.noeud_2
if(est_transition) then
le_dernier_element(**) = element
le_premier_element(**) = element + 1
endif
enddo
le_dernier_element(**) = arc_seg2.num(/2)
nombre_composantes_connexes = le_premier_element(/1)
C --------------------------------------------------------------------
C On fait le travail
C --------------------------------------------------------------------
C Comme un noeud a ses coordonnees + sa densite il faut prendre
C dim + 1 pour obtenir ses coordonnees a partir de xcoor
idim1 = idim + 1
tangent = 0.D0
binormal = (/ 0.D0, 0.D0, 1.D0 /)
ab = 0.D0
bc = 0.D0
SEGACT,MCOORD
do composante_connexe=1,nombre_composantes_connexes
C Travail sur tous les noeuds interieurs
C **************************************
premier = le_premier_element(composante_connexe)
dernier = le_dernier_element(composante_connexe)
nombre_iterations = dernier - premier + 1
noeud_debut = arc_seg2.num(1, premier)
noeud_fin = arc_seg2.num(2, dernier)
est_ouvert = noeud_debut.ne.noeud_fin
if(est_ouvert) nombre_iterations = nombre_iterations - 1
do element=premier,(premier + nombre_iterations - 1)
C Pour chaque 2eme noeud d'element on calcule d'abord le
C vecteur binormal, puis on estime le vecteur tangent,
C puis on calcule le vecteur normal par produit vectoriel,
C et enfin on recalcule le vecteur tangent par produit
C vectoriel pour etre sur que les 3 vecteurs sont orthogonaux
ia = arc_seg2.num(1, element)
ib = arc_seg2.num(2, element)
if(.not.est_ouvert.and.element.eq.dernier) then
ic = arc_seg2.num(2, premier)
else
ic = arc_seg2.num(2, element + 1)
endif
do i=1,idim
oa(i) = xcoor((ia-1)*idim1 + i)
ob(i) = xcoor((ib-1)*idim1 + i)
oc(i) = xcoor((ic-1)*idim1 + i)
enddo
if(idim.eq.3) then
do i=1,3
ab(i) = ob(i) - oa(i)
bc(i) = oc(i) - ob(i)
enddo
norme_bin = norme_bin + xpetit
sont_colineaires = norme_bin
$ .le.(norme_ab*norme_bc*xzprec)
if(sont_colineaires) then
C On tente de prendre le vecteur binormal en A
do i=1,3
binormal(i) = vpocha(numero_du_poi1(ia), 6 + i)
enddo
norme_bin = norme_bin + xpetit
if(.not.a_egale_b(norme_bin, 1.D0)) then
C Il n'y a pas de vecteur unitaire en A donc on appelle perpen
endif
else
endif
endif
do i=1,idim
tangent(i) = oc(i) - oa(i)
enddo
do i=1,idim
enddo
enddo
C Travail sur les extermites (si le contour est ouvert)
C ****************************************************
if(est_ouvert) then
C On fait une boucle pour traiter les deux extremites :
C - on calcule le vecteur tangent
C - on calcule la binormale si on est en 3D (par orthonormalisation
C de la valeur voisine ou en appelant perpen si contour = 1 element)
C - on calcule la normale par le produit vectoriel des deux vecteurs precedents
C (attention a la boucle, si contour = 1 element alors dernier - premier = 0 !)
ecart = max(1, dernier - premier)
do element=premier,dernier,ecart
ia = arc_seg2.num(1, element)
ib = arc_seg2.num(2, element)
if(element.eq.premier) then
noeud_calcul = ia
noeud_voisin = ib
else
noeud_calcul = ib
noeud_voisin = ia
endif
do i=1,idim
oa(i) = xcoor((ia-1)*idim1 + i)
ob(i) = xcoor((ib-1)*idim1 + i)
tangent(i) = ob(i) - oa(i)
enddo
if(idim.eq.3) then
if(premier.ne.dernier) then
do i=1,3
enddo
do i=1,3
binormal(i) = binormal(i) - t_scal_b * tangent(i)
enddo
else
endif
endif
do i=1,idim
enddo
enddo
C Si un seul element, on met les memes valeurs au deuxieme noeud
if(premier.eq.dernier) then
do i=1,idim
enddo
endif
endif
enddo
SEGDES,MCOORD
segsup numero_du_poi1
C segsup arc_seg2
segsup le_premier_element, le_dernier_element
C On finalise les segments du CHPOINT
nsoupo = 1
nat = 1
segini repere
repere.jattri(1) = 1
repere.ifopoi = ifour
repere.mtypoi = ' '
repere.mochde = 'REPERE DE FRENET'
segini msoupo
repere.ipchp(1) = msoupo
igeoc = poi1_de_arc
do j=1,idim
do i=1,idim
nocomp(idim*(j-1) + i) = les_composantes(3*(j-1) + i)
noharm(idim*(j-1) + i) = nifour
enddo
enddo
ipoval = mpoval
segdes repere, msoupo, mpoval
END
					© Cast3M 2003 - Tous droits réservés.
					Mentions légales