diff options
Diffstat (limited to 'Dragon/src/g2s_segArc.f90')
| -rw-r--r-- | Dragon/src/g2s_segArc.f90 | 2310 |
1 files changed, 2310 insertions, 0 deletions
diff --git a/Dragon/src/g2s_segArc.f90 b/Dragon/src/g2s_segArc.f90 new file mode 100644 index 0000000..f323f6a --- /dev/null +++ b/Dragon/src/g2s_segArc.f90 @@ -0,0 +1,2310 @@ +! +!----------------------------------------------------------------------- +! +!Purpose: +! Collect processing functions related to geometric elements. +! +!Copyright: +! Copyright (C) 2001 Ecole Polytechnique de Montreal. +! This library is free software; you can redistribute it and/or +! modify it under the terms of the GNU Lesser General Public +! License as published by the Free Software Foundation; either +! version 2.1 of the License, or (at your option) any later version. +! +!Author(s): +! G. Civario (CS-SI) +! +!Comments: +! Une structure "t_segArc" est definie, avec tous les champs necessaires aux +! calculs. On stocke par ailleurs ces elements dans un tableau global de +! pointeurs "tabSegArc". +! \\\\ +! variable globale: +! - tabSegArc : le tableau de travail principal +! \\\\ +! fonctions du module: +! - initializeTabSegArc : mise a zero des tableaux +! - destroyTabSegArc : liberation de la memoire +! - createSeg : constructeur de segment +! - createArc : constructeur de cercle ou d'arc de cercle +! - giveOrigine : retourne les coordonnees de l'origine d'un segArc +! - giveExtremite : retourne les coordonnees de l'extremite d'un segArc +! - extremitesArc : determination des points extremites d'un arc +! - estColieaire : test de la colinearite de 2 segments +! - isAngleInArc : teste l'appartenance d'un angle au domaine d'un arc +! - isIn : teste l'appartenance d'un point, sur le support d'un segment ou +! d'un arc, au segment ou a l'arc +! - isSameWay : teste si deux segments alignes ont meme orientation +! - turnBackSide : retourne le segment donne en entree +! - adjustMix : ajuste les milieux a droite et a gauche d'un segment, par +! rapport a ceux d'un segment de reference le contenant +! - interSgAr : calcule les points d'intersection entre un segment et un arc +! - interSgSg : calcule les points d'intersection entre deux segments +! - interSgSg_V2 : recherche les points d'itersection entre deux segments +! (extremites inclues) +! - interArcArc : calcule les points d'intersection entre deux arcs +! - translateAndTurnTriSg : effectue une translation-rotation d'un cote +! de triangle (fonction tres specifique) +! - giveExtremalsAngles : donne les angles d'incidence des extrmites d'un +! element, par rapport a un point +! - drawSegArc : affiche le tableau des elements dans un fichier postscript +! - coupeCercle : intersecte les couronnes et les clusters +! - splitSegsForSect : coupe l'encadrement d'une cellule rectangulaire en cas +! de sectorisation +! - majSectori : met a jour la donnee sur le secteur des elements +! - addSegsAndClean : ajout de nouveaux segments lors de la mise cote a cote +! des differentes cellules, et elimination des doublons +! - cutClusters : prise en compte des intersections couronnes/cluster, et +! elimination de elements internes aux clusters +! - segWithSameCoord : true if the transmitted segments have the same coordinates +! +!----------------------------------------------------------------------- +! +module segArc + use constUtiles + use constType + use derivedPSPLOT + + implicit none + + interface printSegArc + module procedure printSegArc1, printSegArc2 + end interface printSegArc + + type t_segArc + integer :: typ !1=segment, 2=arc de cercle + double precision :: x,y !origine si 1 , centre si 2 + double precision :: dx,dy !extremite si 1 + double precision :: r !rayon si 2 + double precision :: a,b !angle debut et fin si 2 (entre -pi et pi) + integer :: mixg =0!numero de couronne a gauche ou interieur + integer :: mixd =0!numero de couronne a droite ou exterieur + integer :: nodeg =0!node a gauche ou interieur + integer :: noded =0!node a droite ou exterieur + integer :: indCellPg=0 !cellulePlaced d'origine a gauche + integer :: indCellPd=0 !cellulePlaced d'origine a droite + integer :: sectg=0 !numero du secteur a gauche dans la cellule + integer :: sectd=0 !numero du secteur a droite dans la cellule + integer :: neutronicMixg=0 !milieux neutronique a gauche + integer :: neutronicMixd=0 !milieux neutronique a droite + logical :: clusg=.false. ! circle belong to a cluster + logical :: clusd=.false. ! circle belong to a cluster + end type t_segArc + + integer,parameter :: tseg=1 , tcer=2 , tarc=3 , fooMix=-99 , fooNode=-999 , & + & tRec=1 , tHex=2 , tTri=3 + + !type of geometry + integer :: typgeo + + !variable globale de type tableau d'elements geometriques + type(t_segArc), dimension(:), pointer :: tabSegArc + + ! storage of cutting straights and segments + type(t_segArc), dimension(:), allocatable :: tabStrCut,tabSegCut + + type segArcArrayBis + type(t_segArc) :: sa + logical :: keep + end type segArcArrayBis + + type segArcArrayTer + type(t_segArc) :: sa + logical :: keep + logical :: cl !condition limite ou cluster selon les cas + end type segArcArrayTer + + ! Programmation defensive + integer :: alloc_ok + +contains + + function createSeg(ox,oy,ex,ey,mg,md) + double precision,intent(in) :: ox,oy,ex,ey + integer,intent(in) :: mg,md + type(t_segArc) :: createSeg + + createSeg%typ = tseg + createSeg%x = ox ; createSeg%y = oy + createSeg%dx = ex ; createSeg%dy = ey + createSeg%r = 0.d0 + createSeg%a = 0.d0 ; createSeg%b = 0.d0 + createSeg%mixg = mg ; createSeg%mixd = md + createSeg%nodeg = fooNode ; createSeg%noded = fooNode + createSeg%indCellPg = 0 ; createSeg%indCellPd = 0 + createSeg%sectg = 0 ; createSeg%sectd = 0 + createSeg%neutronicMixg = 0 ; createSeg%neutronicMixd = 0 + createSeg%clusg = .false. ; createSeg%clusd = .false. + end function createSeg + + function copySegExceptOrigin(ox,oy,Seg) + double precision,intent(in) :: ox,oy + type(t_segArc),intent(in) :: Seg + type(t_segArc) :: copySegExceptOrigin + if (Seg%typ /= tseg) call XABORT("copySegExceptOrigin : inconsistency") + copySegExceptOrigin = Seg + copySegExceptOrigin%x = ox ; copySegExceptOrigin%y = oy + end function copySegExceptOrigin + + function copySegExceptEnd(ex,ey,Seg) + double precision,intent(in) :: ex,ey + type(t_segArc),intent(in) :: Seg + type(t_segArc) :: copySegExceptEnd + if (Seg%typ /= tseg) call XABORT("copySegExceptEnd : inconsistency") + copySegExceptEnd = Seg + copySegExceptEnd%dx = ex ; copySegExceptEnd%dy = ey + end function copySegExceptEnd + + function copySegWithNewExtrems(ox,oy,ex,ey,seg) + double precision, intent(in) :: ox, oy, ex, ey + type(t_segArc),intent(in) :: Seg + type(t_segArc) :: copySegWithNewExtrems + if (Seg%typ /= tseg) call XABORT("copySegWithNewExtrems: inconsistency") + copySegWithNewExtrems = Seg + copySegWithNewExtrems%x = ox ; copySegWithNewExtrems%y = oy + copySegWithNewExtrems%dx = ex ; copySegWithNewExtrems%dy = ey + end function copySegWithNewExtrems + + function copyUTurnSeg(seg) + type(t_segArc), intent(in) :: seg + type(t_segArc) :: copyUTurnSeg + if (Seg%typ /= tseg) call XABORT("copyUTurnSeg : inconsistency") + copyUTurnSeg%typ = tseg + copyUTurnSeg%x = seg%dx ; copyUTurnSeg%y = seg%dy + copyUTurnSeg%dx = seg%x ; copyUTurnSeg%dy = seg%y + copyUTurnSeg%r = seg%r ; copyUTurnSeg%a = seg%a ; copyUTurnSeg%b = seg%b + copyUTurnSeg%mixg = seg%mixd ; copyUTurnSeg%mixd = seg%mixg + copyUTurnSeg%nodeg = seg%noded ; copyUTurnSeg%noded = seg%nodeg + copyUTurnSeg%indCellPg = seg%indCellPd ; copyUTurnSeg%indCellPd = seg%indCellPg + copyUTurnSeg%sectg = seg%sectd ; copyUTurnSeg%sectd = seg%sectg + copyUTurnSeg%neutronicMixg = seg%neutronicMixd + copyUTurnSeg%neutronicMixd = seg%neutronicMixg + end function copyUTurnSeg + + function createArc(cx,cy,r,a,b,mi,me) + double precision,intent(in) :: cx,cy,r,a,b + integer,intent(in) :: mi,me + type(t_segArc) :: createArc + + createArc%a = a ; createArc%b = b + if (isEqual(createArc%a,createArc%b)) then ; createArc%typ = tcer + else ; createArc%typ = tarc + end if + createArc%x = cx ; createArc%y = cy + createArc%dx = 0.d0 ; createArc%dy = 0.d0 + createArc%r = r + createArc%mixg = mi ; createArc%mixd = me + createArc%nodeg = fooNode ; createArc%noded = fooNode + createArc%indCellPg = 0 ; createArc%indCellPd = 0 + createArc%sectg = 0 ; createArc%sectd = 0 + createArc%neutronicMixg = 0 ; createArc%neutronicMixd = 0 + end function createArc + + function copyArcExceptOrigin(o,Arc) + double precision,intent(in) :: o + type(t_segArc),intent(in) :: Arc + type(t_segArc) :: copyArcExceptOrigin + if (Arc%typ /= tarc) call XABORT("copyArcExceptOrigin : inconsistency") + copyArcExceptOrigin = Arc + copyArcExceptOrigin%a = o + end function copyArcExceptOrigin + + function copyArcExceptEnd(e,Arc) + double precision,intent(in) :: e + type(t_segArc),intent(in) :: Arc + type(t_segArc) :: copyArcExceptEnd + if (Arc%typ /= tarc) call XABORT("copyArcExceptEnd : inconsistency") + copyArcExceptEnd = Arc + copyArcExceptEnd%b = e + end function copyArcExceptEnd + + function copyArcWithNewAngles(o,e,Arc) + double precision,intent(in) :: o, e + type(t_segArc),intent(in) :: Arc + type(t_segArc) :: copyArcWithNewAngles + if (Arc%typ /= tarc) call XABORT("copyArcWithNewAngles : inconsistency") + copyArcWithNewAngles = Arc + copyArcWithNewAngles%a = o + copyArcWithNewAngles%b = e + end function copyArcWithNewAngles + + function createArcFromCircle(o,e,Circ) + double precision,intent(in) :: o, e + type(t_segArc),intent(in) :: Circ + type(t_segArc) :: createArcFromCircle + if (Circ%typ /= tcer) call XABORT("createArcFromCircle : inconsistency") + createArcFromCircle = Circ + createArcFromCircle%typ = tarc + createArcFromCircle%a = o + createArcFromCircle%b = e + end function createArcFromCircle + + subroutine giveOrigine(sa,xx,yy) + type(t_segArc),intent(in) :: sa + double precision,intent(out) :: xx,yy + select case(sa%typ) + case(tseg) ; xx = sa%x ; yy = sa%y + case(tarc) ; xx = sa%x+sa%r*cos(sa%a) ; yy=sa%y+sa%r*sin(sa%a) + case(tcer) ; xx = sa%x+sa%r ; yy = sa%y + end select + end subroutine giveOrigine + + subroutine giveExtremite(sa,xx,yy) + type(t_segArc),intent(in) :: sa + double precision,intent(out) :: xx,yy + select case(sa%typ) + case(tseg) ; xx = sa%dx ; yy = sa%dy + case(tarc) ; xx = sa%x+sa%r*cos(sa%b) ; yy=sa%y+sa%r*sin(sa%b) + case(tcer) ; xx = sa%x+sa%r ; yy = sa%y + end select + end subroutine giveExtremite + + subroutine giveFourPointsOnCircle(sa,P1,P2,P3,P4) + type(t_segArc), intent(in) :: sa + type(t_point), intent(out) :: P1,P2,P3,P4 + if (sa%typ/=tcer) call XABORT("giveFourPointsOnCircle : bad use") + P1 = t_point(sa%x+sa%r,sa%y) + P2 = t_point(sa%x-sa%r,sa%y) + P3 = t_point(sa%x,sa%y+sa%r) + P4 = t_point(sa%x,sa%y-sa%r) + + end subroutine giveFourPointsOnCircle + + subroutine extremitesArc(ar,pt1x,pt1y,pt2x,pt2y) + type(t_segArc),intent(in) :: ar + double precision,intent(out) :: pt1x,pt1y,pt2x,pt2y + + pt1x=ar%x+ar%r*cos(ar%a) ; pt1y=ar%y+ar%r*sin(ar%a) + pt2x=ar%x+ar%r*cos(ar%b) ; pt2y=ar%y+ar%r*sin(ar%b) + end subroutine extremitesArc + + subroutine MediumPointOnArc(Ar,P) + type(t_segArc), intent(in) :: Ar + type(t_point), intent(out) :: P + double precision :: angle + if (Ar%a < Ar %b) then + angle = angleNormal((Ar%a + Ar%b) * 0.5) + else + angle = angleNormal((Ar%a + Ar%b ) *0.5 + pi_c) + endif + p%x = Ar%x + Ar%r * cos(angle) + p%y = Ar%y + Ar%r * sin(angle) + end subroutine MediumPointOnArc + + function estColineaire(sa1,sa2) + type(t_segArc),intent(in) :: sa1,sa2 + logical :: estColineaire + + if (sa1%typ/=tseg .or. sa2%typ/=tseg) then + estColineaire = .false. + else + estcolineaire = estcoli(sa1%dx-sa1%x,sa1%dy-sa1%y,sa2%dx-sa2%x,sa2%dy-sa2%y) + end if + end function estColineaire + + function isAngleInArc(a,arc) + double precision,intent(in) :: a + type(t_segArc),intent(in) :: arc + integer :: isAngleInArc + double precision :: angl + !dit si un angle est sur l'intervalle d'un arc : 0 -> pas dessus, + ! 1 -> c'est l'origine, 2 -> entre les deux, 3 -> c'est l'extremite + if (arc%typ==tcer) then + isAngleInArc = 2 + return + end if + + angl = angleNormal(a) + if (isEqualConst(arc%a,angl)) then ; isAngleInArc = 1 + else if (isEqualConst(arc%b,angl)) then ; isAngleInArc = 3 + else if (arc%a<arc%b) then + if((arc%a<angl).and.(angl<arc%b)) then ; isAngleInArc = 2 + else ; isAngleInArc = 0 + end if + else + if((arc%b<angl).and.(angl<arc%a)) then ; isAngleInArc = 0 + else ; isAngleInArc = 2 + end if + end if + end function isAngleInArc + + function isIn(ptx,pty,sa) + double precision,intent(in) :: ptx,pty + type(t_segArc),intent(in) :: sa + integer :: isIn + + double precision :: angl + + !dit si un point est sur un segment ou un arc : 0 -> pas dessus, + ! 1 -> c'est l'origine, 2 -> entre les deux, 3 -> c'est l'extremite + !ATTENTION :le point doit etre deja sur la droite ou le cercle d'appui + if (sa%typ==tseg) then + if (isEqualConst(sa%x,ptx) .and. isEqualConst(sa%y,pty)) then + isIn = 1 + else if (isEqualConst(sa%dx,ptx) .and. isEqualConst(sa%dy,pty)) then + isIn = 3 + else if (((sa%x-ptx)*(sa%dx-ptx)+(sa%y-pty)*(sa%dy-pty))<0) then + isIn = 2 + else + isIn = 0 + end if + else + angl = calculeAngle(sa%x,sa%y,ptx,pty) + isIn = isAngleInArc(angl,sa) + end if + end function isIn + + function isIn_V2(ptx,pty,sa) + double precision,intent(in) :: ptx,pty + type(t_segArc),intent(in) :: sa + integer :: isIn_V2 + + double precision :: angl, tmp + + !dit si un point est sur un segment ou un arc : 0 -> pas dessus, + ! 1 -> c'est l'origine, 2 -> entre les deux, 3 -> c'est l'extremite + !ATTENTION :le point doit etre deja sur la droite ou le cercle d'appui + if (sa%typ==tseg) then + if (isEqualConst(sa%x,ptx) .and. isEqualConst(sa%y,pty)) then + isIn_V2 = 1 + else if (isEqualConst(sa%dx,ptx) .and. isEqualConst(sa%dy,pty)) then + isIn_V2 = 3 + else + tmp = (sa%x-ptx)*(sa%dx-ptx)+(sa%y-pty)*(sa%dy-pty) + if (tmp < dp_0) then + isIn_V2 = 2 + else if (isEqualConst(tmp,dp_0)) then + isIn_V2 = 4 + else + isIn_V2 = 0 + end if + end if + elseif (sa%typ == tarc) then + angl = calculeAngle(sa%x,sa%y,ptx,pty) + isIn_V2 = isAngleInArc(angl,sa) + else + tmp = sqrt((sa%x-ptx)*(sa%x-ptx)+(sa%y-pty)*(sa%y-pty)) + if (isEqualConst(tmp,sa%r)) then + isIn_V2 = 2 + else + isIn_V2 = 0 + endif + end if + end function isIn_V2 + + function isSameWay(sg1,sg2) + type(t_segArc),intent(in) :: sg1,sg2 + logical :: isSameWay + !dit si 2 segments alignes ont meme orientation + + isSameWay=(((sg1%dx-sg1%x)*(sg2%dx-sg2%x)+(sg1%dy-sg1%y)*(sg2%dy-sg2%y))>0) + end function isSameWay + + subroutine AddSA(SA,szSA) + type(t_segArc), intent(in) :: SA + integer, intent(inout) :: szSA + if (szSA == size(tabSegArc)) call XABORT("AddSA : memory problem") + szSA = szSA + 1 + tabSegArc(szSA) = SA + end subroutine AddSA + + subroutine Add2SA(SA1,SA2,szSA) + type(t_segArc), intent(in) :: SA1,SA2 + integer, intent(inout) :: szSA + if (szSA == size(tabSegArc)) call XABORT("Add2SA : memory problem") + szSA = szSA + 2 + tabSegArc(szSA-1) = SA1 + tabSegArc(szSA) = SA2 + end subroutine Add2SA + + function ReplaceSA(newSA,iSA) + type(t_segArc), intent(in) :: newSA + integer, intent(in) :: iSA + type(t_segArc) :: ReplaceSA + ReplaceSA = newSA + tabSegArc(iSA) = newSA + end function ReplaceSA + + subroutine SlideSA(iSA,szSA) + integer, intent(in) :: iSA + integer, intent(inout) :: szSA + tabSegArc(iSA:szSA-1) = tabSegArc(iSA+1:szSA) + szSA = szSA - 1 + end subroutine SlideSA + + subroutine AddSC(SC,szSC) + type(t_segArc), intent(in) :: SC + integer, intent(inout) :: szSC + if (szSC == size(tabSegCut)) then + write(6,*) szSC,size(tabSegCut) + call XABORT("AddSC : memory problem") + endif + szSC = szSC + 1 + tabSegCut(szSC) = SC + end subroutine AddSC + + subroutine Add2SC(SC1,sC2,szSC) + type(t_segArc), intent(in) :: SC1,SC2 + integer, intent(inout) :: szSC + if (szSC == size(tabSegCut)) call XABORT("Add2SC : memory problem") + szSC = szSC + 2 + tabSegCut(szSC-1) = SC1 + tabSegCut(szSC) = SC2 + end subroutine Add2SC + + function ReplaceSC(newSC,iSC) + type(t_segArc), intent(in) :: newSC + integer, intent(in) :: iSC + type(t_segArc) :: ReplaceSC + ReplaceSC = newSC + tabSegCut(iSC) = newSC + end function ReplaceSC + + subroutine OverlaidSegmentsManagement(n1, n2, iSC, szSC, SC, iSA, szSA, SA) + integer, intent(in) :: n1, n2 + integer, intent(inout) :: iSC, szSC, iSA, szSA + type(t_SegArc), intent(inout) :: SC, SA + type(t_segArc) :: SC1, SC2, SC3, SA1, SA2 + select case(n1) + case(11) ! SC and SA have same origin + select case(n2) + case(23) + SA1 = CopySegExceptOrigin(SC%dx,SC%dy,SA) + SA = ReplaceSA(SA1,iSA) + iSA = iSA + 1 + case(32) ! end of SA internal to SC + SC1 = CopySegExceptOrigin(SA%dx,SA%dy,SC) + SC2 = CopySegExceptEnd(SA%dx,SA%dy,SC) + call AddSC(SC1,szSC) + SC = ReplaceSC(SC2,iSC) + call SlideSA(iSA,szSA) + case(33) ! SC and SA have same end + call SlideSA(iSA,szSA) + case default + call XABORT("OverlaidSegmentsManagement : impossible circumstance") + end select + case(12) ! the origin of SC is internal to SA + select case (n2) + case(21) + SC1 = CopySegExceptEnd(SA%x,SA%y,SC) + SC2 = CopySegExceptOrigin(SA%x,SA%y,SC) + SA1 = CopySegExceptOrigin(SC%x,SC%y,SA) + SC = ReplaceSC(SC1,iSC) + SA = ReplaceSA(SA1,iSA) + call AddSC(SC2,szSC) + iSA = iSA + 1 + case(23) + SC1 = CopySegExceptEnd(SA%x,SA%y,SC) + SC2 = CopySegExceptOrigin(SA%x,SA%y,SC) + SC3 = CopySegWithNewExtrems(SA%x,SA%y,SA%dx,SA%dy,SC) + SA1 = CopySegExceptOrigin(SC%dx,SC%dy,SA) + SC = ReplaceSC(SC3,iSC) + SA = ReplaceSA(SA1,iSA) + call AddSC(SC2,szSC) + iSa = iSA + 1 + case(31) + SC1 = CopySegExceptOrigin(SA%x,SA%y,SC) + SC2 = CopySegWithNewExtrems(SA%dx,SA%dy,SA%x,SA%y,SC) + SC = ReplaceSC(SC2,iSC) + call AddSC(SC1,szSC) + call SlideSA(iSA,szSA) + case(32) + if (isSameWay(SC,SA)) then + SC1 = CopySegExceptEnd(SA%x,SA%y,SC) + SC2 = CopySegExceptOrigin(SA%dx,SA%dy,SC) + SC3 = CopySegWithNewExtrems(SA%x,SA%y,SA%dx,SA%dy,SC) + SC = ReplaceSC(SC3,iSC) + else + SC1 = CopySegExceptEnd(SA%dx,SA%dy,SC) + SC2 = CopySegExceptOrigin(SA%x,SA%y,SC) + SC3 = CopySegWithNewExtrems(SA%dx,SA%dy,SA%x,SA%y,SC) + SC = ReplaceSC(SC3,iSC) + endif + call Add2SC(SC1,SC2,szSC) + call SlideSA(iSA,szSA) + case(33) + SC1 = CopySegExceptEnd(SA%x,SA%y,SC) + SC2 = CopySegWithNewExtrems(SA%x,SA%y,SA%dx,SA%dy,SC) + SC = ReplaceSC(SC2,iSC) + call AddSC(SC1,szSC) + call SlideSA(iSA,szSA) + case default + call XABORT("OverlaidSegmentsManagement : impossible circumstance") + end select + case(13) ! the origin of SC is the end of SA + select case(n2) + case(21) + SA1 = CopySegExceptOrigin(SC%x,SC%y,SA) + call AddSA(SA1,szSA) + iSA = iSA + 1 + case(31) + SC1 = CopySegWithNewExtrems(SA%dx,SA%dy,SA%x,SA%y,SC) + SC = ReplaceSC(SC1,iSC) + call SlideSA(iSA,szSA) + case(32) + SC1 = CopySegExceptEnd(SA%dx,SA%dy,SC) + SC2 = CopySegExceptOrigin(SA%dx,SA%dx,SC) + SC = ReplaceSC(SC2,iSC) + call AddSC(SC1,szSC) + call SlideSA(iSa,szSA) + case default + write(6,*) "Pb n1,n2",n1,N2 + call XABORT("OverlaidSegmentsManagement : impossible circumstance") + end select + case(21) + select case(n2) + case(12) + SC1 = CopySegExceptEnd(SA%x,SA%y,SC) + SC2 = CopySegExceptOrigin(SA%x,SA%y,SC) + SA1 = CopySegExceptOrigin(SC%x,SC%y,SA) + SC = ReplaceSC(SC1,iSC) + call AddSC(SC2,szSC) + SA = ReplaceSA(SA1,iSA) + iSA = iSA + 1 + case(13) + SA1 = CopySegExceptOrigin(SC%x,SC%y,SC) + SA = ReplaceSA(SA1,iSA) + iSA = iSA + 1 + case(23) + if (isSameWay(SC,SA)) then + SA1 = CopySegExceptEnd(SC%x,SC%y,SA) + SA2 = CopySegExceptOrigin(SC%dx,SC%dy,SA) + else + SA1 = CopySegExceptEnd(SC%Dx,SC%Dy,SA) + SA2 = CopySegExceptOrigin(SC%x,SC%y,SA) + endif + SA = ReplaceSA(SA1,iSA) + call AddSC(SC2,szSC) + iSA = iSA + 1 + case(32) + SC1 = CopySegExceptEnd(SA%dx,SA%dy,SC) + SC2 = CopySegExceptOrigin(SA%dx,SA%dy,SC) + SA1 = CopySegExceptEnd(SC%x,SC%y,SA) + SC = ReplaceSC(SC1,iSC) + call AddSC(SC2,szSC) + SA = ReplaceSA(SA1,iSA) + iSA = iSA + 1 + case(33) + SA1 = CopySegExceptEnd(SC%x,SC%y,SC) + SA = ReplaceSA(SA1,iSA) + iSA = iSA + 1 + case default + write(6,*) "Pb n1,n2",n1,N2 + call XABORT("OverlaidSegmentsManagement : impossible circumstance") + end select + case(23) + select case (n2) + case(11) + SA1 = CopySegExceptOrigin(SC%dx,SC%dy,SA) + SA = ReplaceSA(SA1,iSA) + iSA = iSA + 1 + case(12) + SC1 = CopySegExceptEnd(SA%x,SA%y,SC) + SC2 = CopySegExceptOrigin(SA%x,SA%y,SC) + SC = ReplaceSC(SC1,iSC) + call AddSC(SC2,szSC) + SA1 = CopySegExceptOrigin(SC%dx,SC%dy,SA) + SA = ReplaceSA(SA1,iSA) + iSA = iSA + 1 + case(21) + if (isSameWay(SC,SA)) then + SA1 = CopySegExceptEnd(SC%x,SC%y,SA) + SA2 = CopySegExceptOrigin(SC%dx,SC%dy,SA) + else + SA1 = CopySegExceptEnd(SC%dx,SC%dy,SA) + SA2 = CopySegExceptOrigin(SC%x,SC%y,SA) + endif + SA = ReplaceSA(SA1,iSA) + call AddSA(SA2,szSA) + iSA = iSA + 1 + case(31) + SA1 = CopySegExceptEnd(SC%dx,SC%dy,SA) + SA = ReplaceSA(SA1,iSA) + iSA = iSA + 1 + case(32) + SC1 = CopySegExceptEnd(SA%dx,SA%dy,SC) + SC2 = CopySegExceptOrigin(SA%dx,SA%dy,SC) + SA1 = CopySegExceptEnd(SC%dx,SC%dy,SA) + SC = ReplaceSC(SC1,iSC) + SA = ReplaceSA(SA1,iSA) + call AddSC(SC2,szSC) + iSA = iSA + 1 + case default + write(6,*) "Pb n1,n2",n1,N2 + call XABORT("OverlaidSegmentsManagement : impossible circumstance") + end select + case(31) + select case (n2) + case(12) + SC1 = CopySegExceptEnd(SA%x,SA%y,SC) + SC2 = CopySegExceptOrigin(SA%x,SA%y,SC) + SC = ReplaceSC(SC1,iSC) + call AddSc(SC2,szSC) + call SlideSA(iSA,szSA) + case(13) + SC1 = CopySegWithNewExtrems(SA%dx,SA%dy,SA%x,SA%y,SC) + SC = ReplaceSC(SC1,iSC) + call SlideSA(iSA,szSA) + case(23) + SA1 = CopySegExceptEnd(SC%dx,SC%dy,SA) + SA = ReplaceSA(SA1,iSA) + iSA = iSA + 1 + case default + write(6,*) "Pb n1,n2",n1,N2 + call XABORT("OverlaidSegmentsManagement : impossible circumstance") + end select + case(32) + select case (n2) + case(11) + SC1 = CopySegExceptEnd(SA%dx,SA%dy,SC) + SC2 = CopySegExceptOrigin(SA%dx,SA%dy,SC) + SC = ReplaceSC(SC1,iSC) + call AddSC(SC2,szSC) + iSA = iSA + 1 + case(12) + if (isSameWay(SA,SC)) then + SC1 = CopySegExceptEnd(SA%x,SA%y,SC) + SC2 = CopySegExceptOrigin(SA%dx,SA%dy,SC) + SC3 = CopySegWithNewExtrems(SA%x,SA%y,SA%dx,SA%dy,SC) + SC = ReplaceSC(SC3,iSC) + else + SC1 = CopySegExceptEnd(SA%dx,SA%dy,SC) + SC2 = CopySegExceptOrigin(SA%x,SA%y,SC) + SC3 = CopySegWithNewExtrems(SA%dx,SA%dy,SA%x,SA%y,SC) + SC = ReplaceSC(SC3,iSC) + end if + call Add2SC(SC1,SC2,szSC) + call SlideSA(iSA,szSA) + case(13) + SC1 = CopySegExceptEnd(SA%dx,SA%dy,SC) + SC2 = CopySegExceptOrigin(SA%dx,SA%dy,SC) + SC = ReplaceSC(SC1,iSC) + call AddSC(SC2,szSC) + call SlideSA(iSA,szSA) + case(21) + SC1 = CopySegExceptEnd(SA%dx,SA%dy,SC) + SC2 = CopySegExceptOrigin(SA%dx,SA%dy,SC) + SA1 = CopySegExceptOrigin(SC%x,SC%y,SA) + SC = ReplaceSC(SC1,iSC) + SA = ReplaceSA(SA1,iSA) + call AddSC(SC2,szSC) + iSA = iSA + 1 + case(23) + SC1 = CopySegExceptEnd(SA%dx,SA%dy,SC) + SC2 = CopySegExceptOrigin(SA%dx,SA%dy,SC) + SA1 = CopySegExceptOrigin(SC%dx,SC%dy,SA) + SC = ReplaceSC(SC1,iSC) + SA = ReplaceSA(SA1,iSA) + call AddSC(SC2,szSC) + iSA = iSA + 1 + case default + write(6,*) "Pb n1,n2",n1,N2 + call XABORT("OverlaidSegmentsManagement : impossible circumstance") + end select + case(33) + select case (n2) + case(11) + SC1 = CopySegWithNewExtrems(SA%x,SA%y,SA%dx,SA%dy,SC) + SC = ReplaceSC(SC1,iSC) + call SlideSA(iSA,szSA) + case(12) + SC1 = CopySegExceptEnd(SA%x,SA%y,SC) + SC2 = CopySegWithNewExtrems(SA%x,SA%y,SA%dx,SA%dy,SC) + SC = ReplaceSC(SC2,iSC) + call AddSC(SC1,szSC) + call SlideSA(iSA,szSA) + case(21) + SA1 = CopySegExceptEnd(SC%x,SC%y,SA) + SA = ReplaceSA(SA1,iSA) + iSA = iSA + 1 + case default + write(6,*) "Pb n1,n2",n1,N2 + call XABORT("OverlaidSegmentsManagement : impossible circumstance") + end select + case default + write(6,*) "Pb n1,n2",n1,N2 + call XABORT("OverlaidSegmentsManaement : ??") + end select + end subroutine OverlaidSegmentsManagement + + function turnBackSide(sg) + type(t_segArc),intent(inout) :: sg + type(t_segArc) :: turnBackSide + !tourne le sens du segment en entree + + turnBackSide=createSeg(sg%dx,sg%dy,sg%x,sg%y,sg%mixd,sg%mixg) + turnBackSide%nodeg=sg%noded + turnBackSide%noded=sg%nodeg + turnBackSide%indCellPg=sg%indCellPd + turnBackSide%indCellPd=sg%indCellPg + turnBackSide%sectg=sg%sectd + turnBackSide%sectd=sg%sectg + turnBackSide%neutronicMixg=sg%neutronicMixd + turnBackSide%neutronicMixd=sg%neutronicMixg + sg=turnBackSide + end function turnBackSide + + subroutine adjustMix(sgToAdjust,sgOfRef) + type(t_segArc),intent(inout) :: sgToAdjust + type(t_segArc),intent(in) :: sgOfRef + !ajuste les milieux a droite et a gauche de sgToAdjust + !par rapport a ceux de sgOfRef (sgToAdjust doit etre inclus dans sgOfRef) + if (sgOfRef%mixg/=fooMix) then + sgToAdjust%mixg = sgOfRef%mixg + sgToAdjust%indCellPg = sgOfRef%indCellPg + sgToAdjust%sectg = sgOfRef%sectg + sgToAdjust%neutronicMixg = sgOfRef%neutronicMixg + end if + if (sgOfRef%mixd/=fooMix) then + sgToAdjust%mixd = sgOfRef%mixd + sgToAdjust%indCellPd = sgOfRef%indCellPd + sgToAdjust%sectd = sgOfRef%sectd + sgToAdjust%neutronicMixd = sgOfRef%neutronicMixd + end if + end subroutine adjustMix + + logical function interSgAr_V2(sg,ar, n1, n2, P1, P2) + ! Return true only if there is at least an intersection between sg and ar. + ! If there is an point of intersection or an tangency point, P1 is this point. + ! If there are two intersection points, P1 and P2 are these points. + ! N1 and n2 let us pinpoint the point of intersection on both segment and arc. + ! If there is no point of intersection, the values for n1 and n2 are 0. + type(t_segArc),intent(in) :: sg,ar + integer, intent(out):: n1, n2 + type (t_point), intent(out) :: P1, P2 + + double precision :: sox, soy, sfx, sfy, cx, cy, ray, aox, aoy + double precision :: prjx, prjy, d, u, v, norm, tmp, Ix, Iy, Jx, Jy + integer :: IinS,IinA,JinS,JinA + + ! Initialization + n1 = 0 ; n2 = 0 + P1 = t_point(dp_0,dp_0) ; P2 = t_point(dp_0,dp_0) + InterSgAr_V2 = .false. + ! Coordinates + sox = sg%x ; sfx = sg%dx ; soy = sg%y ; sfy = sg%dy + cx = ar%x ; cy = ar%y ; ray = ar%r + + ! Special case : ar is a point + if ((ar%typ == tarc.and.isEqualConst(angleNormal(ar%a),angleNormal(ar%b)))) then + call giveOrigine(ar,aox,aoy) + if (isIn(aox,aoy,sg) /= 0) then + interSgAr_V2 =.true. ; n1 = isIn(aox,aoy,sg)+10 + P1 = t_point(aox,aoy) + endif + goto 10 + endif + ! Special case : sg is a point + if (isEqualConst(sox,sfx).and.isEqualConst(soy,sfy)) then + d = sqrt((sox-cx)*(sox-cx) + (soy-cy)*(soy-cy)) + if (isEqualConst(d,ray)) then + interSgAr_V2 =.true. ; n1 = 1+isIn(sox,soy,ar)*10 + P1 = t_point(sox,soy) + endif + goto 10 + endif + ! Distance Segment-Arc + d = distance(cx,cy,sox,soy,sfx,sfy,prjx,prjy) + ! Distance analysis + if (.not. isEqualConst(d,ar%r)) then + if (d < ray) then + ! no one, one or two distinct intersection points + ! P1 before and P2 after on the straight for segment + u = sfx - sox ; v = sfy - soy ; norm = u*u + v*v + if (.not.isEqualConst(sqrt(norm),dp_0)) then + tmp = sqrt((ray*ray - d*d)/norm) + u = tmp*u ; v = tmp*v + Ix=prjx-u ; Iy=prjy-v ; IinS=isIn_V2(Ix,Iy,sg) ; IinA=isIn(Ix,Iy,ar) + Jx=prjx+u ; Jy=prjy+v ; JinS=isIn_V2(Jx,Jy,sg) ; JinA=isIn(Jx,Jy,ar) + if (IinS/=0.and.IinA/=0) then + interSgAr_V2 = .true. ; n1 = IinS + 10*IinA ; P1 = t_point(Ix,Iy) + if (JinS/=0.and.JinA/=0) then + n2 = JinS + 10*JinA ; P2 = t_point(Jx,Jy) + goto 10 + endif + else if (JinS/=0.and.JinA/=0) then + interSgAr_V2 = .true. ; n1 = JinS + 10*JinA ; P1 = t_point(Jx,Jy) + goto 10 + end if + else + call XABORT("interSgAr_V2 : seg was not detected as a point but its norm is zero") + end if + end if + else + ! Tangency point + Ix=prjx ; Iy=prjy ; IinS=isIn(Ix,Iy,sg) ; IinA=isIn(Ix,Iy,ar) + if ((IinS/=0.and.IinA/=0)) then + interSgAr_V2=.true. ; n1 = 100 + 10 * IinA + IinS ; P1 = t_point(Ix,Iy) + end if + end if + ! +10 continue + return + end function interSgAr_V2 + + + function interSgAr(sg,ar,pt1x,pt1y,pt2x,pt2y) + type(t_segArc),intent(in) :: sg,ar + double precision,intent(out) :: pt1x,pt1y,pt2x,pt2y + integer :: interSgAr + + double precision :: prjx,prjy,d + double precision :: u,v,tmp,Ix,Iy,Jx,Jy + integer :: IinS,IinA,JinS,JinA + !renvoie le nombre de points d'intersection entre sg et ar, + !et leurs coordonnees eventuelles + !Si un seul point d'intersection, renvoi 1 si pt==I et -1 si pt==J + !Si l'arc et le segment sont tangents, renvoie 2, et pt1=pt2 + + interSgAr = 0 + pt1x=0.d0 ; pt1y=0.d0 ; pt2x=1.d0 ; pt2y=1.d0 + d = distance(ar%x,ar%y,sg%x,sg%y,sg%dx,sg%dy,prjx,prjy) + if (.not. isEqualConst(d,ar%r)) then + if (d>ar%r) then + interSgAr = 0 + else + !2 points d'intersection distincts I et J avec + !I avant J sur la droite d'appui du segment + u=sg%dx-sg%x ; v=sg%dy-sg%y + tmp=sqrt((ar%r*ar%r-d*d)/(u*u+v*v)) + u=tmp*u ; v=tmp*v + Ix=prjx-u ; Iy=prjy-v ; IinS=isIn(Ix,Iy,sg) ; IinA=isIn(Ix,Iy,ar) + Jx=prjx+u ; Jy=prjy+v ; JinS=isIn(Jx,Jy,sg) ; JinA=isIn(Jx,Jy,ar) + if ((IinS/=0.and.IinA/=0).and.(IinS==2.or.IinA==2)) then + interSgAr=1 ; pt1x=Ix ; pt1y=Iy + end if + if ((JinS/=0.and.JinA/=0).and.(JinS==2.or.JinA==2)) then + if (interSgAr==1) then + interSgAr=2 ; pt2x=Jx ; pt2y=Jy + else + interSgAr=-1 ; pt1x=Jx ; pt1y=Jy + end if + end if + end if + else + Ix=prjx ; Iy=prjy ; IinS=isIn(Ix,Iy,sg) ; IinA=isIn(Ix,Iy,ar) + if ((IinS/=0.and.IinA/=0).and.(IinS==2.or.IinA==2)) then + interSgAr=2 ; pt1x=Ix ; pt1y=Iy ; pt2x=Ix ; pt2y=Iy + end if + end if + end function interSgAr + + logical function InterSgSg_V2(sg1,sg2,n1, n2, P1,P2) + type(t_segArc),intent(in) :: sg1,sg2 + integer, intent(inout) :: n1, n2 + type(t_point), intent(out) :: P1, P2 + + double precision :: xo1, xf1, xo2, xf2, yo1, yf1, yo2, yf2 + double precision :: min1, min2, max1, max2, m, prodvect + double precision :: a1, a2, b1, b2, y + + ! Initialization + n1 = 0 ; n2 = 0 + P1 = t_point(dp_0,dp_0) ; P2 = t_point(dp_0,dp_0) + InterSgSg_V2 = .false. + + ! Coordinates + xo1=sg1%x ; xf1 =sg1%dx ; yo1 = sg1%y ; yf1 = sg1%dy + xo2=sg2%x ; xf2 =sg2%dx ; yo2 = sg2%y ; yf2 = sg2%dy + + ! Very Special case : point instead of segment + min1 = sqrt((xf1-xo1)*(xf1-xo1)+(yf1-yo1)*(yf1-yo1)) + min2 = sqrt((xf2-xo2)*(xf2-xo2)+(yf2-yo2)*(yf2-yo2)) + if (isEqualConst(min1,dp_0)) then + prodvect = (xf2-xo2)*(yo1-yo2)-(yf2-yo2)*(xo1-xo2) + if (isEqualConst(prodvect,dp_0) .and. (isIn(xo1,yo1,Sg2)/=0)) then + InterSgSg_V2 = .true. ; n1 = 1 ; P1 = t_point(xo1,yo1) + endif + goto 10 + elseif(isEqualConst(min2,dp_0)) then + prodvect = (xf1-xo1)*(yo2-yo1)-(yf1-yo1)*(xo2-xo1) + if (isEqualConst(prodvect,dp_0) .and. (isIn(xo2,yo2,Sg1)/=0)) then + InterSgSg_V2 = .true. ; n1 = 1 ; P1 = t_point(xo2,yo2) + endif + goto 10 + else + + ! Special case : two vertical segments + if (IsEqualConst(xo1,xf1).and.IsEqualConst(xo2,xf2)) then + if (IsEqualConst(xo1,xo2)) then + min1 = min(yo1,yf1) ; max1 = max(yo1,yf1) + min2 = min(yo2,yf2) ; max2 = max(yo2,yf2) + if (isEqualConst(min1,max2).or.isEqualConst(min2,max1)) then + InterSgSg_V2 = .true. ; n1 = 1 + if (isEqualConst(min1,max2)) P1 = t_point(xo1,min1) + if (isEqualConst(max1,min2)) P1 = t_point(xo2,min2) + elseif (max2 < min1 .or. max1 < min2) then + InterSgSg_V2 = .false. + else + InterSgSg_V2 = .true. + n1 = 1 ; P1 = t_point(xo1,max(min1,min2)) + n2 = 1 ; P2 = t_point(xo1,min(max1,max2)) + endif + endif + else + ! Special case : only one vertical segment + if (isEqualConst(xo1,xf1).and..not.isEqualConst(xo2,xf2)) then + a2 = (yf2 - yo2) / (xf2 - xo2) ; b2 = yo2 - a2 * xo2 + if ((isEqualConst(xo1,min(xo2,xf2)).or.xo1>min(xo2,xf2)) .and.& + (isEqualConst(xo2,max(xo2,xf2)).or.xo1<max(xo2,xf2)))then + y = a2 * xo1 + b2 + if ((isEqualConst(y,min(yo1,yf1)).or.y>min(yo1,yf1)).and.& + (isEqualConst(y,max(yo1,yf1)).or.y<max(yo1,yf1)).and.& + (isEqualConst(y,min(yo2,yf2)).or.y>min(yo2,yf2)).and.& + (isEqualConst(y,max(yo2,yf2)).or.y<max(yo2,yf2))) then + InterSgSg_V2 = .true. ; n1 = 1 ; P1 = t_point(xo1,y) + else + InterSgSg_V2 = .false. + endif + else + InterSgSg_V2 = .false. + endif + elseif (isEqualConst(xo2,xf2).and..not.isEqualConst(xo1,xf1)) then + if ((isEqualConst(xo2,min(xo1,xf1)).or.xo2>min(xo1,xf1) ).and.& + (isEqualConst(xo2,max(xo1,xf1)).or.xo2<max(xo1,xf1))) then + a1 = (yf1 - yo1) / (xf1 - xo1) ; b1 = yo1 - a1 * xo1 + y = a1 * xo2 + b1 + if ((isEqualConst(y,min(yo1,yf1)).or.y>min(yo1,yf1)).and.& + (isEqualConst(y,max(yo1,yf1)).or.y<max(yo1,yf1)).and.& + (isEqualConst(y,min(yo2,yf2)).or.y>min(yo2,yf2)).and.& + (isEqualConst(y,max(yo2,yf2)).or.y<max(yo2,yf2))) then + InterSgSg_V2 = .true. ; n1 = 1 ; P1 = t_point(xo2,y) + else + InterSgSg_V2 = .false. + endif + else + InterSgSg_V2 = .false. + endif + else + ! general case + a1 = (yf1 - yo1) / (xf1 - xo1) ; b1 = yo1 - a1 * xo1 + a2 = (yf2 - yo2) / (xf2 - xo2) ; b2 = yo2 - a2 * xo2 + min1 = min(xo1,xf1) ; max1 = max(xo1,xf1) + min2 = min(xo2,xf2) ; max2 = max(xo2,xf2) + ! parallel lines + if (isEqualCOnst(a1,a2)) then + if (.not. isEqualConst(b1,b2)) then + InterSgSg_V2 = .false. + else + if (max2 < min1 .or. max1 < min2) then + InterSgSg_V2 = .false. + elseif(isEqualConst(min1,max2).or. & + isEqualCOnst(max1,min2)) then + InterSgSg_V2 = .true. ; n1 = 1 + if (isEqualConst(min1,max2)) then + P1 = t_point(min1,a1*min1+b1) + else + P1 = t_point(min2,a2*min2+b2) + endif + else + InterSgSg_V2 = .true. + m = max(min1,min2) + n1 = 1 ; P1 = t_point(m, a1*m+b1) + m = min(max1,max2) + n2 = 1 ; P2 = t_point(m, a1*m+b1) + endif + endif + ! Secant lines + else + m = (b2-b1)/(a1-a2) + if ( (isEqualConst(m,min1).or.m>min1) .and. & + (isEqualConst(m,max1).or.m<max1) .and. & + (isEqualConst(m,min2).or.m>min2) .and. & + (isEqualConst(m,max2).or.m<max2)) then + InterSgSg_V2 = .true. + n1 = 1; P1 = t_point(m, a1*m+b1) + else + InterSgSg_V2 = .false. + endif + endif + end if + end if + endif + ! Points qualification +10 continue + if (n1 /= 0) then + xo1 = P1%x ; yo1 = P1%y + n1 = isIn(xo1,yo1,Sg1) + 10 * isIn(xo1,yo1,Sg2) + endif + if (n2 /= 0) then + xo1 = P2%x ; yo1 = P2%y + n2 = isIn(xo1,yo1,Sg1) + 10 * isIn(xo1,yo1,Sg2) + ! bug correction made on May 17, 2019 + if((n1.EQ.13).and.(n2.EQ.32)) n2=21 + endif + end function InterSgSg_V2 + + function interSgSg(sg1,sg2,ix,iy) + type(t_segArc),intent(in) :: sg1,sg2 + double precision,intent(out) :: ix,iy + logical :: interSgSg + + double precision :: A1,B1,C1,A2,B2,C2,delta + ix = 0.d0 ; iy = 0.d0 + A1=sg1%y-sg1%dy ; B1=sg1%dx-sg1%x ; C1=sg1%x*sg1%dy-sg1%dx*sg1%y + A2=sg2%y-sg2%dy ; B2=sg2%dx-sg2%x ; C2=sg2%x*sg2%dy-sg2%dx*sg2%y + delta = A1*B2-A2*B1 + interSgSg = .not. isEqualConst(delta,0.d0) + if (.not. interSgSg) return + delta = 1./delta + ix = (B1*C2-B2*C1)*delta ; iy = (A2*C1-A1*C2)*delta + interSgSg = (isIn(ix,iy,sg1)==2 .and. isIn(ix,iy,sg2)==2) + end function interSgSg + + function translateAndTurnTriSg(cx,cy,turn,sg) + double precision,intent(in) :: cx,cy + integer,intent(in) :: turn + type(t_segArc),intent(in) :: sg + type(t_segArc) :: translateAndTurnTriSg + + translateAndTurnTriSg = sg + select case(turn) + case(1) + translateAndTurnTriSg%x = sg%x + cx + translateAndTurnTriSg%y = sg%y + cy + translateAndTurnTriSg%dx = sg%dx + cx + translateAndTurnTriSg%dy = sg%dy + cy + case(2) + translateAndTurnTriSg%x = 5.d-1*sg%x - sqrt3_2d*sg%y + cx + translateAndTurnTriSg%y = 5.d-1*sg%y + sqrt3_2d*sg%x + cy + translateAndTurnTriSg%dx = 5.d-1*sg%dx - sqrt3_2d*sg%dy + cx + translateAndTurnTriSg%dy = 5.d-1*sg%dy + sqrt3_2d*sg%dx + cy + case(3) + translateAndTurnTriSg%x = -5.d-1*sg%x - sqrt3_2d*sg%y + cx + translateAndTurnTriSg%y = -5.d-1*sg%y + sqrt3_2d*sg%x + cy + translateAndTurnTriSg%dx = -5.d-1*sg%dx - sqrt3_2d*sg%dy + cx + translateAndTurnTriSg%dy = -5.d-1*sg%dy + sqrt3_2d*sg%dx + cy + case(4) + translateAndTurnTriSg%x = -sg%x + cx + translateAndTurnTriSg%y = -sg%y + cy + translateAndTurnTriSg%dx = -sg%dx + cx + translateAndTurnTriSg%dy = -sg%dy + cy + case(5) + translateAndTurnTriSg%x = -5.d-1*sg%x + sqrt3_2d*sg%y + cx + translateAndTurnTriSg%y = -5.d-1*sg%y - sqrt3_2d*sg%x + cy + translateAndTurnTriSg%dx = -5.d-1*sg%dx + sqrt3_2d*sg%dy + cx + translateAndTurnTriSg%dy = -5.d-1*sg%dy - sqrt3_2d*sg%dx + cy + case(6) + translateAndTurnTriSg%x = 5.d-1*sg%x + sqrt3_2d*sg%y + cx + translateAndTurnTriSg%y = 5.d-1*sg%y - sqrt3_2d*sg%x + cy + translateAndTurnTriSg%dx = 5.d-1*sg%dx + sqrt3_2d*sg%dy + cx + translateAndTurnTriSg%dy = 5.d-1*sg%dy - sqrt3_2d*sg%dx + cy + case(7) + translateAndTurnTriSg%mixg = sg%mixd + translateAndTurnTriSg%mixd = sg%mixg + translateAndTurnTriSg%x = sg%x + cx + translateAndTurnTriSg%y = -sg%y + cy + translateAndTurnTriSg%dx = sg%dx + cx + translateAndTurnTriSg%dy = -sg%dy + cy + case(8) + translateAndTurnTriSg%mixg = sg%mixd + translateAndTurnTriSg%mixd = sg%mixg + translateAndTurnTriSg%x = 5.d-1*sg%x - sqrt3_2d*sg%y + cx + translateAndTurnTriSg%y = -5.d-1*sg%y - sqrt3_2d*sg%x + cy + translateAndTurnTriSg%dx = 5.d-1*sg%dx - sqrt3_2d*sg%dy + cx + translateAndTurnTriSg%dy = -5.d-1*sg%dy - sqrt3_2d*sg%dx + cy + case(9) + translateAndTurnTriSg%mixg = sg%mixd + translateAndTurnTriSg%mixd = sg%mixg + translateAndTurnTriSg%x = -5.d-1*sg%x - sqrt3_2d*sg%y + cx + translateAndTurnTriSg%y = 5.d-1*sg%y - sqrt3_2d*sg%x + cy + translateAndTurnTriSg%dx = -5.d-1*sg%dx - sqrt3_2d*sg%dy + cx + translateAndTurnTriSg%dy = 5.d-1*sg%dy - sqrt3_2d*sg%dx + cy + case(10) + translateAndTurnTriSg%mixg = sg%mixd + translateAndTurnTriSg%mixd = sg%mixg + translateAndTurnTriSg%x = -sg%x + cx + translateAndTurnTriSg%y = sg%y + cy + translateAndTurnTriSg%dx = -sg%dx + cx + translateAndTurnTriSg%dy = sg%dy + cy + case(11) + translateAndTurnTriSg%mixg = sg%mixd + translateAndTurnTriSg%mixd = sg%mixg + translateAndTurnTriSg%x = -5.d-1*sg%x + sqrt3_2d*sg%y + cx + translateAndTurnTriSg%y = 5.d-1*sg%y + sqrt3_2d*sg%x + cy + translateAndTurnTriSg%dx = -5.d-1*sg%dx + sqrt3_2d*sg%dy + cx + translateAndTurnTriSg%dy = 5.d-1*sg%dy + sqrt3_2d*sg%dx + cy + case(12) + translateAndTurnTriSg%mixg = sg%mixd + translateAndTurnTriSg%mixd = sg%mixg + translateAndTurnTriSg%x = 5.d-1*sg%x + sqrt3_2d*sg%y + cx + translateAndTurnTriSg%y = -5.d-1*sg%y + sqrt3_2d*sg%x + cy + translateAndTurnTriSg%dx = 5.d-1*sg%dx + sqrt3_2d*sg%dy + cx + translateAndTurnTriSg%dy = -5.d-1*sg%dy + sqrt3_2d*sg%dx + cy + end select + end function translateAndTurnTriSg + + function interArcArc(clus,ring,aClus,bClus,aRing,bRing,revert) + type(t_segArc),intent(in) :: ring,clus + double precision,intent(out) :: aClus,bClus,aRing,bRing + logical,intent(out) :: revert !les arcs sont dans le meme sens? + integer :: interArcArc + + double precision :: d,maxD,minD,aC,aR,d2,rr2,rc2 + integer :: inClus,inRing + logical :: aIn,bIn + + !donne le nombre de points d'intersection entre clus et ring + !et les angles eventuels d'intersection dans clus et ring + !avec pour reference l'arc clus (pour les point designes) + interArcArc = 0 + aClus = 0.d0 ; bClus = 0.d0 + aRing = 0.d0 ; bRing = 0.d0 + + d = longVect(ring%x-clus%x,ring%y-clus%y) + maxD = ring%r + clus%r + epsilon + minD = abs(ring%r-clus%r) - epsilon + d2 = d**2 ; rr2 = ring%r**2 ; rc2 = clus%r**2 + revert = (rr2>(d2+rc2)).or.(rc2>(d2+rr2)) + + if (d>(maxD+epsilon).or.d<(minD-epsilon)) return !pas d'intersection + + if (isEqualConst(d,maxD).or.isEqualConst(d,minD)) then + !tangence entre les deux cercles d'appuis + aClus = calculeAngle(clus%x,clus%y,ring%x,ring%y) + if (revert) aClus = angleNormal(aClus - pi_c) + inRing = isIn(clus%x+clus%r*cos(aClus),clus%y+clus%r*sin(aClus),ring) + aRing = calculeAngle(ring%x,ring%y,clus%x,clus%y) + inClus = isIn(ring%x+ring%r*cos(aRing),ring%y+ring%r*sin(aRing),clus) + if (inRing==2 .and. inClus==2) interArcArc = 1 !dans les arcs + return + end if + + !il y a intersection reelle des deux cercles d'appuis + ! l'angle a1 adjacent a r1 est determinable a l'aide de la formule + ! cos(a1) = (d\B2+r1\B2-r2\B2)/(2*d*r1) (idem mutatis-mutandis pour a2) + aC = acos((d2+rc2-rr2)/(2*d*clus%r)) + aClus = angleNormal(calculeAngle(clus%x,clus%y,ring%x,ring%y) - aC) + bClus = angleNormal(calculeAngle(clus%x,clus%y,ring%x,ring%y) + aC) + aR = acos((d2+rr2-rc2)/(2*d*ring%r)) + aRing = angleNormal(calculeAngle(ring%x,ring%y,clus%x,clus%y) - aR) + bRing = angleNormal(calculeAngle(ring%x,ring%y,clus%x,clus%y) + aR) + aIn = (isAngleInArc(aClus,clus)==2) .and. (isAngleInArc(aRing,ring)==2) + bIn = (isAngleInArc(bClus,clus)==2) .and. (isAngleInArc(bRing,ring)==2) + if (aIn .and. bIn) then + interArcArc = 2 + else if (aIn) then + interArcArc = 1 + else if (bIn) then + interArcArc = 1 + aClus = bClus + aRing = bRing + end if + end function interArcArc + + function giveExtremalsAngles(sa,cx,cy,ao,ae) + type(t_segArc),intent(in) :: sa + double precision,intent(in) :: cx,cy + double precision,intent(out) :: ao,ae + logical :: giveExtremalsAngles + + double precision :: ox,oy,ex,ey + + select case(sa%typ) + case(tcer) + ! on sort avec une valeur false + ao = 0.d0 ; ae=0.d0 ; giveExtremalsAngles = .false. + return + case(tarc) + call extremitesArc(sa,ox,oy,ex,ey) + case(tseg) + ox = sa%x ; oy = sa%y ; ex = sa%dx ; ey = sa%dy + end select + ao = angleNormal(calculeAngle(cx,cy,ox,oy)) + ae = angleNormal(calculeAngle(cx,cy,ex,ey)) + giveExtremalsAngles = .not.( (isEqualConst(cx,ox).and.isEqualConst(cy,oy))& + .or.(isEqualConst(cx,ex).and.isEqualConst(cy,ey)) ) + end function giveExtremalsAngles + + subroutine drawSegArc(fileNbr,szSA,withNodes,drawMix,zoomx,zoomy) + integer,intent(in) :: fileNbr,szSA + logical,intent(in) :: withNodes,drawMix + real,intent(in) :: zoomx(2),zoomy(2) + + type(t_segArc) :: sa + integer :: i + real :: cx,cy,angl,lx,ly,tailleNbr,delx,dely + + g_psp_bBoxXmin = 1.e10 + g_psp_bBoxYmin = 1.e10 + g_psp_bBoxXmax = -1.e10 + g_psp_bBoxYmax = -1.e10 + !recuperation des donnees permettants le centrage + do i = 1,szSA + sa = tabSegArc(i) + if (sa%typ==tseg) then + g_psp_bBoxXmin = min(real(sa%x),real(sa%dx),g_psp_bBoxXmin) + g_psp_bBoxYmin = min(real(sa%y),real(sa%dy),g_psp_bBoxYmin) + g_psp_bBoxXmax = max(real(sa%x),real(sa%dx),g_psp_bBoxXmax) + g_psp_bBoxYmax = max(real(sa%y),real(sa%dy),g_psp_bBoxYmax) + else + g_psp_bBoxXmin = min(real(sa%x-sa%r),g_psp_bBoxXmin) + g_psp_bBoxYmin = min(real(sa%y-sa%r),g_psp_bBoxYmin) + g_psp_bBoxXmax = max(real(sa%x+sa%r),g_psp_bBoxXmax) + g_psp_bBoxYmax = max(real(sa%y+sa%r),g_psp_bBoxYmax) + end if + end do + delx = g_psp_bBoxXmax - g_psp_bBoxXmin + dely = g_psp_bBoxYmax - g_psp_bBoxYmin + g_psp_bBoxXmax = g_psp_bBoxXmin + zoomx(2)*delx + g_psp_bBoxXmin = g_psp_bBoxXmin + zoomx(1)*delx + g_psp_bBoxYmax = g_psp_bBoxYmin + zoomy(2)*dely + g_psp_bBoxYmin = g_psp_bBoxYmin + zoomy(1)*dely + lx = 0.1 * ( g_psp_bBoxXmax - g_psp_bBoxXmin ) + ly = 0.1 * ( g_psp_bBoxYmax - g_psp_bBoxYmin ) + write(*,10) g_psp_bBoxXmin,g_psp_bBoxXmax,g_psp_bBoxYmin,g_psp_bBoxYmax + 10 format(' g2s_segArc: plot domain=(',1p,e14.7,':',e14.7,',',e14.7,':',e14.7,')') + g_psp_bBoxXmin = g_psp_bBoxXmin - lx + g_psp_bBoxYmin = g_psp_bBoxYmin - ly + g_psp_bBoxXmax = g_psp_bBoxXmax + lx + g_psp_bBoxYmax = g_psp_bBoxYmax + ly + tailleNbr = min(595./(g_psp_bBoxXmax-g_psp_bBoxXmin), & + 842./(g_psp_bBoxYmax-g_psp_bBoxYmin)) + tailleNbr = 3.6 / tailleNbr + !impression + call psinit(fileNbr,.true.) + do i = 1,szSA + sa = tabSegArc(i) + if (sa%typ==tseg) then + call line(sa%x,sa%y,sa%dx,sa%dy) + cx=real((sa%dx+sa%x)*0.5d0) ; cy=real((sa%dy+sa%y)*0.5d0) + angl = real(calculeAngle(sa%x,sa%y,sa%dx,sa%dy)*rad2deg-90.d0) + if (withNodes .and. drawMix) then + call keknum(cx,cy,tailleNbr,real(sa%nodeg),angl,-1,2) + call keknum(cx,cy,tailleNbr,real(sa%noded),angl,-1,0) + else if (drawMix) then + call keknum(cx,cy,tailleNbr,real(sa%neutronicMixg),angl,-1,2) + call keknum(cx,cy,tailleNbr,real(sa%neutronicMixd),angl,-1,0) + end if + else if (sa%typ==tcer) then + call arc(sa%x,sa%y,sa%r,0.d0,180.d0) + call arc(sa%x,sa%y,sa%r,180.d0,360.d0) + cx=real(sa%x+sa%r) ; cy=real(sa%y) + if (withNodes .and. drawMix) then + call keknum(cx,cy,tailleNbr,real(sa%nodeg),0.,-1,2) + call keknum(cx,cy,tailleNbr,real(sa%noded),0.,-1,0) + else if (drawMix) then + call keknum(cx,cy,tailleNbr,real(sa%neutronicMixg),0.,-1,2) + call keknum(cx,cy,tailleNbr,real(sa%neutronicMixd),0.,-1,0) + end if + else + call arc(sa%x,sa%y,sa%r,sa%a*rad2deg,sa%b*rad2deg) + if (sa%b>sa%a) then + angl=real((sa%b+sa%a)*0.5d0) + else + angl=real((sa%b+sa%a)*0.5d0+pi_c) + end if + cx=real(sa%x+cos(angl)*sa%r) ; cy=real(sa%y+sin(angl)*sa%r) + angl=real(angl*rad2deg) + if (withNodes .and. drawMix) then + call keknum(cx,cy,tailleNbr,real(sa%nodeg),angl,-1,2) + call keknum(cx,cy,tailleNbr,real(sa%noded),angl,-1,0) + else if (drawMix) then + call keknum(cx,cy,tailleNbr,real(sa%neutronicMixg),angl,-1,2) + call keknum(cx,cy,tailleNbr,real(sa%neutronicMixd),angl,-1,0) + end if + end if + end do + call plotnd() + end subroutine drawSegArc + + subroutine coupeCercle(indDeb,szSA,nbSeg,typ) + integer,intent(in) :: indDeb,nbSeg,typ + integer,intent(inout) :: szSA + + type(t_segArc) :: sg,ar + double precision :: pt1x,pt1y,pt2x,pt2y,angl1,angl2,midx,midy,tmp + integer :: i,j,k,tailleAv,tailleAp,nbPtInter + type(segArcArrayBis),dimension(:),allocatable :: tmpTabSegArc + + ! pour programmation defensive + integer :: taille_table_temp + + !RQ: indDeb est l'indice du dernier element du tableau qui + ! ne doit pas etre pris en compte. nbSeg est le nombre + ! de segments paralleles aux axes, et typ correspond au type (3,4,6,ou...) + ! CS-IV : Correction des commentaires d'origine + ! CS-IV : indDeb : indice du dernier element a ne pas prendre en compte + ! CS-IV : (point de depart) + ! CS-IV : nbSeg : nombre de SA a prendre en charge + ! CS-IV : szSA : nombre total de SA dans le tableau + + !preparation du tableau de travail + tailleAp = szSA-indDeb + + ! CS-IV : pourquoi ce 25 ?(on considere que la decoupe ne va pas + ! CS-IV : accroitre le nombre de segments de plus de 25 fois + ! CS-IV : ce coef devrait etre reflechi et dependre du nbr de cercles et + ! CS-IV : et de segments + + ! pour programmation defensive + taille_table_temp = 25*tailleAp + allocate(tmpTabSegArc(1:taille_table_temp),stat=alloc_ok) + if (alloc_ok /= 0) call XABORT("G2S: coupeCercle (1) => allocation pb") + + !copie des segments et arcs construits dans le tableau + !temporaire + ! CS-IV : et suppression dans le tableau initial + tmpTabSegArc(1:tailleAp)%sa = tabSegArc(indDeb+1:indDeb+tailleAp) + tmpTabSegArc(1:tailleAp)%keep = .true. + + szSa = indDeb + ! on coupe tout les elements possible presents, en ne gardant pas ceux qui + ! sont a couper, mais seulement les morceaux obtenus + ! pour i->segment, pour j->arc ou cercle + do + tailleAv = tailleAp + i = 0 + do + i = i+1 + if (.not. tmpTabSegArc(i)%keep) then + if (i/=tailleAv ) cycle + exit + end if + sg = tmpTabSegArc(i)%sa + if (sg%typ/=tseg) then + if (i/=tailleAv ) cycle + exit + end if + ! CS-IV : le SA tmpTabSegArc(i) est un segment + do j = 1,tailleAv + if ((j==i).or.(.not. tmpTabSegArc(j)%keep)) cycle + ar = tmpTabSegArc(j)%sa + if (ar%typ==tseg) cycle + ! CS-IV : le SA tmpTabSegArc(j) est un arc + nbPtInter = interSgAr(sg,ar,pt1x,pt1y,pt2x,pt2y) + if (nbPtInter==2) then + !!deux points d'intersection : + ! CS-IV : on obtient 3 segments et 2 arcs + tmpTabSegArc(i)%keep=.false. ; tmpTabSegArc(j)%keep=.false. + ! => 3 segments (qui gardent les caracteristiques sect*) + do k = 1,3 + tailleAp=tailleAp+1 + ! pour programmation defensive + if (tailleAP > taille_table_temp) & + call XABORT("G2S : memory problem in routine CoupeCercle (1)") + tmpTabSegArc(tailleAp)%sa=sg + end do + tmpTabSegArc(tailleAp-2)%sa%dx=pt1x + tmpTabSegArc(tailleAp-2)%sa%dy=pt1y + tmpTabSegArc(tailleAp-1)%sa%x=pt1x + tmpTabSegArc(tailleAp-1)%sa%y=pt1y + tmpTabSegArc(tailleAp-1)%sa%dx=pt2x + tmpTabSegArc(tailleAp-1)%sa%dy=pt2y + tmpTabSegArc(tailleAp)%sa%x=pt2x + tmpTabSegArc(tailleAp)%sa%y=pt2y + tmpTabSegArc(tailleAp-2)%sa%mixg=ar%mixd + tmpTabSegArc(tailleAp-2)%sa%mixd=ar%mixd + tmpTabSegArc(tailleAp-1)%sa%mixg=ar%mixg + tmpTabSegArc(tailleAp-1)%sa%mixd=ar%mixg + tmpTabSegArc(tailleAp)%sa%mixg=ar%mixd + tmpTabSegArc(tailleAp)%sa%mixd=ar%mixd + ! elimination d'un eventuel segment nul + do k = 0,2 + tmpTabSegArc(tailleAp-k)%keep= .not. & + & ( (isEqual( tmpTabSegArc(tailleAp-k)%sa%x , & + & tmpTabSegArc(tailleAp-k)%sa%dx) ) .and. & + & (isEqual( tmpTabSegArc(tailleAp-k)%sa%y , & + & tmpTabSegArc(tailleAp-k)%sa%dy) ) ) + end do + angl1=calculeAngle(ar%x,ar%y,pt1x,pt1y) + angl2=calculeAngle(ar%x,ar%y,pt2x,pt2y) + !travail sur les arcs + if (ar%typ==tcer) then + !c'etait un cercle complet + if (isEqualAngl(angl1,angl2)) then !tangence + tailleAp=tailleAp+1 + ! pour programmation defensive + if (tailleAP > taille_table_temp) & + call XABORT("G2S : memory problem in routine CoupeCercle (2)") + tmpTabSegArc(tailleAp)%sa=ar + tmpTabSegArc(tailleAp)%keep=.true. + tmpTabSegArc(tailleAp)%sa%typ=tarc + tmpTabSegArc(tailleAp)%sa%a=angl1 + tmpTabSegArc(tailleAp)%sa%b=angl1 + !positionnement des sect* + if (estAGauche(sg%x,sg%y,sg%dx,sg%dy,ar%x,ar%y)) then + !cercle completement a gauche de sg + tmpTabSegArc(tailleAp)%sa%sectg=sg%sectg + tmpTabSegArc(tailleAp)%sa%sectd=sg%sectg + else + !cercle completement a droite de sg + tmpTabSegArc(tailleAp)%sa%sectg=sg%sectd + tmpTabSegArc(tailleAp)%sa%sectd=sg%sectd + end if + else !pas tangence + !un arc de chaque cote de sg (1\B0 a drt, 2\B0 a gch) + do k = 1,2 + tailleAp=tailleAp+1 + ! pour programmation defensive + if (tailleAP > taille_table_temp) & + call XABORT("G2S : memory problem in routine CoupeCercle (3)") + tmpTabSegArc(tailleAp)%sa=ar + tmpTabSegArc(tailleAp)%keep=.true. + tmpTabSegArc(tailleAp)%sa%typ=tarc + end do + tmpTabSegArc(tailleAp-1)%sa%a=angl1 + tmpTabSegArc(tailleAp-1)%sa%b=angl2 + tmpTabSegArc(tailleAp-1)%sa%sectg=sg%sectd + tmpTabSegArc(tailleAp-1)%sa%sectd=sg%sectd + tmpTabSegArc(tailleAp)%sa%a=angl2 + tmpTabSegArc(tailleAp)%sa%b=angl1 + tmpTabSegArc(tailleAp)%sa%sectg=sg%sectg + tmpTabSegArc(tailleAp)%sa%sectd=sg%sectg + end if + else !c'etait deja un arc de cercle + do k = 1,3 + tailleAp=tailleAp+1 + ! pour programmation defensive + if (tailleAP > taille_table_temp) & + call XABORT("G2S : memory problem in routine CoupeCercle (4)") + tmpTabSegArc(tailleAp)%sa=ar + end do + tmpTabSegArc(tailleAp-2)%sa%b=angl1 + !on test si on est bien dans le bon sens + if (isIn(pt2x,pt2y,tmpTabSegArc(tailleAp-2)%sa)==2) then + !on est a l'envers (ouverture a droite) + tmpTabSegArc(tailleAp-2)%sa%b=angl2 + tmpTabSegArc(tailleAp-1)%sa%a=angl2 + tmpTabSegArc(tailleAp-1)%sa%b=angl1 + tmpTabSegArc(tailleAp)%sa%a=angl1 + !ajustement des sect* + tmpTabSegArc(tailleAp-2)%sa%sectg=sg%sectd + tmpTabSegArc(tailleAp-2)%sa%sectd=sg%sectd + tmpTabSegArc(tailleAp-1)%sa%sectg=sg%sectg + tmpTabSegArc(tailleAp-1)%sa%sectd=sg%sectg + tmpTabSegArc(tailleAp)%sa%sectg=sg%sectd + tmpTabSegArc(tailleAp)%sa%sectd=sg%sectd + else !on est a l'endroit (ouverture a gauche) + tmpTabSegArc(tailleAp-1)%sa%a=angl1 + tmpTabSegArc(tailleAp-1)%sa%b=angl2 + tmpTabSegArc(tailleAp)%sa%a=angl2 + !ajustement des sect* + tmpTabSegArc(tailleAp-2)%sa%sectg=sg%sectg + tmpTabSegArc(tailleAp-2)%sa%sectd=sg%sectg + tmpTabSegArc(tailleAp-1)%sa%sectg=sg%sectd + tmpTabSegArc(tailleAp-1)%sa%sectd=sg%sectd + tmpTabSegArc(tailleAp)%sa%sectg=sg%sectg + tmpTabSegArc(tailleAp)%sa%sectd=sg%sectg + end if + do k = 0,2 + tmpTabSegArc(tailleAp-k)%keep=.not. & + & ( isEqualAngl( tmpTabSegArc(tailleAp-k)%sa%a , & + & tmpTabSegArc(tailleAp-k)%sa%b ) ) + end do + end if + i=0 + exit + else if (abs(nbPtInter)==1) then + !! un seul point d'intersection + ! CS-IV : on obtient 2 segments & 2 arcs + tmpTabSegArc(i)%keep=.false. + tmpTabSegArc(j)%keep=.false. + do k = 1,2 + tailleAp=tailleAp+1 + ! pour programmation defensive + if (tailleAP > taille_table_temp) & + call XABORT("G2S : memory problem in routine CoupeCercle (5)") + tmpTabSegArc(tailleAp)%sa=sg + end do + tmpTabSegArc(tailleAp-1)%sa%dx=pt1x + tmpTabSegArc(tailleAp-1)%sa%dy=pt1y + tmpTabSegArc(tailleAp)%sa%x=pt1x + tmpTabSegArc(tailleAp)%sa%y=pt1y + if (nbPtInter==1) then + !intersection en I (origne de sg a l'exterieur de ar) + tmpTabSegArc(tailleAp-1)%sa%mixg=ar%mixd + tmpTabSegArc(tailleAp-1)%sa%mixd=ar%mixd + tmpTabSegArc(tailleAp)%sa%mixg=ar%mixg + tmpTabSegArc(tailleAp)%sa%mixd=ar%mixg + else + !intersection en J (origne de sg a l'interieur de ar) + tmpTabSegArc(tailleAp-1)%sa%mixg=ar%mixg + tmpTabSegArc(tailleAp-1)%sa%mixd=ar%mixg + tmpTabSegArc(tailleAp)%sa%mixg=ar%mixd + tmpTabSegArc(tailleAp)%sa%mixd=ar%mixd + end if + do k = 0,1 + tmpTabSegArc(tailleAp-k)%keep=.not. & + & ( ( isEqual( tmpTabSegArc(tailleAp-k)%sa%x , & + & tmpTabSegArc(tailleAp-k)%sa%dx ) ) .and.& + & ( isEqual( tmpTabSegArc(tailleAp-k)%sa%y , & + & tmpTabSegArc(tailleAp-k)%sa%dy ) ) ) + end do + angl1=calculeAngle(ar%x,ar%y,pt1x,pt1y) + if (ar%typ==tcer) then + !ar etait un cercle + tailleAp=tailleAp+1 + ! pour programmation defensive + if (tailleAP > taille_table_temp) & + call XABORT("G2S : memory problem in routine CoupeCercle (6)") + tmpTabSegArc(tailleAp)%sa=ar + tmpTabSegArc(tailleAp)%sa%typ=tarc + tmpTabSegArc(tailleAp)%sa%a=angl1 + tmpTabSegArc(tailleAp)%sa%b=angl1 + tmpTabSegArc(tailleAp)%keep=.true. + !pas d'ajustement des sect*, car l'arc n'est ni d'un cote + !ni de l'autre + else + do k = 1,2 + tailleAp=tailleAp+1 + ! pour programmation defensive + if (tailleAP > taille_table_temp) & + call XABORT("G2S : memory problem in routine CoupeCercle (7)") + tmpTabSegArc(tailleAp)%sa=ar + end do + tmpTabSegArc(tailleAp-1)%sa%b=angl1 + tmpTabSegArc(tailleAp)%sa%a=angl1 + !ajustement des sect* + if (nbPtInter==1) then + !intersection en I (origne de sg a l'exterieur de ar) + tmpTabSegArc(tailleAp-1)%sa%sectg=sg%sectg + tmpTabSegArc(tailleAp-1)%sa%sectd=sg%sectg + tmpTabSegArc(tailleAp)%sa%sectg=sg%sectd + tmpTabSegArc(tailleAp)%sa%sectd=sg%sectd + else + !intersection en J (origne de sg a l'interieur de ar) + tmpTabSegArc(tailleAp-1)%sa%sectg=sg%sectd + tmpTabSegArc(tailleAp-1)%sa%sectd=sg%sectd + tmpTabSegArc(tailleAp)%sa%sectg=sg%sectg + tmpTabSegArc(tailleAp)%sa%sectd=sg%sectg + end if + do k = 0,1 + tmpTabSegArc(tailleAp-k)%keep=.not. & + & ( isEqualAngl( tmpTabSegArc(tailleAp-k)%sa%a , & + & tmpTabSegArc(tailleAp-k)%sa%b ) ) + end do + end if + i=0 + exit + end if + end do + if (i==tailleAv) exit + end do + if ((tailleAp==tailleAv) .and. (i==tailleAv)) exit + end do + + !on elimine les elements en dehors des limites de la cellule, et on remet le + !milieu exterieur a la cellule a fooMix + !Remarque : les elements tmpTabSegArc(1:nbSeg)%sa sont les segments + !initiaux paralleles aux bords du domaine. Ils peuvent etre a jeter + !(keep==.false.), mais ils servent tout de meme de reference. Pour savoir + !si ils sont au bord de la cellule, on teste si le milieu est fooMix. + !Si oui, on elimine tous les elements qui sont de ce cote. + if (typ==tRec .or. typ==tHex) then + do i = 1,nbSeg + sg = tmpTabSegArc(i)%sa + do j = 1,tailleAp + ar = tmpTabSegArc(j)%sa + if (ar%typ==tseg) then + if (.not. & + (estColi(sg%dx-sg%x,sg%dy-sg%y,ar%dx-ar%x,ar%dy-ar%y) & + .and. pointsAlignes(sg%x,sg%y,sg%dx,sg%dy,ar%x,ar%y)) & + ) cycle + if (sg%mixd==fooMix) then + tmpTabSegArc(j)%sa%mixd=fooMix + else if (sg%mixg==fooMix) then + tmpTabSegArc(j)%sa%mixg=fooMix + end if + cycle + end if + if ((j==i) .or. (.not. tmpTabSegArc(j)%keep)) cycle + if (ar%b>ar%a) then + angl1=(ar%b+ar%a)*0.5d0 + else + angl1=(ar%b+ar%a)*0.5d0+pi_c + end if + !point milieu de l'arc + midx=ar%x+ar%r*cos(angl1) + midy=ar%y+ar%r*sin(angl1) + !sinus de l'angle (OE,OM) + tmp = sin( calculeAngle(sg%x,sg%y,midx,midy) - & + & calculeAngle(sg%x,sg%y,sg%dx,sg%dy) ) + if (sg%mixd==fooMix) then !on garde a gauche + tmpTabSegArc(j)%keep=(tmp>0.).or.(isEqualAngl(ar%a,ar%b).and. & + & estAGauche(sg%x,sg%y,sg%dx,sg%dy,ar%x,ar%y)) + else if (sg%mixg==fooMix) then !on garde a droite + tmpTabSegArc(j)%keep=(tmp<0.).or.(isEqualAngl(ar%a,ar%b).and. & + & estADroite(sg%x,sg%y,sg%dx,sg%dy,ar%x,ar%y)) + end if + end do + end do + else + call XABORT("G2S : type of geometrie not supported") + end if + + !elimination des segments nuls eventuellement restants + do i = 1,tailleAp + sg = tmpTabSegArc(i)%sa + if (sg%typ==tseg) tmpTabSegArc(i)%keep=tmpTabSegArc(i)%keep .and. & + .not.(isEqual(tmpTabSegArc(i)%sa%x,tmpTabSegArc(i)%sa%dx) .and. & + isEqual(tmpTabSegArc(i)%sa%y,tmpTabSegArc(i)%sa%dy)) + end do + + !on recupere dans le tableau general les elements restants + do i = 1,tailleAp + if (.not. tmpTabSegArc(i)%keep) cycle + szSa = szSa+1 + tabSegArc(szSa) = tmpTabSegArc(i)%sa + end do + + !on nettoie le tableau temporaire + deallocate(tmpTabSegArc) + end subroutine coupeCercle + + subroutine splitSegsForSect(indDeb,szSA) + integer,intent(in) :: indDeb + integer,intent(inout) :: szSA + + type(t_segArc) :: sgi,sgj + integer :: i,j + + ! pour programmation defensive + integer :: taille_table_tabSegArc + + !! permet de spliter les segments en bordure de domaine, + !! losqu'ils sont interceptes par les segments delimitants + !! la sectorisation. Si on a intersection, c'est toujours a + !! l'interieur d'un segment de bordure, et au bout d'un segment + !! de secteur. -->^-----> <-----^<-- + !! Dans ce cas, on split ainsi: (1) i | szSA ou: (2) szSA | i + + ! pour programmation defensive + taille_table_tabSegArc = size(tabSegArc) + + i = indDeb + do + i = i + 1 + if (i>szSA) exit + sgi=tabSegArc(i) + if (sgi%typ/=tseg) cycle + do j = indDeb+1,szSA + if (j==i) cycle + sgj=tabSegArc(j) + if (sgj%typ/=tseg) cycle + if (PointsAlignes(sgi%x,sgi%y,sgi%dx,sgi%dy,sgj%dx,sgj%dy).and.& + (isIn(sgj%dx,sgj%dy,sgi)==2).and. & + .not.PointsAlignes(sgi%x,sgi%y,sgi%dx,sgi%dy,sgj%x,sgj%y)) then + szSA=szSA+1 + ! pour programmation defensive + if (szSA > taille_table_tabSegArc) & + call XABORT("G2S : memory problem in routine splitSegsForSect") + tabSegArc(szSA) = sgi + tabSegArc(i)%dx = sgj%dx ; tabSegArc(i)%dy = sgj%dy + tabSegArc(szSA)%x = sgj%dx ; tabSegArc(szSA)%y = sgj%dy + + if (estAGaucheStrict(sgj%x,sgj%y,sgj%dx,sgj%dy,sgi%x,sgi%y)) then + !! cas (1) + tabSegArc(i)%sectg = sgj%sectg + tabSegArc(i)%sectd = sgj%sectg + tabSegArc(szSA)%sectg = sgj%sectd + tabSegArc(szSA)%sectd = sgj%sectd + else + !! cas (2) + tabSegArc(i)%sectg = sgj%sectd + tabSegArc(i)%sectd = sgj%sectd + tabSegArc(szSA)%sectg = sgj%sectg + tabSegArc(szSA)%sectd = sgj%sectg + end if + sgi = tabSegArc(i) + end if + end do + end do + end subroutine splitSegsForSect + + subroutine majSectori(indDeb,szSA,sectori,typGeo,cx,cy) + double precision, parameter :: PI = 3.141592653589793d0 + integer,intent(in) :: indDeb,szSA,sectori,typGeo + double precision,intent(in) :: cx,cy + !met a jour les secteurs pour les elements + + double precision :: ao,ae !angles origine et extremite + integer :: i,j,nbSect,oIn,eIn + logical :: goodAngles + double precision,dimension(9) :: limit + + if ((typGeo/=tRec).and.(typGeo/=tHex)) & + call XABORT("G2S: internal error with typGeo in subroutine majSectori") + !creation des zones angulaires + nbSect = 0 + select case(sectori) + case(S_not) + return !rien a faire + case(S_X_tot) + if (typGeo == tRec) then + nbSect = 4 + limit(1) = pi_2_c*5.d-1 ; limit(2) = pi_2_c*1.5d0 + limit(3) = -limit(2) ; limit(4) = -limit(1) + limit(5) = limit(1) + else + nbSect = 6 + limit(1) = 0.d0 ; limit(2) = pi_3_c ; limit(3) = pi_3_c*2.d0 + limit(4) = pi_c ; limit(5) = -limit(3) ; limit(6) = -limit(2) + limit(7) = limit(1) + end if + case(S_T_tot) + nbSect = 4 + limit(1) = 0.d0 ; limit(2) = pi_2_c + limit(3) = pi_c ; limit(4) = -limit(2) + limit(5) = limit(1) + case(S_TX_tot) + nbSect = 8 + limit(1) = 0.d0 ; limit(2) = pi_2_c*5.d-1 + limit(3) = pi_2_c ; limit(4) = pi_2_c*1.5d0 + limit(5) = pi_c ; limit(6) = -limit(4) + limit(7) = -limit(3) ; limit(8) = -limit(2) + limit(9) = limit(1) + case(S_TXS_tot) + nbsect = 8 + limit(1) = PI/8. + do i=1, 7 + limit(i+1) = limit(i) + PI/4. + enddo + limit(9) = limit(1) + case(S_WM_tot) + nbsect = 8 + limit(1) = PI/8. + do i=1, 7 + limit(i+1) = limit(i) + PI/4. + enddo + limit(9) = limit(1) + case default + call XABORT("G2S: internal error with sectori in subroutine majSectori") + end select + !traitement des elements + do i = indDeb+1,szSA + if (tabSegArc(i)%typ == tcer) cycle !on ne s'interesse pas aux cercles + !on recupere les angles des bouts + goodAngles = giveExtremalsAngles(tabSegArc(i),cx,cy,ao,ae) + if (.not.goodAngles) cycle !une des extremites est le centre + ! => on ne s'en occupe pas + do j = 1,nbSect + !boucle sur les secteurs + oIn = isAngleInInterval(ao,limit(j),limit(j+1)) + eIn = isAngleInInterval(ae,limit(j),limit(j+1)) + if ((oIn==0) .or. (eIn==0)) then + !pas dans le secteur + cycle !on passe au secteur suivant + else if ((oIn==2) .or. (eIn==2)) then + !on est completement dans le secteur + tabSegArc(i)%sectg = j + tabSegArc(i)%sectd = j + exit !on sort de la boucle en j + else if (oIn/=eIn) then + !element occupant le secteur angulaire total => idem cas precedent + tabSegArc(i)%sectg = j + tabSegArc(i)%sectd = j + exit !on sort de la boucle en j + else + !les 2 extremites sont sur le meme separateur + ! => on ne s'en occupe pas + exit !on sort de la boucle en j + end if + end do + end do + end subroutine majSectori + + subroutine addSegsAndClean(sizeSA) + integer,intent(inout) :: sizeSA + + integer :: i,j,sizeTmp + integer :: oj,ej !test l'appartenance a sgi des bouts de sgj + type(t_segArc) :: sgi,sgj + type(segArcArrayBis),dimension(:),allocatable :: tmpTab + + ! pour programmation defensive + integer :: taille_table_temp, taille_table_tabSegArc + + ! copie dans un tableau temporaire des segments et nettoyage du tableau + ! global + ! pour programmation defensive + taille_table_temp = sizeSA*10 + taille_table_tabSegArc = size(tabSegArc) + + allocate(tmpTab(taille_table_temp),stat=alloc_ok) + if (alloc_ok /= 0) call XABORT("G2S: addSegsAndClean(1) => allocation pb") + tmpTab(1:sizeSA)%sa=tabSegArc(1:sizeSA) + tmpTab(1:sizeSA)%keep=.true. + + sizeTmp=sizeSA + i=0 + do + i = i+1 + if (i>sizeTmp) exit + if (.not. tmpTab(i)%keep) cycle + if (tmpTab(i)%sa%typ/=tseg) cycle + sgi=tmpTab(i)%sa !c'est bien un segment a garder pour le moment + j = 0 + do + j = j+1 + if (j>sizeTmp) exit + if (j==i) cycle + if (.not. tmpTab(j)%keep) cycle + if (tmpTab(j)%sa%typ/=tseg) cycle + sgj=tmpTab(j)%sa + if (.not. estColineaire(sgi,sgj)) cycle + if (.not. pointsAlignes(sgi%x,sgi%y,sgi%dx,sgi%dy,sgj%x,sgj%y)) cycle + !on renverse le sens de sgj si besoin + if (.not. isSameWay(sgi,sgj)) sgj=turnBackSide(tmpTab(j)%sa) + oj=isIn(sgj%x,sgj%y,sgi) ; ej=isIn(sgj%dx,sgj%dy,sgi) + select case(ej) !seuls cas 0,2,3 utiles pour ej + case(0) !seuls cas 0,1,2 utiles pour oj + select case(oj) + case(0) !si isIn(sgi%x,sgi%y,sgj)/=2 rien sinon, sgi dans sgj + if (isIn(sgi%x,sgi%y,sgj)/=2) cycle + call adjustMix(tmpTab(i)%sa,sgj) + sizeTmp=sizeTmp+1 + ! pour programmation defensive + if (sizeTmp > taille_table_temp) & + call XABORT("G2S : memory problem in addSegsAndClean (1)") + tmpTab(sizeTmp)%keep=.true. ; tmpTab(sizeTmp)%sa=sgj + tmpTab(j)%sa%dx=sgi%x ; tmpTab(j)%sa%dy=sgi%y + tmpTab(sizeTmp)%sa%x=sgi%dx ; tmpTab(sizeTmp)%sa%y=sgi%dy + case(1) !origines confondues et sgi dans sgj + call adjustMix(tmpTab(i)%sa,sgj) + tmpTab(j)%sa%x=sgi%dx ; tmpTab(j)%sa%y=sgi%dy + case(2) !sgi et sgj s'intersectent reellement (sgj au dessus) + sizeTmp=sizeTmp+1 + ! pour programmation defensive + if (sizeTmp > taille_table_temp) & + call XABORT("G2S : memory problem in addSegsAndClean (2)") + tmpTab(sizeTmp)%keep=.true. ; tmpTab(sizeTmp)%sa=sgi + tmpTab(i)%sa%dx=sgj%x ; tmpTab(i)%sa%dy=sgj%y + tmpTab(sizeTmp)%sa%x=sgj%x ; tmpTab(sizeTmp)%sa%y=sgj%y + tmpTab(sizeTmp)%sa%dx=sgi%dx ; tmpTab(sizeTmp)%sa%dy=sgi%dy + call adjustMix(tmpTab(sizeTmp)%sa,sgj) + tmpTab(j)%sa%x=sgi%dx ; tmpTab(j)%sa%y=sgi%dy + end select + case(2) !seuls cas 0,1,2 utiles pour oj + select case(oj) + case(0) !sgi et sgj s'intersectent reellement (sgj en dessous) + sizeTmp=sizeTmp+1 + ! pour programmation defensive + if (sizeTmp > taille_table_temp) & + call XABORT("G2S : memory problem in addSegsAndClean (3)") + tmpTab(sizeTmp)%keep=.true. ; tmpTab(sizeTmp)%sa=sgi + tmpTab(i)%sa%x=sgj%dx ; tmpTab(i)%sa%y=sgj%dy + tmpTab(sizeTmp)%sa%x=sgi%x ; tmpTab(sizeTmp)%sa%y=sgi%y + tmpTab(sizeTmp)%sa%dx=sgj%dx ; tmpTab(sizeTmp)%sa%dy=sgj%dy + call adjustMix(tmpTab(sizeTmp)%sa,sgj) + tmpTab(j)%sa%dx=sgi%x ; tmpTab(j)%sa%dy=sgi%y + case(1) !origines confondues et sgj dans sgi + call adjustMix(tmpTab(j)%sa,sgi) + tmpTab(i)%sa%x=sgj%dx ; tmpTab(i)%sa%y=sgj%dy + case(2) !sgj dans sgi + call adjustMix(tmpTab(j)%sa,sgi) + sizeTmp=sizeTmp+1 + ! pour programmation defensive + if (sizeTmp > taille_table_temp) & + call XABORT("G2S : memory problem in addSegsAndClean (4)") + tmpTab(sizeTmp)%keep=.true. ; tmpTab(sizeTmp)%sa=sgi + tmpTab(i)%sa%dx=sgj%x ; tmpTab(i)%sa%dy=sgj%y + tmpTab(sizeTmp)%sa%x=sgj%dx ; tmpTab(sizeTmp)%sa%y=sgj%dy + end select + case(3) !seuls cas 0,1,2 utiles pour oj + select case(oj) + case(0) !extremites confondues et sgi dans sgj + call adjustMix(tmpTab(i)%sa,sgj) + tmpTab(j)%sa%dx=sgi%x ; tmpTab(j)%sa%dy=sgi%y + case(1) !sgi et sgj confondus + call adjustMix(tmpTab(i)%sa,sgj) + tmpTab(j)%keep=.false. + case(2) !extremites confondues et sgj dans sgi + call adjustMix(tmpTab(j)%sa,sgi) + tmpTab(i)%sa%dx=sgj%x ; tmpTab(i)%sa%dy=sgj%y + end select + end select + end do + end do + + do i = 1,sizeTmp + if (tmpTab(i)%keep) then + if (tmpTab(i)%sa%typ==tseg) then + if (isEqual(tmpTab(i)%sa%x,tmpTab(i)%sa%dx).and. & + isEqual(tmpTab(i)%sa%y,tmpTab(i)%sa%dy)) tmpTab(i)%keep=.false. + end if + end if + end do + + !recopie dans le tableau global des elements a conserver + sizeSA=0 + do i = 1,sizeTmp + if (tmpTab(i)%keep) then + sizeSA=sizeSA+1 + ! pour programmation defensive + if (sizeSA > taille_table_tabSegArc) & + call XABORT("G2S : memory problem in addSegsAndClean (5)") + tabSegArc(sizeSA) = tmpTab(i)%sa + end if + end do + deallocate(tmpTab) + + end subroutine addSegsAndClean + + subroutine cutClusters(nbRing,nbClus,szSa) + integer,intent(in) :: nbRing,nbClus + integer,intent(inout) :: szSa + + integer :: i,j,szTmp,nbInter + double precision :: aClus,bClus,aRing,bRing + logical :: revert,eqA,eqB + type(t_segArc) :: ring,clus + type(segArcArrayTer),dimension(:),allocatable :: tmpTabAr + + ! pour programmation defensive + integer :: taille_table_temp + + taille_table_temp = nbRing*nbClus*4 !ca me semble suffisant (note de l'auteur ) + allocate(tmpTabAr(taille_table_temp),stat=alloc_ok) + if (alloc_ok /= 0) call XABORT("G2S: cutCluster(1) => allocation pb") + szTmp = 0 + + !initialisation du tableau temporaire + !recopie des cluster et des anneaux dans l'ordre inverse de leur + !creation => du plus grand vers le plus petit + do i = 1,nbClus + szTmp = szTmp + 1 + tmpTabAr(szTmp)%keep = .true. + tmpTabAr(szTmp)%cl = .true. + tmpTabAr(szTmp)%sa = tabSegArc(szSa) + szSa = szSa - 1 + end do + do i = 1,nbRing + szTmp = szTmp + 1 + tmpTabAr(szTmp)%keep = .true. + tmpTabAr(szTmp)%cl = .false. + tmpTabAr(szTmp)%sa = tabSegArc(szSa) + szSa = szSa - 1 + end do + + i=0 + do + i = i+1 + if (i>szTmp) exit + if (.not. (tmpTabAr(i)%keep .and. tmpTabAr(i)%cl)) cycle + clus = tmpTabAr(i)%sa + j = 0 + do + j = j+1 + if (j>szTmp) exit + if ((.not. tmpTabAr(j)%keep) .or. tmpTabAr(j)%cl) cycle + ring = tmpTabAr(j)%sa + nbInter = interArcArc(clus,ring,aClus,bClus,aRing,bRing,revert) + select case(nbInter) + case(2) + if (clus%typ==tcer) then + !demi cercle interieur + tmpTabAr(i)%sa%typ = tarc + tmpTabAr(i)%sa%mixd = ring%mixg + tmpTabAr(i)%sa%a = aClus + tmpTabAr(i)%sa%b = bClus + clus = tmpTabAr(i)%sa + !demi cercle exterieur + szTmp = szTmp + 1 + ! programmation defensive + if (sztmp > taille_table_temp) & + call XABORT("G2S : memory problem in routine cutClusters (1)") + tmpTabAr(szTmp)%keep = .true. + tmpTabAr(szTmp)%cl = .true. + tmpTabAr(szTmp)%sa = clus + tmpTabAr(szTmp)%sa%mixd = ring%mixd + tmpTabAr(szTmp)%sa%a = bClus + tmpTabAr(szTmp)%sa%b = aClus + else + eqA = isEqualAngl(clus%a,aClus) + eqB = isEqualAngl(clus%b,bClus) + !debut + if (.not.eqA) then + szTmp = szTmp + 1 + ! programmation defensive + if (sztmp > taille_table_temp) & + call XABORT("G2S : memory problem in routine cutClusters (2)") + tmpTabAr(szTmp)%keep = .true. + tmpTabAr(szTmp)%cl = .true. + tmpTabAr(szTmp)%sa = clus + tmpTabAr(szTmp)%sa%mixd = ring%mixd + tmpTabAr(szTmp)%sa%b = aClus + end if + !fin + if (.not.eqB) then + szTmp = szTmp + 1 + ! programmation defensive + if (sztmp > taille_table_temp) & + call XABORT("G2S : memory problem in routine cutClusters (3)") + tmpTabAr(szTmp)%keep = .true. + tmpTabAr(szTmp)%cl = .true. + tmpTabAr(szTmp)%sa = clus + tmpTabAr(szTmp)%sa%mixd = ring%mixd + tmpTabAr(szTmp)%sa%a = bClus + end if + !milieu + if ((.not.eqA).or.(.not.eqB)) then + tmpTabAr(i)%sa%a = aClus + tmpTabAr(i)%sa%b = bClus + tmpTabAr(i)%sa%mixd = ring%mixg + clus = tmpTabAr(i)%sa + end if + end if + if (ring%typ==tcer) then + tmpTabAr(j)%sa%typ = tarc + tmpTabAr(j)%sa%a = bRing + tmpTabAr(j)%sa%b = aRing + ring = tmpTabAr(j)%sa + else + tmpTabAr(j)%keep = .false. + eqA = isEqualAngl(ring%a,aRing) + eqB = isEqualAngl(ring%b,bRing) + !premier bout d'arc + if (.not.eqA) then + szTmp = szTmp + 1 + ! programmation defensive + if (sztmp > taille_table_temp) & + call XABORT("G2S : memory problem in routine cutClusters (4)") + tmpTabAr(szTmp)%keep = .true. + tmpTabAr(szTmp)%cl = .false. + tmpTabAr(szTmp)%sa = ring + tmpTabAr(szTmp)%sa%b = aRing + end if + !second bout d'arc + if (.not.eqB) then + szTmp = szTmp + 1 + ! programmation defensive + if (sztmp > taille_table_temp) & + call XABORT("G2S : memory problem in routine cutClusters (5)") + tmpTabAr(szTmp)%keep = .true. + tmpTabAr(szTmp)%cl = .false. + tmpTabAr(szTmp)%sa = ring + tmpTabAr(szTmp)%sa%a = bRing + end if + end if + case(1) + !a priori, tel que l'algo est fait, le cas ne se produit que si + !le cluster est tangent a un anneau + !travail sur l'anneau + if (ring%typ==tcer) then + tmpTabAr(j)%sa%typ = tarc + tmpTabAr(j)%sa%a = aRing + tmpTabAr(j)%sa%b = aRing + ring = tmpTabAr(j)%sa + else + tmpTabAr(j)%keep = .false. + eqA = isEqualAngl(ring%a,aRing) + eqB = isEqualAngl(ring%b,aRing) + !premier bout d'arc + if (.not.eqA) then + szTmp = szTmp + 1 + ! programmation defensive + if (sztmp > taille_table_temp) & + call XABORT("G2S : memory problem in routine cutClusters (6)") + tmpTabAr(szTmp)%keep = .true. + tmpTabAr(szTmp)%cl = .false. + tmpTabAr(szTmp)%sa = ring + tmpTabAr(szTmp)%sa%b = aRing + end if + !second bout d'arc + if (.not.eqB) then + szTmp = szTmp + 1 + ! programmation defensive + if (sztmp > taille_table_temp) & + call XABORT("G2S : memory problem in routine cutClusters (7)") + tmpTabAr(szTmp)%keep = .true. + tmpTabAr(szTmp)%cl = .false. + tmpTabAr(szTmp)%sa = ring + tmpTabAr(szTmp)%sa%a = aRing + end if + end if + !travail sur le cluster + if (clus%typ==tcer) then + tmpTabAr(i)%sa%typ = tarc + tmpTabAr(i)%sa%a = aClus + tmpTabAr(i)%sa%b = aClus + clus = tmpTabAr(i)%sa + if (revert) then !cluster a l'exterieur de l'anneau + tmpTabAr(i)%sa%mixd = ring%mixd + else !cluster a l'interieur de l'anneau + tmpTabAr(i)%sa%mixd = ring%mixg + end if + else ! le cluster a deja ete coupe => tangence exterieur + ! et derniere utilisation + eqA = isEqualAngl(clus%a,aClus) + eqB = isEqualAngl(clus%b,aClus) + !debut + if (.not.eqA) then + szTmp = szTmp + 1 + ! programmation defensive + if (sztmp > taille_table_temp) & + call XABORT("G2S : memory problem in routine cutClusters (8)") + tmpTabAr(szTmp)%keep = .true. + tmpTabAr(szTmp)%cl = .true. + tmpTabAr(szTmp)%sa = clus + tmpTabAr(szTmp)%sa%mixd = ring%mixd + tmpTabAr(szTmp)%sa%b = aClus + end if + !fin + if (.not.eqB) then + szTmp = szTmp + 1 + ! programmation defensive + if (sztmp > taille_table_temp) & + call XABORT("G2S : memory problem in routine cutClusters (9)") + tmpTabAr(szTmp)%sa%a = aClus + tmpTabAr(szTmp)%sa = clus + tmpTabAr(szTmp)%sa%mixd = ring%mixd + tmpTabAr(szTmp)%sa%a = aClus + end if + !milieu + if ((.not.eqA).or.(.not.eqB)) then + tmpTabAr(i)%keep = .false. + i = 0 + end if + end if + + end select + end do + end do + !recopie des resultats + do i = 1,szTmp + if (.not. tmpTabAr(i)%keep) cycle + szSa = szSa + 1 + tabSegArc(szSa) = tmpTabAr(i)%sa + end do + deallocate(tmpTabAr) + end subroutine cutClusters + + logical function segWithSameCoord(S1,S2,n) + type(t_segArc), intent(in) :: S1, S2 + integer, intent(out) :: n + + segWithSameCoord = .false. ; n=0 + if (isEqualConst(S1%x,S2%x)) then + if (isEqualConst(S1%dx,S2%dx)) then + if (isEqualConst(S1%y,S2%y)) then + if (isEqualConst(S1%dy,S2%dy)) then + segWithSameCoord = .true. ; n=1 + endif + endif + endif + elseif (isEqualConst(S1%x,S2%dx)) then + if (isEqualConst(S1%dx,S2%x)) then + if (isEqualConst(S1%y,S2%dy)) then + if (isEqualConst(S1%dy,S2%y)) then + segWithSameCoord = .true. ; n=-1 + endif + endif + endif + endif + end function segWithSameCoord + + subroutine PrintTabSegArc(szSA) + integer, intent(in) :: szSA + type(t_segArc) :: sa + integer :: i + + write(*,10) szSA + + do i = 1, szSA + sa = tabSegArc(i) + if (sa%typ == tseg) then + write(*,20) i, sa%x, sa%y, sa%dx, sa%dy + elseif (sa%typ == tarc) then + write(*,30) i, sa%x, sa%y, sa%r, sa%a, sa%b + elseif (sa%typ == tcer) then + write(*,35) i, sa%x, sa%y, sa%r + else + write(*,38) i, sa%typ, sa%x, sa%y + endif + write(*,40) sa%sectg, sa%sectd + write(*,50) sa%mixg, sa%mixd + write(*,60) sa%nodeg, sa%noded + write(*,70) sa%indcellpg, sa%indcellpd + write(*,80) sa%neutronicMixg,sa%neutronicMixd + enddo + +10 format("Number of SegArc :", i4) +20 format("N. SegArc ", i6," segment type : ",/, & + "|-> origin/extrem : (", f7.4, ";", f7.4,")/(", f7.4, ";", f7.4,")") +30 format("N. SegArc ", i6," arc type:",/, & + "|-> center/radius/angles : (", f7.4,";",f7.4,")/", f7.4,"/",f7.4,";", f7.4) +35 format("N. SegArc ", i6," circle type :",/, & + "|-> center/radius : (", f7.4,";",f7.4,")/", f7.4) +38 format("N. SegArc ", i6," unknown type :",/, & + "|-> type/origin/ : (", i6,"/",f7.4,";",f7.4,")") +40 format( "|-> sectg sectd : ", i6,2x,i6) +50 format( "|-> mixg mixd : ", i6,2x,i6) +60 format( "|-> nodeg noded : ", i6,2x,i6) +70 format( "|-> IndCellPg IndCellPd : ", i6,2x,i6) +80 format( "|-> neutronicMixg neutronicMixd : ", i6,2x,i6) + end subroutine PrintTabSegArc + + subroutine PrintSegArc1(i) + integer, intent(in) ::i + type(t_segArc) :: sa + + sa = tabSegArc(i) + if (sa%typ == tseg) then + write(*,20) i, sa%x, sa%y, sa%dx, sa%dy + elseif (sa%typ == tarc) then + write(*,30) i, sa%x, sa%y, sa%r, sa%a, sa%b + elseif (sa%typ == tcer) then + write(*,35) i, sa%x, sa%y, sa%r + else + write(*,38) i, sa%typ, sa%x, sa%y + endif + write(*,40) sa%sectg, sa%sectd + write(*,50) sa%mixg, sa%mixd + write(*,60) sa%nodeg, sa%noded + write(*,70) sa%indcellpg, sa%indcellpd + write(*,80) sa%neutronicMixg,sa%neutronicMixd + +20 format("N. SegArc ", i6," segment type : ",/, & + "|-> origin/extrem : (", f7.4, ";", f7.4,")/(", f7.4, ";", f7.4,")") +30 format("N. SegArc ", i6," arc type:",/, & + "|-> center/radius/angles : (", f7.4,";",f7.4,")/", f7.4,"/",f7.4,";", f7.4) +35 format("N. SegArc ", i6," circle type :",/, & + "|-> center/radius : (", f7.4,";",f7.4,")/", f7.4) +38 format("N. SegArc ", i6," unknown type :",/, & + "|-> type/origin/ : (", i6,"/",f7.4,";",f7.4,")") +40 format( "|-> sectg sectd : ", i6,2x,i6) +50 format( "|-> mixg mixd : ", i6,2x,i6) +60 format( "|-> nodeg noded : ", i6,2x,i6) +70 format( "|-> IndCellPg IndCellPd : ", i6,2x,i6) +80 format( "|-> neutronicMixg neutronicMixd : ", i6,2x,i6) + + end subroutine PrintSegArc1 + + subroutine PrintSegArc2(sa) + type(t_segArc), intent(in) :: sa + + if (sa%typ == tseg) then + write(*,20) sa%x, sa%y, sa%dx, sa%dy + elseif (sa%typ == tarc) then + write(*,30) sa%x, sa%y, sa%r, sa%a, sa%b + elseif (sa%typ == tcer) then + write(*,35) sa%x, sa%y, sa%r + else + write(*,38) sa%typ, sa%x, sa%y + endif + write(*,40) sa%sectg, sa%sectd + write(*,50) sa%mixg, sa%mixd + write(*,60) sa%nodeg, sa%noded + write(*,70) sa%indcellpg, sa%indcellpd + write(*,80) sa%neutronicMixg,sa%neutronicMixd + +20 format(" Segment type : ",/, & + "|-> origin/extrem : (", f7.4, ";", f7.4,")/(", f7.4, ";", f7.4,")") +30 format(" Arc type:",/, & + "|-> center/radius/angles : (", f7.4,";",f7.4,")/", f7.4,"/",f7.4,";", f7.4) +35 format("Circle type :",/, & + "|-> center/radius : (", f7.4,";",f7.4,")/", f7.4) +38 format("unknown type :",/, & + "|-> type/origin/ : (", i6,"/",f7.4,";",f7.4,")") +40 format( "|-> sectg sectd : ", i6,2x,i6) +50 format( "|-> mixg mixd : ", i6,2x,i6) +60 format( "|-> nodeg noded : ", i6,2x,i6) +70 format( "|-> IndCellPg IndCellPd : ", i6,2x,i6) +80 format( "|-> neutronicMixg neutronicMixd : ", i6,2x,i6) + + end subroutine PrintSegArc2 + + + +end module segArc |
