! ! split(m2,w,mmin,sigma,iseed,dwmax,dw,nprog,mprog) ! ! This version has been modified to allow a factor ! G0 (sigma(m1)/sigma(m2)^gamma_1 (delta_c2/sigma(m2))^gamma_2 ! to be inserted into the normal Press-Schechter expression for dn/dq . ! The parameters G0, gamma_1 and gamma_2 are specified in the module ! modified_merger_tree.F90 . ! The subroutine has w as an extra argument and so a corresponding change ! has to be made to make_tree.F90 ! ! Subroutine to do single binary split. ! ! Input: ! ------ ! m2: input mass ! mmin: minimum mass to resolve ! iseed: random number seed ! dwmax: max timstep dw (w=deltc(a)) ! sigma(m,dlsigdlm): FUNCTION to compute sigma(m) & dln(sigma)/dln(m) ! ! Output: ! ------- ! dw: actual time step in units of change in delta_c ! nprog: (=0,1,2) number of progenitors with m>mmin after split ! mprog(2): array containing masses of progenitors with m>mmin ! ! ---------------------------- ! Theory: ! ! Defining q=m/m2, qmin=mmin/m2 ! (1) generate 0 or 1 progenitors with qmin0 and d(alpha)/dm>0, then the factor ! v(q) = sigma(q*m2)^2/(sigma(q*m2)^2-sigma(m2)^2)^(3/2) ! is monotonically increasing and ln(v) vs ln(q) is concave upwards ! for 00 ! and mu=ln(sigma(qmin m2)/sigma(m2/2)) / ln(qmin) for gamma_1<0 ! ! -------------------------------------- ! ! Given a halo mass m2 and minimum mass mmin: ! ! 1) Compute some values that are used repeatedly ! ! 2) Find the power-law B*q^beta used in R(q) ! ! 3) Compute a "timestep" dw (dw = deltac1-deltac2 ) ! subject to two constraints specified by parameters eps1 and eps2 ! such that in this interval there is small but finite probablity ! that the halo will have formed from the merger of two halos both ! of mass greater than mmin, and also the constraint dw1/2 if (gamma_1 .le. 0.0) then mu =-log(sig_qmin/sig_hf) / log(2.0*qmin) else mu=alpha_hf end if gfac1= gfac0 * ((sig_hf/sig_m2)**gamma_1) / (2.0**(mu*gamma_1)) ! ! 2) Find B and beta such that B*q^beta = v(q) at q=qmin and q=1/2 ! where v(q) = sigma(q*m2)^2/(sigma(q*m2)^2-sigma(m2)^2)^(3/2). ! diff_qmin=sigsq_qmin-sigsq_m2 diff12_qmin=sqrt(diff_qmin) diff32_qmin=diff_qmin*diff12_qmin #ifdef DEBUG if (diff32_qmin.le.0.0) stop 'split(): DEBUG/FATAL - diff32_qmin<=0 !' #endif v_qmin=sigsq_qmin/diff32_qmin ! diff_hf=sigsq_hf-sigsq_m2 diff12_hf=sqrt(diff_hf) diff32_hf=diff_hf*diff12_hf #ifdef DEBUG if (diff32_hf.le.0) stop 'split(): DEBUG/FATAL - diff32_hf<=0 !' #endif v_hf=sigsq_hf/diff32_hf ! sfac=sqrt(2*(sigma(m2/2)^2 - sigma(m2)^2)), used in (3) below sfac=SQRT2*diff12_hf ! #ifdef DEBUG if (v_hf.le.0) stop 'split(): DEBUG/FATAL v_hf<=0 !' if (qmin.le.0) stop 'split(): DEBUG/FATAL qmin<=0 !' #endif beta=log(v_qmin/v_hf)/log(2.0*qmin) if (beta.le.0.0) then write (0,*) 'split(): FATAL - beta<0' write (0,*) ' qmin = ',qmin,', log(2*qmin) = ',log(2.0*qmin) write (0,*) ' v_qmin = ',v_qmin write (0,*) ' v_hf = ',v_hf write (0,*) ' log(v_qmin/v_hf) = ',log(v_qmin/v_hf) write (0,*) ' beta = ',beta write (0,*) ' This can probably be avoided by increasing EPSQ.' stop end if two_pow_beta=2.0**beta b=v_hf*two_pow_beta eta=beta-1.0-gamma_1*mu #ifdef DEBUG if (two_pow_beta.le.0) stop 'split(): DEBUG/FATAL - two_pow_beta<=0 !' #endif half_pow_eta=2.0**(-eta)! 2^(-eta) ! ! 3) Set time step dw and compute mean number of progeny before rejection. ! N.B.: special case eta=0 if (abs(eta).gt.EPSETA) then ! eta != 0 eta_inv=1.0/eta qminexp=qmin**eta ! Used again in section 6) ffac=half_pow_eta-qminexp ! Used again in section 6) dn_dw=SQRT2OPI*alpha_hf*b*eta_inv*ffac*gfac1 else ! beta = 1 dn_dw=-SQRT2OPI*alpha_hf*b*log(2.0*qmin)*gfac1 end if ! if (dn_dw.gt.0.0) then dw_eps2=eps2/dn_dw else dw_eps2=dwmax end if dw=min(eps1*sfac,dw_eps2,dwmax) n_av=dn_dw*dw ! ! 4) Compute the mean fraction of mass in objects of mass less than mmin. #ifdef DEBUG if (diff12_qmin.le.0) stop 'split(): DEBUG/FATAL - diff12_qmin<=0 !' #endif z=sig_m2/diff12_qmin f=SQRT2OPI*dw * gfac0 * J_UNRESOLVED(z) /sig_m2 ! ! 5) Randomly choose one or zero progeny depending on n_av. random=ran3(iseed) if (random.le.n_av) then #ifdef DEBUG nc1=nc1+1 #endif ! 6) Select a value of q with a power-law q**(eta-1) distribution. ! N.B.: eta=0 is special case. random=ran3(iseed) ! if (abs(eta).gt.EPSETA) then ! eta != 0 q_pow_eta=qminexp+random*ffac ! q^eta q=q_pow_eta**eta_inv else ! eta = 0 q=qmin*(2.0*qmin)**(-random) end if ! 7) Compute rejection probability. sig_q=sigma(q*m2,dlsigdlm) ! sigma(q m2), alpha_q sigsq_q=sig_q**2 alpha_q=-dlsigdlm diff12_q=sqrt(sigsq_q-sigsq_m2) v_q=sigsq_q/diff12_q**3 ! Acceptance probability=R(q)<1 r_q=(alpha_q/alpha_hf)*((sig_q*(2.0*q)**mu/sig_hf)**gamma_1) * & & v_q/(b*q**beta) ! #ifdef DEBUG ! If the assumptions regarding the behaviour of sigma(m) that ! are stated in the PCH appendix are true and the code is implemented ! correctly then r_q should always be <1 (to within rounding) error. ! ! If this is not the case print out some warning and diagnostic information if (r_q.gt.1.00001) then write(0,*) 'R(q)=',r_q,'>1!!:' write(0,*) 'alpha_q/alpha_hf,v_q/(b*q**beta), & & (sig_q*(2q)**mu/sig_hf)**gamma_1',alpha_q/alpha_hf,v_q/(b*q**beta),& & (sig_q*(2.0*q)**mu/sig_hf)**gamma_1 if (alpha_q/alpha_hf.gt.1.00001) then write(0,*) 'alpha_q,alpha_hf,q,m2=',alpha_q,alpha_hf,q,m2 end if if (v_q/(b*q**beta).gt.1.00001) then write(0,*) 'v_q,b,q,beta=',v_q,b,q,beta end if if ((sig_q*(2.0*q)**mu/sig_hf)**gamma_1.gt.1.00001) then write(0,*) 'sig_q,q,mu,sig_m2,gamma_1=',sig_q,q,mu,sig_m2,gamma_1 end if end if #endif random=ran3(iseed) if (random.ge.r_q) q=0.0 ! Reject fragment #ifdef DEBUG if (random.lt.r_q) nc2=nc2+1 ! Count number of acceptances. #endif else q=0.0 ! No fragment. end if ! ! Calculate mass of other progenitor in pair, and count how many with m>mmin. mprog(2)=q*m2 if (mprog(2).le.mmin) then nprog=1 else nprog=2 end if ! mprog(1)=(1-q-f)*m2 ! Adjust for mass frac in progenitors m(1-f)/2 mtemp=mprog(1) mprog(1)=mprog(2) mprog(2)=mtemp end if ! else ! qmin>1/2 and so only progenitors are unresolved diff_hf=sigsq_hf-sigsq_m2 diff12_hf=sqrt(diff_hf) sfac=SQRT2*diff12_hf dw=min(eps1*sfac,dwmax) !ensure linear dependence on dw and < dwmax diff_qmin=sigsq_qmin-sigsq_m2 if (diff_qmin.lt.0.0) then ! diff_qmin<0 which should be impossible but may have ! occured as within rounding error m2=mmin. diff_qmin=0.0 end if diff12_qmin=sqrt(diff_qmin) if (diff12_qmin.gt.SQRT2OPI*dw) then #ifdef DEBUG if (diff12_qmin.le.0) stop 'split(): DEBUG/FATAL diff12_qmin<=0 !' #endif z=sig_m2/diff12_qmin f=SQRT2OPI*dw * gfac0 * J_UNRESOLVED(z) /sig_m2 else f=1.0 end if mprog(1)=(1-f)*m2 ! Adjust for mass frac in progenitors m