- 积分
- 60278
- 贡献
-
- 精华
- 在线时间
- 小时
- 注册时间
- 2011-6-13
- 最后登录
- 1970-1-1
|
登录后查看更多精彩内容~
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
好久没有发原创的东西了,根本原因是水平有限,百无一能,看到论坛的大牛们都在晒自己的大作,亚历山大啊,只有埋头苦干,奋起直追了,闲话少叙,回归正题。
今天发的是一个瓦赫宁根派模型(主要是WOFOST 和 ORYZA2000)的天气文件生成代码,由于模型是事先做好的,说句实话,这些模型的用户体验确实不好,有些东西总感觉不那么舒服顺畅,比如里面所用的逐日气象资料,相对来说,格式的要求十分严格,稍微错一点,最后来一个 simulation filed,那个抓狂的心啊...
先给大家show一下模型自带的天气文件的格式,看着很简单,如果看了user‘s manual ,就知道这里面的纠结之处了
- *---------------------------------------------------------------------------*
- * Station name: Swifterbant, Netherlands
- * Year: 1977
- * Author: Peter Uithol -99.000: NIL VALUE
- * Source: Natuur- en Weerkunde (J.G. Krom)
- * Comments: Missing values are exchanged with daily weather
- * data from synoptic station de Bilt, Netherlands
- * Measured vapour pressure at day 130 was 1.19 kPa
- * this was above saturated vapour pressure 1.16 kPa
- * so the measured vapour pressure was substituted
- * with the saturated vapour pressure.
- *
- * Longitude: 5 38 E, latitude: 52 34 N, altitude: -4 m.
- *
- * Column Daily value
- * 1 station number
- * 2 year
- * 3 day
- * 4 irradiation (kJ m-2 d-1)
- * 5 minimum temperature (degrees Celsius)
- * 6 maximum temperature (degrees Celsius)
- * 7 early morning vapour pressure (kPa)
- * 8 mean wind speed (height: 2 m) (m s-1)
- * 9 precipitation (mm d-1)
- *
- ** WCCDESCRIPTION=Netherlands, Swifterbant
- ** WCCFORMAT=2
- ** WCCYEARNR=1977
- *---------------------------------------------------------------------------*
- 5.63 52.57 -4. -0.18 -0.55
- 2 1977 1 1410. 2.0 9.0 0.810 6.1 2.5
- 2 1977 2 2330. -0.1 5.0 0.650 2.6 0.0
- 2 1977 3 810. 0.3 4.7 0.720 4.6 2.7
- 2 1977 4 1820. -1.0 4.4 0.680 1.7 0.9
- .....
复制代码
上面的就是模型自带的CABOWE文件,如果将该模式本地化,还要根据当地的气象资料,替换这里面的内容,包括温湿度,风速,水汽压,常规的做法是在excel里面按照格式要求将*-------------*下面的内容做好,然后粘贴到文本中,如果像我做的内容,研究n个省里面nn个站的话,而且还是十余年的内容(一个站一年就要生成一个文件啊),那这样的方法显然就不行了,只有死磕的写个程序了,最初以为很简单,按照格式写一下就行了,直到动了手才知道,里面很复杂,平年闰年,缺测值,地理信息,台站信息,为方便日后理解,我还在台站信息里加了中文台站名,后来又证明模式不认识中文,又加了拼音,还有一些非观测内容比如辐射量,水汽压等等,都要在中间计算,慢慢改了好久,才把最终的文件都做了出来,跟大家一起分享,一个人的水平毕竟有限,希望大家多多之处里面的错误和不足(没有删除测试以及说明行,希望便于大家理解,多多批评)。
首先,进行数据说明,格式如下,一个省份一个文件
最左边是站号,具体每一列代表什么意思,见下图(示例,着重看看要素代码)
由于还需要在最终的作物文件中写入台站的地理信息,因此又把每个省的台站信息进行了统计,格式如图
每个省的台站数量不同,平闰年的天数不同,为了高效,编程过程中使用了动态数组
贴代码了
- program JR
- implicit none
- integer i,j,line,m,l,line2,k,sl,sp !line为数据文件的行数 line2 台站信息文件的描述,sl为站名的字符串长度,sp为台站名的长度
- character hehe !求取行数所用
- character*5 sitenumber
- character*2 temp !后缀名转换的中间文件
- character*8 filename !引入汉语站名,欲作为文件名,由于wofost不认可,只将其作为文件内部的注释用
- character*8,allocatable::chinesename(:) !引入了汉语站名 为更方便
- integer,allocatable::provsite(:) !省台站数组
- character*3 lastname !后缀名
- !character*5 sitename !原定以为文件名,由于wofost特殊要求,暂弃用
- character*20 factsite !实际的站名 为汉语拼音,非站号
- real corr !纬度的度数与弧度之间的转换系数
- real lati
- real,allocatable::dat(:,:) !数据文件数组
- real,allocatable::geodata(:,:) ! 台站地理信息 第一列为纬度,第二列精度,第三列海拔高度
- integer,allocatable::site(:) !台站号数组
- character*12,allocatable::actname(:) !台站名数组
- character*8 prov(4)
- REAL LONGTI,heigh !精度 高度
- integer,allocatable::jday(:) !日叙述
- integer*4::result
- integer,external::systemqq
- integer :: time(0:1),timeOff
- real,allocatable::dr(:),detla(:),ws(:),ra(:),rs(:),nn(:),rss(:) !通过日照时数计算辐射的中间变量,ws不是windspeed,需注意
- corr=3.14/180 !公式所用纬度为弧度,corr为换算系数
- CALL SYSTEM_CLOCk(TIME(0))
- data prov/'Hebei','Jiangsu','Henan','Shandong'/
- result=systemqq("mkdir D:\SURFDATA")
- !data provsite/58027,58040,58138,58141,58144,58150,58238,58241,58251,58259,58265,58343,58345,58358/
- do sp=1,4
- result=systemqq("mkdir D:\SURFDATA"//trim(prov(sp))//"")
- line2=0
- open(10,file=''//trim(prov(sp))//'data.txt',status='old')
- do while(10)
- read(10,*,end=200) hehe
- line2=line2+1
- enddo
- 200 continue
- allocate(geodata(line2,3))
- allocate(site(line2))
- allocate(actname(line2))
- allocate(provsite(line2))
- allocate(chinesename(line2))
- rewind(10)
- do i=1,line2
- read(10,*) site(i),actname(i),(geodata(i,j),j=1,3),chinesename(i)
- end do
- close(10)
- do m=1,line2
- provsite(m)=site(m)
- enddo
- ! 测试行
- !do i=1,line2
- ! print*, provsite(i),site(i),geodata(i,1),geodata(i,3),actname(i)
- !enddo
- open (11,file=''//trim(prov(sp))//'.txt',status='old')
- line=0
- do while(11)
- read(11,*,end=100) hehe
- line=line+1
- end do
- 100 continue
- allocate(dat(line-1,11))
- allocate(jday(line-1))
- allocate(dr(line-1))
- allocate(detla(line-1))
- allocate(ws(line-1))
- allocate(ra(line-1))
- allocate(rs(line-1))
- allocate(nn(line-1))
- allocate(rss(line-1))
- !allocate(longti(line))
- !allocate(heigh(line))
- !allocate(factsite(line))
- !allocate(lati(line))
- ! print*,'haha' 测试行
- rewind(11)
- read(11,*) hehe
- do i=1,line-1
- read(11,*) (dat(i,j),j=1,11)
- end do
- close(11)
- !@@@@@@@@@@@@@@@@@@@@@日序计算@@@@@@@@@@@@@@@@@@
- do i=1,line-1
- jday(i)=int(275*(dat(i,3)/9)-30+dat(i,4))-2
- if((mod(int(dat(i,2)),4)==0.and.mod(int(dat(i,2)),100)/=0.or.mod(int(dat(i,2)),400)==0))then
- if(dat(i,3)>2) then
- jday(i)=jday(i)+1
- else
- jday(i)=jday(i)+2
- endif
- elseif(dat(i,3)<3) then
- jday(i)=jday(i)+2
- end if
- enddo
- !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- do i=1,line-1
- !@@@@@@@@@@@@@不同台站不同纬度,纬度筛选@@@@@@@
- do m=1,line2
- if (int(dat(i,1))==site(m)) then
- lati=geodata(m,1)*corr
- else
- endif
- enddo
- !日照时数数据检测,若缺测,用线性内插法订正
- if(dat(i,11)>=32700) then
- dat(i,11)=(dat(i-1,11)+dat(i+1,11))/2
- endif
- !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- !@@@@@@@@@@@@@@@计算每日的辐射@@@@@@@@@@@@@@@@
- detla(i)=0.4209*sin(jday(i)*0.0172-1.39)
- dr(i)=1+0.033*cos(0.0172*jday(i))
- ws(i)=acos(-1*tan(lati)*tan(detla(i)))
- ra(i)=37.6*dr(i)*((ws(i))*sin(lati)*sin(detla(i))+cos(lati)*cos(detla(i))*sin(ws(i)))
- nn(i)=24*ws(i)/3.14
- rss(i)=(0.25+(0.5)*dat(i,11)/(10*nn(i)))*ra(i)
- !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- !print*,rss(i)
- enddo !this do is for do i=1,line
- !stop
- !@@@@@@@@@@@@@@@@@@创建wofost天气文件@@@@@@@@@@@@@@@@@@
- !@@@@@@@@数据订正@@@@@@@
- do i=1,line-1 ! 降水缺测数据筛选,若缺测或痕量,定义为0
- if (dat(i,9)>=32000) then
- dat(i,9)=0
- endif
- enddo
- !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- do m=1,line2
- do k=1,line2
- if (provsite(m)==site(k)) then !根据台站号进行地理信息的赋值
- lati=geodata(k,1)
- longti=geodata(k,2)
- heigh=geodata(k,3)
- factsite=actname(k)
- filename=chinesename(k)
- write(sitenumber,'(I5)') site(k)
- else
- endif
- enddo
- do l=2000,2011
- if (l-2000<10) then
- write(temp,'(I1)') l-2000
- lastname='00'//trim(temp)//''
- else
- write(temp,'(i2)') l-2000
- lastname='0'//trim(temp)//''
- endif
- open(int(m*l/2),file='D:\surfdata\'//TRIM(PROV(SP))//'\'//trim(factsite)//'1.'//trim(lastname)//'',status='replace')
- sl=len(trim(factsite))
- print*,sl, factsite
- !@@@@@@@@@@@@@@@@@@@ WOFOST头文件创建@@@@@@@@@@@@@@@@@@@@@@
- write(int(m*l/2),"(A63)") '*-------------------------------------------------------------*'
- write(int(m*l/2),"(A15,A8,2X,A5,a17)") '* Station name:',trim(filename),SITENUMBER,','//trim(prov(sp))//'-China'
- WRITE(int(m*l/2),"(A7,I5)") '* Year:',l
- write(int(m*l/2),"(A16,A47)") '* Author: TOPMAD','-99.000: NIL VALUE'
- WRITE(int(m*l/2),"(a15)") '* Source: NUIST'
- WRITE(int(m*l/2),"(A63)") '* Comments: missing data is cauculated with interpoltion method'
- WRITE(int(m*l/2),"(a1)") '*'
- write(int(m*l/2),"(A54)") '* 缺测的日照时数通过前后两日的日照时数之和的平均值订正'
- write(int(m*l/2),"(A31)") '* 痕量以及缺测降水数据均订正为0'
- WRITE(int(m*l/2),"(a1)") '*'
- WRITE(int(m*l/2),"(a)") '* visit bbs.06climate.com get more information aboust us'
- WRITE(int(m*l/2),"(A12,I3,1X,I2,A14,I2,1X,I2,1X,A11,F7.1,A5)") '* Longitude:',INT(longti),INT((LONGTI-INT(LONGTI))*60),'E, latitude: ',INT(lati),INT((LATI-INT(LATI))*60),'N, altitude:',heigh,'m.'
- WRITE(int(m*l/2),"(a1)") '*'
- write(int(m*l/2),"(A21)") '* Column Daily value'
- write(int(m*l/2),"(A24)") '* 1 station number'
- write(int(m*l/2),"(A14)") '* 2 year'
- write(int(m*l/2),"(A13)") '* 3 day'
- write(int(m*l/2),"(A52)") '* 4 irradiation (kJ m-2 d-1)'
- write(int(m*l/2),"(A57)") '* 5 minimum temperature (degrees Celsius)'
- write(int(m*l/2),"(A57)") '* 6 maximum temperature (degrees Celsius)'
- write(int(m*l/2),"(A45)") '* 7 early morning vapour pressure (kPa)'
- write(int(m*l/2),"(A47)") '* 8 mean wind speed (height: 2 m) (m s-1)'
- write(int(m*l/2),"(A48)") '* 9 precipitation (mm d-1)'
- WRITE(int(m*l/2),"(a1)") '*'
- ! if (sl==4.and.sp==1) then
- write(int(m*l/2),"(A18,A,A12)") '** WCCDESCRIPTION=',trim(factsite),','//trim(prov(sp))//'-China'
- WRITE(int(m*l/2),"(a14)") '** WCCFORMAT=2'
- write(int(m*l/2),"(A13,I4)") '** WCCYEARNR=',l
- write(int(m*l/2),"(A63)") '*-------------------------------------------------------------*'
- write(int(m*l/2),"(f7.2,2x,f7.2,2x,f7.2,2x,f7.2,1x,f5.1)") LONGTI,LATI,HEIGH,-0.25,-0.5
- ! wofoso可以用日照时数或者辐射,如果用日照时数,上面的0.25 0.5就要是正的,如果用辐射,就要是0或负数
- do i=1,line-1
- if((int(dat(i,1))==provsite(m)).and.(int(dat(i,2))==l))then
- write(int(m*l/2),'(A1,2X,I4,1X,I3,1X,F10.2,1X,F6.2,1X,F6.2,1X,F6.2,1X,F5.2,1X,F6.2)') '1',INT(dat(i,2)),jday(i),rss(i)*1000,DAT(I,7)/10,DAT(i,6)/10,dat(i,8)/100,(dat(i,10)/10)*4.87/log(678-5.42),dat(i,9)/10
- endif
- enddo !this enddo is for i=1,line
- close(int(m*l/2))
- end do !for m=1,line
- end do ! for l=2000,2011
- !@@@@@@@@@@@释放@@@@@@@@@@@
- deallocate(dat)
- deallocate(jday)
- deallocate(dr)
- deallocate(detla)
- deallocate(ws)
- deallocate(ra)
- deallocate(rs)
- deallocate(nn)
- deallocate(rss)
- deallocate(provsite)
- deallocate(geodata)
- deallocate(site)
- deallocate(actname)
- deallocate(chinesename)
- enddo !this end do is for do sp=1,4(省份循环)
- !@@@@@@@@@用时统计@@@@@@@@@@@
- CALL SYSTEM_CLOCk(TIME(1))
- TIMEOFF=TIME(1)-TIME(0)
- write(*,'(A15,1X,I3,A1)') 'TIME CONSUME:',timeoff,'S'
- end
复制代码
这就是完成4个省的cabowe文件的代码,仔细看其实不难,就是相对繁琐一些,如果需要,将里面的代码稍加改动,便可变为己用
希望大家多对立面的任何错误和不足进行批评指正,老五在此先有礼了
|
评分
-
查看全部评分
|