diff options
Diffstat (limited to 'Dragon/src/g2s_pretraitement.f90')
| -rw-r--r-- | Dragon/src/g2s_pretraitement.f90 | 2243 |
1 files changed, 2243 insertions, 0 deletions
diff --git a/Dragon/src/g2s_pretraitement.f90 b/Dragon/src/g2s_pretraitement.f90 new file mode 100644 index 0000000..baf20ad --- /dev/null +++ b/Dragon/src/g2s_pretraitement.f90 @@ -0,0 +1,2243 @@ +! +!----------------------------------------------------------------------- +! +!Purpose: +! Preprocessing of geometric data recovered from a geometry LCM data +! structure. +! +!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: +! Ce fichier regroupe toutes les actions effectuees en amont du code, pour +! verifier et completer le jeux de donnees geometriques. Il utilise de maniere +! intensive l'api de PyLCM. +! Les fonctions de ce fichier ont ete initialement developpees en python, puis +! traduite en fortran90. C'est pourquoi la forme des algorithmes peut etre +! parfois deroutante... +! \\\\ +! Le module pretraitement definit quelques constantes, dont en particulier la +! precision admise en entree du code (pour la coherence des donnees). +! De plus, les matrices "composeRotRec" et "composeRotTri" permettent +! d'effectuer la composition de deux transformations definies selon le mode +! Dragon. +! \\\\ +! Le seul pretraitement qui soit reellement delicat, est celui qui correspond +! a une geometrie de type gigogne rectangulaire. Il est effectue par la routine +! "creerEtChargerNewDataRec", et est documente dans le source de cette routine. +! +!----------------------------------------------------------------------- +! +module pretraitement + use boundcond + use cast + use celluleBase + use cellulePlaced + use constType + use GANLIB + + implicit none + + real,parameter :: geomPrec = 1.e-4 + real,parameter :: sqrt_3f = 1.732050807568 + + !composeRotXXX(t1,t2)=t2ot1 + integer,dimension(8,8),parameter :: composeRotRec = & + & reshape((/1,2,3,4,5,6,7,8, & + & 2,3,4,1,8,5,6,7, & + & 3,4,1,2,7,8,5,6, & + & 4,1,2,3,6,7,8,5, & + & 5,6,7,8,1,2,3,4, & + & 6,7,8,5,4,1,2,3, & + & 7,8,5,6,3,4,1,2, & + & 8,5,6,7,2,3,4,1/) , (/8,8/)) + + integer,dimension(12,12),parameter :: composeRotTri = & + & reshape((/ 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12, & + & 2, 3, 4, 5, 6, 1, 8, 9,10,11,12, 7, & + & 3, 4, 5, 6, 1, 2, 9,10,11,12, 7, 8, & + & 4, 5, 6, 1, 2, 3,10,11,12, 7, 8, 9, & + & 5, 6, 1, 2, 3, 4,11,12, 7, 8, 9,10, & + & 6, 1, 2, 3, 4, 5,12, 7, 8, 9,10,11, & + & 7,12,11,10, 9, 8, 1, 6, 5, 4, 3, 2, & + & 8, 7,12,11,10, 9, 2, 1, 6, 5, 4, 3, & + & 9, 8, 7,12,11,10, 3, 2, 1, 6, 5, 4, & + & 10, 9, 8, 7,12,11, 4, 3, 2, 1, 6, 5, & + & 11,10, 9, 8, 7,12, 5, 4, 3, 2, 1, 6, & + & 12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1/) , (/12,12/)) + +contains + subroutine prepareData(geoIp,sizeB,sizeP,lgMaxGig) + type(c_ptr),intent(in):: geoIp + integer,intent(inout) :: sizeB,sizeP,lgMaxGig + + integer,dimension(40) :: st + type(c_ptr) :: ip + integer :: nbNewMix,i + + !premier completion de la structure geometrique pour transformer + !les constructions melangeant MIX et CELL, en des constructions + !uniformes de ce point de vue + + nbNewMix = 0 + call separateMixAndCell(geoIp,nbNewMix) + + ip = geoIp + !creation des cellules de bases + call buildCellsBase(ip,sizeB,'/ ') + ip = geoIp + + call LCMGET(ip,'STATE-VECTOR',st) + select case(st(1)) + case(G_Car2d,G_Carcel) + geomTyp = RecTyp + call creerEtChargerNewDataRec(ip,sizeB,sizeP) + case(G_Hex,G_Hexcel) + geomTyp = HexTyp + call creerEtChargerNewDataHex(ip,sizeB,sizeP) + case(G_Tri) + geomTyp = TriaTyp + call creerEtChargerNewDataTri(ip,sizeB,sizeP) + case(G_Tube) + geomTyp = TubeTyp + if (sizeB/=1) call XABORT("G2S: more than one cellule in a cylindrical& + & geometry") + sizeP = 1 + tabCellulePlaced(1)%indice = 1 + tabCellulePlaced(1)%xcenter = 0.d0 + tabCellulePlaced(1)%ycenter = 0.d0 + tabCellulePlaced(1)%turn = 1 + allocate (tabCellulePlaced(1)%gig(1),stat=alloc_ok) + if (alloc_ok /= 0) call XABORT("G2S: prepareData(2) => allocation pb") + tabCellulePlaced(1)%gig = 1 + allocate (tabCellulePlaced(1)%mrg(1),stat=alloc_ok) + if (alloc_ok /= 0) call XABORT("G2S: prepareData(3) => allocation pb") + tabCellulePlaced(1)%mrg = 1 + case default + call XABORT("G2S: Type of geometry not supported") + end select + + lgMaxGig = 0 + do i = 1,sizeP + lgMaxGig = max(lgMaxGig,size(tabCellulePlaced(i)%gig)) + end do + end subroutine prepareData + + recursive subroutine separateMixAndCell(ipIn,nbNewMix) + type(c_ptr),intent(in):: ipIn + integer,intent(inout) :: nbNewMix + + type(c_ptr) :: ip,jp + integer :: i,lgC,lg,ty,indOfCellToAdd,mixToPut,nbCellToAdd,lgC2 + character*12 :: newCellName,text12 + integer,dimension(40) :: sv,newSv + integer,dimension(:),allocatable :: mix + character*12,dimension(:),allocatable :: cell + + ip = ipIn + call LCMLEN(ip,'CELL ',lgC,ty) + lgC = lgC/3 + if (lgC/=0) then !il y a des sous-cellules + allocate(cell(lgC),stat=alloc_ok) + if (alloc_ok /= 0) call XABORT("G2S: separateMixAndCell(1) => allocation pb") + call LCMGTC(ip,'CELL ',12,lgC,cell) + do i = 1,lgC + !traitement recursif sur les sous cellules de la cellule courante + call LCMLEN(ip,cell(i),lg,ty) + if (ty==0) then !la sous cellule est bien definie ici + jp=LCMDID(ip,cell(i)) + call separateMixAndCell(jp,nbNewMix) + end if + end do + deallocate(cell) + !test sur la mixite de la cellule courante + call LCMLEN(ip,'MIX ',lg,ty) + allocate(mix(lg),stat=alloc_ok) + if (alloc_ok /= 0) call XABORT("G2S: prepareData(2) => allocation pb") + call LCMGET(ip,'MIX ',mix) + nbCellToAdd = count(mix(:lg)>0) + if (nbCellToAdd/=0) then !la cellule courante est mixte MIX/CELL + call LCMGET(ip,'STATE-VECTOR',sv) + newSv(:) = 0 + newSv(1) = sv(1) + newSv(2) = 0 + newSv(3) = 1 + newSv(4) = 1 + newSv(5) = 0 + newSv(6) = 1 + newSv(7) = 1 + allocate(cell(lg),stat=alloc_ok) + if (alloc_ok /= 0) call XABORT("G2S: prepareData(3) => allocation pb") + cell(:lg)=' ' + call LCMLEN(ip,'CELL ',lgC2,ty) + lgC2 = lgC2/3 + call LCMGTC(ip,'CELL ',12,lgC2,cell) + indOfCellToAdd = lgC + do i = 1,lg + if (mix(i)>0) then + !creation d'une nouvelle cellule + nbNewMix = nbNewMix+1 + indOfCellToAdd = indOfCellToAdd+1 + mixToPut = mix(i) + mix(i) = -indOfCellToAdd + text12 = i2s(nbNewMix) + newCellName = 'Nmix'//text12(:8) + cell(indOfCellToAdd) = newCellName + jp=LCMDID(ip,newCellName) + call LCMPUT(jp,'MIX ',1,1,mixToPut) + newSv(7) = mixToPut + call LCMPUT(jp,'STATE-VECTOR',40,1,newSv) + call LCMPUT(jp,'NCODE ',6,1,(/0,0,0,0,0,0/)) + call LCMPUT(jp,'ICODE ',6,1,(/0,0,0,0,0,0/)) + text12='L_GEOM' + call LCMPTC(jp,'SIGNATURE',12,text12) + call LCMPUT(jp,'ZCODE ',6,2,(/0.,0.,0.,0.,0.,0./)) + end if + end do + !modification du STATE-VECTOR, du MIX et du CELL de la + !cellule courante + sv(9) = sv(9)+nbCellToAdd + call LCMPUT(ip,'STATE-VECTOR',40,1,sv) + call LCMPUT(ip,'MIX ',lg,1,mix) + call LCMPTC(ip,'CELL ',12,lg,cell) + deallocate(cell) + end if + deallocate(mix) + end if + end subroutine separateMixAndCell + + subroutine creerEtChargerNewDataRec(geoIp,szB,szP) + type(c_ptr),intent(in):: geoIp + integer,intent(inout) :: szB,szP + + !effectue le pretraitement initialement ecrit en python. + !celui-ci utilisait intensivement les dictionnaires python. + !Ceux-ci seront donc remplaces par des objets LCM + type(c_ptr) :: ip,sidesIp,lCentreIp,lMinMaxIp,centreCalculesIp,lcIp,dicoIp + integer :: szLc + + ip = geoIp + !modification de la geometrie dans le cas diagonal, par ajout des + !cellules manquantes dans la gigogne exterieure (ceci pour permettre + !la mise en oeuvre du traitement general aux geometries rectangulaires) + call traiteConditionDiagonale(ip) + !creation de la liste des carres + call LCMOP(lcIp,'lc ',0,1,0) + call creeListeCellules(lcIp,ip,szLc) + !creation du dictionnaire de verification des donnees geometriques + call LCMOP(dicoIp,'dico ',0,1,0) + call creeDico(dicoIp,lcIp,szLc) + + !creation de la liste des longueurs des cotes et resolution du systeme + call LCMOP(sidesIp,'sides ',0,1,0) + call resoudDico(dicoIp,sidesIp) + !cree et prepare la liste des centres des cellules de base, + !avec leur gigogne d'origine + !et destruction du dictionnaire + call LCMOP(lCentreIp,'centres ',0,1,0) + call prepareCentres(lCentreIp,lcIp,sidesIp,dicoIp) + call LCMCL(dicoIp,2) + !preparation des longeurs de la gigogne exterieure, et des coordonnees + !min et max de ses sous cellules + call LCMOP(lMinMaxIp,'minAndMaxXY ',0,1,0) + call prepareMinMax(lMinMaxIp,lCentreIp) + !resolution du systeme donnant les coordonnees des centres des cellules + !de base et stockage dans une nouvelle structure + call LCMOP(centreCalculesIp,'resCentres ',0,1,0) + call calculeCentre(centreCalculesIp,lCentreIp,0) + !compilation des resultats et ajout dans la geometrie des nouvelles donnees + call compileResutats(ip,centreCalculesIp,sidesIp,lMinMaxIp) + call LCMCL(lcIp,2) + call LCMCL(centreCalculesIp,2) + call LCMCL(sidesIp,2) + call LCMCL(lMinMaxIp,2) + !utilisation des donnees (on accroche le traitement classique developpe + !pour python) + call chargerNewData(geoIp,szB,szP) + end subroutine creerEtChargerNewDataRec + + subroutine traiteConditionDiagonale(geoIp) + type(c_ptr),intent(in) :: geoIp + + integer :: i,j,k,pos,n,lgAv,lgAp,lg,ty + integer,dimension(6) :: ncode + integer,dimension(40) :: sv + integer,dimension(:),allocatable :: mixAv,mixAp,turnAv,turnAp + integer,dimension(:),allocatable :: mergeAv,mergeAp + + call LCMGET(geoIp,'NCODE ',ncode) + if ((ncode(1)/=B_Diag) .and. (ncode(2)/=B_Diag)) & + return !pas de condition DIAG + call LCMGET(geoIp,'STATE-VECTOR',sv) + if (sv(8)==0) return !pas de sous cellules + call LCMLEN(geoIp,'MIX ',lgAv,ty) + n = (nint(sqrt(1.+8.*lgAv)) - 1) / 2 + lgAp = n*n + + allocate(mixAv(lgAv),turnAv(lgAv),mergeAv(lgAv),stat=alloc_ok) + if (alloc_ok /= 0) call XABORT("G2S: traiteConditionDiagonale(1) => allocation pb") + allocate(mixAp(lgAp),turnAp(lgAp),mergeAp(lgAp),stat=alloc_ok) + if (alloc_ok /= 0) call XABORT("G2S: traiteConditionDiagonale(2) => allocation pb") + call LCMGET(geoIp,'MIX ',mixAv) + call LCMLEN(geoIp,'TURN ',lg,ty) + if (lg == 0) then + turnAv(:lgAv) = 1 + else + call LCMGET(geoIp,'TURN ',turnAv) + end if + call LCMLEN(geoIp,'MERGE ',lg,ty) + if (lg == 0) then + mergeAV(:lgAv) = (/(i,i=1,lgAv)/) + else + call LCMGET(geoIp,'MERGE ',mergeAV) + end if + + pos = 0 + if ((ncode(1)==B_Diag) .and. (ncode(4)==B_Diag)) then !triangle inf + do i = 1,n + do j = 1,i-1 + k = i + ((j-1)*(2*n-j))/2 + pos = pos + 1 + mixAp(pos) = mixAv(k) + mergeAP(pos) = mergeAV(k) + turnAp(pos) = composeRotRec(turnAv(k),6) + end do + do j = i,n + k = j + ((i-1)*(2*n-i))/2 + pos = pos + 1 + mixAp(pos) = mixAv(k) + mergeAP(pos) = mergeAV(k) + turnAp(pos) = turnAv(k) + end do + end do + else if ((ncode(2)==B_Diag) .and. (ncode(3)==B_Diag)) then !triangle sup + do i = 1,n + do j = 1,i + k = j + (i*(i-1))/2 + pos = pos + 1 + mixAp(pos) = mixAv(k) + mergeAP(pos) = mergeAV(k) + turnAp(pos) = turnAv(k) + end do + do j = i+1,n + k = i + (j*(j-1))/2 + pos = pos + 1 + mixAp(pos) = mixAv(k) + mergeAP(pos) = mergeAV(k) + turnAp(pos) = composeRotRec(turnAv(k),6) + end do + end do + else + call XABORT("G2S: internal error in routine traiteConditionDiagonale") + end if + + call LCMPUT(geoIp,'MIX ',pos,1,mixAp) + call LCMPUT(geoIp,'TURN ',pos,1,turnAp) + call LCMPUT(geoIp,'MERGE ',pos,1,mergeAp) + deallocate(mixAv,turnAv,mixAp,turnAp,mergeAv,mergeAp) + end subroutine traiteConditionDiagonale + + subroutine creeListeCellules(lcIp,geoIp,nbCarre) + type(c_ptr),intent(in) :: lcIp,geoIp + integer,intent(out) :: nbCarre + + integer :: nbAV + + nbCarre = 0 + call rempliListeCellules(lcIp,geoIp,nbCarre) + do + nbAV = nbCarre + call rempliListeCellules(lcIp,geoIp,nbCarre) + if (nbCarre==nbAV) exit + end do + end subroutine creeListeCellules + + subroutine rempliListeCellules(lcIp,geoIp,nbCarre) + type(c_ptr),intent(in):: lcIp,geoIp + integer,intent(inout) :: nbCarre + + character*12 :: subName + type(c_ptr) :: subIp,jplist + integer :: i,j,long,typ,nbCell,long2 + character*12,dimension(:),allocatable :: dataCh12 + + if (nbCarre==0) then + nbCarre = 1 + jplist=LCMDID(lcIp,'root ') + call LCMEQU(geoIp,jplist) + end if + subName = ' ' + do i = 1,nbCarre + call LCMNXT(lcIp,subName) + subIp=LCMGID(lcIp,subName) + call LCMLEN(subIp,'CELL ',long,typ) + if (long/=0) then + nbCell = long/3 + allocate(dataCh12(nbCell),stat=alloc_ok) + if (alloc_ok /= 0) call XABORT("G2S: rempliListeCellules => allocation pb") + call LCMGTC(subIp,'CELL ',12,nbCell,dataCh12) + do j = 1,nbCell + call LCMLEN(subIp,dataCh12(j),long,typ) + call LCMLEN(lcIp,dataCh12(j),long2,typ) + if (long/=0.and.long2==0) then + call LCMSIX(subIp,dataCh12(j),1) + nbCarre = nbCarre + 1 + jplist=LCMDID(lcIp,dataCh12(j)) + call LCMEQU(subIp,jplist) + call LCMSIX(subIp,dataCh12(j),2) + end if + end do + deallocate(dataCh12) + end if + end do + end subroutine rempliListeCellules + + subroutine creeDico(dicoIp,lcIp,szLc) + type(c_ptr),intent(in) :: dicoIp,lcIp + integer,intent(in) :: szLc + + character*12 :: carreName,sideName,tmpStr,arrayName,nbStr + type(c_ptr) :: cIp,dIp,dJp + integer :: i,j,k,long,typ,lenMix,ind,lignNbr,lenCell + real :: side + integer,dimension(40) :: sv + integer,dimension(:),allocatable :: mix,turn,turnStr,merg,mergStr + character*12,dimension(:),allocatable :: cell,tabCh + + !initialisation + dIp = dicoIp + carreName = ' ' + do i = 1,szLc + call LCMNXT(lcIp,carreName) + cIp=LCMGID(lcIp,carreName) + sideName = 'x' // carreName(1:11) + do j = 1,2 + call getSquareSide(cIp,j,side) + dJp=LCMDID(dIp,sideName) + call LCMPUT(dJp,'value',1,2,side) + sideName(1:1)='y' + end do + end do + !remplissage + dIp = dicoIp + carreName = ' ' + lignNbr = 0 + do k = 1,szLc + !tavail sur la kieme cellule + call LCMNXT(lcIp,carreName) + cIp=LCMGID(lcIp,carreName) + call LCMGET(cIp,'STATE-VECTOR',sv) + lenMix = sv(3)*sv(4) + if ((sv(1)/=G_Car2d).or.(sv(9)==0)) cycle !pas d'info a retirer + call LCMLEN(cIp,'CELL ',lenCell,typ) + lenCell=lenCell/3 + allocate(mix(lenMix),turn(lenMix),cell(lenCell),merg(lenMix),stat=alloc_ok) + if (alloc_ok /= 0) call XABORT("G2S: creeDico(1) => allocation pb") + call LCMLEN(cIp,'TURN ',long,typ) + if (long==0) then + turn(:lenMix) = 1 + else + call LCMGET(cIp,'TURN ',turn) + end if + call LCMLEN(cIp,'MERGE ',long,typ) + if (long==0) then + merg(:lenMix) = (/(i,i=1,lenMix)/) + else + call LCMGET(cIp,'MERGE ',merg) + end if + call LCMGET(cIp,'MIX ',mix) + !on teste si tous les milieux sont bien negatifs + do i = 1,lenMix + if (mix(i)<0) cycle + call XABORT("G2S: error, meltig MIX and CELL not supported") + end do + call LCMGTC(cIp,'CELL ',12,lenCell,cell) + !travail sur l'axe des x + allocate(tabCh(2*sv(3)-1),turnStr(sv(3)),mergStr(sv(3)),stat=alloc_ok) + if (alloc_ok /= 0) call XABORT("G2S: creeDico(2) => allocation pb") + tabCh = '+' + sideName = 'x' // carreName(1:11) + dJp=LCMDID(dIp,sideName) + do j = 1,sv(4) + do i = 1,sv(3) + ind = i+(j-1)*sv(3) + tmpStr = tourne('x',turn(ind)) // cell(-mix(ind))(1:11) + tabCh(2*i-1) = tmpStr + turnStr(i) = turn(ind) + mergStr(i) = merg(ind) + end do + lignNbr = lignNbr + 1 + nbStr = i2s(lignNbr) + arrayName = "array" // nbStr(:7) + call LCMPTC(dJp,arrayName,12,2*sv(3)-1,tabCh) + arrayName = "turns" // nbStr(:7) + call LCMPUT(dJp,arrayName,sv(3),1,turnStr) + arrayName = "merge" // nbStr(:7) + call LCMPUT(dJp,arrayName,sv(3),1,mergStr) + call exploiteStr(tabCh,cIp,sideName,dicoIp,lignNbr) + end do + deallocate(tabCh,turnStr,mergStr) + !travail sur l'axe des y + allocate(tabCh(2*sv(4)-1),turnStr(sv(4)),mergStr(sv(4)),stat=alloc_ok) + if (alloc_ok /= 0) call XABORT("G2S: creeDico(3) => allocation pb") + tabCh = '+' + sideName(1:1) = 'y' + dJp=LCMDID(dIp,sideName) + do i = 1,sv(3) + do j = 1,sv(4) + ind = i+(j-1)*sv(3) + tmpStr = tourne('y',turn(ind)) // cell(-mix(ind))(1:11) + tabCh(2*j-1) = tmpStr + turnStr(j) = turn(ind) + mergStr(j) = merg(ind) + end do + lignNbr = lignNbr + 1 + nbStr = i2s(lignNbr) + arrayName = "array" // nbStr(:7) + call LCMPTC(dJp,arrayName,12,2*sv(4)-1,tabCh) + arrayName = "turns" // nbStr(:7) + call LCMPUT(dJp,arrayName,sv(4),1,turnStr) + arrayName = "merge" // nbStr(:7) + call LCMPUT(dJp,arrayName,sv(4),1,mergStr) + call exploiteStr(tabCh,cIp,sideName,dicoIp,lignNbr) + end do + deallocate(tabCh,turnStr,mergStr) + !fin du travail sur la cellule + deallocate(mix,turn,cell,merg) + end do + end subroutine creeDico + + function tourne(axe,turn) + character,intent(in) :: axe + integer,intent(in) :: turn + character :: tourne + + tourne = axe + if (mod(turn,2)==1) return + if (axe=='x') then + tourne = 'y' + else + tourne = 'x' + end if + end function tourne + + subroutine exploiteStr(inStr,carreIp,sideName,dicoIp,lignNbr) + character*12,dimension(:),intent(in) :: inStr + type(c_ptr),intent(in) :: carreIp,dicoIp + character*12,intent(in) :: sideName + integer,intent(inout) :: lignNbr + + character*12,dimension((size(inStr)+1)/2) :: tmpStr,workStr + character*12,dimension(:),allocatable :: resStr + real,dimension(:),allocatable :: mesh + character*12 :: name2 + type(c_ptr) :: workIp + integer :: i,j,k,nbOcc,szTS,szIS,nbRest,long,typ + character*12 :: arrayName,name1,meshName,number,text12 + real :: value,res + + workIp = dicoIp + szIS = size(inStr) + szTS = (szIS+1)/2 + !on enleve les "+" dans le tableau + do i = 1,szTS + tmpStr(i)=inStr(2*i-1) + enddo + !creation a partir de r=a+b+c+b+a, de a=r-b-c-b/2, + ! b=r-a-c-a/2 et c=r-a-b-b-a + do i = 1,szTS + nbOcc = 0 + do j = 1,szTS + if (tmpStr(j)==tmpStr(i)) then + nbOcc = nbOcc + 1 + else if (j > nbOcc) then + workStr(j-nbOcc) = tmpStr(j) + end if + end do + nbRest = szTS - nbOcc + if (nbOcc==1) then + allocate(resStr(2*nbRest+1),stat=alloc_ok) + if (alloc_ok /= 0) call XABORT("G2S: exploiteStr(2) => allocation pb") + else + allocate(resStr(2*nbRest+3),stat=alloc_ok) + if (alloc_ok /= 0) call XABORT("G2S: exploiteStr(3) => allocation pb") + end if + resStr(1) = sideName + do k = 1,nbRest + resStr(2*k) = '-' + resStr(2*k+1) = workStr(k) + end do + long=2*nbRest+1 + if (nbOcc/=1) then + resStr(2*nbRest+2) = '/' + number = i2s(nbOcc) + resStr(2*nbRest+3) = number + long=2*nbRest+3 + end if + lignNbr = lignNbr + 1 + text12 = i2s(lignNbr) + arrayName = "expl" // text12(:8) + call LCMSIX(workIp,tmpStr(i),1) + call LCMPTC(workIp,arrayName,12,long,resStr) + call LCMSIX(workIp,tmpStr(i),2) + deallocate(resStr) + !exploitation orthogonale de la chaine ('xa + xb' => ya=yb) + name1 = tourne(tmpStr(i)(1:1),2) // tmpStr(i)(2:12) + do k = 1,nbRest + name2 = tourne(workStr(k)(1:1),2) // workStr(k)(2:12) + lignNbr = lignNbr + 1 + arrayName = "orth" // text12(:8) + call LCMSIX(workIp,name1,1) + call LCMPTC(workIp,arrayName,12,name2) + call LCMSIX(workIp,name1,2) + end do + end do + !exploitation eventuelle du maillage en entree + if (sideName(1:1)=='x') then + meshName = 'MESHX' + else if (sideName(1:1)=='y') then + meshName = 'MESHY' + else + call XABORT("G2S: internal error in subroutine exploiteStr") + end if + call LCMLEN(carreIp,meshName,long,typ) + if (long/=0) then + allocate(mesh(long),stat=alloc_ok) + if (alloc_ok /= 0) call XABORT("G2S: exploiteStr(4) => allocation pb") + call LCMGET(carreIp,meshName,mesh) + do i = 1,szTS + call getValueOf(tmpStr(i),workIp,value) + res = mesh(i+1)-mesh(i) + if ((value>0.) .and. (abs(value-res)>geomPrec)) then + write(6,*) " ",meshName," -> ",tmpStr(i) + call XABORT("G2S: error, incoherent geometry(1)") + endif + call setValueOf(tmpStr(i),workIp,res) + end do + deallocate(mesh) + end if + end subroutine exploiteStr + + subroutine getSquareSide(cIp,axis,side) + type(c_ptr),intent(in) :: cIp + integer,intent(in) :: axis + real,intent(out) :: side + + integer :: typ,long + real,dimension(:),allocatable :: tr + + side = -1. + if (axis==1) then !axe des x + call LCMLEN(cIp,'MESHX ',long,typ) + if (long/=0) then + allocate(tr(long),stat=alloc_ok) + if (alloc_ok /= 0) call XABORT("G2S: getSquareSide(1) => allocation pb") + call LCMGET(cIp,'MESHX ',tr) + side = tr(long) - tr(1) + deallocate(tr) + end if + else if (axis==2) then !axe des y + call LCMLEN(cIp,'MESHY ',long,typ) + if (long/=0) then + allocate(tr(long),stat=alloc_ok) + if (alloc_ok /= 0) call XABORT("G2S: getSquareSide(2) => allocation pb") + call LCMGET(cIp,'MESHY ',tr) + side = tr(long) - tr(1) + deallocate(tr) + end if + else + call XABORT("G2S: internal error in subroutine getSquareSide") + end if + end subroutine getSquareSide + + subroutine getValueOf(sideName,dicoIp,value) + character*12,intent(in) :: sideName + type(c_ptr),intent(in) :: dicoIp + real,intent(out) :: value + + type(c_ptr) :: ip,jp + character*131 :: hsmg + integer :: long,typ + + ip = dicoIp + jp = LCMGID(ip,sideName) + call LCMLEN(jp,'value',long,typ) + if(long == 0) then + write(hsmg,'(36hG2S: value key missing for sideName=,a,5h (1).)') trim(sideName) + call LCMLIB(ip) + call LCMLIB(jp) + call XABORT(hsmg) + endif + call LCMGET(jp,'value',value) + end subroutine getValueOf + + subroutine setValueOf(sideName,dicoIp,value) + character*12,intent(in) :: sideName + type(c_ptr),intent(in) :: dicoIp + real,intent(in) :: value + + type(c_ptr) :: ip,jp + + ip = dicoIp + jp = LCMDID(ip,sideName) + call LCMPUT(jp,'value',1,2,value) + end subroutine setValueOf + + subroutine resoudDico(dicoIp,resIp) + type(c_ptr),intent(in) :: dicoIp,resIp + + logical :: newVal,flag1,flag2,empty,lcm + character*12 :: sideName,saveSideName,namlcm,nammy + character*131:: hsmg + type(c_ptr) :: ip,jp + integer :: ilong,long,typ + real :: val + + !la resolution se fait en travaillant sur toutes les variables une a une + !on resout les unes apres les autres toutes les equations regissant + !chaque variable (si possible) + ! on teste a chaque passe si on a trouve une nouvelle valeur + ! si oui on continue, sinon (apres une nouvelle passe infructueuse), on + ! arrete le traitement et on teste si tous les resultats sont bons + ! oui -> on sort ; non -> on abandonne car manque de donnees + + flag1 = .true. + do + flag2 = flag1 !garde la valeur de flag1 a l'essai precedent + flag1 = .false. + sideName = ' ' + call LCMINF(dicoIp,namlcm,nammy,empty,ilong,lcm) + if (.not. empty) then + call LCMNXT(dicoIp,sideName) + saveSideName = sideName + do !boucle sur toutes les donnees du dico + newVal = evaluateEquation(dicoIp,sideName) + !test si newVal a ete vrai au moins une fois + if (newVal) flag1 = .true. + call LCMNXT(dicoIp,sideName) + if (sideName == saveSideName) exit + end do + end if + if (.not.(flag1 .or. flag2)) then + !il ne s'est rien passe au cours des 2 tentatives + !precedentes => on abandonne si une valeur est non resolue + saveSideName = sideName + do !boucle sur toutes les donnees du dico + call getValueOf(sideName,dicoIp,val) + if (val<0) then !une valeur est non resolue -> ABORT + write(6,*) "Curent values of geometry :" + saveSideName = sideName + do !boucle sur toutes les donnees du dico + call getValueOf(sideName,dicoIp,val) + write(6,*) " ",sidename," -> ",val + call LCMNXT(dicoIp,sideName) + if (sideName == saveSideName) exit + end do + call XABORT("G2S: not enought data in the geometry(1)") + end if + call LCMNXT(dicoIp,sideName) + if (sideName == saveSideName) exit + end do + exit !toutes les valeurs sont bonnes + end if + end do + !recopie des resultats + ip = dicoIp + sideName = ' ' + call LCMINF(ip,namlcm,nammy,empty,ilong,lcm) + if (empty) return + call LCMNXT(ip,sideName) + saveSideName = sideName + do + jp=LCMGID(ip,sideName) + call LCMLEN(jp,'value',long,typ) + if(long == 0) then + write(hsmg,'(36hG2S: value key missing for sideName=,a,5h (2).)') trim(sideName) + call LCMLIB(ip) + call LCMLIB(jp) + call XABORT(hsmg) + endif + call LCMGET(jp,'value',val) + call LCMPUT(resIp,sideName,1,2,val) + call LCMNXT(ip,sideName) + if (sideName == saveSideName) exit + end do + end subroutine resoudDico + + function evaluateEquation(dicoIp,sideName) + type(c_ptr),intent(in) :: dicoIp + character*12,intent(in) :: sideName + logical :: evaluateEquation + !evaluation une a une des equations de dico relatives a sideName + !retourne .true. si nouvelle affectation et .false. sinon + + real :: res,val + double precision :: dres + type(c_ptr) :: sideIp + integer :: i,long,typ,ilong + logical :: goodLine,empty,lcm + character*12 :: eqName,saveEqName,namlcm,nammy + character*12,dimension(:),allocatable :: str + + evaluateEquation = .false. + sideIp = dicoIp + call LCMSIX(sideIp,sideName,1) + eqName = ' ' + call LCMINF(sideIp,namlcm,nammy,empty,ilong,lcm) + if (empty) call XABORT("G2S: intenal error in data structure in & + &function evaluateEquation") + call LCMNXT(sideIp,eqName) + saveEqName = eqName + do !recherche de la premiere occurence d'une arrayXXX + call LCMNXT(sideIp,eqName) + if (eqName(1:5)=='array') exit + if (eqName==saveEqName) then + !pas de donnee interessante => on quitte + return + end if + end do + saveEqName = eqName + do !boucle sur toutes les equations de sideName + if (eqName(1:5)/='array') then + call LCMNXT(sideIp,eqName) + if (eqName==saveEqName) exit + cycle + end if + !on travaille sur une arrayXXX + goodLine = .true. + call LCMLEN(sideIp,eqName,long,typ) + long = long/3 + allocate(str(long),stat=alloc_ok) + if (alloc_ok /= 0) call XABORT("G2S: evaluateEquation => allocation pb") + call LCMGTC(sideIp,eqName,12,long,str) + call getValueOf(str(1),dicoIp,res) + if (res<0) then + goodLine = .false. + end if + dres = res + do i = 2,long,2 + if (str(i)=='+') then + call getValueOf(str(i+1),dicoIp,val) + if (val<0) then + goodLine = .false. + exit + end if + dres = dres + val + else if (str(i)=='-') then + call getValueOf(str(i+1),dicoIp,val) + if (val<0) then + goodLine = .false. + exit + end if + dres = dres - val + else if (str(i)=='/') then + val = s2i(str(i+1)) + dres = dres / val + else + call XABORT("G2S: internal error in function evaluateEquation") + end if + end do + res = real(dres) + !si on sort normalement de la boucle, on teste la coherence + !ou on assigne le resultat obtenu + if (goodLine) then + call getValueOf(sideName,dicoIp,val) + if (val<0) then + call setValueOf(sideName,dicoIp,res) + evaluateEquation = .true. !on a resolu une nouvelle equation + else if (abs(val-res)>geomPrec) then + call XABORT("G2S: error, incoherent geometry(2)") + end if + end if + deallocate(str) + call LCMNXT(sideIp,eqName) + if (eqName==saveEqName) exit + end do + end function evaluateEquation + + subroutine prepareCentres(lCentreIpIn,lcIp,sidesIp,dicoIpIn) + type(c_ptr),intent(in) :: lCentreIpIn,lcIp,sidesIp,dicoIpIn + + type(c_ptr) :: tmpIp,coordCentIp,ip,dicoIp,lCentreIp + integer :: i,j,lg,lgc,ty,dimValToPut,nbArray,gigNum,ilong + logical :: empty,lcm + character*12 :: namlcm,nammy + character*12 :: carreName,saveCarreName,tmpName,eqName,saveEqName + character*12 :: sideName,saveSideName,arrayName,saveArrayName + character*12 :: turnName,mergeName + real :: saveVal,val + real,dimension(:),allocatable :: valToPut,xx,yy + integer,dimension(40) :: sv + integer,dimension(:),allocatable :: turns,merg + character*12,dimension(:),allocatable :: eqStr,arrayNameStr + + lCentreIp = lCentreIpIn + dicoIp = dicoIpIn + !initialisation de la liste et creation et initialisation + !d'une liste temporaire a partir du dictionnaire utilise a + !l'etape precedente, et d'un autre temporaire appelle coordCent + call LCMOP(tmpIp,'lCtemp ',0,1,0) + carreName = ' ' + call LCMINF(lcIp,namlcm,nammy,empty,ilong,lcm) + if (empty) call XABORT("G2S: intenal error in data structure in & + &subroutine prepareCentres") + call LCMNXT(lcIp,carreName) + saveCarreName = carreName + do + !travail sur lCtemp + call LCMSIX(tmpIp,carreName,1) + tmpName = 'x' // carreName(1:11) + call LCMSIX(dicoIp,tmpName,1) + eqName = ' ' + call LCMNXT(dicoIp,eqName) + saveEqName = eqName + do + if (eqName(1:5)=='array') then !l'equation est a conserver + call putEquationIn(dicoIp,eqName,tmpIp) + end if + call LCMNXT(dicoIp,eqName) + if (eqName==saveEqName) exit + end do + call LCMSIX(dicoIp,tmpName,2) + call LCMSIX(tmpIp,carreName,2) + !travail sur lCentre + call LCMSIX(lCentreIp,carreName,1) + call LCMSIX(lCentreIp,carreName,2) + call LCMNXT(lcIp,carreName) + if (carreName==saveCarreName) exit + end do + + !creation d'un autre temporaire appelle coordCent + call LCMOP(coordCentIp,'lCoordCent ',0,1,0) + sideName = ' ' + call LCMNXT(dicoIp,sideName) + saveSideName = sideName + do + call LCMSIX(dicoIp,sideName,1) + eqName = ' ' + call LCMNXT(dicoIp,eqName) + saveEqName = eqName + do + if (eqName(1:5)=='array') then !l'equation est a exploiter + call LCMLEN(dicoIp,eqName,lg,ty) + lg = lg / 3 + dimValToPut = (lg+1) / 2 + allocate(eqStr(lg),valToPut(dimValToPut),stat=alloc_ok) + if (alloc_ok /= 0) call XABORT("G2S: prepareCentres(1) => allocation pb") + call LCMGTC(dicoIp,eqName,12,lg,eqStr) + !calcul des coordonnees des sous cellules de la cellule + !consideree et stockage de la valeur obtenu dans coordCent + call LCMGET(sidesIp,sideName,val) + valToPut(1) = -0.5 * val + call LCMGET(sidesIp,eqStr(1),val) + valToPut(1) = valToPut(1) + 0.5 * val + do i = 2,dimValToPut + saveVal = val + call LCMGET(sidesIp,eqStr(2*i-1),val) + valToPut(i) = valToPut(i-1) + 0.5 * (val+saveVal) + end do + call LCMPUT(coordCentIp,sideName,dimValToPut,2,valToPut) + deallocate(eqStr,valToPut) + exit !on sort car on n'a pas a verifier la coherence + end if + call LCMNXT(dicoIp,eqName) + if (eqName==saveEqName) exit + end do + call LCMSIX(dicoIp,sideName,2) + call LCMNXT(dicoIp,sideName) + if (sideName==saveSideName) exit + end do + + carreName = ' ' + call LCMNXT(lcIp,carreName) + saveCarreName = carreName + do + ip=LCMGID(lcIp,carreName) + call LCMGET(ip,'STATE-VECTOR',sv) + !recuperation des noms des equations utiles + call LCMSIX(tmpIp,carreName,1) + call LCMINF(tmpIp,namlcm,nammy,empty,ilong,lcm) + if (.not. empty) then + allocate(arrayNameStr(max(sv(3),sv(4)))) + nbArray = 0 + arrayName = ' ' + call LCMNXT(tmpIp,arrayName) + saveArrayName = arrayName + do + if (arrayName(1:5)/='array') then + call LCMNXT(tmpIp,arrayName) + if (arrayName == saveArrayName) exit + cycle + end if + nbArray = nbArray + 1 + arrayNameStr(nbArray) = arrayName + call LCMNXT(tmpIp,arrayName) + if (arrayName == saveArrayName) exit + end do + !trie des noms des equations + call sortTabCh12(arrayNameStr,nbArray) + !travail sur les equations + gigNum = 0 + do i = 1,nbArray + arrayName = arrayNameStr(i) + call LCMLEN(tmpIp,arrayName,lgc,ty) + lgc = lgc / 3 + allocate(eqStr(lgc)) + lg = (lgc+1) / 2 + allocate(turns(lg),merg(lg),xx(lg),yy(nbArray)) + call LCMGTC(tmpIp,arrayName,12,lgc,eqStr) + turnName = 'turns' // arrayName(6:12) + call LCMGET(tmpIp,turnName,turns) + mergeName = 'merge' // arrayName(6:12) + call LCMGET(tmpIp,mergeName,merg) + do j = 1,lg + gigNum = gigNum + 1 + sideName = 'x' // carreName(1:11) + call LCMGET(coordCentIp,sideName,xx) + sideName(1:1) = 'y' + call LCMGET(coordCentIp,sideName,yy) + sideName=eqStr(2*j-1)(2:12) + !ajout du resultat dans lCentre + call addInRes(lCentreIp,sideName,carreName, & + & xx(j),yy(i),turns(j),gigNum,merg(j)) + end do + deallocate(eqStr,turns,merg,xx,yy) + end do + deallocate(arrayNameStr) + end if + + call LCMSIX(tmpIp,carreName,2) + call LCMNXT(lcIp,carreName) + if (carreName==saveCarreName) exit + end do + !destruction du repertoire 'root' dans lCentre + call LCMDEL(lCentreIp,'root ') + !fermeture des temporaires + call LCMCL(coordCentIp,2) + call LCMCL(tmpIp,2) + end subroutine prepareCentres + + subroutine addInRes(ipIn,extName,intName,xx,yy,turn,gigNum,merg) + type(c_ptr),intent(in) :: ipIn + integer,intent(in) :: turn,gigNum,merg + character*12,intent(in) :: extName,intName + real,intent(in) :: xx,yy + + real,dimension(:),allocatable :: tabR + integer,dimension(:),allocatable :: tabI + character*12 :: reg,gigName + integer :: lg,ty + type(c_ptr) :: ip + + ip = ipIn + call LCMSIX(ip,extName,1) + call LCMSIX(ip,intName,1) + reg = 'x' + call LCMLEN(ip,reg,lg,ty) + allocate(tabR(lg+1)) + !ajout de xx + if (lg /= 0) call LCMGET(ip,reg,tabR) + tabR(lg+1) = xx + call LCMPUT(ip,reg,lg+1,2,tabR) + !ajout de yy + reg = 'y' + if (lg /= 0) call LCMGET(ip,reg,tabR) + tabR(lg+1) = yy + call LCMPUT(ip,reg,lg+1,2,tabR) + deallocate(tabR) + !ajout de turn + reg = 't' + allocate(tabI(lg+1)) + if (lg /= 0) call LCMGET(ip,reg,tabI) + tabI(lg+1) = turn + call LCMPUT(ip,reg,lg+1,1,tabI) + deallocate(tabI) + !ajout de la gigogne et du merge + gigName = i2s(lg+1) + call LCMSIX(ip,gigName,1) + reg = 'gig' + call LCMPUT(ip,reg,1,1,gigNum) + reg = 'mrg' + call LCMPUT(ip,reg,1,1,merg) + call LCMSIX(ip,gigName,2) + call LCMSIX(ip,intName,2) + call LCMSIX(ip,extName,2) + end subroutine addInRes + + subroutine sortTabCh12(tab,sz) + character*12,dimension(:),intent(inout) :: tab + integer,intent(in) :: sz + + integer :: indMax,i,s1,s2 + logical :: trie + character*12 :: tmp + + do indMax = sz,2,-1 + trie = .true. + do i = 1,indMax-1 + s1 = s2i(tab(i)(6:12)) + s2 = s2i(tab(i+1)(6:12)) + if (s2<s1) then + tmp=tab(i+1) ; tab(i+1)=tab(i) ; tab(i)=tmp + trie = .false. + end if + end do + if (trie) exit + end do + end subroutine sortTabCh12 + + subroutine putEquationIn(dicoIp,eqName,lCentreIp) + type(c_ptr),intent(in) :: dicoIp,lCentreIp + character*12,intent(in) :: eqName + + character*12,dimension(:),allocatable :: str12 + integer,dimension(:),allocatable :: turns,merg + character*12 :: turnsName,mergeName + integer :: lg,ty,lgt + + call LCMLEN(dicoIp,eqName,lg,ty) + if (lg/=0) then + turnsName = 'turns' // eqName(6:12) + mergeName = 'merge' // eqName(6:12) + lg = lg/3 + lgt = (lg+1)/2 + allocate(str12(lg),turns(lgt),merg(lgt)) + call LCMGTC(dicoIp,eqName,12,lg,str12) + call LCMGET(dicoIp,turnsName,turns) + call LCMGET(dicoIp,mergeName,merg) + call LCMPTC(lCentreIp,eqName,12,lg,str12) + call LCMPUT(lCentreIp,turnsName,lgt,1,turns) + call LCMPUT(lCentreIp,mergeName,lgt,1,merg) + deallocate(str12,turns,merg) + else + call XABORT("G2S: internal error in subroutine putEquationIn") + end if + end subroutine putEquationIn + + subroutine prepareMinMax(lMinMaxIp,lCentreIp) + type(c_ptr),intent(in) :: lMinMaxIp,lCentreIp + + character*12 :: carreName,saveCarreName,namlcm,nammy + type(c_ptr) :: ipLC + integer :: lg,ty,ilong + logical :: empty,lcm + real :: minX,maxX,minY,maxY + real,dimension(:),allocatable :: xx,yy + + ipLC = lCentreIp + minX = 0. ; maxX = 0. ; minY = 0. ; maxY = 0. + carreName = ' ' + call LCMINF(ipLC,namlcm,nammy,empty,ilong,lcm) + if (.not. empty) then !plus d'une seule cellule + call LCMNXT(ipLC,carreName) + saveCarreName = carreName + do + call LCMSIX(ipLC,carreName,1) + call LCMLEN(ipLC,'root ',lg,ty) + if (lg/=0) then + call LCMSIX(ipLC,'root ',1) + call LCMLEN(ipLC,'x ',lg,ty) + allocate(xx(lg)) + call LCMGET(ipLC,'x ',xx) + call LCMLEN(ipLC,'y ',lg,ty) + allocate(yy(lg)) + call LCMGET(ipLC,'y ',yy) + minX = min(minX,minval(xx)) + maxX = max(maxX,maxval(xx)) + minY = min(minY,minval(yy)) + maxY = max(maxY,maxval(yy)) + deallocate(xx,yy) + call LCMSIX(ipLC,'root ',2) + end if + call LCMSIX(ipLC,carreName,2) + call LCMNXT(ipLC,carreName) + if (carreName==saveCarreName) exit + end do + end if + call LCMPUT(lMinMaxIp,'minX ',1,2,minX) + call LCMPUT(lMinMaxIp,'maxX ',1,2,maxX) + call LCMPUT(lMinMaxIp,'minY ',1,2,minY) + call LCMPUT(lMinMaxIp,'maxY ',1,2,maxY) + end subroutine prepareMinMax + + recursive subroutine calculeCentre(resIp,lcIp,deep) + type(c_ptr),intent(inout) :: resIp + type(c_ptr),intent(in) :: lcIp + integer,intent(in) :: deep + + character*12 :: dirName,saveDirName,subDirName,saveSubDirName + character*12 :: namlcm,nammy + type(c_ptr) :: valuesIp,tmpLcIp,cpResIp,tmpDic + integer :: i,lg,ty,nbGig,ilong + logical :: empty,lcm + + call LCMEQU(lcIp,resIp) + tmpLcIp = lcIp + dirName = ' ' + call LCMINF(tmpLcIp,namlcm,nammy,empty,ilong,lcm) + if (empty) then + !une seule cellule => traitement particulier + call LCMSIX(resIp,'root ',1) + call LCMSIX(resIp,'root ',1) + call LCMPUT(resIp,'x ',1,2,0.) + call LCMPUT(resIp,'y ',1,2,0.) + call LCMPUT(resIp,'t ',1,1,1) + call LCMSIX(resIp,'1 ',1) + call LCMPUT(resIp,'gig ',1,1,1) + call LCMPUT(resIp,'mrg ',1,1,1) + call LCMSIX(resIp,'1 ',2) + call LCMSIX(resIp,'root ',2) + call LCMSIX(resIp,'root ',2) + return + end if + call LCMOP(valuesIp,'temporariObj',0,1,0) + call LCMNXT(tmpLcIp,dirName) + saveDirName = dirName + nbGig = 0 + do + call LCMSIX(tmpLcIp,dirName,1) + subDirName = ' ' + call LCMINF(tmpLcIp,namlcm,nammy,empty,ilong,lcm) + if (.not. empty) then + call LCMNXT(tmpLcIp,subDirName) + saveSubDirName = subDirName + do + call LCMLEN(valuesIp,subDirName,lg,ty) + if (lg==0) then + nbGig = nbGig + 1 + call LCMSIX(valuesIp,subDirName,1) + call LCMSIX(valuesIp,subDirName,2) + end if + call LCMNXT(tmpLcIp,subDirName) + if (subDirName==saveSubDirName) exit + end do + end if + call LCMSIX(tmpLcIp,dirName,2) + call LCMNXT(tmpLcIp,dirName) + if (dirName==saveDirName) exit + end do + !test de sortie de la recurrence + if (nbGig <= 1) then + call LCMEQU(lcIp,resIp) + call LCMCL(valuesIp,2) + return + end if + !liste des cellules a garder + dirName = ' ' + call LCMNXT(lcIp,dirName) + saveDirName = dirName + do + call LCMLEN(valuesIp,dirName,lg,ty) + if (lg==0) call LCMDEL(resIp,dirName) + call LCMNXT(lcIp,dirName) + if (dirName==saveDirName) exit + end do + + dirName = ' ' + call LCMNXT(lcIp,dirName) + saveDirName = dirName + do + call LCMLEN(valuesIp,dirName,lg,ty) + if (lg==0) then + call LCMSIX(tmpLcIp,dirName,1) + subDirName = ' ' + call LCMNXT(tmpLcIp,subDirName) + saveSubDirName = subDirName + do + call LCMSIX(tmpLcIp,subDirName,1) + if (subDirName/='root') then + call LCMLEN(tmpLcIp,'t ',lg,ty) + do i = 1,lg + call LCMOP(tmpDic,'tmpDic ',0,1,0) + call translateDic(tmpDic,lcIp,dirName,subDirName,i) + call mergeDic(resIp,dirName,tmpDic) + call LCMCL(tmpDic,2) + end do + else + call LCMOP(tmpDic,'tmpDic ',0,1,0) + call LCMSIX(tmpDic,subDirName,1) + call LCMEQU(tmpLcIp,tmpDic) !copie uniquement de la branche + !interresante (lc[dirname]['root']) + call LCMSIX(tmpDic,subDirName,2) + call mergeDic(resIp,dirName,tmpDic) + call LCMCL(tmpDic,2) + end if + call LCMSIX(tmpLcIp,subDirName,2) + call LCMNXT(tmpLcIp,subDirName) + if (subDirName==saveSubDirName) exit + end do + call LCMSIX(tmpLcIp,dirName,2) + end if + call LCMNXT(lcIp,dirName) + if (dirName==saveDirName) exit + end do + !iteration + call LCMOP(cpResIp,'resCentres ',0,1,0) + call LCMEQU(resIp,cpResIp) + call calculeCentre(resIp,cpResIp,deep+1) + call LCMCL(cpResIp,2) + !elimination des cellules non terminales si deep==0 + if (deep==0) then + dirName = ' ' + call LCMNXT(valuesIp,dirName) + saveDirName = dirName + do + call LCMLEN(resIp,dirName,lg,ty) + if (lg/=0) call LCMDEL(resIp,dirName) + call LCMNXT(valuesIp,dirName) + if (dirName==saveDirName) exit + end do + end if + call LCMCL(valuesIp,2) + end subroutine calculeCentre + + subroutine translateDic(resIp,dicIp,dName,sDName,ind) + type(c_ptr),intent(in) :: resIp,dicIp + integer,intent(in) :: ind + character*12,intent(in) :: dName,sDName + !effectue la translation dans le repere de la cellule englobante + !de la liste des cellules de dicIp[sDName], suivant les vecteurs de + !dicIp[dName][sDName] (qui comprennent x(i),y(i),t(i),[`i`][gig] i=1,sz) + + character*12 :: dirName,saveDirName,gigName + type(c_ptr) :: tmpRes,tmpDic + integer :: i,lg,ty,tval,lggigI,lggigval + real :: xval,yval + integer,dimension(:),allocatable :: tt,gigI,gigval,mrgI,mrgval + real,dimension(:),allocatable :: xx,yy + + tmpRes = resIp ; tmpDic = dicIp + !recuperation des donnees de translation + call LCMSIX(tmpDic,dName,1) + call LCMSIX(tmpDic,sDName,1) + call LCMLEN(tmpDic,'t ',lg,ty) + allocate(xx(lg),yy(lg),tt(lg)) + call LCMGET(tmpDic,'t ',tt) ; tval = tt(ind) + call LCMGET(tmpDic,'x ',xx) ; xval = xx(ind) + call LCMGET(tmpDic,'y ',yy) ; yval = yy(ind) + deallocate(xx,yy,tt) + gigName = i2s(ind) + call LCMSIX(tmpDic,gigName,1) + call LCMLEN(tmpDic,'gig ',lggigval,ty) + allocate(gigval(lggigval),mrgval(lggigval)) + call LCMGET(tmpDic,'gig ',gigval) + call LCMGET(tmpDic,'mrg ',mrgval) + tmpDic = dicIp + !translation + call LCMSIX(tmpDic,sDName,1) + dirName = ' ' + call LCMNXT(tmpDic,dirName) + saveDirName = dirName + do + call LCMSIX(tmpDic,dirName,1) + call LCMSIX(tmpRes,dirName,1) + call LCMLEN(tmpDic,'t ',lg,ty) + allocate(xx(lg),yy(lg),tt(lg)) + call LCMGET(tmpDic,'t ',tt) + call LCMGET(tmpDic,'x ',xx) + call LCMGET(tmpDic,'y ',yy) + do i = 1,lg + gigName = i2s(i) + call LCMSIX(tmpDic,gigName,1) + call LCMSIX(tmpRes,gigName,1) + call LCMLEN(tmpDic,'gig ',lggigI,ty) + allocate(gigI(lggigI+lggigval),mrgI(lggigI+lggigval)) + call LCMGET(tmpDic,'gig ',gigI) + call LCMGET(tmpDic,'mrg ',mrgI) + call translateWithTurn(xx(i),yy(i),tt(i),xval,yval,tval) + gigI(lggigI+1:lggigI+lggigval) = gigval + call LCMPUT(tmpRes,'gig ',lggigI+lggigval,1,gigI) + mrgI(lggigI+1:lggigI+lggigval) = mrgval + call LCMPUT(tmpRes,'mrg ',lggigI+lggigval,1,mrgI) + deallocate(gigI,mrgI) + call LCMSIX(tmpRes,gigName,2) + call LCMSIX(tmpDic,gigName,2) + end do + call LCMPUT(tmpRes,'t ',lg,1,tt) + call LCMPUT(tmpRes,'x ',lg,2,xx) + call LCMPUT(tmpRes,'y ',lg,2,yy) + deallocate(xx,yy,tt) + call LCMSIX(tmpRes,dirName,2) + call LCMSIX(tmpDic,dirName,2) + call LCMNXT(tmpDic,dirName) + if (dirName==saveDirName) exit + end do + deallocate(gigval,mrgval) + end subroutine translateDic + + subroutine translateWithTurn(xx,yy,tt,xval,yval,tval) + real,intent(inout) :: xx,yy + integer,intent(inout) :: tt + real,intent(in) :: xval,yval + integer,intent(in) :: tval + + select case(geomTyp) + case(RecTyp) + select case (tt) + case(1) + xx=xx+xval ; yy=yy+yval + case(2) + xx=xx+yval ; yy=yy-xval + case(3) + xx=xx-xval ; yy=yy-yval + case(4) + xx=xx-yval ; yy=yy+xval + case(5) + xx=xx-xval ; yy=yy+yval + case(6) + xx=xx+yval ; yy=yy+xval + case(7) + xx=xx+xval ; yy=yy-yval + case(8) + xx=xx-yval ; yy=yy-xval + end select + tt = composeRotRec(tval,tt) + case(TriaTyp) + select case (tt) + case(1) + xx=xx+xval ; yy=yy+yval + case(2) + xx=xx+0.5*(xval-sqrt_3f*yval) + yy=yy+0.5*(yval+sqrt_3f*xval) + case(3) + xx=xx+0.5*(-xval-sqrt_3f*yval) + yy=yy+0.5*(-yval+sqrt_3f*xval) + case(4) + xx=xx-xval ; yy=yy-yval + case(5) + xx=xx+0.5*(-xval+sqrt_3f*yval) + yy=yy+0.5*(-yval-sqrt_3f*xval) + case(6) + xx=xx+0.5*(xval+sqrt_3f*yval) + yy=yy+0.5*(yval-sqrt_3f*xval) + case(7) + xx=xx+xval ; yy=yy-yval + case(8) + xx=xx+0.5*(xval-sqrt_3f*yval) + yy=yy-0.5*(yval+sqrt_3f*xval) + case(9) + xx=xx+0.5*(-xval-sqrt_3f*yval) + yy=yy-0.5*(-yval+sqrt_3f*xval) + case(10) + xx=xx-xval ; yy=yy+yval + case(11) + xx=xx+0.5*(-xval+sqrt_3f*yval) + yy=yy+0.5*(yval+sqrt_3f*xval) + case(12) + xx=xx+0.5*(xval+sqrt_3f*yval) + yy=yy-0.5*(yval-sqrt_3f*xval) + end select + tt = composeRotTri(tval,tt) + case default + call XABORT("G2S: internal error in subroutine translateWithTurn") + end select + end subroutine translateWithTurn + + subroutine mergeDic(resIp,dirName,otherDicIp) + type(c_ptr),intent(in) :: resIp,otherDicIp + character*12,intent(in) :: dirName + !concatene deux dictionnaires (res[dirName] et otherDic) + !contenants des positions (x,y,t,(1:gig),..,(size(t):gig)) + + character*12 :: sdName,nGig,namlcm,nammy + type(c_ptr) :: tmpResIp,tmpOtherIp + integer :: i,lg,ty,lgN,lgO,ilong + logical :: empty,lcm + real,dimension(:),allocatable :: nra,ora + integer,dimension(:),allocatable :: nia,oia,mrg + + tmpResIp = resIp ; tmpOtherIp = otherDicIp + call LCMSIX(tmpResIp,dirName,1) + call LCMINF(tmpOtherIp,namlcm,nammy,empty,ilong,lcm) + if (empty) return !### + sdName = ' ' + call LCMNXT(tmpOtherIp,sdName) + call LCMSIX(tmpOtherIp,sdName,1) + call LCMSIX(tmpResIp,sdName,1) + call LCMLEN(tmpResIp,'t ',lgN,ty) + if (lgN/=0) then !le repertoire existait deja => ajout de donnees + call LCMLEN(tmpOtherIp,'t ',lgO,ty) + allocate(nra(lgO+lgN),ora(lgO),nia(lgO+lgN),oia(lgO)) + !t + call LCMGET(tmpResIp,'t ',nia) + call LCMGET(tmpOtherIp,'t ',oia) + nia(lgN+1:lgO+lgN) = oia + call LCMPUT(tmpResIp,'t ',lgO+lgN,1,nia) + !x + call LCMGET(tmpResIp,'x ',nra) + call LCMGET(tmpOtherIp,'x ',ora) + nra(lgN+1:lgO+lgN) = ora + call LCMPUT(tmpResIp,'x ',lgO+lgN,2,nra) + !y + call LCMGET(tmpResIp,'y ',nra) + call LCMGET(tmpOtherIp,'y ',ora) + nra(lgN+1:lgO+lgN) = ora + call LCMPUT(tmpResIp,'y ',lgO+lgN,2,nra) + deallocate(nra,ora,nia,oia) + lg = lgO + do i = 1,lg + nGig = i2s(i) + call LCMSIX(tmpOtherIp,nGig,1) + call LCMLEN(tmpOtherIp,'gig ',lgO,ty) + allocate(oia(lgO),mrg(lgO)) + call LCMGET(tmpOtherIp,'gig ',oia) + call LCMGET(tmpOtherIp,'mrg ',mrg) + call LCMSIX(tmpOtherIp,nGig,2) + nGig = i2s(i+lgN) + call LCMSIX(tmpResIp,nGig,1) + call LCMPUT(tmpResIp,'gig ',lgO,1,oia) + call LCMPUT(tmpResIp,'mrg ',lgO,1,mrg) + call LCMSIX(tmpResIp,nGig,2) + deallocate(oia,mrg) + end do + else !le repertoire n'existait pas encore => affectation directe + !call LCMEQU(tmpOtherIp,tmpResIp) + call LCMLEN(tmpOtherIp,'t ',lg,ty) + allocate(ora(lg),oia(lg)) + !t + call LCMGET(tmpOtherIp,'t ',oia) + call LCMPUT(tmpResIp,'t ',lg,1,oia) + !x + call LCMGET(tmpOtherIp,'x ',ora) + call LCMPUT(tmpResIp,'x ',lg,2,ora) + !y + call LCMGET(tmpOtherIp,'y ',ora) + call LCMPUT(tmpResIp,'y ',lg,2,ora) + deallocate(ora,oia) + do i = 1,lg + nGig = i2s(i) + call LCMSIX(tmpOtherIp,nGig,1) + call LCMLEN(tmpOtherIp,'gig ',lgO,ty) + allocate(oia(lgO),mrg(lgO)) + call LCMGET(tmpOtherIp,'gig ',oia) + call LCMGET(tmpOtherIp,'mrg ',mrg) + call LCMSIX(tmpOtherIp,nGig,2) + call LCMSIX(tmpResIp,nGig,1) + call LCMPUT(tmpResIp,'gig ',lgO,1,oia) + call LCMPUT(tmpResIp,'mrg ',lgO,1,mrg) + call LCMSIX(tmpResIp,nGig,2) + deallocate(oia,mrg) + end do + end if + end subroutine mergeDic + + subroutine compileResutats(geoIp,lCentreIp,lSideIp,boundDataIp) + type(c_ptr),intent(in) :: geoIp,lCentreIp,lSideIp,boundDataIp + + type(c_ptr) :: geo,centres + integer :: i,lg,ty,lgG + character*12 :: carreName,saveCarreName,gigName,num,mrgName + real,dimension(2) :: sideXY + real,dimension(4) :: minmaxXY + real,dimension(:),allocatable :: xx,yy + integer,dimension(:),allocatable :: tt,gigI,mrgI + + geo = geoIp ; centres = lCentreIp + call LCMSIX(geo,'NEW-DATA ',1) + carreName = ' ' + call LCMNXT(centres,carreName) + saveCarreName = carreName + do + call LCMSIX(geo,carreName,1) + !SIDEXY + call LCMGET(lSideIp,'x'//carreName,sideXY(1)) + call LCMGET(lSideIp,'y'//carreName,sideXY(2)) + if (geomTyp==RecTyp) then + call LCMPUT(geo,'SIDEXY ',2,2,sideXY) + else + call LCMPUT(geo,'SIDEXY ',2,2,sideXY(1)) + end if + !COORDX , COORDY , TURN , POSi + call LCMSIX(centres,carreName,1) + call LCMSIX(centres,'root ',1) + call LCMLEN(centres,'t ',lg,ty) + allocate(xx(lg),yy(lg),tt(lg)) + call LCMGET(centres,'x ',xx) + call LCMPUT(geo,'COORDX ',lg,2,xx) + call LCMGET(centres,'y ',yy) + call LCMPUT(geo,'COORDY ',lg,2,yy) + call LCMGET(centres,'t ',tt) + call LCMPUT(geo,'TURN ',lg,1,tt) + do i = 1,lg + num = i2s(i) + gigName = num + call LCMSIX(centres,gigName,1) + call LCMLEN(centres,'gig ',lgG,ty) + allocate(gigI(lgG),mrgI(lgG)) + call LCMGET(centres,'gig ',gigI) + call LCMGET(centres,'mrg ',mrgI) + call LCMSIX(centres,gigName,2) + gigName = 'POS' // num(:9) + call LCMPUT(geo,gigName,lgG,1,gigI) + mrgName = 'MRG' // num(:9) + call LCMPUT(geo,mrgName,lgG,1,mrgI) + deallocate(gigI,mrgI) + end do + deallocate(xx,yy,tt) + call LCMSIX(centres,'root ',2) + call LCMSIX(centres,carreName,2) + !on cycle + call LCMSIX(geo,carreName,2) + call LCMNXT(centres,carreName) + if (carreName==saveCarreName) exit + end do + !donnes sur les CL + call LCMSIX(geo,'BOUND-DATA ',1) + !SIDEXY + call LCMGET(lSideIp,'xroot ',sideXY(1)) + call LCMGET(lSideIp,'yroot ',sideXY(2)) + call LCMPUT(geo,'SIDEXY ',2,2,sideXY) + !MINMAXXY + call LCMGET(boundDataIp,'minX ',minmaxXY(1)) + call LCMGET(boundDataIp,'minY ',minmaxXY(2)) + call LCMGET(boundDataIp,'maxX ',minmaxXY(3)) + call LCMGET(boundDataIp,'maxY ',minmaxXY(4)) + call LCMPUT(geo,'MINMAXXY ',4,2,minmaxXY) + end subroutine compileResutats + + subroutine creerEtChargerNewDataHex(geoIp,szB,szP) + type(c_ptr),intent(in) :: geoIp + integer,intent(inout) :: szB,szP + + real,dimension(:),allocatable :: txx,tyy + integer,dimension(:),allocatable :: turn,mix,merg + character*12,dimension(:),allocatable :: cells + real :: side + double precision :: sdX,sdY + integer,dimension(40) :: sv + type(c_ptr) :: ip + integer :: nbH,lg,typ,iHex,i,j,k,l + integer :: a,b,aa,bb,nbC,ind,lgSide + integer,dimension(6) :: da,db + real,dimension(4) :: fooData + + ip = geoIp + !ajout de donnees pour le cas d'une seule cellule + call LCMSIX(ip,'NEW-DATA ',1) + call LCMSIX(ip,'BOUND-DATA ',1) + fooData = 0. + call LCMPUT(ip,'MINMAXXY ',4,2,fooData) + call LCMSIX(ip,'BOUND-DATA ',2) + call LCMSIX(ip,'NEW-DATA ',2) + !placement des cellules + call LCMGET(ip,'STATE-VECTOR',sv) + nbH=sv(3) + nbC=sv(9) + if ((sv(8)==0).and.(nbH==1)) then !pas de sous-cellules + call giveSide(ip,szB,side) + fooData(1)=2.0*side + fooData(2)=2.0*sqrt(0.75)*side + call LCMPUT(ip,'SIDEXY ',4,2,fooData) + call chargerNewData(geoIp,szB,szP) + return + end if + allocate(txx(nbH),tyy(nbH),turn(nbH),mix(nbH),merg(nbH)) + call LCMGET(ip,'MIX ',mix) + call LCMLEN(ip,'TURN ',lg,typ) + if (lg/=0) then + call LCMGET(ip,'TURN ',turn) + else + turn = 1 + end if + call LCMLEN(ip,'MERGE ',lg,typ) + if (lg/=0) then + call LCMGET(ip,'MERGE ',merg) + else + merg(:nbH) = (/(i,i=1,nbH)/) + end if + call LCMGET(ip,'IHEX ',iHex) + lgSide = 0 + select case(iHex) + case(H_S30) + a = -1 ; l = 0 ; i = 0 + do + i = i + 1 + do j = 0,1 + a = a + 1 ; b = j + do k = 1,i + l = l + 1 ; txx(l) = a ; tyy(l) = b ; lgSide = 2*b ; b = b + 2 + if (l==nbH) goto 10 + end do + end do + end do + case(H_SA60) + l = 0 ; i = -1 + do + i = i + 1 ; a = i ; b = -i + do j = 0,i + l = l + 1 ; txx(l) = a ; tyy(l) = b ; lgSide = 2*b ; b = b + 2 + if (l==nbH) goto 10 + end do + end do + case(H_SB60) + a = -1 ; l = 0 ; i = 0 + do + i = i + 1 + do j = 0,1 + a = a + 1 ; b = j + do k = 0,i + l = l + 1 ; txx(l) = a ; tyy(l) = b ; lgSide = 2*b ; b = b + 2 + if (l==nbH) goto 10 + end do + aa = a ; bb = b + do k = 0,i-1 + l = l + 1 ; aa = aa - 1 ; bb = bb + 1 + txx(l) = aa ; tyy(l) = bb + if (l==nbH) goto 10 + end do + end do + end do + case(H_S90) + da = (/0,-1,0,0,0,0/) ; db = (/2,1,0,0,0,0/) ; l = 1 ; i = 0 + txx(l) = 0 ; tyy(l) = 0 + if (l==nbH) goto 10 + do + i = i + 1 ; a = i ; b = -i + do j = 1,2 + do k = 1,i + a = a + da(j) ; b = b + db(j) + if (b>=0) then + l = l + 1 ; txx(l) = a ; tyy(l) = b ; lgSide = b + if (l==nbH) goto 10 + end if + end do + end do + end do + case(H_R120) + da = (/0,-1,0,0,0,0/) ; db = (/2,1,0,0,0,0/) ; l = 1 ; i = 0 + txx(l) = 0 ; tyy(l) = 0 + if (l==nbH) goto 10 + do + i = i + 1 ; a = i ; b = -i + do j = 1,2 + do k = 1,i + a = a + da(j) ; b = b + db(j) + l = l + 1 ; txx(l) = a ; tyy(l) = b ; lgSide = b + if (l==nbH) goto 10 + end do + end do + end do + case(H_R180) + da = (/1,0,-1,0,0,0/) ; db = (/1,2,1,0,0,0/) ; l = 1 ; i = 0 + txx(l) = 0 ; tyy(l) = 0 + if (l==nbH) goto 10 + do + i = i + 1 ; a = 0 ; b = -2*i + do j = 1,3 + do k = 1,i + a = a + da(j) ; b = b + db(j) + l = l + 1 ; txx(l) = a ; tyy(l) = b ; lgSide = b + if (l==nbH) goto 10 + end do + end do + end do + case(H_SA180) + da = (/1,0,-1,0,0,0/) ; db = (/1,2,1,0,0,0/) ; l = 1 ; i = 0 + txx(l) = 0 ; tyy(l) = 0 + if (l==nbH) goto 10 + do + i = i + 1 ; a = 0 ; b = -2*i + l = l + 1 ; txx(l) = a ; tyy(l) = b + if (l==nbH) goto 10 + do j = 1,3 + do k = 1,i + a = a + da(j) ; b = b + db(j) + l = l + 1 ; txx(l) = a ; tyy(l) = b ; lgSide = b + if (l==nbH) goto 10 + end do + end do + end do + case(H_SB180) + da = (/0,-1,-1,0,0,0/) ; db = (/2,1,-1,-2,0,0/) ; l = 1 ; i = 0 + txx(l) = 0 ; tyy(l) = 0 + if (l==nbH) goto 10 + do + i = i + 1 ; a = i ; b = -i + do j = 1,4 + do k = 1,i + if (b>=0) then + l = l + 1 ; txx(l) = a ; tyy(l) = b ; lgSide = -2*a + if (l==nbH) goto 10 + end if + a = a + da(j) ; b = b + db(j) + end do + end do + end do + case(H_Complete) + da = (/-1,-1,0,1,1,0/) ; db = (/1,-1,-2,-1,1,2/) ; l = 1 ; i = 0 + txx(l) = 0 ; tyy(l) = 0 + if (l==nbH) goto 10 + do + i = i + 1 ; a = i ; b = i + do j = 1,6 + do k = 1,i + l = l + 1 ; txx(l) = a ; tyy(l) = b ; lgSide = 2*a + if (l==nbH) goto 10 + a = a + da(j) ; b = b + db(j) + end do + end do + end do + end select +10 continue !sortie de la boucle de remplissage des positions (bhaaa, un goto) + call giveSide(ip,szB,side) + sdX = side*1.5d0 ; sdY = side*0.5d0*sqrt(3.d0) + bCData%sidexy(1) = side ; bCData%sidexy(2) = lgSide * sdY + if (sv(8)==0) then !no sub-geometries + do j = 1,nbH + szP = szP + 1 + tabCellulePlaced(szP)%indice = 1 + tabCellulePlaced(szP)%xcenter = txx(j)*sdX + tabCellulePlaced(szP)%ycenter = tyy(j)*sdY + tabCellulePlaced(szP)%turn = turn(j) + allocate(tabCellulePlaced(szP)%gig(1)) + tabCellulePlaced(szP)%gig(1) = j + allocate(tabCellulePlaced(szP)%mrg(1)) + tabCellulePlaced(szP)%mrg(1) = merg(j) + enddo + else + allocate(cells(nbC)) + call LCMGTC(ip,'CELL ',12,nbC,cells) + do i = 1,szB + ind = 0 + do j = 1,szB + if (cells(i)==tabCelluleBase(j)%name) then + ind = j + exit + end if + end do + if (ind==0) call XABORT("G2S: internal error in function& + & creerEtChargerNewDataHex") + do j = 1,nbH + if (mix(j)==-i) then + !on va creer une cellule placee d'indice ind en position j + szP = szP + 1 + tabCellulePlaced(szP)%indice = ind + tabCellulePlaced(szP)%xcenter = txx(j)*sdX + tabCellulePlaced(szP)%ycenter = tyy(j)*sdY + tabCellulePlaced(szP)%turn = turn(j) + allocate(tabCellulePlaced(szP)%gig(1)) + tabCellulePlaced(szP)%gig(1) = j + allocate(tabCellulePlaced(szP)%mrg(1)) + tabCellulePlaced(szP)%mrg(1) = merg(j) + end if + end do + end do + deallocate(cells) + endif + deallocate(txx,tyy,turn,mix,merg) + end subroutine creerEtChargerNewDataHex + + subroutine giveSide(ip,szB,side) + type(c_ptr),intent(in) :: ip + integer,intent(in) :: szB + real,intent(inout) :: side + + integer :: i,lg,typ + logical :: gotIt + double precision :: dside + + gotIt = .false. + call LCMLEN(ip,'SIDE ',lg,typ) + if (lg/=0) then + call LCMGET(ip,'SIDE ',side) + gotIt = .true. + dside = side + end if + do i = 1,szB + if (tabCelluleBase(i)%ok(n_side)) then + if (gotIt) then + if (.not. isEqual(tabCelluleBase(i)%side,dside)) & + & call XABORT("G2S: Error in the value of argument SIDE& + & in the geometry") + else + gotIt = .true. + dside = tabCelluleBase(i)%side + end if + else if (gotIt) then + tabCelluleBase(i)%side = dside + end if + end do + if (.not. gotIt) then + call XABORT("G2S: Error in the value of argument SIDE in the geometry") + end if + do i = 1,szB + tabCelluleBase(i)%ok(n_side) = .true. + tabCelluleBase(i)%side = dside + end do + side = real(dside) + end subroutine giveSide + + subroutine creerEtChargerNewDataTri(geoIp,szB,szP) + type(c_ptr),intent(in):: geoIp + integer,intent(inout) :: szB,szP + + type(c_ptr) :: ip,lcIp,dicoIp,sidesIp,lCentreIp,centreCalculesIp + integer :: szLc + + ip = geoIp + !creation de la liste des triangles + call LCMOP(lcIp,'lc ',0,1,0) + call creeListeCellules(lcIp,ip,szLc) + + !creation d'une structure pour le calcul des longueurs des cotes + call LCMOP(dicoIp,'dico ',0,1,0) + call creeStructure(dicoIp,lcIp,szLc) + + !creation de la liste des longueurs des cotes et resolution du systeme + !et destruction de la structure + call LCMOP(sidesIp,'sides ',0,1,0) + call resoudStructure(dicoIp,sidesIp) + call LCMCL(dicoIp,2) + + !cree et prepare la liste des centres des cellules de base, + !avec leur gigogne d'origine + call LCMOP(lCentreIp,'centres ',0,1,0) + call prepareCentresTri(lCentreIp,lcIp,szLc,sidesIp) + + !resolution du systeme donnant les coordonnees des centres des cellules + !de base et stockage dans une nouvelle structure + call LCMOP(centreCalculesIp,'resCentres ',0,1,0) + call calculeCentre(centreCalculesIp,lCentreIp,0) + + !compilation des resultats et ajout dans la geometrie des nouvelles donnees + call compileResutatsTri(ip,lcIp,szLc,centreCalculesIp,sidesIp) + call LCMCL(lcIp,2) + call LCMCL(centreCalculesIp,2) + call LCMCL(sidesIp,2) + !utilisation des donnees (on accroche le traitement classique developpe + !pour python) + call chargerNewData(geoIp,szB,szP) + end subroutine creerEtChargerNewDataTri + + subroutine creeStructure(dicoIp,lcIp,szLc) + type(c_ptr),intent(in) :: dicoIp,lcIp + integer,intent(in) :: szLc + + character*12 :: triName + type(c_ptr) :: triIp,dIp + integer :: i,j,k,lg,ty,lenMix,lignNbr + real :: side,value + integer,dimension(40) :: sv + integer,dimension(:),allocatable :: mix + character*12,dimension(:),allocatable :: cell + + !initialisation + dIp = dicoIp + triName = ' ' + do i = 1,szLc + call LCMNXT(lcIp,triName) + triIp=LCMGID(lcIp,triName) + side = -1. + call LCMLEN(triIp,'SIDE ',lg,ty) + if (lg/=0) call LCMGET(triIp,'SIDE ',side) + call LCMSIX(dIp,triName,1) + call LCMPUT(dIp,'value',1,2,side) + call LCMSIX(dIp,triName,2) + end do + !remplissage + dIp = dicoIp + triName = ' ' + lignNbr = 0 + do k = 1,szLc + !tavail sur la kieme cellule + call LCMNXT(lcIp,triName) + triIp=LCMGID(lcIp,triName) + call LCMGET(triIp,'STATE-VECTOR',sv) + call LCMLEN(triIp,'MIX ',lenMix,ty) + if ((lenMix==1).or.(sv(9)==0)) cycle !pas d'info a retirer + allocate(mix(lenMix),cell(sv(9))) + call LCMGET(triIp,'MIX ',mix) + !on teste si tous les milieux sont bien negatifs + do i = 1,lenMix + if (mix(i)<0) cycle + call XABORT("G2S: error, meltig MIX and CELL not supported") + end do + call LCMGTC(triIp,'CELL ',12,sv(9),cell) + !on traite les donnees + !dans le triangle considere + call LCMSIX(dIp,triName,1) + value = 1.*sv(3) + do i = 1,lenMix + call LCMPUT(dIp,cell(-mix(i)),1,2,value) + end do + call LCMSIX(dIp,triName,2) + !dans les autres + value = 1./sv(3) + do i = 1,sv(9) + call LCMSIX(dIp,cell(i),1) + do j = 1,sv(9) + if (j==i) cycle + call LCMPUT(dIp,cell(j),1,2,1.) + end do + call LCMPUT(dIp,triName,1,2,value) + call LCMSIX(dIp,cell(i),2) + end do + deallocate(mix,cell) + end do + end subroutine creeStructure + + subroutine resoudStructure(dicoIp,resIp) + type(c_ptr),intent(in) :: dicoIp,resIp + + type(c_ptr) :: dIp + logical :: fini,flag1,flag2 + integer :: long,typ + character*12 :: triName,saveTriName + character*131:: hsmg + real :: val + + fini = .false. + flag1 = .true. + do + if (fini) exit + fini = .true. + flag2 = flag1 !garde la valeur de flag1 a l'essai precedent + flag1 = .false. + triName = ' ' + call LCMNXT(dicoIp,triName) + saveTriName = triName + do !boucle sur toutes les donnees du dico + fini = fini .and. evaluateLine(dicoIp,triName) + !test si fini a ete vrai au moins une fois + if (fini) flag1 = .true. + call LCMNXT(dicoIp,triName) + if (triName == saveTriName) exit + end do + if (.not.(flag1 .or. flag2)) then + !il ne s'est rien passe au cours des 2 tentatives + !precedentes => on abandonne + call XABORT("G2S: not enought data in the geometry(2)") + end if + end do + !recopie des resultats + dIp = dicoIp + triName = ' ' + call LCMNXT(dIp,triName) + saveTriName = triName + do + call LCMSIX(dIp,triName,1) + call LCMLEN(dIp,'value',long,typ) + if(long == 0) then + write(hsmg,'(36hG2S: value key missing for triName=,a,5h (3).)') trim(triName) + call LCMLIB(dIp) + call LCMLIB(dicoIp) + call XABORT(hsmg) + endif + call LCMGET(dIp,'value',val) + call LCMPUT(resIp,triName,1,2,val) + call LCMSIX(dIp,triName,2) + call LCMNXT(dIp,triName) + if (triName == saveTriName) exit + end do + end subroutine resoudStructure + + function evaluateLine(dicoIp,triName) + type(c_ptr),intent(in) :: dicoIp + character*12,intent(in) :: triName + logical :: evaluateLine + + type(c_ptr) :: triIp + integer :: long,typ + character*12 :: eqName,saveEqName + character*131:: hsmg + real :: factor,val,res + + evaluateLine = .true. + triIp = dicoIp + call LCMSIX(triIp,triName,1) + eqName = ' ' + call LCMNXT(triIp,eqName) + saveEqName = eqName + do !boucle sur toutes les equations de triName + if (eqName=='value') then + call LCMNXT(triIp,eqName) + if (eqName==saveEqName) exit + end if + call getValueOf(eqName,dicoIp,val) + if (val<0.) then + evaluateLine = .false. + else + call LCMGET(triIp,eqName,factor) + res = val * factor + call LCMLEN(triIp,'value',long,typ) + if(long == 0) then + write(hsmg,'(36hG2S: value key missing for eqName=,a,5h (4).)') trim(eqName) + call LCMLIB(triIp) + call LCMLIB(dicoIp) + call XABORT(hsmg) + endif + call LCMGET(triIp,'value',val) + if (val<0.) then + call LCMPUT(triIp,'value',1,2,res) + else if (abs(val-res)>geomPrec) then + call XABORT("G2S: error, incoherent geometry(3)") + end if + end if + call LCMNXT(triIp,eqName) + if (eqName==saveEqName) exit + end do + end function evaluateLine + + subroutine prepareCentresTri(lCentreIp,lcIp,szLc,sidesIp) + type(c_ptr),intent(in) :: lCentreIp,lcIp,sidesIp + integer,intent(in) :: szLc + + character*12 :: triName + type(c_ptr) :: triIp + integer :: i,j,k,lenMix,ind,iTri,lg,ty + real :: dsidex,dsidey,xi,yj + integer,dimension(40) :: sv + real,dimension(:),allocatable :: xx,yy + integer,dimension(:),allocatable :: mix,turn,merg + character*12,dimension(:),allocatable :: cell + + triName = ' ' + do k = 1,szLc + !tavail sur la kieme cellule + call LCMNXT(lcIp,triName) + triIp=LCMGID(lcIp,triName) + call LCMGET(triIp,'STATE-VECTOR',sv) + call LCMLEN(triIp,'MIX ',lenMix,ty) + if ((lenMix==1).or.(sv(9)==0)) cycle !pas d'info a retirer + allocate(mix(lenMix),turn(lenMix),merg(lenMix), & + xx(lenMix),yy(lenMix),cell(sv(9))) + call LCMGET(triIp,'MIX ',mix) + call LCMGET(triIp,'TURN ',turn) + call LCMLEN(triIp,'MERGE ',lg,ty) + if (lg/=0) then + call LCMGET(triIp,'MERGE ',merg) + else + merg = (/(i,i=1,lenMix)/) + end if + call LCMGTC(triIp,'CELL ',12,sv(9),cell) + call LCMGET(sidesIp,cell(1),dsidex) + dsidex = 0.5*dsidex + dsidey = sqrt_3f*dsidex + iTri = T_ST60 + if (triName=='root') call LCMGET(triIp,'ITRI ',iTri) + select case(iTri) + case(T_ST60) !triangle normal ou 'root en ST60' + ind = 0 + yj = (1-sv(4))*0.5*dsidey + do j = 1,sv(4) + xi = (j-sv(3))*dsidex + do i = 1,2*(sv(3)-j)+1 + ind = ind + 1 + xx(ind) = xi + yy(ind) = yj + xi = xi + dsidex + end do + yj = yj + dsidey + end do + case(T_S30) + ind = 0 + yj = 0.5*dsidey + do j = 1,sv(4) + xi = (3*j-2)*dsidex + do i = 1,sv(3)-3*(j-1) + ind = ind + 1 + xx(ind) = xi + yy(ind) = yj + xi = xi + dsidex + end do + yj = yj + dsidey + end do + case(T_SA60) + ind = 0 + yj = -(2*sv(4)-1)*0.5*dsidey + do j = 1,sv(4) + xi = (3*(sv(4)-j)+1)*dsidex + do i = 1,3*j-2+mod(sv(3)-1,3) + ind = ind + 1 + xx(ind) = xi + yy(ind) = yj + xi = xi + dsidex + end do + yj = yj + dsidey + end do + yj = 0.5*dsidey + do j = 1,sv(4) + xi = (3*j-2)*dsidex + do i = 1,sv(3)-3*(j-1) + ind = ind + 1 + xx(ind) = xi + yy(ind) = yj + xi = xi + dsidex + end do + yj = yj + dsidey + end do + case(T_Complete) + ind = 0 + yj = (1-sv(4))*0.5*dsidey + do j = 1,sv(4) + xi = (j-sv(3))*dsidex + do i = 1,2*sv(3) + ind = ind + 1 + xx(ind) = xi + yy(ind) = yj + xi = xi + dsidex + end do + yj = yj + dsidey + end do + end select + do i = 1,lenMix + call addInRes(lCentreIp,cell(-mix(i)),triName,xx(i), & + yy(i),turn(i),i,merg(i)) + end do + deallocate(mix,turn,merg,xx,yy,cell) + end do + end subroutine prepareCentresTri + + subroutine compileResutatsTri(geoIp,lcIp,szLc,centreCalculesIp,sidesIp) + type(c_ptr),intent(in) :: geoIp,lcIp,centreCalculesIp,sidesIp + integer,intent(in) :: szLc + + type(c_ptr) :: lMinMaxIp,sidexyIp + integer :: i,iTri + character*12 :: cellName + real :: val + integer,dimension(40) :: sv + + call LCMOP(lMinMaxIp,'minAndMaxXY ',0,1,0) + call LCMPUT(lMinMaxIp,'minX ',1,2,0.) + call LCMPUT(lMinMaxIp,'maxX ',1,2,0.) + call LCMPUT(lMinMaxIp,'minY ',1,2,0.) + call LCMPUT(lMinMaxIp,'maxY ',1,2,0.) + + call LCMOP(sidexyIp,'sidesXY ',0,1,0) + cellName = ' ' + do i = 1,szLc + call LCMNXT(lcIp,cellName) + call LCMGET(sidesIp,cellName,val) + call LCMPUT(sidexyIp,'x'//cellName(1:11),1,2,val) + call LCMPUT(sidexyIp,'y'//cellName(1:11),1,2,val) + if (cellName=='root') then !modification de xroot et yroot si besoin + call LCMGET(geoIp,'STATE-VECTOR',sv) + call LCMGET(geoIp,'ITRI ',iTri) + select case(iTri) + case(T_Complete) + val=val*sv(4)/real(sv(3)) + call LCMPUT(sidexyIp,'y'//cellName(1:11),1,2,val) + case(T_S30,T_SA60) + val=val/real(sv(3)) + call LCMPUT(sidexyIp,'x'//cellName(1:11),1,2,val) + val=val*int((sv(3)+1)/2) + call LCMPUT(sidexyIp,'y'//cellName(1:11),1,2,val) + end select + end if + end do + + call compileResutats(geoIp,centreCalculesIp,sidexyIp,lMinMaxIp) + + call LCMCL(lMinMaxIp,2) + call LCMCL(sidexyIp,2) + end subroutine compileResutatsTri + +end module pretraitement |
