1. 运行准备
(1)区分冷启动和暖启动:通俗的来讲,冷启动指的是不使用上一次模式跑出的数据;暖启动指的是使用上一次模式跑出的数据。
(2)区分各变量含义:
2. 具体步骤分解
2.1 背景误差协方差矩阵B0
**简单介绍:**背景误差协方差矩阵算的是模式跑的同一个时间点所用不同时间的误差,举个例子就是从0点跑到24点和从12点跑到24点的误差。
代码位置:WRFDA/var/scripts/gen_be/gen_be_wrapper.ksh
**使用方法:**gen_be 的输入数据是 WRF 预测,用于生成模型扰动,用作预测误差估计的代理。对于 NMC 方法,模型扰动是同时有效的预测之间的差异(例如,T+24 减去 T+12 是区域应用的典型值,T+48 减去 T+24 是全球应用的典型值)。然后可以通过对一段时间(例如一个月)内的这些预报差异进行平均来获得背景误差的气候估计。给定来自集合预测系统 (EPS) 的输入,输入是集合预报,创建的模型扰动是转换后的集合扰动。 gen_be 代码旨在处理预测差异或基于集合的扰动。
运行结果示例:
注意文件名以及文件所在的文件夹名
2.2 观测数据文件y0,R
**简单介绍:**主要是为了生成同化可用的观测数据文件,处理为ASCII 或PREPBUFR 格式。外来的观测数据需要改写成LITTLE_R格式,由于本次示例是从该网站获得。
**代码和程序位置:**WRFDA/var/obsproc/obserr.txt WRFDA/var/obsproc/obsproc.exe
WRFDA/var/obsproc/prepbufr_table_filename(当OUTPUT_OB_FORMAT=1或3时需要链接)
3.运行流程
背景误差协方差矩阵B0可在运行同化之前先生成背景误差协方差文件,同化时直接使用。
3.1 冷启动
**流程:**WRF-real----obsproc—更新初始场—更新边界场—WRF-wrf
示例脚本:
#!/bin/bash
DATE=2011092800
RUN_TYPE=cycle
DOMAIN_ID=01
NPROC=6
DATDIR=/home/WRF/Data
run_dir=/home/WRF/Project/
DA_SRCDIR=/home/WRF/WRF4.0v2/WRFDA
project_name=test_WRF
TIMEWINDOW1=-1h30m
TIMEWINDOW2=1h30m
CYCLE_PERIOD=06
lon_e=105
lon_w=125
lat_n=24
lat_s=12
VERTICAL_GRID_NUMBER=33
GRID_DISTANCE=9000
WRFDIR=${run_dir}${project_name}/WRF
RUN_BASEDIR=${run_dir}${project_name}/run
BIN_DIR=${DA_SRCDIR}/var/build
WEST_EAST_GRID_NUMBER=$[(lon_w-lon_e)*111000/GRID_DISTANCE+10]
SOUTH_NORTH_GRID_NUMBER=$[(lat_n-lat_s)*111000/GRID_DISTANCE+10]
lat_ns=$[(lat_n+lat_s)/2]
lon_we=$[(lon_w+lon_e)/2]
DATE_MIN=$(${BIN_DIR}/da_advance_time.exe ${DATE} ${TIMEWINDOW1} -w)
DATE_MAX=$(${BIN_DIR}/da_advance_time.exe ${DATE} ${TIMEWINDOW2} -w)
PREV_DATE=$(${BIN_DIR}/da_advance_time.exe ${DATE} -${CYCLE_PERIOD})
VARBC_PREV_DATE=$(${BIN_DIR}/da_advance_time.exe ${DATE} -24)
if [ ! -d "${RUN_BASEDIR}" ];then
mkdir ${RUN_BASEDIR}
else
rm -rf ${RUN_BASEDIR}
mkdir ${RUN_BASEDIR}
fi
cd ${DA_SRCDIR}
source ../libraries.sh
#-----------------------------------------------------------ob-------------------------------------------
echo "处理观测数据ob"
mkdir ${RUN_BASEDIR}/ob
cd ${RUN_BASEDIR}/ob
#-----链接一些必要的文件
cp ${DATDIR}/'OBS_'${DATE} ./
ln -fs ${DA_SRCDIR}/var/obsproc/obserr.txt ./obserr.txt
ln -fs ${DA_SRCDIR}/var/obsproc/prepbufr_table_filename ./prepbufr_table_filename
ln -fs ${DA_SRCDIR}/var/obsproc/obsproc.exe .
touch namelist.obsproc
cat > namelist.obsproc << EOF
&record1
obs_gts_filename = 'OBS_${DATE}',
obs_err_filename = 'obserr.txt',
gts_from_mmm_archive = .true.,
/
&record2
time_window_min = ${DATE_MIN},
time_analysis = ${DATE:0:4}-${DATE:4:2}-${DATE:6:2}_${DATE:8:2}:00:00,
time_window_max = ${DATE_MAX},
/
&record3
max_number_of_obs = 400000,
fatal_if_exceed_max_obs = .TRUE.,
/
&record4
qc_test_vert_consistency = .TRUE.,
qc_test_convective_adj = .TRUE.,
qc_test_above_lid = .TRUE.,
remove_above_lid = .false.,
domain_check_h = .true.,
Thining_SATOB = .false.,
Thining_SSMI = .false.,
Thining_QSCAT = .false.,
calc_psfc_from_qnh = .true.,
/
&record5
print_gts_read = .TRUE.,
print_gpspw_read = .TRUE.,
print_recoverp = .TRUE.,
print_duplicate_loc = .TRUE.,
print_duplicate_time = .TRUE.,
print_recoverh = .TRUE.,
print_qc_vert = .TRUE.,
print_qc_conv = .TRUE.,
print_qc_lid = .TRUE.,
print_uncomplete = .TRUE.,
/
&record6
ptop = 1000.0,
base_pres = 100000.0,
base_temp = 290.0,
base_lapse = 50.0,
base_strat_temp = 215.0,
base_tropo_pres = 20000.0
/
&record7
IPROJ = 1,
PHIC = ${lat_ns},
XLONC = ${lon_we},
TRUELAT1= ${lat_s},
TRUELAT2= ${lat_n},
MOAD_CEN_LAT = ${lat_ns},
STANDARD_LON = ${lon_we},
/
&record8
IDD = 1,
MAXNES = 1,
NESTIX = 256, 200, 136, 181, 211,
NESTJX = 158, 200, 181, 196, 211,
DIS = 9, 10., 3.3, 1.1, 1.1,
NUMC = 1, 1, 2, 3, 4,
NESTI = 1, 40, 28, 35, 45,
NESTJ = 1, 60, 25, 65, 55,
/
&record9
PREPBUFR_OUTPUT_FILENAME = 'prepbufr_output',
PREPBUFR_TABLE_FILENAME = 'prepbufr_table_filename',
OUTPUT_OB_FORMAT = 3
use_for = '3DVAR',
num_slots_past = 3,
num_slots_ahead = 3,
write_synop = .true.,
write_ship = .true.,
write_metar = .true.,
write_buoy = .true.,
write_pilot = .true.,
write_sound = .true.,
write_amdar = .true.,
write_satem = .true.,
write_satob = .true.,
write_airep = .true.,
write_gpspw = .true.,
write_gpsztd= .true.,
write_gpsref= .true.,
write_gpseph= .true.,
write_ssmt1 = .true.,
write_ssmt2 = .true.,
write_ssmi = .true.,
write_tovs = .true.,
write_qscat = .true.,
write_profl = .true.,
write_bogus = .true.,
write_airs = .true.,
/
EOF
./obsproc.exe
#-----------------------------------------------------ini-----------------------------------------
echo "更新初始场"
rm -rf ${RUN_BASEDIR}/ini
mkdir ${RUN_BASEDIR}/ini
cd ${RUN_BASEDIR}/ini
#-----链接一些必要的文件
ln -fs ${DA_SRCDIR}/run/LANDUSE.TBL ./LANDUSE.TBL
ln -fs ${RUN_BASEDIR}/ob/obs_gts_${DATE:0:4}-${DATE:4:2}-${DATE:6:2}_${DATE:8:2}:00:00.3DVAR ./ob.ascii
ln -fs ${DATDIR}/be.dat ./be.dat
cp -p ${WRFDIR}/wrfinput_d01 ./fg
touch namelist.input
cat > namelist.input << EOF
&wrfvar1
var4d=false,
print_detail_grad=false,
/
&wrfvar2
/
&wrfvar3
ob_format=2,
/
&wrfvar4
/
&wrfvar5
/
&wrfvar6
max_ext_its=1,
ntmax=50,
orthonorm_gradient=true,
/
&wrfvar7
cv_options=5,
/
&wrfvar8
/
&wrfvar9
/
&wrfvar10
test_transforms=false,
test_gradient=false,
/
&wrfvar11
/
&wrfvar12
/
&wrfvar13
/
&wrfvar14
/
&wrfvar15
/
&wrfvar16
/
&wrfvar17
/
&wrfvar18
analysis_date=${DATE:0:4}-${DATE:4:2}-${DATE:6:2}_${DATE:8:2}:00:00,
/
&wrfvar19
/
&wrfvar20
/
&wrfvar21
time_window_min=${DATE_MIN},
/
&wrfvar22
time_window_max=${DATE_MAX},
/
&time_control
start_year=${DATE:0:4},
start_month=${DATE:4:2},
start_day=${DATE:6:2},
start_hour=${DATE:8:2},
end_year=${DATE:0:4},
end_month=${DATE:4:2},
end_day=${DATE:6:2},
end_hour=${DATE:8:2},
/
&fdda
/
&domains
e_we=${WEST_EAST_GRID_NUMBER},
e_sn=${SOUTH_NORTH_GRID_NUMBER},
e_vert=${VERTICAL_GRID_NUMBER},
dx=${GRID_DISTANCE},
dy=${GRID_DISTANCE},
/
&dfi_control
/
&tc
/
&physics
mp_physics = 3,
ra_lw_physics = 1,
ra_sw_physics = 1,
radt = 30,
sf_sfclay_physics = 1,
sf_surface_physics = 2,
bl_pbl_physics = 1,
bldt = 0,
cu_physics = 1,
cudt = 5,
isfflx = 1,
ifsnow = 1,
icloud = 1,
surface_input_source = 1,
num_soil_layers = 4,
sf_urban_physics = 0,
/
&scm
/
&dynamics
/
&bdy_control
/
&grib2
/
&fire
/
&namelist_quilt
/
&perturbation
/
EOF
ln -sf ${DA_SRCDIR}/var/build/da_wrfvar.exe ./da_wrfvar.exe
mpirun -np 6 ./da_wrfvar.exe
#-----------------------------------------------------bdy-----------------------------------------
echo "更新边界场"
mkdir ${RUN_BASEDIR}/bdy
cd ${RUN_BASEDIR}/bdy
cp ${WRFDIR}/wrfbdy_d01 ./wrfbdy_d01
touch parame.in
cat > parame.in << EOF
&control_param
da_file = '${RUN_BASEDIR}/ini/wrfvar_output',
wrf_bdy_file = './wrfbdy_d01'
wrf_input = '${WRFDIR}/wrfinput_d01',
domain_id = 1
cycling = .false.
debug = .true.
low_bdy_only = .false.
update_lsm = .true.
var4d_lbc = .false.
/
EOF
ln -sf ${DA_SRCDIR}/var/build/da_update_bc.exe ./da_update_bc.exe
./da_update_bc.exe
#----------------------------------------------------wrf-------------------------------------------
cd ${WRFDIR}
ln -fs ${RUN_BASEDIR}/bdy/wrfbdy_d01 ./wrfbdy_d01
ln -fs ${RUN_BASEDIR}/ini/wrfvar_output ./wrfinput_d01
mpirun -np 20 ./wrf.exe
#---------------------------------------------------result-----------------------------------------
mkdir ${run_dir}/result
cd ${run_dir}/result
cp ${WRFDIR}/wrfout* ./
cd ${run_dir}
3.2 热启动
**流程:**WRF-wrf----obsproc—更新底边界—更新初始场—更新边界场—WRF-wrf
示例脚本:
#!/bin/bash
DATE=2011092806
RUN_TYPE=cycle
DOMAIN_ID=01
NPROC=6
DATDIR=/home/WRF/Data
run_dir=/home/WRF/Project/
DA_SRCDIR=/home/WRF/WRF4.0v2/WRFDA
project_name=test_WRF
TIMEWINDOW1=-1h30m
TIMEWINDOW2=1h30m
CYCLE_PERIOD=06
lon_e=105
lon_w=125
lat_n=24
lat_s=12
VERTICAL_GRID_NUMBER=33
GRID_DISTANCE=9000
WRFDIR=${run_dir}${project_name}/WRF
RUN_BASEDIR=${run_dir}${project_name}/run
BIN_DIR=${DA_SRCDIR}/var/build
WEST_EAST_GRID_NUMBER=$[(lon_w-lon_e)*111000/GRID_DISTANCE+10]
SOUTH_NORTH_GRID_NUMBER=$[(lat_n-lat_s)*111000/GRID_DISTANCE+10]
lat_ns=$[(lat_n+lat_s)/2]
lon_we=$[(lon_w+lon_e)/2]
DATE_MIN=$(${BIN_DIR}/da_advance_time.exe ${DATE} ${TIMEWINDOW1} -w)
DATE_MAX=$(${BIN_DIR}/da_advance_time.exe ${DATE} ${TIMEWINDOW2} -w)
PREV_DATE=$(${BIN_DIR}/da_advance_time.exe ${DATE} -${CYCLE_PERIOD})
VARBC_PREV_DATE=$(${BIN_DIR}/da_advance_time.exe ${DATE} -24)
if [ ! -d "${RUN_BASEDIR}" ];then
mkdir ${RUN_BASEDIR}
else
rm -rf ${RUN_BASEDIR}
mkdir ${RUN_BASEDIR}
fi
cd ${DA_SRCDIR}
source ../libraries.sh
#-----------------------------------------------------------ob-------------------------------------------
echo "处理观测数据ob"
mkdir ${RUN_BASEDIR}/ob
cd ${RUN_BASEDIR}/ob
#-----链接一些必要的文件
cp ${DATDIR}/'OBS_'${DATE} ./
ln -fs ${DA_SRCDIR}/var/obsproc/obserr.txt ./obserr.txt
ln -fs ${DA_SRCDIR}/var/obsproc/prepbufr_table_filename ./prepbufr_table_filename
ln -fs ${DA_SRCDIR}/var/obsproc/obsproc.exe .
touch namelist.obsproc
cat > namelist.obsproc << EOF
&record1
obs_gts_filename = 'OBS_${DATE}',
obs_err_filename = 'obserr.txt',
gts_from_mmm_archive = .true.,
/
&record2
time_window_min = ${DATE_MIN},
time_analysis = ${DATE:0:4}-${DATE:4:2}-${DATE:6:2}_${DATE:8:2}:00:00,
time_window_max = ${DATE_MAX},
/
&record3
max_number_of_obs = 400000,
fatal_if_exceed_max_obs = .TRUE.,
/
&record4
qc_test_vert_consistency = .TRUE.,
qc_test_convective_adj = .TRUE.,
qc_test_above_lid = .TRUE.,
remove_above_lid = .false.,
domain_check_h = .true.,
Thining_SATOB = .false.,
Thining_SSMI = .false.,
Thining_QSCAT = .false.,
calc_psfc_from_qnh = .true.,
/
&record5
print_gts_read = .TRUE.,
print_gpspw_read = .TRUE.,
print_recoverp = .TRUE.,
print_duplicate_loc = .TRUE.,
print_duplicate_time = .TRUE.,
print_recoverh = .TRUE.,
print_qc_vert = .TRUE.,
print_qc_conv = .TRUE.,
print_qc_lid = .TRUE.,
print_uncomplete = .TRUE.,
/
&record6
ptop = 1000.0,
base_pres = 100000.0,
base_temp = 290.0,
base_lapse = 50.0,
base_strat_temp = 215.0,
base_tropo_pres = 20000.0
/
&record7
IPROJ = 1,
PHIC = ${lat_ns},
XLONC = ${lon_we},
TRUELAT1= ${lat_s},
TRUELAT2= ${lat_n},
MOAD_CEN_LAT = ${lat_ns},
STANDARD_LON = ${lon_we},
/
&record8
IDD = 1,
MAXNES = 1,
NESTIX = 256, 200, 136, 181, 211,
NESTJX = 158, 200, 181, 196, 211,
DIS = 9, 10., 3.3, 1.1, 1.1,
NUMC = 1, 1, 2, 3, 4,
NESTI = 1, 40, 28, 35, 45,
NESTJ = 1, 60, 25, 65, 55,
/
&record9
PREPBUFR_OUTPUT_FILENAME = 'prepbufr_output',
PREPBUFR_TABLE_FILENAME = 'prepbufr_table_filename',
OUTPUT_OB_FORMAT = 3
use_for = '3DVAR',
num_slots_past = 3,
num_slots_ahead = 3,
write_synop = .true.,
write_ship = .true.,
write_metar = .true.,
write_buoy = .true.,
write_pilot = .true.,
write_sound = .true.,
write_amdar = .true.,
write_satem = .true.,
write_satob = .true.,
write_airep = .true.,
write_gpspw = .true.,
write_gpsztd= .true.,
write_gpsref= .true.,
write_gpseph= .true.,
write_ssmt1 = .true.,
write_ssmt2 = .true.,
write_ssmi = .true.,
write_tovs = .true.,
write_qscat = .true.,
write_profl = .true.,
write_bogus = .true.,
write_airs = .true.,
/
EOF
./obsproc.exe
#-----------------------------------------------------low-----------------------------------------
echo "更新底边界"
mkdir ${RUN_BASEDIR}/low
cd ${RUN_BASEDIR}/low
cp -p ${run_dir}/result/wrfout_d${DOMAIN_ID}_${DATE:0:4}-${DATE:4:2}-${DATE:6:2}_${DATE:8:2}:00:00 ./fg
touch parame.in
cat > parame.in << EOF
&control_param
da_file = './fg'
wrf_input = '${WRFDIR}/wrfinput_d01'
domain_id = ${DOMAIN_ID}
debug = .false.
update_lateral_bdy = .false.
update_low_bdy = .true.
update_lsm = .false.
iswater = 16
/
EOF
ln -sf ${DA_SRCDIR}/var/build/da_update_bc.exe ./da_update_bc.exe
./da_update_bc.exe
#-----------------------------------------------------ini-----------------------------------------
echo "更新初始场"
mkdir ${RUN_BASEDIR}/ini
cd ${RUN_BASEDIR}/ini
#-----链接一些必要的文件
ln -fs ${DA_SRCDIR}/run/LANDUSE.TBL ./LANDUSE.TBL
ln -fs ${RUN_BASEDIR}/ob/obs_gts_${DATE:0:4}-${DATE:4:2}-${DATE:6:2}_${DATE:8:2}:00:00.3DVAR ./ob.ascii
ln -fs ${DATDIR}/be.dat ./be.dat
cp -p ${RUN_BASEDIR}/low/fg ./fg
touch namelist.input
cat > namelist.input << EOF
&wrfvar1
var4d=false,
print_detail_grad=false,
/
&wrfvar2
/
&wrfvar3
ob_format=2,
/
&wrfvar4
/
&wrfvar5
/
&wrfvar6
max_ext_its=1,
ntmax=50,
orthonorm_gradient=true,
/
&wrfvar7
cv_options=5,
/
&wrfvar8
/
&wrfvar9
/
&wrfvar10
test_transforms=false,
test_gradient=false,
/
&wrfvar11
/
&wrfvar12
/
&wrfvar13
/
&wrfvar14
/
&wrfvar15
/
&wrfvar16
/
&wrfvar17
/
&wrfvar18
analysis_date=${DATE:0:4}-${DATE:4:2}-${DATE:6:2}_${DATE:8:2}:00:00,
/
&wrfvar19
/
&wrfvar20
/
&wrfvar21
time_window_min=${DATE_MIN},
/
&wrfvar22
time_window_max=${DATE_MAX},
/
&time_control
start_year=${DATE:0:4},
start_month=${DATE:4:2},
start_day=${DATE:6:2},
start_hour=${DATE:8:2},
end_year=${DATE:0:4},
end_month=${DATE:4:2},
end_day=${DATE:6:2},
end_hour=${DATE:8:2},
/
&fdda
/
&domains
e_we=${WEST_EAST_GRID_NUMBER},
e_sn=${SOUTH_NORTH_GRID_NUMBER},
e_vert=${VERTICAL_GRID_NUMBER},
dx=${GRID_DISTANCE},
dy=${GRID_DISTANCE},
/
&dfi_control
/
&tc
/
&physics
mp_physics = 3,
ra_lw_physics = 1,
ra_sw_physics = 1,
radt = 30,
sf_sfclay_physics = 1,
sf_surface_physics = 2,
bl_pbl_physics = 1,
bldt = 0,
cu_physics = 1,
cudt = 5,
isfflx = 1,
ifsnow = 1,
icloud = 1,
surface_input_source = 1,
num_soil_layers = 4,
sf_urban_physics = 0,
/
&scm
/
&dynamics
/
&bdy_control
/
&grib2
/
&fire
/
&namelist_quilt
/
&perturbation
/
EOF
ln -sf ${DA_SRCDIR}/var/build/da_wrfvar.exe ./da_wrfvar.exe
mpirun -np 6 ./da_wrfvar.exe
#-----------------------------------------------------bdy-----------------------------------------
echo "更新边界场"
mkdir ${RUN_BASEDIR}/bdy
cd ${RUN_BASEDIR}/bdy
cp ${WRFDIR}/wrfbdy_d01 ./wrfbdy_d01
touch parame.in
cat > parame.in << EOF
&control_param
da_file = '${RUN_BASEDIR}/ini/wrfvar_output',
wrf_bdy_file = './wrfbdy_d01'
wrf_input = '${WRFDIR}/wrfinput_d01',
domain_id = 1
cycling = .false.
debug = .true.
low_bdy_only = .false.
update_lsm = .true.
var4d_lbc = .false.
/
EOF
ln -sf ${DA_SRCDIR}/var/build/da_update_bc.exe ./da_update_bc.exe
./da_update_bc.exe
#----------------------------------------------------wrf-------------------------------------------
cd ${WRFDIR}
ln -fs ${RUN_BASEDIR}/bdy/wrfbdy_d01 ./wrfbdy_d01
ln -fs ${RUN_BASEDIR}/ini/wrfvar_output ./wrfinput_d01
mpirun -np 20 ./wrf.exe
#---------------------------------------------------result-----------------------------------------
if [ ! -d "${run_dir}result" ];then
mkdir ${run_dir}result
fi
cd ${run_dir}result
cp ${WRFDIR}/wrfout* ./
cd ${run_dir}