**==xspexriv.spg processed by SPAG 4.50J at 11:24 on 27 Feb 1996 SUBROUTINE XSPEXRIV(Ear,Ne,Param,Ifl,Photar) IMPLICIT NONE INTEGER Ne , Ifl REAL Ear(0:Ne) , Param(*) , Photar(Ne) c Driver for angle-dependent reflection from an exponentially-cutoff c power law and ionized medium. c It needs to be compiled together with xspexrav.f (neutral reflection). c c See Magdziarz & Zdziarski, 1995, MNRAS. c See Zdziarski et al., 1995, ApJL 438, L63 for description of c calculation of ionization (based on Done et al. 1992, ApJ 395, 275). c The abundances are defined by the command abund c c The output spectrum is the sum of the cutoff power law and the c reflection component. c The reflection component alone can be obtained c for scale (see below) = rel_refl < 0. Then the actual c reflection normalization is |scale|. Note that you need to c change then the limits of rel_refl. The range of rel_refl in that case c should exclude zero (as then the direct component appears). c c If E_c=0, there is no cutoff in the power law. c c This version allows for changes of the vector 'ear' between subsequent c calls. c c c number of model parameters:9 c 1: Gamma, power law photon index, N_E prop. to E^{-Gamma} c 2: E_c, the cutoff energy in keV (if E_c=0 there is no cutoff; c one needs to change the lower limit for that) c 3: scale, scaling factor for reflection; if <0, no direct component c (scale=1 for isotropic source above disk) c 4: redshift, z c 5: abundance of elements heavier than He relative to c the solar abundances c 6: iron abundance relative to the solar abundances c 7: cosine of inclination angle c 8: disk temperature in K c 9: disk ionization parameter = L/nR^2 c algorithm: c a[E*(1+z)]=E^{-Gamma}*exp(-E/E_c)+scale*reflection c Normalization is the photon flux at 1 keV (photons keV^-1 cm^-2 s^-1) c of the cutoff power law only (without reflection) c and in the earth frame. c c INCLUDE '../../inc/xspec.inc' INTEGER isptot, ispref, isppow, ix, iphotaux INTEGER i , j , jmax, ierr, nesave LOGICAL firstcall CHARACTER contxt*127 SAVE isptot, ispref, isppow, ix, iphotaux SAVE firstcall, nesave DATA isptot, ispref, isppow, ix, iphotaux, nesave/6*-1/ DATA firstcall/.TRUE./ ierr = 0 IF ( firstcall ) THEN CALL xwrite('Compton reflection from ionized medium.',5) CALL xwrite('See help for details.',5) CALL xwrite('If you use results of this model in a paper,',5) CALL xwrite & ('please refer to Magdziarz & Zdziarski 1995 MNRAS, 273, 837',5) CALL xwrite('Questions: Andrzej Zdziarski, aaz@camk.edu.pl',5) firstcall = .FALSE. ENDIF IF ( Ne .NE. nesave ) THEN CALL udmget(Ne+1, 6, isptot, ierr) contxt = 'Failed to get memory for sptot' IF ( ierr .NE. 0 ) GOTO 999 CALL udmget(Ne+1, 6, ispref, ierr) contxt = 'Failed to get memory for spref' IF ( ierr .NE. 0 ) GOTO 999 CALL udmget(Ne+1, 6, isppow, ierr) contxt = 'Failed to get memory for sppow' IF ( ierr .NE. 0 ) GOTO 999 CALL udmget(Ne+1, 6, ix, ierr) contxt = 'Failed to get memory for x' IF ( ierr .NE. 0 ) GOTO 999 CALL udmget(Ne+1, 6, iphotaux, ierr) contxt = 'Failed to get memory for photaux' IF ( ierr .NE. 0 ) GOTO 999 nesave = Ne ENDIF c x is in the source frame DO 100 i = 0 , Ne MEMR(ix+i) = (Ear(i)/511.)*(1.+Param(4)) 100 CONTINUE jmax = Ne + 1 c x is the energy array (units m_e c^2) c sppow is the exp. cutoff power law alone (E F_E) c spref is the reflected spectrum array (E F_E) c sptot is the total spectrum array (E F_E), = sppow if no reflection c all dimensions = jmax CALL POWREFJ(Param,MEMR(ix),jmax,MEMR(isptot),MEMR(isppow), & MEMR(ispref)) DO 200 j = 0 , jmax-1 MEMR(iphotaux+j) = MEMR(isptot+j)/Ear(j)**2 200 CONTINUE DO 300 i = 1 , Ne Photar(i) = .5*(MEMR(iphotaux+i)+MEMR(iphotaux+i-1)) & *(Ear(i)-Ear(i-1)) 300 CONTINUE 999 CONTINUE IF ( ierr .NE. 0 ) THEN CALL xwrite(contxt, 10) ENDIF RETURN END **==powrefj.spg processed by SPAG 4.50J at 11:24 on 27 Feb 1996 SUBROUTINE POWREFJ(Param,X,Jmax,Sptot,Sppow,Spref) c IMPLICIT NONE REAL gamma , ec , scale , z_red , normfac , xm , xn REAL temp , xi REAL ab_ , ab0 , SPP0 , SPPC REAL Param(*) , Sptot(*) , Sppow(*) , Spref(*) , X(*) INTEGER Jmax , j EXTERNAL SPP0 , SPPC c-------- C INPUT: c the power law photon index: gamma = Param(1) c the break energy in units of m_e c^2 ec = Param(2)/511 c the scaling factor for the reflected spectrum; c 1 corresponds to seeing equal c contributions from the reflected and direct spectra scale = Param(3) c redshift z_red = Param(4) c abundance ab_ = LOG10(Param(5)) c relative Iron abundance ab0 = LOG10(Param(6)) c Cosine of inclination angle xm = Param(7) c reflecting matter temperature temp = Param(8) c ionization parameter xi = Param(9) c-------- c normalization is at 1 keV in the Earth frame of the power law only xn = (1+z_red)/511 IF ( ec.EQ.0. ) THEN normfac = 1/SPP0(1/xn,gamma,ec) IF ( scale.NE.0. ) THEN CALL GREENCJ(X,Jmax,Spref,xm,ab_,ab0,SPP0,gamma,ec,temp,xi) DO 120 j = 1 , Jmax Spref(j) = Spref(j)*ABS(scale)*normfac 120 CONTINUE ELSE DO 140 j = 1 , Jmax Spref(j) = 0 140 CONTINUE ENDIF IF ( scale.GE.0 ) THEN DO 160 j = 1 , Jmax Sppow(j) = SPP0(1/X(j),gamma,ec)*normfac Sptot(j) = Sppow(j) + Spref(j) 160 CONTINUE ELSE DO 180 j = 1 , Jmax Sptot(j) = Spref(j) 180 CONTINUE ENDIF ELSE normfac = 1/SPPC(1/xn,gamma,ec) IF ( scale.NE.0. ) THEN CALL GREENCJ(X,Jmax,Spref,xm,ab_,ab0,SPPC,gamma,ec,temp,xi) DO 200 j = 1 , Jmax Spref(j) = Spref(j)*ABS(scale)*normfac 200 CONTINUE ELSE DO 220 j = 1 , Jmax Spref(j) = 0 220 CONTINUE ENDIF IF ( scale.GE.0 ) THEN DO 240 j = 1 , Jmax Sppow(j) = SPPC(1/X(j),gamma,ec)*normfac Sptot(j) = Sppow(j) + Spref(j) 240 CONTINUE ELSE DO 260 j = 1 , Jmax Sptot(j) = Spref(j) 260 CONTINUE ENDIF ENDIF RETURN END **==greencj.spg processed by SPAG 4.50J at 11:24 on 27 Feb 1996 c ------------------------------------------------------------------ c SUBROUTINE GREENCJ(X,Jmax,Spref,Xm,Ab_,Ab0,SPP,Gamma,Ec,Temp,Xi) c calculates the reflected spectrum c ab0 - iron log10 abundance relative to hydrogen IMPLICIT NONE REAL Ab0 , Ab_ , ddy , dy , dym , Ec , fjc , Gamma , GNRJ , & GRXYH , GRXYL , SIGMABFJ , SPP , sr , srp , Temp , Xi , xjd , & xjl , xkabs , Xm REAL xmin , xmo , xnor , xrefmax , xtransh , xtransl , y , y0 , & ymin INTEGER i , j , Jmax , jmin , jrefmax , jtransh , jtransl , nc , & ncp REAL X(*) , Spref(*) REAL pm1(19) , pmx(26) , apf, ap(3) EXTERNAL SPP c precision factor for Green's function integration ncp = 100 c ranges for different methods xmin = 2.E-4 xtransl = 0.01957 xtransh = 0.02348 ymin = .03333 c angle dependent parameters xmo = MAX(.05,MIN(.95,Xm)) CALL PM1Y(xmo,pm1) CALL PMXY(xmo,pmx) ap(2) = apf(xmo) ap(3) = 0.381 xrefmax = 1/(ymin+pmx(26)) jmin = 0 DO 100 j = 1 , Jmax IF ( X(j).GT.xmin ) GOTO 200 jmin = j 100 CONTINUE 200 jtransl = 0 DO 300 j = MAX(1,jmin) , Jmax IF ( X(j).GT.xtransl ) GOTO 400 jtransl = j 300 CONTINUE 400 jtransh = 0 DO 500 j = MAX(1,jtransl) , Jmax IF ( X(j).GT.xtransh ) GOTO 600 jtransh = j 500 CONTINUE 600 jrefmax = 0 DO 700 j = MAX(1,jtransh) , Jmax IF ( X(j).GT.xrefmax ) GOTO 800 jrefmax = j 700 CONTINUE 800 DO 900 j = 1 , jmin Spref(j) = 0 900 CONTINUE c----------------------- DO 1000 j = jmin + 1 , jtransl xkabs = SIGMABFJ(j,X,jtransh,Gamma,Temp,Xi,Ab_,Ab0,xnor) Spref(j) = SPP(1/X(j),Gamma,Ec)*GNRJ(xkabs,xmo) 1000 CONTINUE c----------------------- IF ( jmin.GE.jtransl ) xkabs = SIGMABFJ(1,X,MAX(1,jtransh),Gamma, & Temp,Xi,Ab_,Ab0,xnor) ap(1) = xnor/1.21 xjl = ALOG(xtransl) xjd = ALOG(xtransh) - xjl DO 1100 j = jtransl + 1 , jtransh fjc = .5*SIN(3.14159*((ALOG(X(j))-xjl)/xjd-.5)) xkabs = SIGMABFJ(j,X,jtransh,Gamma,Temp,Xi,Ab_,Ab0,xnor) y = 1/X(j) Spref(j) = SPP(y,Gamma,Ec)*GNRJ(xkabs,xmo) dym = y - ymin dy = MIN(2.0,dym) ddy = (dy-pmx(26))/(ncp+1) y0 = y - dy sr = SPP(y0,Gamma,Ec)*GRXYL(pm1,pmx,dy,y0,ap) dy = pmx(26) y0 = y - dy sr = .5*(sr+SPP(y0,Gamma,Ec)*GRXYL(pm1,pmx,dy,y0,ap)) DO 1050 i = 1 , ncp dy = dy + ddy y0 = y - dy sr = sr + SPP(y0,Gamma,Ec)*GRXYL(pm1,pmx,dy,y0,ap) 1050 CONTINUE sr = sr*ddy IF ( dym.GT.2. ) THEN ddy = dym - 2 nc = INT(ncp*ddy/(dym-pmx(26))) ddy = ddy/(nc+1) dy = dym y0 = y - dy srp = SPP(y0,Gamma,Ec)*GRXYH(pm1,pmx,dy,y0,ap) dy = 2 y0 = y - dy srp = .5*(srp+SPP(y0,Gamma,Ec)*GRXYH(pm1,pmx,dy,y0,ap)) DO 1060 i = 1 , nc dy = dy + ddy y0 = y - dy srp = srp + SPP(y0,Gamma,Ec)*GRXYH(pm1,pmx,dy,y0,ap) 1060 CONTINUE sr = sr + srp*ddy ENDIF Spref(j) = (.5-fjc)*Spref(j) + (.5+fjc)*sr*X(j) 1100 CONTINUE c----------------------- DO 1200 j = jtransh + 1 , jrefmax y = 1/X(j) dym = y - ymin dy = MIN(2.0,dym) ddy = (dy-pmx(26))/(ncp+1) y0 = y - dy sr = SPP(y0,Gamma,Ec)*GRXYL(pm1,pmx,dy,y0,ap) dy = pmx(26) y0 = y - dy sr = .5*(sr+SPP(y0,Gamma,Ec)*GRXYL(pm1,pmx,dy,y0,ap)) DO 1150 i = 1 , ncp dy = dy + ddy y0 = y - dy sr = sr + SPP(y0,Gamma,Ec)*GRXYL(pm1,pmx,dy,y0,ap) 1150 CONTINUE sr = sr*ddy IF ( dym.GT.2. ) THEN ddy = dym - 2 nc = INT(ncp*ddy/(dym-pmx(26))) ddy = ddy/(nc+1) dy = dym y0 = y - dy srp = SPP(y0,Gamma,Ec)*GRXYH(pm1,pmx,dy,y0,ap) dy = 2 y0 = y - dy srp = .5*(srp+SPP(y0,Gamma,Ec)*GRXYH(pm1,pmx,dy,y0,ap)) DO 1160 i = 1 , nc dy = dy + ddy y0 = y - dy srp = srp + SPP(y0,Gamma,Ec)*GRXYH(pm1,pmx,dy,y0,ap) 1160 CONTINUE sr = sr + srp*ddy ENDIF Spref(j) = sr*X(j) 1200 CONTINUE c---------------------- DO 1300 j = jrefmax + 1 , Jmax Spref(j) = 0 1300 CONTINUE RETURN END **==gnrj.spg processed by SPAG 4.50J at 11:24 on 27 Feb 1996 c ------------------------------------------------------------------ c c Reflection factor for nonrelativistic Compton reflection, c reflection orders >1 approximated with isotropic phase function, c and approximation of H-function by Basko ApJ 223,268,(1978), c valid up to 14keV; c sig - sigma_bf per hydrogen atom in sigma_Thomson units c xm - cosine of the angle between normal to the slab and the c observation direction REAL FUNCTION GNRJ(Sig,Xm) IMPLICIT NONE REAL Sig , Xm REAL al0 , al1 , al2 , xl , x2 , x4 , SQ3 PARAMETER (SQ3=1.732051) al0 = 1/(1+Sig/1.21) al1 = SQRT(1-al0) al2 = SQ3*al1 xl = LOG(1+1/Xm) x2 = Xm*Xm x4 = x2*x2 GNRJ = .5*al0*Xm*(.375*((3-2*x2+3*x4)*xl+(3*x2-1)*(.5-Xm)) & +((1+(1/al1-1)*(1-LOG(1+al2)/al2))*(1+Xm*SQ3)/(1+Xm*al2)-1) & *xl) RETURN END **==sigmabfj.spg processed by SPAG 4.50J at 11:24 on 27 Feb 1996 c ------------------------------------------------------------------- c FUNCTION SIGMABFJ(In,X,N,Gamma0,Temp0,Xi0,Ab_0,Ab0,Asc0) c bound-free cross section for ionized matter with cosmic abundances c and variable iron abundance (in units of solar iron abundance) c per hydrogen atom in units of the Thomson cross section c e is in units of 511 keV INCLUDE '../../inc/xspec.inc' REAL ab , Ab0 , ab_ , Ab_0 , asc , Asc0 , gamma , Gamma0 , & SIGMABFJ , temp , Temp0 , WARMABJ , xas , xi , Xi0 INTEGER i , In , N , nold, ierr INTEGER iopac, ixold REAL X(*) LOGICAL fl1 , firstflag CHARACTER contxt*80 CHARACTER*4 fgsolr,fgsolr0 EXTERNAL fgsolr SAVE iopac , gamma , temp , xi , ab_ , ab , asc , ixold , nold , & fl1 , firstflag,fgsolr0 DATA nold, iopac, ixold /0,2*-1/ DATA gamma , temp , xi , ab_ , ab/0. , 0. , 0. , 99999. , 99999./ DATA firstflag , fl1/2*.TRUE./ DATA fgsolr0/' '/ ierr = 0 c In this version, changes of ear during one xspec session are allowed. if(fgsolr().ne.fgsolr0)then fl1=.true. fgsolr0=fgsolr() endif IF ( (gamma.NE.Gamma0) .OR. (temp.NE.Temp0) .OR. (xi.NE.Xi0) .OR. & (ab_.NE.Ab_0) .OR. (ab.NE.Ab0) ) THEN gamma = Gamma0 temp = Temp0 xi = Xi0 ab = Ab0 ab_ = Ab_0 firstflag = .TRUE. fl1 = .TRUE. xas = .01947 asc = 1.503E2*WARMABJ(xas,gamma,temp,xi,ab_,ab,firstflag, & .false.)*xas**3 ENDIF IF ( (ixold.EQ.-1) .OR. (X(In).NE.MEMR(ixold+In-1)) & .OR. (N.NE.nold) ) THEN CALL udmget(N, 6, iopac, ierr) contxt = 'Failed to get memory for opac' IF ( ierr .NE. 0 ) GOTO 999 CALL udmget(N, 6, ixold, ierr) contxt = 'Failed to get memory for xold' IF ( ierr .NE. 0 ) GOTO 999 nold = N DO 50 i = 1 , N MEMR(ixold+i-1) = X(i) 50 CONTINUE fl1 = .TRUE. ENDIF IF ( fl1 ) THEN DO 100 i = 1 , N MEMR(iopac+i-1) = 1.503E2*WARMABJ(X(i),gamma,temp,xi,ab_,ab, & firstflag,.false.) 100 CONTINUE fl1 = .FALSE. ENDIF Asc0 = asc SIGMABFJ = MEMR(iopac+In-1) 999 CONTINUE IF ( ierr .NE. 0 ) THEN CALL xwrite(contxt, 10) SIGMABFJ = 0. ENDIF RETURN END **==warmabj.spg processed by SPAG 4.50J at 11:24 on 27 Feb 1996 c ------------------------------------------------------------------- FUNCTION WARMABJ(X0,Gamma,Temp,Xi,Ab_,Ab0,Firstflag,qHHe) REAL WARMABJ , X0 , Gamma , Temp , Xi , Ab_ , Ab0 LOGICAL Firstflag, qHHe INCLUDE '../../inc/xspec.inc' REAL clcwrm REAL aw(20), abo(20), e(800) INTEGER z(20), iab0, imax INTEGER isigma, iion, iint, iarec, inum, iratio, ierr CHARACTER*72 contxt COMMON /aprmdt/ isigma, iion, z, aw, abo, e, iab0, imax SAVE iint, iarec, inum, iratio DATA isigma, iion, iint, iarec, inum, iratio /6*-1/ ierr = 0 C Get the memory for the arrays required by CLCWRM IF ( isigma .EQ. -1 ) THEN CALL udmget(20*30*800, 6, isigma, ierr) contxt = 'Failed to get memory for sigma array' IF ( ierr .NE. 0 ) GOTO 999 CALL xwrite('Memory acquired for sigma array', 25) ENDIF IF ( iion .EQ. -1 ) THEN CALL udmget(20*30*10, 6, iion, ierr) contxt = 'Failed to get memory for ion array' IF ( ierr .NE. 0 ) GOTO 999 CALL xwrite('Memory acquired for ion array', 25) ENDIF IF ( iint .EQ. -1 ) THEN CALL udmget(20*30, 6, iint, ierr) contxt = 'Failed to get memory for int array' IF ( ierr .NE. 0 ) GOTO 999 CALL xwrite('Memory acquired for int array', 25) ENDIF IF ( iarec .EQ. -1 ) THEN CALL udmget(20*30, 6, iarec, ierr) contxt = 'Failed to get memory for arec array' IF ( ierr .NE. 0 ) GOTO 999 CALL xwrite('Memory acquired for arec array', 25) ENDIF IF ( inum .EQ. -1 ) THEN CALL udmget(20*30, 7, inum, ierr) contxt = 'Failed to get memory for num array' IF ( ierr .NE. 0 ) GOTO 999 CALL xwrite('Memory acquired for num array', 25) ENDIF IF ( iratio .EQ. -1 ) THEN CALL udmget(20*30, 7, iratio, ierr) contxt = 'Failed to get memory for ratio array' IF ( ierr .NE. 0 ) GOTO 999 CALL xwrite('Memory acquired for ratio array', 25) ENDIF C Call the routine to do the calculation WARMABJ = CLCWRM(X0,Gamma,Temp,Xi,Ab_,Ab0,Firstflag,qHHe, & MEMR(isigma),MEMR(iion),MEMR(iint),MEMR(iarec), & MEMD(inum),MEMD(iratio), z, aw, abo, e, iab0, & imax) 999 CONTINUE IF ( ierr .NE. 0 ) THEN CALL xwrite(contxt, 10) WARMABJ = 0. ENDIF RETURN END c ------------------------------------------------------------------- FUNCTION CLCWRM(X0,Gamma,Temp,Xi,Ab_,Ab0,Firstflag,qHHe,sigma, & ion,int,arec,num,ratio,z,aw,abo,e,iab0,imax) c calculate cross-sections using Daltabuit and Cox, use cosmic c abundances, and radiative recombination rates from c Aldrovandi and Pequignot 1973 and explicit formula c for recombination to hydrogenlike atoms c result in units of 10^-22 IMPLICIT NONE REAL CLCWRM , X0 , Gamma , Temp , Xi , Ab_ , Ab0 REAL t4 , z2 , e1 , e2 , re , rp , ab_d REAL aw(20) , abo(20) , ab(20) , ion(20,30,*) , y REAL int(20,*) , arec(20,*) REAL denom , xp , sigmaeff , e(800) , sigma(20,30,*) REAL fgabnd REAL*8 num(20,*) , sum , ratio(20,*) , mult , mul(30) , xil INTEGER z(20) , i , j , imax , n , ios , k , iab0 CHARACTER*4 fgsolr0 LOGICAL Firstflag, qHHe CHARACTER fgsolr*4, el_name*2 EXTERNAL fgsolr, el_name c DATA fgsolr0/' '/ SAVE ab,fgsolr0 C If necessary load the arrays from the iond_mm.dat and mansig.dat C files CALL ldapmr(z, aw, abo, ion, sigma, e, iab0, imax) C initialize other arrays if((fgsolr().ne.fgsolr0).or.firstflag)then fgsolr0=fgsolr() do i=1,imax abo(i)=fgabnd(el_name(z(i))) enddo c insert external abundances (ab_, ab0) ab_d = 10.**Ab_ DO 100 i = 1 , imax IF ( z(i).GT.2 ) THEN ab(i) = abo(i)*ab_d ELSE IF ( qHHe ) THEN ab(i) = abo(i) ELSE ab(i) = 0. ENDIF ENDIF 100 CONTINUE IF ( iab0.GT.0 ) ab(iab0) = abo(iab0)*10.**Ab0 endif IF ( Firstflag ) THEN IF ( Xi.GT.1.E-20 ) THEN c normalized temperature t4 = Temp*.0001 c calculate recombination coefficients - radiative and dielectric c from Aldrovandi+Pequignot 1973 Astro, astrophys 25 137 DO 120 i = 1 , imax , 1 DO 110 j = 1 , z(i) - 1 , 1 e1 = EXP(-ion(i,j,5)/t4) e2 = EXP(-ion(i,j,7)/t4) arec(i,j) = ion(i,j,2)*(t4**(-ion(i,j,3))) & + ion(i,j,4)*(t4**(-1.5)) & *e1*(1.+ion(i,j,6)*e2) 110 CONTINUE c do radiative recomb to hydrogenic ion NB assumed gaunt factor=1 c from Gould+Thakur 1970 ann phys 61 351. z2 = z(i)**2 y = 15.8*z2/t4 arec(i,z(i)) = 1.033E-3*z2*(1.735+LOG(y)+1/(6.*y)) & /SQRT(t4) 120 CONTINUE c first normalise photon spectrum denom = 0. DO 140 k = 1 , 720 , 1 denom = denom + (e(k)**(1-Gamma))*(e(k+1)-e(k)) 140 CONTINUE denom = 1/denom c calculate the photoionization integrals and population balance DO 160 i = 1 , imax , 1 DO 150 j = 1 , z(i) , 1 int(i,j) = 0.0 c do integral in log10 (eV) from lowest energy c to the maximum energy- use same energy grid c as the cross-sections are defined on DO 145 k = 1 , 720 , 1 int(i,j) = int(i,j) + sigma(i,j,k)*(e(k)**(-Gamma)) & *(e(k+1)-e(k)) 145 CONTINUE int(i,j) = int(i,j)*denom c const=7.958d-2/2.43d+4 ratio(i,j) = DLOG(3.2749D-6*int(i,j)/arec(i,j)) 150 CONTINUE 160 CONTINUE c calculate population numbers c set sum=1 as the sum=1+A21+A32A21+.... c complicated because floating range limit DO 220 i = 1 , imax , 1 xil = DLOG(DBLE(Xi)) mult = 0.D0 DO 170 j = z(i) , 1 , -1 mul(j) = 0.D0 DO 165 n = j , 1 , -1 mul(j) = mul(j) + ratio(i,n) 165 CONTINUE mul(j) = mul(j) + j*xil IF ( mul(j).GT.mult ) mult = mul(j) 170 CONTINUE DO 180 j = z(i) , 1 , -1 mul(j) = mul(j) - mult 180 CONTINUE sum = 0.D0 DO 190 j = z(i) , 1 , -1 sum = sum + DEXP(mul(j)) 190 CONTINUE sum = sum + DEXP(-mult) num(i,1) = -mult - DLOG(sum) DO 200 j = 2 , z(i) + 1 , 1 num(i,j) = num(i,j-1) + ratio(i,j-1) + xil 200 CONTINUE DO 210 j = 1 , z(i) + 1 , 1 num(i,j) = DEXP(num(i,j)) 210 CONTINUE 220 CONTINUE ELSE DO 240 i = 1 , imax , 1 num(i,1) = 1. DO 230 j = 2 , z(i) + 1 , 1 num(i,j) = 0. 230 CONTINUE 240 CONTINUE ENDIF Firstflag = .FALSE. ENDIF c ------------------------------------------------------------------- c xp = X0*5.11E5 sigmaeff = 0. IF ( xp.LT.e(721) ) THEN c pick closest energy bin k = 1 DO WHILE ( e(k).LT.xp ) k = k + 1 ENDDO re = (xp-e(k-1))/(e(k)-e(k-1)) DO 300 i = 1 , imax , 1 DO 260 j = 1 , z(i) , 1 sigmaeff = sigmaeff + SNGL(num(i,j))*ab(i) & *(sigma(i,j,k-1) & +re*(sigma(i,j,k)-sigma(i,j,k-1))) 260 CONTINUE 300 CONTINUE ELSE re = (xp/e(721))**(-3) DO 350 i = 1 , imax , 1 rp = ab(i)*re DO 320 j = 1 , z(i) , 1 sigmaeff = sigmaeff + SNGL(num(i,j))*sigma(i,j,721)*rp 320 CONTINUE 350 CONTINUE ENDIF sigmaeff = sigmaeff*6.6E-5 CLCWRM = sigmaeff RETURN END c ------------------------------------------------------------------- c SUBROUTINE ldapmr(z, aw, abo, ion, sigma, e, iab0, imax) REAL aw(20), abo(20), ion(20,30,*), sigma(20,30,*), e(*) INTEGER z(20), iab0 INTEGER i, j, k, imax, ios INTEGER ilun10 , ilun11 , lenn REAL fgabnd CHARACTER*2 el_name CHARACTER*128 absfil, wrtstr LOGICAL qfirst INTEGER lenact CHARACTER fgdatd*128 EXTERNAL lenact, fgdatd DATA qfirst /.TRUE./ IF ( .NOT.qfirst ) RETURN qfirst = .FALSE. c set up constants and read in data if first time round iab0 = 0 CALL GETLUN(ilun10) absfil = fgdatd() lenn = lenact(absfil) absfil = absfil(:lenn)//'iond_mm.dat' CALL OPENWR(ilun10,absfil,'old',' ',' ',0,0,ios) IF ( ios .NE. 0 ) THEN WRITE(wrtstr,'(a,i5)') 'Failed to open iond_mm.dat : ios = ', & ios CALL xwrite(wrtstr, 10) RETURN ENDIF c open(unit=10,file='iond_mm.dat',status='old',iostat=ios) c open(unit=11,file='mansig.data',status='old') c ilun10=10 c ilun11=11 i = 1 READ (ilun10,*,IOSTAT=ios) z(i) , aw(i) , abo(i) IF ( z(i).EQ.26 ) iab0 = i c NB j=1 is ground state, j=z(i)=fully charged DO WHILE ( ios.EQ.0 ) DO 20 j = 1 , z(i) , 1 READ (ilun10,*) ion(i,j,1) , ion(i,j,2) , ion(i,j,3) , & ion(i,j,4) , ion(i,j,5) , ion(i,j,6) , & ion(i,j,7) , ion(i,j,8) , ion(i,j,9) , & ion(i,j,10) c change units of coefficients ion(i,j,2) = ion(i,j,2)*1.E+10 ion(i,j,4) = ion(i,j,4)*1.E+04 ion(i,j,5) = ion(i,j,5)*1.E-04 ion(i,j,7) = ion(i,j,7)*1.E-04 20 CONTINUE i = i + 1 READ (ilun10,*,IOSTAT=ios) z(i) , aw(i) , abo(i) IF ( z(i).EQ.26 ) iab0 = i ENDDO imax = i - 1 do i=1,imax abo(i)=fgabnd(el_name(z(i))) enddo c ******new bit for xspec CLOSE (UNIT=ilun10) CALL FRELUN(ilun10) c check not overflowing array bounds IF ( imax.GT.20 .OR. z(imax).GT.30 ) THEN CALL xwrite('element array overflowing array bounds', 5) WRITE(wrtstr, '(a,i6)') 'number of elements= ' , imax CALL xwrite(wrtstr, 5) WRITE(wrtstr, '(a,i6)') 'maximum atomic number= ' , z(imax) CALL xwrite(wrtstr, 5) RETURN ENDIF c read in photoionization data from Reilman and Manson ApJ supp 40 1979 CALL GETLUN(ilun11) absfil = fgdatd() lenn = lenact(absfil) absfil = absfil(:lenn)//'mansig.dat' CALL OPENWR(ilun11,absfil,'old',' ',' ',0,0,ios) IF ( ios .NE. 0 ) THEN WRITE(wrtstr,'(a,i5)') 'Failed to open mansig.dat : ios = ', & ios CALL xwrite(wrtstr, 10) RETURN ENDIF DO 50 i = 1 , imax , 1 c now go over all ion states - values come from Reilman c ApJ supp 1979 except hydrogenic which is analytic DO 40 j = 1 , z(i) , 1 c ion identification header READ (ilun11,*) c read in over all energies c the table is valid for 5.eV-19907.7eV DO 30 k = 1 , 721 , 1 READ (ilun11,*) e(k) , sigma(i,j,k) c change units of sigma sigma(i,j,k) = sigma(i,j,k)/6.6E-27 30 CONTINUE 40 CONTINUE 50 CONTINUE c ******new bit for xspec CLOSE (UNIT=ilun11) CALL FRELUN(ilun11) c close(ilun10) c close(ilun11) c end of data set up c ------------------------------------------------------------------- c RETURN END c ------------------------------------------------------------------- c function el_name(z) CHARACTER*2 el_name,elt_long(28) INTEGER z DATA elt_long & /'H ','He', & 'Li','Be','B ','C ','N ','O ','F ','Ne', & 'Na','Mg','Al','Si','P ','S ','Cl','Ar', & 'K ','Ca','Sc','Ti','V ','Cr','Mn','Fe','Co','Ni'/ el_name=elt_long(z) RETURN END c ------------------------------------------------------------------- c