ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc ccccccccccc c Percolacion en redes cuadradas c Algoritmo de Hoshen-Kopelman c c Andres Medus - Febrero 2010 - admedus@gmail.com ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc ccccccccccc implicit real*8 (a-h,o-z) implicit integer(i-n) parameter (mxd=500,mxd2=mxd*mxd) integer red !Esto solo se usa para ver la red (luego comentarlo) double precision dseed,proba common/salida/red(0:mxd,0:mxd) !Esto solo se usa para ver la red (luego comentarlo) common/arrays/nfile(0:mxd),label(1:mxd2) common/param/nperco,lado,nclus_1,nclus common/reales/pmin,pmax,proba common/seed/dseed cc cc 10 cc MAIN Primero ingresamos todas las entradas desde un archivo externo open(01,file='inputperc.doc',status='old') format(/,i3,///,f7.5,/,f7.5,///,i6,//,i6,//,i1) read(01,10)lado,pmin,pmax,npasos,ntot,nvar close(01) Para ver en pantalla las entradas write(6,*)'Lado de la red: ',lado write(6,*)'Proba minima: ',pmin write(6,*)'Proba maxima: ',pmax write(6,*)'Numero de corridas: ',npasos if(nvar.eq.0) then write(6,*) 'Semilla del randomnu.dat VARIABLE' else write(6,*) 'Semilla del randomnu.dat FIJA' endif proba=pmin !Probabilidad usada para poblar la red cc Abrimos el archivo randomnu.dat para leer la semilla de numeros pseudoaleatorios open(66,file='randomnu.doc',status='unknown') read(66,*)dseed call HK() !llamo Hoshen-Kopelman call output(lado) COMENTAR) call percola() call clusters() tamaños de clusters !!!solo para graficar la red (RECORDAR !subrutina para saber si hay o no percolacion !subrutina para encontrar la distribucion de cc Aqui reescribimos la semilla del randomnu.dat o la dejamos igual if (nvar.eq.0) then rewind(66) !para situarnos al comienzo del archivo write(66,*)dseed endif close(66) STOP END ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc c Subrutina HK: Algoritmo de Hoshen-Kopelman ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc subroutine HK() implicit real*8 (a-h,o-z) implicit integer(i-n) parameter (mxd=500,mxd2=mxd*mxd) integer red !Esto solo se usa para ver la red (luego comentarlo) double precision dseed,proba common/salida/red(0:mxd,0:mxd) !Esto solo se usa para ver la red (luego comentarlo) common/arrays/nfile(0:mxd),label(1:mxd2) common/param/nperco,lado,nclus_1,nclus common/reales/pmin,pmax,proba common/seed/dseed do j=0,lado !comenzamos desde j=0 para desocupar la fila 0 y la columna 0 nfile(j)=0 enddo nclus=0 !etiqueta de clusters label(1:mxd2)=0 nperco=0 cc cc !otra forma de inicializar un array !indicador de percolacion nfile(j) es el vector de etiquetas de filas label es el vector de etiquetas do i=1,lado !loop para las filas do j=1,lado !loop para las columnas cc Antes de actualizar nfile(j) corresponde al estado del sitio j de la fila (i-1), es decir, cc al vecino de abajo del sitio j de la fila i. cc Luego de actualizar nfile(j-1) es el estado de ocupacion del sitio (j1) de la fila i cc y, por lo tanto, el vecino izquierdo del sitio j de la fila i. if(random(dseed).le.proba)then !decido si el sitio j de la fila i estara poblado select case(nfile(j)*nfile(j-1).eq.0) !veo si el vecino izq o el de abajo estan desocupados case(.TRUE.)!alguno de los vecinos esta desocupado if(nfile(j-1).eq.0.and.nfile(j).eq.0)then cc......................si ambos vecinos estan sin poblar, uso una etiqueta nueva nclus=nclus+1 nfile(j)=nclus label(nfile(j))=1 cc......................si alguno de los dos esta poblado, el actual hereda la etiqueta elseif(nfile(j-1).ne.0)then do while(label(nfile(j-1)).lt.0) nfile(j-1)=-label(nfile(j-1)) enddo nfile(j)=nfile(j-1) label(nfile(j))=label(nfile(j))+1 else do while(label(nfile(j)).lt.0) nfile(j)=-label(nfile(j)) enddo label(nfile(j))=label(nfile(j))+1 endif case(.FALSE.)!ambos vecinos estan ocupados do while(label(nfile(j-1)).lt.0) nfile(j-1)=-label(nfile(j-1)) enddo do while(label(nfile(j)).lt.0) nfile(j)=-label(nfile(j)) enddo if(nfile(j-1).eq.nfile(j))then label(nfile(j))=label(nfile(j))+1 elseif(nfile(j-1).lt.nfile(j))then label(nfile(j-1))=label(nfile(j-1))+label(nfile(j))+1 label(nfile(j))=-nfile(j-1)!cambio la etiqueta del vecino de abajo nfile(j)=nfile(j-1) else label(nfile(j))=label(nfile(j-1))+label(nfile(j))+1 label(nfile(j-1))=-nfile(j)!cambio la etiqueta del vecino de la izquierda endif end select else nfile(j)=0 endif enddo !cierro loop de columnas if(i.eq.1)nclus_1=nclus la primera fila !con esto conozco las etiquetas de cccccccccccccccccccccccEsto solo se usa para ver la red (luego comentarlo)ccccccccccccccccccccc do j=1,lado red(i,j)=nfile(j) enddo ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc cccccccccccccccccccccc enddo !cierro loop de filas cccccccccccccccccccccccEsto solo se usa para ver la red (luego comentarlo)ccccccccccccccccccccc do i=1,lado do j=1,lado do while(label(red(i,j)).lt.0) red(i,j)=-label(red(i,j)) enddo enddo enddo ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc cccccccccccccccccccccc return end cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc c Subrutina output para graficar la red y verificar si percola c Luego de probar con redes de 4X4 a 16x16 pueden comentarla cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc subroutine output(lado) implicit real*8 (a-h,o-z) parameter (mxd=500) integer red common/salida/red(0:mxd,0:mxd) character*100 aux,aa 100 format(i2.2) aux=' ' write(6,*) "Configuracion de la red" do ii=1,lado do jj=1,lado write(aa,100) red(ii,jj) ka=index(aux,' ') aux=aux(1:ka-1)//'|'//aa enddo ka=index(aux,' ') aux=aux(1:ka-1) write(6,*) aux aux=' ' enddo return end ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc c Subrutina percola: solo indica si hay o no percolacion ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc subroutine percola() implicit real*8 (a-h,o-z) implicit integer(i-n) parameter (mxd=500,mxd2=mxd*mxd) common/arrays/nfile(0:mxd),label(1:mxd2) common/param/nperco,lado,nclus_1,nclus nperco=0 do ii=1,lado if(nfile(ii).ne.0)then !aqui nfile seria la fila superior do while(label(nfile(ii)).lt.0) nfile(ii)=-label(nfile(ii)) enddo if(nfile(ii).le.nclus_1)then nperco=1 exit !salgo del loop porque ya se que percola endif endif enddo ccccccccccccccCOMENTAR LUEGO DE LAS PRIMERAS CORRIDASccccccccccccccccc if(nperco.eq.0)then write(06,*)':(:(:(:(:(:(: no percola :(:(:(:(:(:(' else write(06,*)'!!!!!!!!!!!!!LA RED PERCOLA!!!!!!!!!!!!!' endif cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc return end ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc c Subrutina clusters(): COMPLETAR!!!!!!!!!!!!!!!!!!!!!!!!!! c ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc subroutine clusters() parameter (mxd=500,mxd2=mxd*mxd) implicit real*8 (a-h,o-z) implicit integer (i-n) common/param/nperco,lado,nclus_1,nclus common/arrays/nfile(0:mxd),label(1:mxd2) return end ccccccccccccccccccccccccccccccccccccccccccccccccccccc double precision function random(dseed) double precision dseed double precision d2p31m,d2p31 data d2p31m/2147483647.d0/ data d2p31/2147483711.d0/ dseed=dmod(16807.d0*dseed,d2p31m) random=dseed/d2p31 return end cccccccccccccccccccccccccccccccccccccccccccccccccccccc