! !----------------------------------------------------------------------- ! !Purpose: ! Creation of an array of type(t_celluleBase) structures. ! !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: ! Il s'agit de toutes les cellules terminales de la geometrie (=celles qui ! ne comportent pas de sous-cellules). ! La creation se fait a l'aide de la routine recursive buildCellsBase. ! Elle explore toute l'arboressence de l'objet PyLCM donne en entree, et appelle ! a chaque niveau la routine writeCellBase. ! Celle-ci teste si la cellule est terminale, et cree une entree dans le tableau ! des cellules de base si c'est le cas. ! La cellule creee est ensuite completee si besoin, et sa coherence est ! verifiee ! \\\\ ! variable globale ! - tabCelluleBase : tableau des cellules de base ! \\\\ ! fonctions du module ! - initializeTabCelluleBase : mise a zero du tableau ! - destoyTabCelluleBase : liberation de la memoire ! - decale : decale les valeurs d'un tableau pour les faire demarer a 0 ! - createCB : constructeur d'une cellule de base ! - destroyCB : destructeur d'une cellule de base ! - createCluster : constructeur d'un cluster ! - sortClusterTab : trie un tableau de clusters ! - verrifieCB : verification de la coherence d'une cellule de base ! - exploiteSplit : exploitation de la donnee split dans la cellule ! - buildCellsBase : fonction recursive de creation du tableau de cellules ! - writeCellBase : creation d'une cellule ! !----------------------------------------------------------------------- ! module celluleBase use constType use GANLIB use segArc, only : alloc_ok implicit none !cluster type t_cluster character*12 :: name !nom integer :: nbrPin !nombre de crayons double precision :: radiusOfPin !rayon de la couronne double precision :: angleOfPin !angle du 1er crayon double precision,dimension(:),pointer :: radius !rayons des anneaux integer,dimension(:),pointer :: mix !milieux des crayons end type t_cluster !cellule generique de plus bas niveau hierarchique dans les gigognes type t_celluleBase character*12 :: name !nom integer,dimension(40) :: sv !state vector integer,dimension(:),allocatable :: mix !milieux integer,dimension(:),allocatable :: merge !regroupements double precision,dimension(:),allocatable :: radius !rayons double precision,dimension(3) :: offcenter !x , y et z double precision,dimension(:),allocatable :: meshx !en commancant a 0.0 double precision,dimension(:),allocatable :: meshy !en commancant a 0.0 double precision :: side !pour tri et hex integer,dimension(:),allocatable :: splitr !>0 rayon; <0 surface integer,dimension(:),allocatable :: splitx !>0 integer,dimension(:),allocatable :: splity !>0 type(t_cluster),dimension(:),pointer :: cluster !les clusters !tableau de bool qui donne la presence ou non de chacun des 10 champs !avec en plus l'indice 0 disant si la cellule est viable (complete) logical,dimension(0:12) :: ok end type t_celluleBase !parametres pour le vecteur ok integer,parameter :: n_sv=1 , n_mix=2 , n_radius=3 , n_offcenter=4 , & & n_meshx=5 , n_meshy=6 , n_side=7 , n_splitr=8 , & & n_splitx=9 , n_splity=10 , n_cluster=11 , n_merge=12 , & & n_tot=0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! declaration d'une variable tableau globale !! type(t_celluleBase),dimension(:),allocatable :: tabCelluleBase !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! contains subroutine initializeTabCelluleBase(dimTabCelluleBase) integer,intent(in) :: dimTabCelluleBase allocate(tabCelluleBase(dimTabCelluleBase),stat=alloc_ok) if (alloc_ok /= 0) call XABORT("G2S: initializeTabCelluleBase(1) => allocation pb") end subroutine initializeTabCelluleBase subroutine destroyTabCelluleBase(szB) integer,intent(in) :: szB integer :: i do i = 1,szB call destroyCB(tabCelluleBase(i)) end do deallocate(tabCelluleBase) end subroutine destroyTabCelluleBase !fait demarer un tableau de reels a 0.0 subroutine decale(tab) ! double precision,dimension(:),pointer :: tab double precision,dimension(:) :: tab integer :: i, lg lg = size(tab) do i = lg,1,-1 tab(i) = tab(i) - tab(1) end do end subroutine decale !remplisage d'une cellule de base subroutine createCB(cell,name,ip) type(t_celluleBase),intent(out) :: cell character*12,intent(in) :: name type(c_ptr),intent(in) :: ip integer :: lg,typ,i,lgm real,dimension(:),allocatable :: tmpTabReal character*12,dimension(:),allocatable :: clusterName cell%name = name call LCMGET(ip,'STATE-VECTOR',cell%sv) cell%ok(n_sv) = .true. call LCMLEN(ip,'MIX ',lgm,typ) cell%ok(n_mix) = (lgm/=0) if(cell%ok(n_mix)) then allocate(cell%mix(lgm),stat=alloc_ok) if (alloc_ok /= 0) call XABORT("G2S: createCB(1) => allocation pb") call LCMGET(ip,'MIX ',cell%mix) else call XABORT("G2S: no mix in the cellule " // name) end if call LCMLEN(ip,'MERGE ',lg,typ) cell%ok(n_merge) = (lg/=0) if(cell%ok(n_merge)) then if(lg/=lgm) call XABORT("G2S: bad dimension for merge in the & &cellule " // name) allocate(cell%merge(lg),stat=alloc_ok) if (alloc_ok /= 0) call XABORT("G2S: createCB(2) => allocation pb") call LCMGET(ip,'MERGE ',cell%merge) else allocate(cell%merge(lgm),stat=alloc_ok) if (alloc_ok /= 0) call XABORT("G2S: createCB(3) => allocation pb") cell%merge(:lgm) = (/(i,i=1,lgm)/) end if call LCMLEN(ip,'RADIUS ',lg,typ) cell%ok(n_radius) = (lg/=0) if(cell%ok(n_radius)) then allocate(cell%radius(lg),tmpTabReal(lg),stat=alloc_ok) if (alloc_ok /= 0) call XABORT("G2S: createCB(4) => allocation pb") call LCMGET(ip,'RADIUS ',tmpTabReal) cell%radius(:lg)=tmpTabReal(:lg) deallocate(tmpTabReal) else if(cell%sv(1)==G_Carcel.or.cell%sv(1)==G_Hexcel) then !cas carcel 0 ou hexcel 0 allocate(cell%radius(1)) cell%radius(1)=0.d0 else !nullify(cell%radius) end if call LCMLEN(ip,'OFFCENTER ',lg,typ) cell%ok(n_offcenter) = (lg/=0) if(cell%ok(n_offcenter)) then allocate(tmpTabReal(lg),stat=alloc_ok) if (alloc_ok /= 0) call XABORT("G2S: createCB(5) => allocation pb") call LCMGET(ip,'OFFCENTER ',tmpTabReal) cell%offcenter=tmpTabReal deallocate(tmpTabReal) else cell%offcenter=0.d0 end if call LCMLEN(ip,'MESHX ',lg,typ) cell%ok(n_meshx) = (lg/=0) if(cell%ok(n_meshx)) then allocate(cell%meshx(lg),tmpTabReal(lg),stat=alloc_ok) if (alloc_ok /= 0) call XABORT("G2S: createCB(6) => allocation pb") call LCMGET(ip,'MESHX ',tmpTabReal) cell%meshx(:lg)=tmpTabReal(:lg) deallocate(tmpTabReal) call decale(cell%meshx) !decalage pour demarer a 0.0 else !nullify(cell%meshx) end if call LCMLEN(ip,'MESHY ',lg,typ) cell%ok(n_meshy) = (lg/=0) if(cell%ok(n_meshy)) then allocate(cell%meshy(lg),tmpTabReal(lg),stat=alloc_ok) if (alloc_ok /= 0) call XABORT("G2S: createCB(7) => allocation pb") call LCMGET(ip,'MESHY ',tmpTabReal) cell%meshy(:lg)=tmpTabReal(:lg) deallocate(tmpTabReal) call decale(cell%meshy) !decalage pour demarer a 0.0 else !nullify(cell%meshy) end if call LCMLEN(ip,'SIDE ',lg,typ) cell%ok(n_side) = (lg/=0) if(cell%ok(n_side)) then allocate(tmpTabReal(lg),stat=alloc_ok) if (alloc_ok /= 0) call XABORT("G2S: createCB(8) => allocation pb") call LCMGET(ip,'SIDE ',tmpTabReal) cell%side=tmpTabReal(1) deallocate(tmpTabReal) else cell%side=0.d0 end if call LCMLEN(ip,'SPLITR ',lg,typ) cell%ok(n_splitr) = (lg/=0) if(cell%ok(n_splitr)) then allocate(cell%splitr(lg),stat=alloc_ok) if (alloc_ok /= 0) call XABORT("G2S: createCB(9) => allocation pb") call LCMGET(ip,'SPLITR ',cell%splitr) else !nullify(cell%splitr) end if call LCMLEN(ip,'SPLITX ',lg,typ) cell%ok(n_splitx) = (lg/=0) if(cell%ok(n_splitx)) then allocate(cell%splitx(lg),stat=alloc_ok) if (alloc_ok /= 0) call XABORT("G2S: createCB(10) => allocation pb") call LCMGET(ip,'SPLITX ',cell%splitx) else if(cell%sv(1)==G_Car2d.or.cell%sv(1)==G_Carcel) then allocate(cell%splitx(cell%sv(3)),stat=alloc_ok) if (alloc_ok /= 0) call XABORT("G2S: createCB(11) => allocation pb") cell%splitx = 1 else allocate(cell%splitx(1)) cell%splitx(1) = 1 end if call LCMLEN(ip,'SPLITY ',lg,typ) cell%ok(n_splity) = (lg/=0) if(cell%ok(n_splity)) then allocate(cell%splity(lg),stat=alloc_ok) if (alloc_ok /= 0) call XABORT("G2S: createCB(12) => allocation pb") call LCMGET(ip,'SPLITY ',cell%splity) else if(cell%sv(1)==G_Car2d.or.cell%sv(1)==G_Carcel) then allocate(cell%splity(cell%sv(4)),stat=alloc_ok) if (alloc_ok /= 0) call XABORT("G2S: createCB(13) => allocation pb") cell%splity = 1 else allocate(cell%splity(1)) cell%splity(1) = 1 end if call LCMLEN(ip,'CLUSTER ',lg,typ) cell%ok(n_cluster) = (lg/=0) if(cell%ok(n_cluster)) then lg = lg/3 allocate(cell%cluster(lg),clusterName(lg),stat=alloc_ok) if (alloc_ok /= 0) call XABORT("G2S: createCB(14) => allocation pb") call LCMGTC(ip,'CLUSTER ',12,lg,clusterName) do i = 1,lg cell%cluster(i) = createCluster(ip,clusterName(i)) end do !on trie le tableau des cluster par rayon croissant call sortClusterTab(cell%cluster) deallocate(clusterName) else nullify(cell%cluster) end if call verrifieCB(cell) call exploiteSplit(cell) end subroutine createCB subroutine destroyCB(cell) type(t_celluleBase),intent(inout) :: cell integer :: i if(allocated(cell%mix)) deallocate(cell%mix) if(allocated(cell%merge)) deallocate(cell%merge) if(allocated(cell%radius)) deallocate(cell%radius) if(allocated(cell%meshx)) deallocate(cell%meshx) if(allocated(cell%meshy)) deallocate(cell%meshy) if(allocated(cell%splitr)) deallocate(cell%splitr) if(allocated(cell%splitx)) deallocate(cell%splitx) if(allocated(cell%splity)) deallocate(cell%splity) if(associated(cell%cluster)) then do i = 1,size(cell%cluster) deallocate(cell%cluster(i)%mix,cell%cluster(i)%radius) !nullify(cluster%mix,cell%cluster(i)%radius) end do deallocate(cell%cluster) end if end subroutine destroyCB function createCluster(cellBIp,clusterName) type(c_ptr),intent(in) :: cellBIp character*12,intent(in) :: clusterName type(t_cluster) :: createCluster type(c_ptr) :: ip integer :: lg,lgx,lgy,ty real :: rpin,apin,cx,cy real,dimension(:),allocatable :: radius real, parameter :: pi = 3.141592653589793 ip = cellBIp call LCMSIX(ip,clusterName,1) createCluster%name = clusterName call LCMLEN(ip,'CPINX ',lgx,ty) call LCMLEN(ip,'CPINY ',lgy,ty) if ((lgx==1).and.(lgy==1)) then createCluster%nbrPin = 1 call LCMGET(ip,'CPINX ',cx) call LCMGET(ip,'CPINY ',cy) rpin = sqrt(cx**2+cy**2) if((cy == 0.0).and.(cy == 0.0)) then rpin = 0.0 apin = 0.0 else if(cy >= 0.0) then apin = acos(cx/rpin) else apin = 2.0*pi-acos(cx/rpin) endif else call LCMGET(ip,'NPIN ',createCluster%nbrPin) call LCMGET(ip,'RPIN ',rpin) call LCMGET(ip,'APIN ',apin) endif createCluster%radiusOfPin = rpin createCluster%angleOfPin = apin call LCMLEN(ip,'MIX ',lg,ty) allocate(radius(lg+1),createCluster%radius(lg+1),createCluster%mix(lg),stat=alloc_ok) if (alloc_ok /= 0) call XABORT("G2S: createCluster => allocation pb") call LCMGET(ip,'RADIUS ',radius) createCluster%radius(:lg+1) = radius(:lg+1) deallocate(radius) call LCMGET(ip,'MIX ',createCluster%mix) end function createCluster subroutine sortClusterTab(clusterPrt) type(t_cluster),dimension(:),pointer :: clusterPrt !trie le tableau des clusters par rayon croissant des couronnes type(t_cluster) :: tmpCluster integer :: sz,indMax,i logical :: trie if(.not. associated(clusterPrt)) return !pas de cluster sz = size(clusterPrt) do indMax = sz,2,-1 trie = .true. do i = 1,indMax-1 if(clusterPrt(i+1)%radiusOfPin1 ly>1 is incompatinle with SECT") select case(sectori) case(S_not) nsectint=1 nsectext=1 case(S_X_tot,S_T_tot) nsectint=4 if(sectorj /= 0) nsectint=1 nsectext=4 case(S_TX_tot,S_TXS_tot) nsectint=8 if(sectorj /= 0) nsectint=1 nsectext=8 case(S_WM_tot) nsectint=12 if(sectorj /= 0) nsectint=1 nsectext=12 end select case(G_Hexcel) select case(sectori) case(S_not) nsectint=1 nsectext=1 case(S_X_tot) nsectint=6 if(sectorj /= 0) nsectint=1 nsectext=6 end select end select if(nx*ny.gt.1) then longueur2=nx*ny*(longueur+1) else longueur2=nsectint*longueur+nsectext endif allocate(tmpRad(longueur+1),tmpMix(longueur2),tmpMrg(longueur2),stat=alloc_ok) if (alloc_ok /= 0) call XABORT("G2S: exploitSplit(1) => allocation pb") tmpRad(1)=0.d0 k = 1 k2= 1 do i = 1,size(cell%splitr) valS = cell%splitr(i) if(valS==0) then call XABORT("G2S : SPLITR may not be null") else if(valS>0) then !on coupe en sous-rayons egaux -> moyenne arthmetique des rayons interval = (cell%radius(i+1)-cell%radius(i))/valS do j = 1,valS if(nx*ny.gt.1) then do ip=1,nx*ny tmpMix((ip-1)*(longueur+1)+k) = cell%mix((ip-1)*(size(cell%radius))+i) tmpMrg((ip-1)*(longueur+1)+k) = (ip-1)*(longueur+1)+k end do else do sect=1,nsectint tmpMix(k2) = cell%mix(nsectint*(i-1)+sect) !! BEFORE tmpMrg(k) = cell%merge(i) tmpMrg(k2) = k2 k2= k2+ 1 end do endif k = k + 1 tmpRad(k) = tmpRad(k-1) + interval end do else !on coupe en sous-surfaces egales -> moyenne geometrique des rayons valS = abs(valS) interval = (cell%radius(i+1)**2-cell%radius(i)**2)/valS do j = 1,valS if(nx*ny.gt.1) then do ip=1,nx*ny tmpMix((ip-1)*(longueur+1)+k) = cell%mix((ip-1)*(size(cell%radius))+i) tmpMrg(k) = (ip-1)*(longueur+1)+k end do else do sect=1,nsectint tmpMix(k2) = cell%mix(nsectint*(i-1)+sect) !! BEFORE tmpMrg(k) = cell%merge(i) tmpMrg(k2) = k2 k2= k2+ 1 end do endif k = k + 1 tmpRad(k) = sqrt(tmpRad(k-1)**2 + interval) end do end if end do if(nx*ny.gt.1) then do ip=1,nx*ny tmpMix(ip*(longueur+1)) = cell%mix(ip*(size(cell%radius))) tmpMrg(ip*(longueur+1)) = ip*(longueur+1) end do else do sect=1,nsectext tmpMix(k2) = cell%mix(nsectint*size(cell%splitr)+sect) !!BEFORE tmpMrg(longueur+1) = cell%merge(size(cell%merge)) tmpMrg(k2) = k2 k2= k2+ 1 end do endif deallocate(cell%radius) ; allocate(cell%radius(longueur+1),stat=alloc_ok) if (alloc_ok /= 0) call XABORT("G2S: exploiteSplit(2) => allocation pb") deallocate(cell%mix) ; allocate(cell%mix(longueur2),stat=alloc_ok) if (alloc_ok /= 0) call XABORT("G2S: exploiteSplit(3) => allocation pb") deallocate(cell%merge) ; allocate(cell%merge(longueur2),stat=alloc_ok) if (alloc_ok /= 0) call XABORT("G2S: exploiteSplit(4) => allocation pb") cell%radius(:longueur+1) = tmpRad(:longueur+1) cell%mix(:longueur2) = tmpMix(:longueur2) ; cell%merge(:longueur2) = tmpMrg(:longueur2) deallocate(tmpRad,tmpMix,tmpMrg) end subroutine exploiteSplit recursive subroutine buildCellsBase(ip,sz,dirname) type(c_ptr),intent(inout):: ip integer,intent(inout) :: sz character*12 ,intent(in) :: dirname character*12 :: namp, savename, subdirname integer :: type, long integer,parameter :: dir=0 call writeCellBase(ip,sz,dirname) namp = ' ' call LCMNXT(ip,namp) savename = namp do if(namp == ' ') exit call LCMLEN(ip,namp,long,type) if(type == dir) then if(namp /= 'BIHET') then subdirname = namp call LCMSIX(ip,namp,1) call buildCellsBase(ip,sz,subdirname) call LCMSIX(ip,namp,2) end if end if call LCMNXT(ip,namp) if(namp == savename) exit end do end subroutine buildCellsBase subroutine writeCellBase(ip,sz,dirname) type(c_ptr),intent(in) :: ip integer,intent(inout) :: sz character*12 ,intent(in) :: dirname integer,dimension(40) :: st !state vector integer :: type, long, i logical :: toCreate call LCMLEN(ip,'STATE-VECTOR',long,type) if(long==0) then !on est dans la partie nouvelle (donnees ajoutees par pretaitement !python => on sort de la subroutine return end if call LCMGET(ip,'STATE-VECTOR',st) call LCMLEN(ip,'NPIN ',long,type) ! pour tester si c'est un cluster if(st(8)==0 .and. long==0) then !pas de sous-cellules toCreate = .true. do i = 1,sz if(tabCelluleBase(i)%name==dirname) toCreate = .false. end do if(toCreate) then sz = sz + 1 !!$ allocate(tabCelluleBase(sz)%p,stat=alloc_ok) !!$ if (alloc_ok /= 0) call XABORT("G2S: writeCellBase => allocation pb") call createCB(tabCelluleBase(sz),dirname,ip) end if end if end subroutine writeCellBase end module celluleBase