c------------------------------------------------------------------------------ c Allocate or alter the allocation of memory to halo tree arrays c and galaxy property arrays c c On first call nhalomax=0 and the array size is set to a estimate of c based on the parent halo mass, the mass resolution and the number of c time steps. c c On subsequent calls no change is made if nhalo falls in the range c nhalomax/SHRINK_IF > nhalo > nhalomax c with the second condition being signalled by ierr=1 and not the c value of nhalo. c c If nhalo is too large nhalomax is increased by a factor GROW c c If nhalo is small compared to nhalomax for TWO consecutive calls c then nhalomax is reduced by the factor SHRINK c c nhalomax is not reduced below the value MINHALOS as once the arrays c are this small there is nothing really to be gained by shrinking them c further. c c If nhalomax gets as large as MAXHALOS then the program gives up. c c subroutine memory(nhalo,nhalomax,ierr,nlev,mphalo,mres, & pjlevel,pmhalo,pjpar,pnchild,pjchild,pwk1,pwk2,pwk3,pwk4,pwk5) *************************************variables********************************* implicit none integer nhalo,nhalomax,ierr,malloc,nlev,nhalo_prev,ifirst real mphalo,mres integer jlevel(*),jpar(*),nchild(*),jchild(*) real mhalo(*),wk1(*),wk2(*),wk3(*),wk4(*),wk5(*) pointer (pjlevel,jlevel),(pmhalo,mhalo),(pjpar,jpar),(pnchild,nchild), & (pjchild,jchild),(pwk1,wk1),(pwk2,wk2),(pwk3,wk3),(pwk4,wk4), & (pwk5,wk5) real mbytes real GROW,SHRINK,SHRINK_IF parameter (GROW=1.414,SHRINK=2.0,SHRINK_IF=4.0) integer MAXHALOS,MINHALOS parameter(MAXHALOS=1e+07,MINHALOS=1e+04) save nhalo_prev,ifirst data ifirst /0/ ******************************************************************************* if (ierr.eq.2) then c Do nothing as it is the arrays internal to make_tree() that c needed resizing and not these main arrays else if (ierr.eq.1 .or. nhalo.gt.nhalomax .or. nhalomax.eq.0) then if (nhalomax.ne.0) then c Release currently allocated memory call free(pjlevel) call free(pmhalo) call free(pjpar) call free(pnchild) call free(pjchild) call free(pwk1) call free(pwk2) call free(pwk3) call free(pwk4) call free(pwk5) nhalomax = GROW*nhalomax else c If first call to the subroutine make an initial estimate c of the memory requirement. This is very rough. nhalomax=min(MAXHALOS,max(int(0.015*(mphalo/mres))*nlev,MINHALOS)) cd write(0,*) 'First guess: nhalomax=',nhalomax,' MAXHALOS=',MAXHALOS end if if(nhalomax.le.MAXHALOS) then pjlevel = malloc(4*nhalomax) pmhalo = malloc(4*nhalomax) pjpar = malloc(4*nhalomax) pnchild = malloc(4*nhalomax) pjchild = malloc(4*nhalomax) pwk1 = malloc(4*nhalomax) pwk2 = malloc(4*nhalomax) pwk3 = malloc(4*nhalomax) pwk4 = malloc(4*nhalomax) pwk5 = malloc(4*nhalomax) if ( pjlevel.eq.0 .or. pmhalo.eq.0 .or. pjpar.eq.0 & .or. pnchild.eq.0 .or. pjchild.eq.0 ) then write(0,*) 'memory(): MALLOC failed for nhalomax=',nhalomax stop end if ierr = 0 mbytes=real(nhalomax*(4*5))/real(1024**2) write(0,*) 'nhalomax=',nhalomax write(0,'(a,f7.1)') & 'main storage= ',mbytes else stop 'memory(): nhalomax>MAXHALOS' end if else if (max(nhalo,nhalo_prev)*SHRINK_IF.lt.nhalomax & .and. nhalomax.gt.MINHALOS) then c If for the 2nd consecutive time nhalo is much smaller c than nhalomax then reduce nhalomax by a factor SHRINK call free(pjlevel) call free(pmhalo) call free(pjpar) call free(pnchild) call free(pjchild) call free(pwk1) call free(pwk2) call free(pwk3) call free(pwk4) call free(pwk5) nhalomax = nhalomax/SHRINK write(0,*) 'shrink: nhalomax=',nhalomax pjlevel = malloc(4*nhalomax) pmhalo = malloc(4*nhalomax) pjpar = malloc(4*nhalomax) pnchild = malloc(4*nhalomax) pjchild = malloc(4*nhalomax) pwk1 = malloc(4*nhalomax) pwk2 = malloc(4*nhalomax) pwk3 = malloc(4*nhalomax) pwk4 = malloc(4*nhalomax) pwk5 = malloc(4*nhalomax) if ( pjlevel.eq.0 .or. pmhalo.eq.0 .or. pjpar.eq.0 & .or. pnchild.eq.0 .or. pjchild.eq.0 ) stop 'malloc failed' mbytes=real(nhalomax*(4*5))/real(1024**2) write(0,'(a,f7.1)') & 'main storage= ',mbytes end if nhalo_prev=nhalo ! save this value for the next call return end