PROGRAM mie IMPLICIT NONE C C-------Mie computations for a size distribution C of homogeneous spheres. c C========================================================== C--Ref : Toon and Ackerman, Applied Optics, 1981 C Stephens, CSIRO, 1979 C Attention : surdimensionement des tableaux C to be compiled with double precision option (-r8 on Sun) C AUTHOR: Olivier Boucher C-------SIZE distribution properties---------------- C--sigma_g : geometric standard deviation C--r_0 : geometric number mean radius (um)/modal radius C--Ntot : total concentration in m-3 c REAL rmin, rmax !----integral bounds in m c c--Nmode= 4 modes for SS in INCA c-- AS, CS, CI, SS c--NDis=1 distribution per mode INTEGER Nmode, Ndis, mode, dis PARAMETER (Nmode=2, Ndis=1) REAL sigma_g(Ndis,Nmode), r_0(Ndis,Nmode), Ntot(Ndis,Nmode) c--sulfate Coarse Soluble (CS) & Accumulation Soluble (AS) c--becareful to list in the correct order if more than 1 dis per mode DATA r_0 /0.433E-6,0.1E-6/ !--meters DATA sigma_g/2.0,1.8/ DATA Ntot /1.0,1.0/ CHARACTER*33 chmode(Nmode) DATA chmode/'Sulfate Coarse Soluble (CS)', . 'Sulfate Accumulation Soluble (AS)'/ c REAL masse,volume,surface,rho PARAMETER (rho=1.769E3) !--dry density kg/m3 Tang and Munkelwitz c c---------- RH growth parameters---------------- c INTEGER Nrh,irh PARAMETER(Nrh=12) REAL RH_tab(Nrh),RH DATA RH_tab/0.,10.,20,30.,40.,50.,60.,70.,80.,85.,90.,95./ REAL rh_growth(Nrh) c c--growth factor normalised to 0% relative humidity for sulfate DATA rh_growth/1.000, 1.000, 1.000, 1.000, 1.169, 1.220, . 1.282, 1.363, 1.485, 1.580, 1.735, 2.085/ c c------------------------------------- c COMPLEX m !----refractive index m=n_r-i*n_i INTEGER Nmax,Nstart !--number of iterations COMPLEX k2, k3, z1, z2 COMPLEX u1,u5,u6,u8 COMPLEX a(1:21000), b(1:21000) COMPLEX I INTEGER n !--loop index REAL pi, nnn COMPLEX nn REAL Q_ext, Q_abs, Q_sca, g, omega !--parameters for radius r REAL x !--size parameter REAL r !--radius REAL sigma_sca, sigma_ext, sigma_abs REAL omegatot, gtot !--averaged parameters COMPLEX ksiz2(-1:21000), psiz2(1:21000) COMPLEX nu1z1(1:21010), nu1z2(1:21010) COMPLEX nu3z2(0:21000) REAL number, deltar INTEGER bin, Nbin, k PARAMETER (Nbin=700) c C---wavelengths STREAMER INTEGER Nwv, NwvmaxSW PARAMETER (NwvmaxSW=25) REAL lambda(1:NwvmaxSW) DATA lambda/0.28E-6, 0.30E-6, 0.33E-6, 0.36E-6, 0.40E-6, . 0.44E-6, 0.48E-6, 0.52E-6, 0.57E-6, 0.64E-6, . 0.69E-6, 0.75E-6, 0.78E-6, 0.87E-6, 1.00E-6, . 1.10E-6, 1.19E-6, 1.28E-6, 1.53E-6, 1.64E-6, . 2.13E-6, 2.38E-6, 2.91E-6, 3.42E-6, 4.00E-6/ c INTEGER nb, nb_lambda PARAMETER (nb_lambda=5) REAL lambda_ref(nb_lambda) DATA lambda_ref /0.443E-6,0.550E-6,0.670E-6,0.765E-6,0.865E-6/ c c--read refractive index from old file with different wavelengths c REAL n_r_tab(1:Nrh,1:NwvmaxSW-1+nb_lambda) REAL n_i_tab(1:Nrh,1:NwvmaxSW-1+nb_lambda) c C---TOA fluxes - Streamer Cs REAL weight(1:NwvmaxSW-1) c DATA weight/0.839920E1, 0.231208E2, 0.322393E2, 0.465058E2, c . 0.678199E2, 0.798964E2, 0.771359E2, 0.888472E2, c . 0.115281E3, 0.727565E2, 0.816992E2, 0.336172E2, c . 0.914603E2, 0.112706E3, 0.658840E2, 0.524470E2, c . 0.391067E2, 0.883864E2, 0.276672E2, 0.681812E2, c . 0.190966E2, 0.250766E2, 0.128704E2, 0.698720E1/ C---TOA fluxes - Tad c DATA weight/ 4.20, 11.56, 16.12, 23.25, 33.91, 39.95, 38.57, c . 44.42, 57.64, 29.36, 47.87, 16.81, 45.74, 56.35, c . 32.94, 26.22, 19.55, 44.19, 13.83, 34.09, 9.55, c . 12.54, 6.44, 3.49/ C---BOA fluxes - Tad DATA weight/ 0.01, 4.05, 9.51, 15.99, 26.07, 33.10, 33.07, . 39.91, 52.67, 27.89, 43.60, 13.67, 42.22, 40.12, . 32.70, 14.44, 19.48, 14.23, 13.43, 16.42, 8.33, . 0.95, 0.65, 2.76/ c REAL lambda_int(1:NwvmaxSW-1+nb_lambda) c REAL final_a(1:NwvmaxSW-1+nb_lambda) REAL final_g(1:NwvmaxSW-1+nb_lambda) REAL final_w(1:NwvmaxSW-1+nb_lambda) REAL final_qext(1:NwvmaxSW-1+nb_lambda) c INTEGER band, NbandSW, NbandLW PARAMETER (NbandSW=6, NbandLW=5) c REAL gcm_a(NbandSW+NbandLW) REAL gcm_g(NbandSW+NbandLW) REAL gcm_w(NbandSW+NbandLW) REAL gcm_qext(NbandSW+NbandLW) REAL gcm_weight_a(NbandSW+NbandLW) REAL gcm_weight_g(NbandSW+NbandLW) REAL gcm_weight_w(NbandSW+NbandLW) REAL gcm_weight_qext(NbandSW+NbandLW) c REAL ss_a(NbandSW+NbandLW+nb_lambda,Nrh) REAL ss_w(NbandSW+NbandLW+nb_lambda,Nrh) REAL ss_g(NbandSW+NbandLW+nb_lambda,Nrh) REAL ss_qext(NbandSW+NbandLW+nb_lambda,Nrh) c INTEGER NwvmaxLW PARAMETER (NwvmaxLW=100) REAL Tb, Planck PARAMETER (Tb=260.0) c INTEGER wv, nb_wv PARAMETER (nb_wv=100) REAL wv_SUL(1:nb_wv) REAL index_r_SUL(1:Nrh,1:nb_wv) REAL index_i_SUL(1:Nrh,1:nb_wv) REAL rh_dummy REAL count_n_r, count_n_i c c------opening output files c OPEN (unit=14, file='SEXT_sulfate_6bands.txt') OPEN (unit=15, file='G_sulfate_6bands.txt') OPEN (unit=16, file='SSA_sulfate_6bands.txt') OPEN (unit=17, file='QEXT_sulfate_6bands.txt') OPEN (unit=24, file='SEXT_sulfate_5wave.txt') OPEN (unit=25, file='QEXT_sulfate_5wave.txt') OPEN (unit=26, file='SABS_sulfate_5wave.txt') c c--initializing wavelengths for calculations c DO Nwv=1, NwvmaxSW-1 lambda_int(Nwv)=( lambda(Nwv)+lambda(Nwv+1) ) /2. ENDDO c DO nb=1, nb_lambda lambda_int(NwvmaxSW-1+nb)=lambda_ref(nb) ENDDO c c--lecture des indices from a high-resolution spectral file c-------RH dependent RI from file c OPEN(unit=20,file='ri_sul_v2') c DO irh=1,Nrh DO wv=1, nb_wv READ (20,*) rh_dummy, wv_SUL(wv), . index_r_SUL(irh,wv), index_i_SUL(irh,wv) ENDDO ENDDO c CLOSE(20) c c---interpolate refractive index to tab values c--take average or closest neighbour wavelength c DO irh=1, Nrh c DO Nwv=1, NwvmaxSW-1+nb_lambda n_r_tab(irh,Nwv)=0.0 n_i_tab(irh,Nwv)=0.0 ENDDO c c--interpolating on our wavelengths c DO Nwv=1, NwvmaxSW-1 c c--first real part count_n_r=0.0 DO wv=1, nb_wv IF (wv_SUL(wv).GT.lambda(Nwv).AND. . wv_SUL(wv).LT.lambda(Nwv+1)) THEN n_r_tab(irh,Nwv)=n_r_tab(irh,Nwv)+index_r_SUL(irh,wv) count_n_r=count_n_r+1.0 ENDIF ENDDO c IF (count_n_r.GT.0.5) THEN c--averaging n_r_tab(irh,Nwv)=n_r_tab(irh,Nwv)/count_n_r ELSE c--otherwise closest neighbour DO wv=1, nb_wv IF (wv_SUL(wv).LT.lambda_int(Nwv)) THEN n_r_tab(irh,Nwv)=index_r_SUL(irh,wv) ENDIF ENDDO ENDIF c c--then imaginary part count_n_i=0.0 DO wv=1, nb_wv IF (wv_SUL(wv).GT.lambda(Nwv).AND. . wv_SUL(wv).LT.lambda(Nwv+1)) THEN n_i_tab(irh,Nwv)=n_i_tab(irh,Nwv)+index_i_SUL(irh,wv) count_n_i=count_n_i+1.0 ENDIF ENDDO c IF (count_n_i.GT.0.5) THEN c--averaging n_i_tab(irh,Nwv)=n_i_tab(irh,Nwv)/count_n_i ELSE c--otherwise closest neighbour DO wv=1, nb_wv IF (wv_SUL(wv).LT.lambda_int(Nwv)) THEN n_i_tab(irh,Nwv)=index_i_SUL(irh,wv) ENDIF ENDDO ENDIF c ENDDO !--wv c ENDDO !--irh c c----------------------------------------------------------- c c--now defining nr and ni for my set of reference wavelengths for SUL DO nb=1, nb_lambda c DO irh=1,Nrh DO wv=1, nb_wv IF (wv_SUL(wv).LT.lambda_ref(nb)) THEN n_r_tab(irh,NwvmaxSW-1+nb)=index_r_SUL(irh,wv) n_i_tab(irh,NwvmaxSW-1+nb)=index_i_SUL(irh,wv) ENDIF ENDDO ENDDO c ENDDO !--nb c OPEN(unit=33,file='output_refr_index_sulfate_for_check.dat') c DO Nwv=1, NwvmaxSW-1+nb_lambda c WRITE(33,*) lambda_int(Nwv), n_r_tab(1,Nwv), n_i_tab(1,Nwv), c . n_r_tab(12,Nwv), n_i_tab(12,Nwv) c ENDDO c CLOSE(33) c c---now start calculations c DO mode=1, Nmode c DO irh=1,Nrh !---------LOOP OVER RH c c-map extra wavelengths to those from input file c rmin=0.002E-6*rh_growth(irh) rmax=30.E-6*rh_growth(irh) c DO Nwv=1, NwvmaxSW-1+nb_lambda c m=CMPLX(n_r_tab(irh,Nwv),-n_i_tab(irh,Nwv)) c pi=4.*ATAN(1.) c I=CMPLX(0.,1.) c sigma_sca=0.0 sigma_ext=0.0 sigma_abs=0.0 gtot=0.0 omegatot=0.0 masse = 0.0 volume=0.0 surface=0.0 c DO bin=0, Nbin !---loop on size bins r=exp(log(rmin)+FLOAT(bin)/FLOAT(Nbin)*(log(rmax)-log(rmin))) x=2.*pi*r/lambda_int(Nwv) deltar=1./FLOAT(Nbin)*(log(rmax)-log(rmin)) c number=0 DO dis=1, Ndis number=number+ . Ntot(dis,mode)/SQRT(2.*pi)/log(sigma_g(dis,mode))* . exp(-0.5*(log(r/(r_0(dis,mode)*rh_growth(irh)))/ . log(sigma_g(dis,mode)))**2) ENDDO c--80% RH mass c masse=masse +4./3.*pi* c . ((r/rh_growth(irh)*rh_growth(9))**3)* c . number*deltar*rho*1.E3 !--g/m3 c--dry aerosol mass masse=masse +4./3.*pi* . ((r/rh_growth(irh))**3)* . number*deltar*rho*1.E3 !--g/m3 c volume=volume+4./3.*pi*(r**3)*number*deltar surface=surface+4.*pi*r**2*number*deltar c k2=m k3=CMPLX(1.0,0.0) z2=CMPLX(x,0.0) z1=m*z2 IF (0.0.LE.x.AND.x.LE.8.) THEN Nmax=INT(x+4*x**(1./3.)+1.)+2 ELSEIF (8..LT.x.AND.x.LT.4200.) THEN Nmax=INT(x+4.05*x**(1./3.)+2.)+1 ELSEIF (4200..LE.x.AND.x.LE.20000.) THEN Nmax=INT(x+4*x**(1./3.)+2.)+1 ELSE WRITE(10,*) 'x out of bound, x=', x STOP ENDIF Nstart=Nmax+10 C-----------loop for nu1z1, nu1z2 nu1z1(Nstart)=CMPLX(0.0,0.0) nu1z2(Nstart)=CMPLX(0.0,0.0) DO n=Nstart-1, 1 , -1 nn=CMPLX(FLOAT(n),0.0) nu1z1(n)=(nn+1.)/z1 - 1./( (nn+1.)/z1 + nu1z1(n+1) ) nu1z2(n)=(nn+1.)/z2 - 1./( (nn+1.)/z2 + nu1z2(n+1) ) ENDDO C------------loop for nu3z2 nu3z2(0)=-I DO n=1, Nmax nn=CMPLX(FLOAT(n),0.0) nu3z2(n)=-nn/z2 + 1./ (nn/z2 - nu3z2(n-1) ) ENDDO C-----------loop for psiz2 and ksiz2 (z2) ksiz2(-1)=COS(REAL(z2))-I*SIN(REAL(z2)) ksiz2(0)=SIN(REAL(z2))+I*COS(REAL(z2)) DO n=1,Nmax nn=CMPLX(FLOAT(n),0.0) ksiz2(n)=(2.*nn-1.)/z2 * ksiz2(n-1) - ksiz2(n-2) psiz2(n)=CMPLX(REAL(ksiz2(n)),0.0) ENDDO C-----------loop for a(n) and b(n) DO n=1, Nmax u1=k3*nu1z1(n) - k2*nu1z2(n) u5=k3*nu1z1(n) - k2*nu3z2(n) u6=k2*nu1z1(n) - k3*nu1z2(n) u8=k2*nu1z1(n) - k3*nu3z2(n) a(n)=psiz2(n)/ksiz2(n) * u1/u5 b(n)=psiz2(n)/ksiz2(n) * u6/u8 ENDDO C-----------------final loop-------------- Q_ext=0.0 Q_sca=0.0 g=0.0 DO n=Nmax-1,1,-1 nnn=FLOAT(n) Q_ext=Q_ext+ (2.*nnn+1.) * REAL( a(n)+b(n) ) Q_sca=Q_sca+ (2.*nnn+1.) * . REAL( a(n)*CONJG(a(n)) + b(n)*CONJG(b(n)) ) g=g + nnn*(nnn+2.)/(nnn+1.) * . REAL( a(n)*CONJG(a(n+1))+b(n)*CONJG(b(n+1)) ) + . (2.*nnn+1.)/nnn/(nnn+1.) * REAL(a(n)*CONJG(b(n))) ENDDO Q_ext=2./x**2 * Q_ext Q_sca=2./x**2 * Q_sca Q_abs=Q_ext-Q_sca IF (AIMAG(m).EQ.0.0) Q_abs=0.0 omega=Q_sca/Q_ext g=g*4./x**2/Q_sca c sigma_sca=sigma_sca+r**2*Q_sca*number*deltar sigma_abs=sigma_abs+r**2*Q_abs*number*deltar sigma_ext=sigma_ext+r**2*Q_ext*number*deltar omegatot=omegatot+r**2*Q_ext*omega*number*deltar gtot =gtot+r**2*Q_sca*g*number*deltar c ENDDO !---bin C------------------------------------------------------------------ sigma_sca=pi*sigma_sca sigma_abs=pi*sigma_abs sigma_ext=pi*sigma_ext gtot=pi*gtot/sigma_sca omegatot=pi*omegatot/sigma_ext c final_g(Nwv)=gtot final_w(Nwv)=omegatot final_a(Nwv)=sigma_ext/masse c c--averaged Qext for Yves final_qext(Nwv)=sigma_ext/(surface/4.) c ENDDO !--loop on wavelength c c---averaging over LMDZ wavebands c DO band=1, NbandSW gcm_a(band)=0.0 gcm_g(band)=0.0 gcm_w(band)=0.0 gcm_qext(band)=0.0 gcm_weight_a(band)=0.0 gcm_weight_g(band)=0.0 gcm_weight_w(band)=0.0 gcm_weight_qext(band)=0.0 ENDDO c c---band 1 is now in the UV, so we take the first wavelength as being representative c---it doesn't matter anyway because all radiation is absorbed in the stratosphere DO Nwv=1,1 band=1 gcm_a(band)=gcm_a(band)+final_a(Nwv)*weight(Nwv) gcm_weight_a(band)=gcm_weight_a(band)+weight(Nwv) c gcm_w(band)=gcm_w(band)+ . final_w(Nwv)*final_a(Nwv)*weight(Nwv) gcm_weight_w(band)=gcm_weight_w(band)+ . final_a(Nwv)*weight(Nwv) c gcm_g(band)=gcm_g(band)+ . final_g(Nwv)*final_a(Nwv)*final_w(Nwv)*weight(Nwv) gcm_weight_g(band)=gcm_weight_g(band)+ . final_a(Nwv)*final_w(Nwv)*weight(Nwv) c gcm_qext(band)=gcm_qext(band)+final_qext(Nwv)*weight(Nwv) gcm_weight_qext(band)=gcm_weight_qext(band)+weight(Nwv) ENDDO c DO Nwv=1,NwvmaxSW-1 c IF (Nwv.LE.5) THEN !--RRTM spectral interval 2 band=2 ELSEIF (Nwv.LE.10) THEN !--RRTM spectral interval 3 band=3 ELSEIF (Nwv.LE.16) THEN !--RRTM spectral interval 4 band=4 ELSEIF (Nwv.LE.21) THEN !--RRTM spectral interval 5 band=5 ELSE !--RRTM spectral interval 6 band=6 ENDIF c gcm_a(band)=gcm_a(band)+final_a(Nwv)*weight(Nwv) gcm_weight_a(band)=gcm_weight_a(band)+weight(Nwv) c gcm_w(band)=gcm_w(band)+ . final_w(Nwv)*final_a(Nwv)*weight(Nwv) gcm_weight_w(band)=gcm_weight_w(band)+ . final_a(Nwv)*weight(Nwv) c gcm_g(band)=gcm_g(band)+ . final_g(Nwv)*final_a(Nwv)*final_w(Nwv)*weight(Nwv) gcm_weight_g(band)=gcm_weight_g(band)+ . final_a(Nwv)*final_w(Nwv)*weight(Nwv) c gcm_qext(band)=gcm_qext(band)+final_qext(Nwv)*weight(Nwv) gcm_weight_qext(band)=gcm_weight_qext(band)+weight(Nwv) ENDDO c DO band=1, NbandSW gcm_a(band)=gcm_a(band)/gcm_weight_a(band) gcm_w(band)=gcm_w(band)/gcm_weight_w(band) gcm_g(band)=gcm_g(band)/gcm_weight_g(band) gcm_qext(band)=gcm_qext(band)/gcm_weight_qext(band) ss_a(band,irh)=gcm_a(band) ss_w(band,irh)=gcm_w(band) ss_g(band,irh)=gcm_g(band) ss_qext(band,irh)=gcm_qext(band) ENDDO c DO nb=NbandSW+1, NbandSW+nb_lambda ss_a(nb,irh)=final_a(NwvmaxSW-1+nb-NbandSW) ss_w(nb,irh)=final_w(NwvmaxSW-1+nb-NbandSW) ss_g(nb,irh)=final_g(NwvmaxSW-1+nb-NbandSW) ss_qext(nb,irh)=final_qext(NwvmaxSW-1+nb-NbandSW) ENDDO c ENDDO !--fin boucle sur RH c c--Outputs C IF (mode.EQ.1) THEN !--only CS because AS treated by internal mixing routine WRITE(14,*) ' ! '//chmode(mode) DO k=1, NbandSW WRITE(14,951) (ss_a(k,irh),irh=1,Nrh) ENDDO WRITE(15,*) ' ! '//chmode(mode) DO k=1, NbandSW WRITE(15,951) (ss_g(k,irh),irh=1,Nrh) ENDDO WRITE(16,*) ' ! '//chmode(mode) DO k=1, NbandSW WRITE(16,951) (ss_w(k,irh),irh=1,Nrh) ENDDO DO k=1, NbandSW WRITE(17,951) (ss_qext(k,irh),irh=1,Nrh) ENDDO c WRITE(24,*) ' ! extinction '//chmode(mode) DO k=NbandSW+1,NbandSW+nb_lambda WRITE(24,951) (ss_a(k,irh),irh=1,Nrh) ENDDO WRITE(26,*) ' ! absorption '//chmode(mode) DO k=NbandSW+1,NbandSW+nb_lambda WRITE(26,951) ((1.0-ss_w(k,irh))*ss_a(k,irh),irh=1,Nrh) ENDDO c WRITE(25,*) ' ! '//chmode(mode) DO k=NbandSW+1,NbandSW+nb_lambda WRITE(25,951) (ss_qext(k,irh),irh=1,Nrh) ENDDO c ENDIF c ENDDO !--boucle sur les modes 951 FORMAT(1X,12(F6.3,','),' &') c CLOSE(14) CLOSE(15) CLOSE(16) CLOSE(17) c CLOSE(24) CLOSE(25) CLOSE(26) c END