爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

搜索
查看: 11997|回复: 7

[源代码] 水汽收支的相关计算问题

[复制链接]

新浪微博达人勋

发表于 2018-5-8 22:47:28 | 显示全部楼层 |阅读模式

登录后查看更多精彩内容~

您需要 登录 才可以下载或查看,没有帐号?立即注册 新浪微博登陆

x
最近刚开始接触大气方面的知识,想计算某地区的水汽净收支,从论坛里找“的程序(输入的是grd文件)修改了一下,我的输入原文件是nc文件,我先使用grads将nc转为dat格式,然后使用fortran读取dat进行计算,目前遇到的问题如下:
1.  nc转dat可不可以一次转化多个变量?
2. 我的转化成dat为啥打不开,说是"描述文件错误"

grads转化nc为dat格式代码:
1.jpg

fortran 程序打开dat文件及运行的报错信息:
2.jpg
4.jpg

grads打开转化的dat文件的报错信息:
3.jpg
请大家帮我看看,谢谢大家
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2018-5-9 09:23:06 | 显示全部楼层
自己顶一下,别沉啊
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2018-5-9 10:23:19 | 显示全部楼层
我印象中是可以一次性转化多个变量的……你的gs我觉得没有什么问题啊
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2018-5-9 10:47:01 | 显示全部楼层
xin729914245 发表于 2018-5-9 10:23
我印象中是可以一次性转化多个变量的……你的gs我觉得没有什么问题啊

您好,谢谢您的回答,多个变量我后面再试试,现在是nc转化成dat后,我的在grads中不能打开,程序里调用也不对,感觉应该是“open(806,file='2007_1.dat',form='unformatted',access='direct',recl=41*65)”这个“recl”设置的有问题?附件是我用的Fortran,您能不能帮忙看看,谢谢


  1. program main
  2. parameter(i_num=41,j_num=65,lev=20)
  3. real ps(i_num,j_num)
  4. real u(i_num,j_num,lev),v(i_num,j_num,lev)
  5. real q(i_num,j_num,lev),p(lev)
  6. real uq(i_num,j_num),vq(i_num,j_num)
  7. real vapour(10),vap_in,vap_out,time
  8. real vap_inp,vap_outp
  9. integer irec,b(10)
  10. character head(4)*10
  11. type str_lev
  12. integer p(20)
  13. end type str_lev
  14. type (str_lev) levels(4)
  15. data p/1000, 975, 950, 925, 900, 875, 850, 800, 825, 775, 750, 700, 650, 600, 550, 500, 450, 400, 350, 300/
  16. data head/'1000-300','1000-800','800-500','500-300'/
  17. time=30*24*60*60/1000/1000
  18. data levels(1)%p/1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1/ ! 1000-300
  19. data levels(2)%p/1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0/ ! 1000-800
  20. data levels(3)%p/0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0/ ! 800-500
  21. data levels(4)%p/0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1/ ! 500-300

  22. !     读入数据
  23. open(806,file='2007_1.dat',form='unformatted',access='direct',recl=41*65)
  24. irec=1
  25. !u(i,j,k)读取u风
  26. do  k=1,20
  27. read(806,rec=irec) ((u(i,j,k),i=1,i_num),j=1,j_num)
  28. irec=irec+1
  29. ! print*,u(i,j,k)
  30. end do
  31. !v(i,j,k)读取v风
  32. do  k=1,20
  33. read(806,rec=irec) ((v(i,j,k),i=1,i_num),j=1,j_num)  
  34. ! print*, v(i,j,k)
  35. irec=irec+1
  36. end do
  37. !q(i,j,k)读取比湿(相对湿度)
  38. do  k=1,20
  39. read(806,rec=irec) ((q(i,j,k),i=1,i_num),j=1,j_num)  
  40. ! print*, q(i,j,k)
  41. irec=irec+1
  42. end do
  43. !读取地面气压
  44. do k=1,1
  45. read(806,rec=irec) ((ps(i,j),i=1,i_num),j=1,j_num)  
  46. irec=irec+1
  47. end do   
  48. open(811,file='result.txt')
  49. write(811,'(10x,7a15)') 'west','north','east','south','all_in','all_out','all'
  50. !    计算水汽通量
  51. do  i=1,4
  52. vapour=0
  53. vap_inp=0
  54. vap_outp=0
  55. uq=0
  56. vq=0
  57. call cal_vap_flux(u,q,ps,p,levels(i)%p,lev,I_NUM,J_NUM,uq)
  58. call cal_vap_flux(v,q,ps,p,levels(i)%p,lev,I_NUM,J_NUM,vq)

  59. !          计算水汽收支
  60. call cal_vapour(uq,vq,i_num,j_num,22,28,23,1,dis(0.),1,vapour(1),vap_inp,vap_outp)
  61. print *,'1 ' ,vapour(1),vap_inp,vap_outp
  62. call cal_vapour(uq,vq,i_num,j_num,23,31,28,2,dis(43.),-1,vapour(2),vap_inp,vap_outp)
  63. print *,'2 ' ,vapour(2),vap_inp,vap_outp
  64. call cal_vapour(uq,vq,i_num,j_num,22,28,31,1,dis(0.),-1,vapour(3),vap_inp,vap_outp)
  65. print *,'3 ' ,vapour(3),vap_inp,vap_outp
  66. call cal_vapour(uq,vq,i_num,j_num,23,31,22,2,dis(38.),1,vapour(4),vap_inp,vap_outp)
  67. print *,'4 ' ,vapour(4),vap_inp,vap_outp
  68. write(811,'(a10,7e15.4)') head(i),(vapour(ii),ii=1,4),vap_inp,vap_outp,vap_inp-vap_outp
  69. end do
  70. close(811)   
  71. end

  72. subroutine cal_vap_flux(u,q,ps,p,ip,lev,I_NUM,J_NUM,uq)
  73. !     计算水汽通量
  74. !    INPUT   U =====> 风速( m/s)
  75. !            q =====> 比湿( kg/kg)
  76. !            ps =====> 地面气压 (hPa)
  77. !            p =====> 气压层(hPa)
  78. !            Ip  =====> 分层计算
  79. !            LEV ====> LEVEL
  80. !            I_NUM ====> 行数
  81. !            J_NUM ====> 列数
  82. !    OUTPUT  uq  ====> 水汽通量
  83. INTEGER LEV,lev_tem,I_NUM,J_NUM
  84. DIMENSION U(I_NUM,J_NUM,LEV),Q(I_NUM,J_NUM,LEV)
  85. dimension PS(I_NUM,J_NUM),P(LEV),Ip(lev)
  86. dimension uq(I_NUM,J_NUM),uq_tem(lev)
  87. uq=0
  88. do 4101 j=1,j_NUM
  89. do 4101 i=1,i_NUM
  90. lev_tem=0

  91. do 4106 k=1,lev
  92. uq_tem(k)=u(i,j,k)*q(i,j,k)
  93. if(ps(i,j).le.p(k)) lev_tem=k
  94. 4106  continue

  95. uq(i,j)=uq_tem(lev_tem+1)*(ps(i,j)-p(lev_tem+1))*IP(lev_tem+1)   
  96. if(i.eq.2.and.j.eq.3) then
  97. write(*,'(i4,6f10.2)') lev_tem,u(i,j,lev_tem+1),q(i,j,lev_tem+1),uq_tem(lev_tem+1),ps(i,j),p(lev_tem+1),uq(i,j)           
  98. endif
  99. do 4111 k= lev_tem+1,lev-1
  100. uq(i,j)=uq(i,j)+(uq_tem(k)+uq_tem(k+1))/2*(p(k)-p(k+1))*IP(k+1)
  101. if(i.eq.2.and.j.eq.3) then
  102. write(*,'(i4,6f10.2)') k,u(i,j,k),q(i,j,k),uq_tem(k),p(k),p(k+1),uq(i,j)           
  103. endif
  104. 4111  continue

  105. 4101  continue

  106. uq=uq/980
  107. print *, uq(2,3)
  108. return
  109. end

  110. subroutine cal_vapour(uq,vq,i_num,j_num,i,j,k,index,dist,bor,vap,vap_in,vap_out)
  111. !      计算水汽收支
  112. !      INPUT   uq =====> u方向水汽通量
  113. !      vq =====> v方向水汽通量
  114. !      I_NUM ====> uq,vq的行数
  115. !      J_NUM ====> uq,vq的列数
  116. !      i =====> 计算时边界的起始点(行或列)
  117. !      j =====> 计算时边界的结束点(行或列)
  118. !      K =====> 计算时边界行列值中固定不变的点
  119. !      index =====> 标示是计算uq方向或vq方向
  120. !      dist =====> 边界长度
  121. !      bor =====> 边界属性标示
  122. !      OUTPUT  vap====>  水汽净通过量
  123. !      vap_in ====> 流入水汽
  124. !      vap_out ====> 流出水汽
  125. integer i_num,j_num,i,j,k,index,bor
  126. real uq(i_num,j_num),vq(i_num,j_num),dist
  127. real vap, vap_in,vap_out
  128. vap=0
  129. time=6.*60*60/1000/1000
  130. do ii=i,j
  131. if(index==2) then
  132. vap=vap+(vq(ii,k)+vq(ii+1,k))*0.5*dist*time  
  133. if((vq(ii,k)+vq(ii+1,k))*bor>=0)  then
  134. vap_in=vap_in+(vq(ii,k)+vq(ii+1,k))*bor*0.5*dist*time
  135. else
  136. vap_out=vap_out-(vq(ii,k)+vq(ii+1,k))*bor*0.5*dist*time
  137. endif
  138. elseif(index==1) then
  139. vap=vap+(uq(k,ii)+uq(k,ii+1))*0.5*dist*time
  140. if((uq(k,ii)+uq(k,ii+1))*bor>=0)  then
  141. vap_in=vap_in+(uq(k,ii)+uq(k,ii+1))*bor*0.5*dist*time
  142. else
  143. vap_out=vap_out-(uq(k,ii)+uq(k,ii+1))*bor*0.5*dist*time
  144. endif
  145. endif
  146. enddo   
  147. end

  148. real function dis(num)
  149. !num 度纬圈上,1个经度的长度,单位 m
  150. real num ,pi
  151. pi=3.1415926
  152. dis= Cos(num * pi / 180) * 6371* 2 * pi / 360 * 1000
  153. end function
复制代码
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2018-5-11 13:16:38 | 显示全部楼层
楼主你经度和纬度方向取的格点数并不是41*65,程序不出错才怪
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2018-5-11 18:49:49 | 显示全部楼层
nunu18 发表于 2018-5-11 13:16
楼主你经度和纬度方向取的格点数并不是41*65,程序不出错才怪

明白了,之前我用的是原数据的格点数,没用转换后dat的格点数,谢谢
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2019-12-18 12:44:32 | 显示全部楼层
楼主,你有那个程序吗?您方便分享一下吗 ,我的贡献不够,无法下载(自动回复:请不要使用迅雷等下载工具,点我查看下载帮助) ,最近急着用
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2024-1-16 18:16:59 | 显示全部楼层
Zhangzh 发表于 2018-5-9 10:47
您好,谢谢您的回答,多个变量我后面再试试,现在是nc转化成dat后,我的在grads中不能打开,程序里调用也 ...

请问62-69行里头数字如22,28,23是啥意思?是否有把研究范围边界划分小边界的图?
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

本版积分规则

Copyright ©2011-2014 bbs.06climate.com All Rights Reserved.  Powered by Discuz! (京ICP-10201084)

本站信息均由会员发表,不代表气象家园立场,禁止在本站发表与国家法律相抵触言论

快速回复 返回顶部 返回列表