⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cape.f90

📁 计算几个复杂的天气诊断指数
💻 F90
📖 第 1 页 / 共 3 页
字号:
!---------------主程序开始
program main
implicit none
!integer,parameter :: x=61,y=34,z=21
integer,parameter :: x=81,y=71,z=21
real,parameter :: T0=273.16
integer i,j,k
real tk(x,y,z),f(x,y,z),h(x,y,z),u(x,y,z),v(x,y,z)    
real citase(x,y,z),q(x,y,z),tdk(x,y,z)     
real cape1(x,y),cin1(x,y),li1(x,y),bcape1(x,y),bic1(x,y),dcape1(x,y),ssi1(x,y)
real p(z),t(z),td(z),fp(z)
real te(120),ta(120)
data p/1000, 975, 950, 925, 900, 850, 800, 750, 700, 650, 600, 550, 500, 450, 400, 350, 300, 250, 200, 150, 100/
real CAPE,PLFC,PE,CIN,LI,PC,TC,BCAPE,BIC,DCAPEX,TCON,CCL,H0,shr,SSI
!-----------------------------------------------
!-------------------------从源文件读入数据
open(1,file='D:\learn\work\diagnosis\myNeed\0126_00\0126_00.dat',status='unknown',form='unformatted',access='direct',recl=x*y*z)
!open(1,file='D:\temp\need\ht1.dat',status='unknown',form='unformatted',access='direct',recl=x*y*z)
read(1,rec=1)  (((tk(i,j,k),i=1,x),j=1,y),k=1,z)
read(1,rec=2)  (((h(i,j,k),i=1,x),j=1,y),k=1,z)
read(1,rec=3)  (((u(i,j,k),i=1,x),j=1,y),k=1,z)
read(1,rec=4)  (((v(i,j,k),i=1,x),j=1,y),k=1,z)
read(1,rec=5)  (((f(i,j,k),i=1,x),j=1,y),k=1,z)
close(1)
!-----------------------------------计算 thse & td
do i=1,x
	do j=1,y
		do k=1,z
		call tem_se(f(i,j,k),tk(i,j,k),p(k),tdk(i,j,k),q(i,j,k),citase(i,j,k))
		print*, tk(i,j,k),h(i,j,k),u(i,j,k),f(i,j,k),tdk(i,j,k)
		pause
		enddo
	enddo
enddo
!--------------------calculate CAPE,CIN,LI,SSI
do i=1,x
	do j=1,y
		do k=1,z
		t(k)=tk(i,j,k)-T0
		td(k)=tdk(i,j,k)-T0
		enddo
 	CALL CAL_CAPE(P,T,TD,z,CAPE,PLFC,PE,CIN,LI,PC,TC)
	call CAL_BCAPE(P,T,TD,z,BCAPE)
	call CAL_BIC(P,T,TD,z,BIC)
	call CAL_DCAPE(P,T,TD,z,DCAPEX)
	H0=3600
	call CAL_SSI(p,H0,H(i,j,:),U(i,j,:),V(i,j,:),z,CAPE,shr,SSI)
    cape1(i,j)=cape
	cin1(i,j)=cin
	li1(i,j)=li
	bcape1(i,j)=bcape
	bic1(i,j)=bic
	dcape1(i,j)=dcapex
	ssi1(i,j)=ssi
	print*, cape1(i,j),cin1(i,j),li1(i,j),bcape1(i,j),bic1(i,j),dcape1(i,j),ssi1(i,j)
!	pause
	enddo
enddo
!---------------把诊断量写入目标文件
open(3,file='D:\learn\work\diagnosis\myNeed\0126_00\cape0126.dat',status='replace',form='unformatted',access='direct',recl=x*y)
!open(3,file='D:\temp\need\ht1_1.dat',status='replace',form='unformatted',access='direct',recl=x*y)
write(3,rec=1)	((cape1(i,j),i=1,x),j=1,y)
write(3,rec=2)	((cin1(i,j),i=1,x),j=1,y)
write(3,rec=3)	((li1(i,j),i=1,x),j=1,y)
write(3,rec=4)	((bcape1(i,j),i=1,x),j=1,y)
write(3,rec=5)	((bic1(i,j),i=1,x),j=1,y)
write(3,rec=6)	((dcape1(i,j),i=1,x),j=1,y)
write(3,rec=7)	((ssi1(i,j),i=1,x),j=1,y)
do k=1,z
	write(3,rec=7+k) ((citase(i,j,k),i=1,x),j=1,y)
	write(3,rec=7+z+k) ((q(i,j,k),i=1,x),j=1,y)
enddo
close(3)
stop 
end program
!---------------计算假相当位温和露点的子程序
SUBROUTINE tem_se(f,t,p,td,q,se)
      T0=273.16
      d=4.9283
      c=6764.9
      ET=6.11*((T0/t)**d)*exp(c/T0-c/t)
      qs=0.622*ET/(p-0.378*ET)
      q=qs*f/100
             call tem_td(q,t,p,td)
                c=0.28586*alog((1000.0/p))
               d=q/(338.52-0.24*t+1.24*td)
               se=t*exp((c+2500*d))
return
end
SUBROUTINE tem_td(q,t,p,td)
      real q,t,p,td,qs,ET
      td=t
        qs=q+1
        do 20, while(q.le.qs)
        td=td-0.02
        if (td<200) goto 10
      T0=273.16
        d=4.9283
        c=6764.9
      ET=6.11*((T0/td)**d)*exp(c/T0-c/td)
      qs=0.622*ET/(p-0.378*ET)
20     continue
10      return
 end 
!-----------------------主程序结束

       SUBROUTINE CAL_CAPE(P,T,TD,LEV,CAPE,PLFC,PE,CIN,LI,PC,TC)
!     THIS SUBROUTINE CALCULATE CONVECTIVE AVAILABLE POTENTIAL ENERGY
!	AND IT IS USED WITH CAL_TC_PC,CAL_TA,CAL_TE,CAL_ENGY,
!	IN WHICH SUBROUTINE CAL_TA AND CAL_TC_PC ARE USED WITH CAL_THSE
!    INPUT   T ======> TEMPERATURE (CELSIUS DEGREE)
!            TD =====> DEW POINT (CELSIUS DEGREE)
!            P ======> PRESSURE   (HPA)
!            LEV ====> LEVEL
!    OUTPUT  CAPE ===> EQUIVALENT POTENTIAL TEMPERATURE   (J/KG)
!            PLFC ===> FREE CONVECTION LEVEL
!            PE =====> EMBALANCE LEVEL
!            CIN ====> CONVECTIVE INHIBITION
!            LI =====> LIFTING INDEX            
!    TEMP ARRAY
! 		   TE =====> ENVIRONMENT TEMPERATURE   (KELVIN)
!            TA =====> PARCEL TEMPERATURE        (KELVIN)
!            TC
      DIMENSION P(LEV),T(LEV),TD(LEV)
      DIMENSION TE(120),TA(120)
      REAL CAPE,TC,PC,THSE,PC0,TC0,TD0,THSE0
      REAL PLFC,PE,LI,CIN
      INTEGER LEV
!    ASSUMING THE BOTTOM POINT AS THE LIFTING LAYER
      THSE=220.
      PC=P(1)
      TC=T(1)
      P0=P(1)
      T0=T(1)
      TD0=TD(1)
      CALL CAL_TC_PC(P0,T0,TD0,PC0,TC0,THSE0)
      PC=PC0
      TC=TC0
      CALL CAL_TE(P,T,TE,LEV)
      CALL CAL_TA(P0,T0,PC,TC,THSE0,TA)
      CALL CAL_PLFC_AND_PE(P,TE,TA,LEV,PLFC,PE)
    CALL CAL_VIR_ENGY(P,T,TD,LEV,TE,TA,CAPE)
!	CALL CAL_CIN1(plfc,P0,TE,TA,CIN)
	CALL CAL_CIN(P0,TE,TA,CIN)
	CALL CAL_LI(P0,TE,TA,LI)
   !   RETURN
      END

      SUBROUTINE CAL_TC_PC(P,T,TD,PC,TC,THSE)
!    CALCULATE LIFTING CONDENSATION LAYER AND LIFTING CONDENSATION TEMPERATURE
!    AND ALSO PSEUDO-POTENTIAL TEMPERATURE AT CONDESAATING POINT
!    INPUT P ========> LIFTING PRESSURE (HPA)
!          T ========> LIFTING TEMPERATURE (CELSIUS DEGREE)
!          TD =======> DEW POINT (CELSIUS DEGREE)
!    OUTPUT
!          PC =======> CONDESATION PRESSURE
!          TC =======> CONDENSATION TEMPERATURE
!          THSE =====> PSEUDO EQUIVALENT POTENTION TEMPERATURE (KELVIN)
      REAL P,T,TD,PC,TC,THSE
      TC=T-(T-TD)*0.976/(0.976-0.000833*(237.3+TD)**2/(273.15+TD))
      PC=P*((273.15+TC)/(273.15+T))**3.5
      CALL CAL_THSE(PC,TC,THSE)
      RETURN
      END

      SUBROUTINE CAL_THSE(P,T,THSE)
!	计算假相当位温,不考虑 0 度以下假相当位温计算公式的差别
      REAL E,A,B,P,T,THSE
      A=7.5*T/(237.3+T)
      E=6.11*10.**A
      B=1000.0/(P-E)
     THSE=(273.16+T)*B**0.286*EXP((2.5*10.**6-2368.*T)*0.622*E/(1004.*(273.16+T)*(P-E)))
      RETURN
      END

      SUBROUTINE CAL_THSE1(P,T,THSE)
!	本子程序考虑 0 度以下,假相当位温计算公式不同
      REAL E,A,B,P,T,THSE
      IF(T.GE.0)A=7.5*T/(237.3+T)
      IF(T.LT.0)A=9.5*T/(265.5+T)
      E=6.11*10.**A
      B=1000.0/(P-E)
      IF(T.GE.0) THSE=(273.16+T)*B**0.286*EXP((597.3+0.5*T)*0.622*E/(0.24*(273.16+T)*(P-E)))
      IF(T.LT.0) THSE=(273.16+T)*B**0.286*EXP((667.0+0.5*T)*0.622*E/(0.24*(273.16+T)*(P-E)))
      RETURN
      END

      SUBROUTINE CAL_TE(PP,TP,TE,KMAX)
!                       p ,T ,TE,LEV
!	********** CALCULATE TEMPERTURE AT EACH LEVEL *********
!	计算层结每隔 10HPA 的温度(对数气压线性内插)
!      PARAMETER (KMAX=30)
      DIMENSION PP(KMAX),TP(KMAX),TE(110)
      REAL P_L
      INTEGER I_NL,IN
      DO K=1,110
      	TE(K)=-60.
      ENDDO
!      WRITE(*,*)(PP(K),K=1,KMAX)
!      WRITE(*,*)(TP(K),K=1,KMAX)
!     PAUSE 31
      I_NL=KMAX
      I=1
      IN=1
101		P_L=INT(PP(I)/10.)*10.0
      	P_T=INT(PP(I+1)/10.)*10.+10.

10	TE(IN)=TP(I)+(TP(I)-TP(I+1))/ALOG(PP(I)/PP(I+1))*ALOG(P_L/PP(I))
      IN=IN+1
      P_L=P_L-10.
      IF(P_T.GT.PP(I))IN=IN-1
      IF(P_L.GE.P_T)GOTO 10
      	I=I+1
!      	IF(PP(I+1).GT.50.OR.(I+1).LT.(I_NL))THEN
      	IF((I+1).LE.(I_NL))THEN
      		GOTO 101
      	ELSE
      		GOTO 20
      	ENDIF
20	CONTINUE
      IF((PP(I_NL).GE.100.).AND.(INT(PP(I_NL)/10.)*10.).EQ.(PP(I_NL))) TE(IN)=TP(I_NL)
      RETURN
      END

      SUBROUTINE CAL_TA(PP0,TP0,PC,TC,THSE,TA)
!	计算状态曲线各整层高度(间隔 10HPA)上的温度
!     INPUT PP0 ======> PRESSURE AT THE LIFTING LEVEL (HPA)
!           TP0 ======> TEMPERATURE AT THE LIFTING LEVEL (CELSIUS DEGREE)
!           PC =======> LIFTING CONDENSATION LEVEL (HPA)
!           TC =======> LIFTING CONDESATION TEMPERATURE (CELSIUS DEGREE)
!           THESE ====> PSEUDO EQUIVALENT POTENTIAL TEMPERATURE (KELVIN)
!     OUTPUT ARRAY
!           TA =======> PARCEL TEMPERATURE AT EACH LEVEL (CELSIUS DEGREE)
      REAL PP0,TP0,PC,TC,THSE,THSE1,THSE2,P_L,T1,T2,RD,CPD
      INTEGER KPC
      DIMENSION TA(110)
	RD=287.04
	CPD=1005.
      DO K=1,110
      	TA(K)=-130.
      ENDDO
!C ************** DRY ADIABATIC PROCESS BEGIN
      KPC=INT(PP0/10)-INT(PC/10)
      P_L=INT(PP0/10.)*10.
      THD=(TP0+273.15)*(1000./PP0)**(RD/CPD)
      DO I=1,KPC
      	TA(I)=THD*(P_L/1000.)**(RD/CPD)-273.15
      	P_L=P_L-10.
      ENDDO
!      DO I=1,KPC
!     	TA(I)=TP0+(TC-TP0)/ALOG(PC/PP0)*ALOG(P_L/PP0)
!      	P_L=P_L-10.
!      ENDDO
! ************** DRY ADIABATIC PROCESS END
      IN=KPC
      T1=TC
      P1=PC
!	WRITE(*,*)' IN = ',IN,' TC = ',TC,' PC = ',PC
      KZERO=1
!	KZERO IS A JUDGEMENT FOR TEMPERATURE
!*************** MOIST ADIABATIC PROCESS BEGIN
10    CALL CAL_THSE(P_L,T1,THSE1)
      CALL CAL_THSE(P_L,T1-0.1,THSE2)
      T2=T1-(THSE1-THSE)/(THSE1-THSE2)*0.1
!	NOTICE DIFFERENCE OF THSE WHEN TEMPERERTURE OBOVE OR BELEOW ZERO
      IF(T2.LT.0.AND.KZERO.EQ.1)THEN
      CALL CAL_THSE(P_L,T2,THSE)
      KZERO=0
      ENDIF	 
      IN=IN+1
      TA(IN)=T2
      T1=T2
      P_L=P_L-10.
!	WRITE(*,*)' T1 = ',T1
!	PAUSE
      IF(P_L.GE.90.)GOTO 10
! *************** MOIST ADIABATIC PROCESS END
      RETURN
      END

      SUBROUTINE CAL_PLFC_AND_PE(P,TE,TA,LEV,PLFC,PE)
!     THIS SUBROUTINE CALCULATE LAYER OF FREE CONVECTION AND EMBALANCE LAYER
!     NOTICE THIS SUBROUTINE IS NOT INDEPENDENT!!!
! 	INPUT  TE =====> ENVIRONMENT TEMPERATURE   (KELVIN)
!            TA =====> PARCEL TEMPERATURE        (KELVIN)
!            P  =====> PRESSURE        (HPA)
!            LEV ====> NUMBER OF LAYER
!     OUTPUT PLFC ===> FREE CONVECTION LAYER  (HPA)
!            PE =====> EMBALANCE PRESSURE  (HPA)
      REAL PLFC,PE
      DIMENSION TE(110),TA(110),P(LEV)
      INTEGER LEV,KLFC
	REAL DELT1,DELT2
!	WRITE(*,'(10F8.2)')(TA(K),K=1,10),(TE(K),K=1,10)
	KLFC=0
!	IF(TA(1).GE.TE(1).AND.TA(2).GT.TE(2))THEN
	IF(TA(1).GT.TE(1).OR.(TA(1).EQ.TE(1).AND.TA(2).GT.TE(2)))THEN
	    PLFC=P(1)
	ELSEIF((TA(1).EQ.TE(1).AND.TA(2).LE.TE(2)).OR.TA(2).LE.TE(2))THEN
          P_L=INT(P(1)/10.)*10
	    P_T=P_L-10
          DO K=2,90
	        IF(TA(K).GT.TE(K))THEN
	            KLFC=K
                  P_B=P_T+10
	            DELT1=TE(K-1)-TA(K-1)
	            DELT2=TA(K)-TE(K)
	            PLFC=(P_B*DELT2+P_T*DELT1)/(DELT1+DELT2)
	            GOTO 290
	         ENDIF
	    P_T=P_T-10
	    ENDDO
	   IF(KLFC.EQ.0)PLFC=99999.9
	ENDIF
290	CONTINUE
 	NB=INT(P(1)/10.)
	NT=INT((P(LEV)-0.001)/10.)+1
	NE=NB-NT+1
	KPE=NE
	IF(INT(P(LEV))/10..EQ.P(LEV)/10.)THEN
	    P_T=P(LEV)
	ELSE
	    P_T=INT(P(LEV)/10.)*10+10.
	ENDIF
	IF(TE(NE).LT.TA(NE))THEN
          PE=99999.9
	ELSE
	    DO K=NE-1,1,-1
	        IF(TE(K).LT.TA(K))THEN
	            KPE=K
                  P_B=P_T+10
	            DELT1=TE(K+1)-TA(K+1)
	            DELT2=TA(K)-TE(K)
	            PE=(P_B*DELT2+P_T*DELT1)/(DELT1+DELT2)
	            GOTO 390
              ENDIF
	    P_T=P_T+10
	    ENDDO
	    IF(KPE.EQ.NE)PE=99999.9
	ENDIF
390   CONTINUE
      RETURN
      END

      SUBROUTINE CAL_VIR_ENGY(P,T,TD,LEV,TE,TA,CAPEV)
!	
!    NOTICE IT IS SUPPORTED BY CAL_TDE,CAL_Q AND CAL_QS
!    INPUT   T ======> TEMPERATURE (CELSIUS DEGREE)
!            TD =====> DEW POINT (CELSIUS DEGREE)
!            P ======> PRESSURE   (HPA)
!            LEV ====> LEVEL
!            TE =====> ENVIRONMENT TEMPERATURE (CELSIUS DEGREE)
!            TA =====> PARCEL TEMPERATURE (CELSIUS DEGREE)
!    OUTPUT
!            CAPEV ==> CONVECTIVE AVAILABLE POTENTIAL ENERGY (J/KG)
!    TEMP ARRAY
!            PDS ====> PRESSURE (HPA)
!            QE =====> SPECIFIC HUMICITY
!            QSE ====> SATURATE SPECIFIC HUMIDITY
!            TDE ====> DEW POINT (CELSIUS DEGREE)
      REAL CAPEV,R,P_L
      DIMENSION TE(110),TA(110),TDE(110),P(LEV),T(LEV),TD(LEV)
	DIMENSION PDS(110),QE(110),QSE(110)
	DO K=1,LEV
	    IF(TD(K).GT.90)TD(K)=T(K)-30.
	ENDDO

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -