LBM 安装-运行-修改-debug
[TOC]
前言
LBM(linear baroclinic model)LBM main (u-tokyo.ac.jp)是日本人开发的线性斜压模式。它运行快,资源占用少,易上手。给定背景场和强迫场,可以得到大气的定常响应。利用LBM可以快速验证自己的猜测和结论。
这几天安装、运行、调试了LBM,大致摸清了整个流程。其中有许多坑点,但都被解决了,下文将记录安装运行流程和坑点。
安装
首先需要向LBM的管理人员索要账号和密码以下载LBM,他的邮箱是 hayashi.michiya@nies.go.jp
我的账号密码记录在所邮箱中。
接着安装LBM的流程基本是跟着洪海旭师兄在CDSN上的博文来的LBM模式学习·保姆级安装及初步使用教程_lbm保姆-CSDN博客 以及 线性斜压模式LBM学习&安装实录 - chinagod - 博客园 (cnblogs.com)
两篇博文分别使用的是ICC和GCC编译模式,我只使用了GCC。第一篇博文提到sysdep_linux20201125.tar.gz 文件,也是从LBM官网上下载。
以下是文件结构
运行
1. 分辨率设置
位置:$LNHOME/Lmake.inc
参见洪海旭博文
2. 生成可执行文件
位置: $LNHOME/model/src
1 | make clean |
结果应在 $LNHOME/model/bin/linux 下生成一个 lbm2.t21ml20ctintgr (数字表示分辨率,随分辨率选择而改变)
3. 编译大气基本态
位置: $LNHOME/solver/util
1 | $ make bs |
位置: $LNHOME/solver/util/SETPAR
1 | &nmcp cncep='大气基本态.t21.grd', |
如果用EC模块,则改
1 | &nmecm cecm='大气基本态.t21.grd', |
修改基本态文件输出位置
1 | &nmbs cbs0='/disk1/xhw/LBM/ln_solver/bs/gt3/ncepsum.t21l20', |
生成大气基本态
1 | $ ./ncepsbs # 调用NCEP模块 |
4. 编译大气强迫场
位置: $LNHOME/solver/util/SETPAR
预先在 $LNHOME/data/ 下创建好 frc 文件夹和 out 文件夹用来存放强迫场和输出文件,文件夹名称可以根据case的内容自定义
修改强迫场输出位置
1 | &nmfin cfm='/disk1/xhw/LBM/ln_solver/data/frc/frc.t21l20.classic.mat', # 用不到可以不改 |
修改强迫方式
1 | &nmvar ovor=f, odiv=f, otmp=t, ops=f, osph=f |
强迫位置、形状
1 | &nmhpr khpr=1, # khpr=1/2代表椭圆/水平均匀的强迫 |
强迫廓线
1 | &nmvpr kvpr=2, # kvpr是垂直廓线的函数(1.是正弦函数,2是gamma函数,3是上下均匀的) |
所有参数的意思都可以查阅:$LNHOME/solver/util/param_list
编译并输出强迫场
位置: $LNHOME/solver/util
1 | $ make clean |
5. 结合强迫场和基本态并运行模式
位置: $LNHOME/model/sh/tintgr
找一个 .csh 文件作为修改模板,可以选择 linear-run.classic.copy.csh ,修改以下内容
1 | setenv FDIR $LNHOME/data/frc # 强迫场所在位置 |
运行模式
1 | csh linear-run.classic.copy.csh |
6. 简短运行流程
1 | # 1. 编译模式 |
运行Debug
如果出现如下错误, 是 /disk1/xhw/LBM/ln_solver/model/src/sysdep/Makedef.linux 和 /disk1/xhw/LBM/ln_solver/model/src/sysdep/Makedef.linux没有设置好。
1 | # 不应该是 -convert big_endian , 这种写法是icc的写法。我用的是gcc,应该在Makedef.linux 中改成 -fconvert=bing-endian |
或
1 | # 这个错误是啥原因忘记了 |
这里再贴一下 /disk1/xhw/LBM/ln_solver/model/src/sysdep/Makedef.linux 和 /disk1/xhw/LBM/ln_solver/solver/include/make.inc.linux
1 | # /disk1/xhw/LBM/ln_solver/model/src/sysdep/Makedef.linux |
1 | # /disk1/xhw/LBM/ln_solver/solver/include/make.inc.linux |
自制强迫场
LBM支持自动生成椭圆等形状的强迫场,包括温度、涡度、散度、气压强迫。然而当我们想要加多个强迫场,比如一个热源,一个冷源就比较麻烦了。但是我们可以自己根据LBM强迫场的格式,生成对应的文件,替换掉LBM自建的强迫场文件。这样可以随心所欲地加入强迫场的强度、形状,而且更贴近观测。
LBM强迫场是由 .grd 和 .ctl 给出的。我们需要做的是,读出 .grd ,查看内部变量内容,分辨率等要素。然后做出自己期望的强迫场,替换掉.grd。具体步骤如下
-
用
cdo将LBM自建强迫场转为 nc 文件方便读取查看。cdo -f nc import_binary frc.t42l20.classic.ctl frc.t42l20.classic.nc -
python 读取
frc.t42l20.classic.nc查看其内容。以设定温度强迫为例。改变nc文件中的t变量。 -
将新的强迫场输出为新的 nc 文件
newFrc.nc。变量t, d ,v 都是多高度层的,而变量p是地面气压是单高度层的,由于后续需要用Grads读取,而Grads无法直接用sdfopen同时读取多个高度维数据集,需要分两个文件读取。所以需要先输出一个newFrc.nc变量包括t,d,v。再另输出一个newFrc_p.nc变量包括p。如果使用xarray.Dataset.to_netcdf()输出nc文件。需添加format='NETCDF3_CLASSIC'forcing['p'].to_netcdf('/disk1/xhw/LBM/ln_solver/data/frc_indianOcean/newFrc_p.nc',format='NETCDF3_CLASSIC')
原因在于如果直接 to_netcdf 输出的是netcdf4,是 little_endian 小字节序的。而LBM全程使用的是 big_endian 大字节序的,会造成不匹配。添加 format='NETCDF3_CLASSIC' 后,python会以netcdf3输出nc文件,这个格式是 little_endian 的。
*注意:LBM 自带的
.ctl的时间填的是TDEF 1 LINEAR 15jan0000 1mo这在转为nc文件并读取后时间会显示为
array([cftime.DatetimeGregorian(-1, 1, 15, 0, 0, 0, 0, has_year_zero=False)],dtype=object)这在后续的处理中可能引起不便,因此可以将 强迫场
.ctl中的时间改为TDEF 1 LINEAR 15jan2000 1mo或在python输出nc文件之前将时间替换forcing['time'] = np.array([np.datetime64('2000-01-15')])
-
得到
newFrc.nc和newFrc_p.nc后,使用Grads读取, 我用的是opengrads气象家园整合版。(由于ip原因,我在服务器上没有用grads,文件是传到本地用grads处理的,原因见ncview安装和踩坑 | XHW’s Blog (664787022.github.io))1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51'reinit'
'sdfopen d:/user/pycode/LBM/makeFrc/newFrc.nc'
'sdfopen d:/user/pycode/LBM/makeFrc/newFrc_p.nc'
'set gxout fwrite'
* 输出参数sq顺序输出,cl覆写,be大字节序输出,可在谷歌查到
'set fwrite -sq -cl -be d:/user/pycode/LBM/makeFrc/newFrc.grd'
'set lon 0 357.1875'
'set lat -87.864 87.864'
* 循环写入顺序: 高度->变量->时间
i=1
while(i<=1)
'set t 'i''
'set dfile 1'
j=1
while(j<=20)
'set z 'j''
'd v'
j=j+1
endwhile
j=1
while(j<=20)
'set z 'j''
'd d'
j=j+1
endwhile
j=1
while(j<=20)
'set z 'j''
'd t'
j=j+1
endwhile
'set dfile 2'
j=1
while(j<=1)
'set z 'j''
'd p'
j=j+1
endwhile
i=i+1
endwhile
'disable fwrite'*注意:在写入之前应该先使用
q ctlinfo看出Grads读取后数据的排列顺序(例如纬度是由北到南还是由南到北,高度是由小到大还是有大到小)。一般来说,不过当时python 输出的顺序是怎样的,Grads读取后纬度是-90~90,高度是0~1(sigma坐标系)。这时写入newFrc.grd后顺序也是这样的。但是LBM给的 强迫场.ctl示例文件是的纬度是-90~90,高度是1~0,且设置了OPTIONS SEQUENTIAL YREV。 本来.ctl与 grads输出的.grd的纬度都是-90~90,是相匹配的。但是设置YREV(y轴reverse)意味着LBM读取 grads输出的.grd会以 90~-90的方式读入,这就反了。而真正需要reverse的是z轴。 所以需要更改.ctl里的option为OPTIONS SEQUENTIAL ZREV。 当然直接更改XDEF、YDEF、ZDEF以匹配输出的.grd也可以。下面给出一个示例.ctl1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27* sample forcing pattern
DSET ^newFrc.grd
* BYTESWAPPED
OPTIONS SEQUENTIAL ZREV
TITLE dumy
UNDEF -999.
OPTIONS big_endian
XDEF 128 LINEAR 0. 2.81250
YDEF 64 LEVELS
-87.864 -85.097 -82.313 -79.526 -76.737 -73.948 -71.158 -68.368 -65.578
-62.787 -59.997 -57.207 -54.416 -51.626 -48.835 -46.045 -43.254 -40.464
-37.673 -34.883 -32.092 -29.301 -26.511 -23.720 -20.930 -18.139 -15.348
-12.558 -9.767 -6.976 -4.186 -1.395 1.395 4.186 6.976 9.767
12.558 15.348 18.139 20.930 23.720 26.511 29.301 32.092 34.883
37.673 40.464 43.254 46.045 48.835 51.626 54.416 57.207 59.997
62.787 65.578 68.368 71.158 73.948 76.737 79.526 82.313 85.097
87.864
ZDEF 20 LEVELS 0.99500 0.97999 0.94995 0.89988 0.82977 0.74468
0.64954 0.54946 0.45447 0.36948 0.29450 0.22953 0.17457 0.12440
0.0846830 0.0598005 0.0449337 0.0349146 0.0248800 0.00829901
TDEF 1 LINEAR 15jan2000 1mo
VARS 4
v 20 99 vor. forcing [s**-2]
d 20 99 div. forcing [s**-2]
t 20 99 temp. forcing [K s**-1]
p 1 99 sfc.Ln(Ps) forcing
ENDVARS-
将生成了
newFrc.grd和对应newFrc.ctl(需同名)放入/disk1/xhw/LBM/ln_solver/data/frc_indianOcean(自建)。修改/disk1/xhw/LBM/ln_solver/model/sh/tintgr里的linear-run.classic.copy3.csh(根据需要调整)。将 FRC 和 SFRC改为自建强迫场路径1
2setenv FRC $FDIR/newFrc.grd # initial perturbation
setenv SFRC $FDIR/newFrc.grd # steady forcing完整文件如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87###
# @Author: xhw
# @Date: 2023-12-10 22:32:50
# @LastEditTime: 2023-12-11 16:18:39
# @FilePath: /xhw/LBM/ln_solver/model/sh/tintgr/linear-run.classic.copy3.csh
# @Description:
###
#!/bin/csh -f
#
# sample script for linear model run (dry model)
#
# NQS command for mail
#@$-q b
#@$-N 1
#@$-me
#
setenv LNHOME /disk1/xhw/LBM/ln_solver # ROOT of model
setenv LBMDIR $LNHOME/model # ROOT of LBM
setenv SYSTEM linux # execute system
setenv RUN $LBMDIR/bin/$SYSTEM/lbm2.t42ml20ctintgr # Excutable file
setenv TDIR $LNHOME/solver/util
#setenv FDIR $LNHOME/data # Directory for Output
setenv FDIR $LNHOME/data/frc_indianOcean # Directory for Output
setenv DIR $LNHOME/data/out_indianOcean # Directory for Output
#setenv BSFILE $LNHOME/bs/gt3/ncepwin.t21l20 # Atm. BS File
setenv BSFILE $LNHOME/bs/gt3/ncepwin.t42l20 # Atm. BS File
setenv RSTFILE $DIR/Restart.amat # Restart-Data File
#setenv FRC $FDIR/frc.t21l20.classic.grd # initial perturbation
#setenv SFRC $FDIR/frc.t21l20.classic.grd # steady forcing
# setenv FRC $FDIR/frc.t42l20.classic.grd # initial perturbation
# setenv SFRC $FDIR/frc.t42l20.classic.grd # steady forcing
setenv FRC $FDIR/newFrc.grd # initial perturbation
setenv SFRC $FDIR/newFrc.grd # steady forcing
setenv TRANS gt2gr
setenv TEND 59
#
#
if (! -e $DIR) mkdir -p $DIR
cd $DIR
\rm SYSOUT
echo job started at `date` > $DIR/SYSOUT
/bin/rm -f $DIR/SYSIN
#
# parameters
#
cat << END_OF_DATA >>! $DIR/SYSIN
&nmrun run='linear model' &end
&nmtime start=0,1,1,0,0,0, end=0,1,$TEND,0,0,0 &end
&nmhdif order=4, tefold=0.5, tunit='DAY' &end
&nmdelt delt=40, tunit='MIN', inistp=2 &end
&nmdamp ddragv=0.5,0.5,0.5,20.,20.,20.,20.,20.,20.,20.,20.,20.,20.,20.,20.,20.,20.,20.,1.,1.,
ddragd=0.5,0.5,0.5,20.,20.,20.,20.,20.,20.,20.,20.,20.,20.,20.,20.,20.,20.,20.,1.,1.,
ddragt=0.5,0.5,0.5,20.,20.,20.,20.,20.,20.,20.,20.,20.,20.,20.,20.,20.,20.,20.,1.,1.,
tunit='DAY' &end
&nminit file='$BSFILE' , DTBFR=0., DTAFTR=0., TUNIT='DAY' &end
&nmrstr file='$RSTFILE', tintv=1, tunit='MON', overwt=t &end
&nmvdif vdifv=1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,
vdifd=1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,
vdift=1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3,1.d3, &end
&nmbtdif tdmpc=0. &end
&nmfrc ffrc='$FRC', oper=f, nfcs=1 &end
&nmsfrc fsfrc='$SFRC', ofrc=t, nsfcs=1, fsend=-1,1,30,0,0,0 &end
&nmchck ocheck=f, ockall=f &end
&nmdata item='GRZ', file='' &end
&nmhisd tintv=1, tavrg=1, tunit='DAY' &end
&nmhist item='PSI', file='psi', tintv=1, tavrg=1, tunit='DAY' &end
&nmhist item='CHI', file='chi', tintv=1, tavrg=1, tunit='DAY' &end
&nmhist item='U', file='u', tintv=1, tavrg=1, tunit='DAY' &end
&nmhist item='V', file='v', tintv=1, tavrg=1, tunit='DAY' &end
&nmhist item='OMGF', file='w', tintv=1, tavrg=1, tunit='DAY' &end
&nmhist item='T', file='t', tintv=1, tavrg=1, tunit='DAY' &end
&nmhist item='Z', file='z', tintv=1, tavrg=1, tunit='DAY' &end
&nmhist item='PS', file='p', tintv=1, tavrg=1, tunit='DAY' &end
END_OF_DATA
#
# run
#
$RUN < $DIR/SYSIN >> $DIR/SYSOUT
#
cd $TDIR
$TRANS
echo job end at `date` >> $DIR/SYSOUT关于Grads
对于使用opengrads气象家园整合版,需要设置一些环境变量。以管理员模式运行编辑器。参考解决opengrads打开NC格式文件显示ununits.dat error的方法-编程作图-气象家园_气象人自己的家园 (06climate.com)
1
2
3
4上面系统变量值根据安装版本不同有所修改,用EXE安装的opengrads2.0设置如下:
在“系统变量”中选“Path"----点“编辑”----加入“C:\OpenGrADS\Contents\Cygwin\Versions\2.0.2.oga.2\i686;”
在“系统变量”中点“新建”----设置变量名“GADDIR”----变量值“C:\OpenGrADS\Contents\Resources\SupportData”
在“系统变量”中点“新建”----设置变量名“GASCRP”----变量值“C:\OpenGrADS\Contents\Resources\Scripts"安装Tips
最近帮别人安装,遇到一些小问题卡了很久,最后解决了。以此记录下
-
SETPAR里的注释问题
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16&nmfgt cfs='/disk1/xhw/LBM/ln_solver/data/out_Barents/psi',
cfc='/disk1/xhw/LBM/ln_solver/data/out_Barents/chi',
cfu='/disk1/xhw/LBM/ln_solver/data/out_Barents/u',
cfv='/disk1/xhw/LBM/ln_solver/data/out_Barents/v',
cfw='/disk1/xhw/LBM/ln_solver/data/out_Barents/w',
cft='/disk1/xhw/LBM/ln_solver/data/out_Barents/t',
cfz='/disk1/xhw/LBM/ln_solver/data/out_Barents/z',
cfp='/disk1/xhw/LBM/ln_solver/data/out_Barents/p',
#cfq='/disk1/xhw/LBM/ln_solver/data/out/q',
#cfx='/disk1/xhw/LBM/ln_solver/data/out/dt',
#cfy='/disk1/xhw/LBM/ln_solver/data/out/dq',
cfo='/disk1/xhw/LBM/ln_solver/data/out_Barents/combined.grd',
fact=1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,
opl=f,
&end
这里9到11行利用
#注释是不行的, 要么删掉这三行,要么将这三行挪到第16行。 否则会出现./gt2gr运行问题 -
gt2gr源码修改gt2gr的源码需要修改。这一点写在了官方FAQ里FAQ about LBM (google.com) 具体做法是在$LNHOME/ln_solver/solver/util/gt2gr.f的97行插入IJ=01
2
3
4
5
6
7
8
9
10500 CONTINUE
READ( IFB ) G
IJ = 0
DO 510 J = 1, JMAX
DO 520 I = 1, IMAX
IJ = IJ + 1
GPS( IJ ) = DBLE( G( I, J) )
520 CONTINUE
510 CONTINUE
CLOSE( IFB )然后重新编译
1
2
3make clean
make
./mkfrcng -
背景的存放位置
默认背景场的生成位置在
1
2
3
4&nmbs cbs0='/disk1/xhw/LBM/ln_solver/bs/gt3/ncepwin.t42l20',
cbs='/disk1/xhw/LBM/ln_solver/bs/grads/ncepwin.t42l20.grd'
&end
这个路径下有官方写好的
.ctl文件,因此运行程序可以自动读取这些文件。有人在生成背景场的时候习惯自己指定位置,这些位置下没有.ctl文件因此运行程序往往会失败(具体表现为模式瞬间运行完成)。 因此要么使用默认的路径即$LNHOME/ln_solver/bs/gt3和$LNHOME/ln_solver/bs/grads, 要么在自定义的路径写写好.ctl文件。
-
-









