300 likes | 500 Views
WRF-Var Overview - differences between V2.2-beta and V3 - setup and run - code structures. Please see other related detailed tutorial presentations available at. http://www.mmm.ucar.edu/wrf/users/tutorial/tutorial_presentation.htm. WRF-Var Overview.
E N D
WRF-Var Overview - differences between V2.2-beta and V3 - setup and run - code structures Please see other related detailed tutorial presentations available at http://www.mmm.ucar.edu/wrf/users/tutorial/tutorial_presentation.htm WRF-Var Overview http://www.mmm.ucar.edu/wrf/users/tutorial/200807/VAR/WRFVAR_Tutorial_overview.pdf WRF-Var System http://www.mmm.ucar.edu/wrf/users/tutorial/200807/VAR/wrfvar_system.pdf
WRF-Var in the WRF Modeling System xlbc Background Preprocessing (WPS , real) xb Cold-Start Background Cycled Background WRF-Var xa Update Lateral & Lower BCs (UPDATE_BC) Observation Preprocessing (OBSPROC) yo , R Forecast (WRF) Radar in ASCII Radiance in BUFR Background Error (gen_be) B0 Blue --> Supported by WRF-Var Team
WRF-Var Version 3.0 (Release April 2008) Major new features: Direct assimilation of satellite radiances (AMSU, AIRS, SSMI/S, etc.). Four-Dimensional Variational Data Assimilation (4D-Var). Ensemble Transform Kalman Filter (ETKF). Hybrid variational/ensemble DA. Enhanced forecast error covariances (e.g. ensemble-based). Major software engineering reorganization. Remove obsolete features (e.g. MM5/GFS-based errors). Verification package Utilization of observations packed in NCEP PREPBUFR format Inclusion of various scripts and NCL based graphics Unified WRF/WRF-Var code repository. Unified WRF/WRF-Var namelist Extended wiki-based documentation. Not included in public release due to lack of funding. Collaborations welcome! From http://www.mmm.ucar.edu/wrf/users/tutorial/200807/VAR/WRFVAR_Tutorial_overview.pdf
Major changes in WRF-Var V3.0 • One tar file includes all WRF-Var components • Code structures • Compilation mechanism • External libraries - LAPACK, BLAS, FFTPACK, BUFR • Bug fixes • namelists • CV options (NCAR BE model only) • Single model (WRF only) • Input/output files naming convention, no more fort.* output • Variables (XICE-> SEAICE, dyn_opt removed) • WRF-Var output precision (double -> float) • Scripts (complicated DATC suite, csh->ksh) • NCL scripts • gen_be (rewritten stage0) • obsproc
V3.0.1.1 Release Notes: ----------------------- Version 3.0.1.1 has only limited bug fixes compared to version 3.0.1. - Improve compiling mechanism - Bug fix for analysis_type="VERIFY" - Bug fix for pseudo obs (spurious moisture increments) - Bug fix for incorrect sonde_sfc number in diagnostic output file jo. V3 Release Notes: ------------------ - For directions on compiling WRF-Var, see below or Users Guide Web page. http://www.mmm.ucar.edu/wrf/users/docs/user_guide_V3/users_guide_chap6.htm - For more information on WRF-Var release, visit WRF Users home page http://www.mmm.ucar.edu/wrf/users For questions, send mail to wrfhelp@ucar.edu ====================================== WRF-Var update history: - V3.0: Apr 4, 2008 - V3.0.1: Aug 6, 2008 ====================================== How to compile and run? ----------------------- - In WRFDA directory, type 'configure wrfda - this will create a configure.wrf file that has appropriate compile options for the supported computers. Note: WRF-Var requires netCDF, BLAS, LAPACK, BUFR libraries. If your netCDF library is installed in some odd directory, set environment variable NETCDF before you type 'configure wrfda'. For example, setenv NETCDF /usr/local/netcdf-pgi setenv BLAS /usr/local/blas setenv LAPACK /usr/local/lapack setenv BUFR /usr/local/bufr WRFDA / README.VAR - Type 'compile all_wrfvar' when you are ready: - If sucessful, this will create da_wrfvar.exe and a set of utilities in directory WRFDA/var/da/. - cd to the appropriate test or run directory to run WRF-Var. See WRFDA/var/test/README for basic instructions on running da_wrfvar.exe ====================================== What is new in WRFDA V3.0? - Major software engineering reorganization. - Unified WRF/WRF-Var code repository. - Unified WRF/WRF-Var namelist - Remove obsolete features (e.g. MM5/GFS-based background errors). ====================================== What is new in WRFDA V3.0 but NOT supported due to current resource limit? - Verification package - Utilization of observations packed in NCEP PREPBUFR format - Inclusion of various scripts and NCL based graphics ====================================== What is NOT in WRFDA V3.0? - satellite radiance data assimilation (hopefully available in the next release) - ensemble and hybrid data assimilation - 4D-VAR
Setup and run WRFDA / var / test / README 1) To run WRF-Var, first create a working directory, for example, WRFDA/var/test, then follow the steps below: cd WRFDA/var/test (go to the working directory) ln -sf WRFDA/run/LANDUSE.TBL ./LANDUSE.TBL ln -sf $DAT_DIR/rc/2007010200/wrfinput_d01 ./fg (link first guess file as fg) ln -sf WRFDA/var/obsproc/obs_gts_2007-01-02_00:00:00.3DVAR ./ob.ascii (link OBSPROC processed observation file as ob.ascii) ln -sf $DAT_DIR/be/be.dat ./be.dat (link background error statistics as be.dat) ln -sf WRFDA/var/da/da_wrfvar.exe ./da_wrfvar.exe (link executable) mkdir trace (if &wrfvar9 trace_use=true) vi namelist.input (a very basic namelist.input for running the tutorial test case is shown below. Only time and domain settings need to be specified for a certain case if using default settings provided in WRFDA/Registry/Registry.wrfvar. However, it is VERY IMPORTANT to make sure the settings in &physics record are consistent with those in your WRF settings.) da_wrfvar.exe >&! wrfda.log
&wrfvar1 / &wrfvar2 / &wrfvar3 / &wrfvar4 / &wrfvar5 / &wrfvar6 / &wrfvar7 / &wrfvar8 / &wrfvar9 trace_use=false, (Note: if not specified, default trace_use=true is applied. A subdirectory trace has to be created in your working directory before running da_wrfvar.exe) / &wrfvar10 / &wrfvar11 / &wrfvar12 / &wrfvar13 / &wrfvar14 / &wrfvar15 / &wrfvar16 / &wrfvar17 / &wrfvar18 analysis_date="2007-01-02_00:00:00.0000", / &wrfvar19 / &wrfvar20 / &wrfvar21 time_window_min="2007-01-01_21:00:00.0000", (this variable is actually not used in WRF-Var for conventional data assimilation. The actual obs time window is deciced in obsproc. Set it to be the same as time_window_min in obsproc namelist.3dvar_obs for your own reference.) / &wrfvar22 time_window_max="2007-01-02_03:00:00.0000", (this variable is actually not used in WRF-Var for conventional data assimilation. The actual obs time window is deciced in obsproc. Set it to be the same as time_window_max in obsproc namelist.3dvar_obs for your own reference.) / &wrfvar23 / namelist.input &time_control start_year=2007, start_month=01, start_day=02, start_hour=00, end_year=2007, end_month=01, end_day=02, end_hour=00, / &dfi_control / &domains e_we=45, e_sn=45, e_vert=28, dx=200000, dy=200000, / &physics (VERY IMPORTANT: it is essential to make sure the settings here are consistent with those in your WRF settings) mp_physics=3, sf_sfclay_physics=1, sf_surface_physics=1, num_soil_layers=5 / &fdda / &dynamics / &bdy_control / &grib2 / &namelist_quilt /
Setup and run WRFDA / var / test / README 2) To run da_update_bc.exe, follow the steps below: cd WRFDA/var/test (the directory where you ran WRF-Var) cp -p $DAT_DIR/rc/2007010200/wrfbdy_d01 ./wrfbdy_d01 (IMPORTANT: make a copy of wrfbdy_d01 as the wrf_bdy_file will be overwritten by da_update_bc.exe) vi param.in &control_param wrfvar_output_file = './wrfvar_output' wrf_bdy_file = './wrfbdy_d01' wrf_input = '$DAT_DIR/rc/2007010200/wrfinput_d01' cycling = .false. (set to .true. if WRF-Var first guess comes from a previous WRF forecast.) debug = .true. low_bdy_only = .false. (set to .true. if inner domain) update_lsm = .false. / ln -sf WRFDA/var/da/da_update_bc.exe ./da_update_bc.exe ./da_updatebc.exe
V3 wrfinput float CLAT(Time, south_north, west_east) ; float CLONG(Time, south_north, west_east) ; float LANDUSEF(Time, land_cat_stag, south_north, west_east) ; float MAPFAC_MX(Time, south_north, west_east) ; float MAPFAC_MY(Time, south_north, west_east) ; float MAPFAC_UX(Time, south_north, west_east_stag) ; float MAPFAC_UY(Time, south_north, west_east_stag) ; float MAPFAC_VX(Time, south_north_stag, west_east) ; float MAPFAC_VY(Time, south_north_stag, west_east) ; float MF_VX_INV(Time, south_north_stag, west_east) ; float PSHLTR(Time, south_north, west_east) ; float Q10(Time, south_north, west_east) ; float QSHLTR(Time, south_north, west_east) ; float SEAICE(Time, south_north, west_east) ; float SOILCBOT(Time, soil_cat_stag, south_north, west_east) ; float SOILCTOP(Time, soil_cat_stag, south_north, west_east) ; float TSHLTR(Time, south_north, west_east) ; V2.2 wrfinput float LAT_LL_D(Time) ; float LAT_LL_T(Time) ; float LAT_LL_U(Time) ; float LAT_LL_V(Time) ; float LAT_LR_D(Time) ; float LAT_LR_T(Time) ; float LAT_LR_U(Time) ; float LAT_LR_V(Time) ; float LAT_UL_D(Time) ; float LAT_UL_T(Time) ; float LAT_UL_U(Time) ; float LAT_UL_V(Time) ; float LAT_UR_D(Time) ; float LAT_UR_T(Time) ; float LAT_UR_U(Time) ; float LAT_UR_V(Time) ; float LON_LL_D(Time) ; float LON_LL_T(Time) ; float LON_LL_U(Time) ; float LON_LL_V(Time) ; float LON_LR_D(Time) ; float LON_LR_T(Time) ; float LON_LR_U(Time) ; float LON_LR_V(Time) ; float LON_UL_D(Time) ; float LON_UL_T(Time) ; float LON_UL_U(Time) ; float LON_UL_V(Time) ; float LON_UR_D(Time) ; float LON_UR_T(Time) ; float LON_UR_U(Time) ; float LON_UR_V(Time) ; float TRATX(Time, south_north, west_east) ; float URATX(Time, south_north, west_east) ; float VRATX(Time, south_north, west_east) ; float XICE(Time, south_north, west_east) ; In case you have any applications using the variables that are available in V2.2 but not V3
V3 wrfout V2.2 wrfout float LAT_LL_D(Time) ; float ALBBCK(Time, south_north, west_east) ; float LAT_LL_T(Time) ; float EDT_OUT(Time, south_north, west_east) ; float LAT_LL_U(Time) ; float EMISS(Time, south_north, west_east) ; float LAT_LL_V(Time) ; float HGT_SHAD(Time, south_north, west_east) ; float LAT_LR_D(Time) ; float MAPFAC_MX(Time, south_north, west_east) ; float LAT_LR_T(Time) ; float MAPFAC_MY(Time, south_north, west_east) ; float LAT_LR_U(Time) ; float MAPFAC_UX(Time, south_north, west_east_stag) ; float LAT_LR_V(Time) ; float MAPFAC_UY(Time, south_north, west_east_stag) ; float LAT_UL_D(Time) ; float MAPFAC_VX(Time, south_north_stag, west_east) ; float LAT_UL_T(Time) ; float MAPFAC_VY(Time, south_north_stag, west_east) ; float LAT_UL_U(Time) ; float MAX_MSTFX(Time) ; float LAT_UL_V(Time) ; float MAX_MSTFY(Time) ; float LAT_UR_D(Time) ; float MF_VX_INV(Time, south_north_stag, west_east) ; float LAT_UR_T(Time) ; float PRATEC(Time, south_north, west_east) ; float LAT_UR_U(Time) ; float QNDROPSOURCE(Time, bottom_top, south_north, west_east) ; float LAT_UR_V(Time) ; float SEAICE(Time, south_north, west_east) ; float LON_LL_D(Time) ; float XICEM(Time, south_north, west_east) ; float LON_LL_T(Time) ; float LON_LL_U(Time) ; float LON_LL_V(Time) ; float LON_LR_D(Time) ; float LON_LR_T(Time) ; float LON_LR_U(Time) ; float LON_LR_V(Time) ; In case you have any applications using the variables that are available in V2.2 but not V3 float LON_UL_D(Time) ; float LON_UL_T(Time) ; float LON_UL_U(Time) ; float LON_UL_V(Time) ; float LON_UR_D(Time) ; float LON_UR_T(Time) ; float LON_UR_U(Time) ; float LON_UR_V(Time) ; float XICE(Time, south_north, west_east) ; dyn_opt
gen_be Major difference is in stage0 Previous stage0 versions: • gen_be_stage0-4 contained in the released WRFVAR 2.2 beta • stand-alone gen_be_Stage0 code provided to CWB. This version of gen_be_Stage0 produces the same results as the gen_be_stage0 in the released WRFVAR 2.2 beta. The difference and advantage is that the stand-alone gen_be_Stage0 is simplified and a lot faster to compile. The current V3 code will produce a little bit different results than the previous codes because of the following major changes: • in stage0, (1) vor, div, psi, chi are calculated on WRF's native C-grid (not interpolated A-grid)(2) compute full psi, chi before differencing (not after differencing)(3) stage0 output with names e.g. pert.2006090100.e001 where the date is perturbation valid time
gen_be For example, if you want to do 24h-12h forecast differences with forecasts initialized every 12 hour, you will have T_FORECAST1=12, T_FORECAST2=24, FILE_INTERVAL=12, and with the following forecasts available and organized as: 2008030700/wrfout_d01_2008-03-07_12:00:00 2008030700/wrfout_d01_2008-03-08_00:00:00 2008030712/wrfout_d01_2008-03-08_00:00:00 2008030712/wrfout_d01_2008-03-08_12:00:00 2008030800/wrfout_d01_2008-03-08_12:00:00 2008030800/wrfout_d01_2008-03-09_00:00:00 2008030812/wrfout_d01_2008-03-09_00:00:00 2008030812/wrfout_d01_2008-03-09_12:00:00 diff.2008030700 has forecast difference from (2008030700/wrfout_d01_2008-03-08_00:00:00 - 2008030712/wrfout_d01_2008-03-08_00:00:00) diff.2008030712 has forecast difference from (2008030712/wrfout_d01_2008-03-08_12:00:00 - 2008030800/wrfout_d01_2008-03-08_12:00:00) diff.2008030800 has forecast difference from (2008030800/wrfout_d01_2008-03-09_00:00:00 - 2008030812/wrfout_d01_2008-03-09_00:00:00) diff.2008030812 has forecast difference from (2008030812/wrfout_d01_2008-03-09_12:00:00 - 2008030900/wrfout_d01_2008-03-09_12:00:00) and so on... V2 pert.2008030800.e001 has forecast difference from (2008030700/wrfout_d01_2008-03-08_00:00:00 - 2008030712/wrfout_d01_2008-03-08_00:00:00) pert.2008030812.e001 has forecast difference from (2008030712/wrfout_d01_2008-03-08_12:00:00 - 2008030800/wrfout_d01_2008-03-08_12:00:00) pert.2008030900.e001 has forecast difference from (2008030800/wrfout_d01_2008-03-09_00:00:00 - 2008030812/wrfout_d01_2008-03-09_00:00:00) pert.2008030912.e001 has forecast difference from (2008030812/wrfout_d01_2008-03-09_12:00:00 - 2008030900/wrfout_d01_2008-03-09_12:00:00) and so on... V3
gen_be - scripts and namelists WRFDA/var/scripts/gen_be/gen_be_wrapper.ksh #! /bin/ksh #----------------------------------------------------------------------- # Script gen_be_wrapper.ksh # # Purpose: Calculates background error statistics for WRF-Var. #----------------------------------------------------------------------- #[1] Define job by overriding default environment variables: export RUN_GEN_BE_STAGE0=true export RUN_GEN_BE_STAGE1=true export RUN_GEN_BE_STAGE2=true export RUN_GEN_BE_STAGE2A=true export RUN_GEN_BE_STAGE3=true export RUN_GEN_BE_STAGE4=true export RUN_GEN_BE_DIAGS=true export RUN_GEN_BE_DIAGS_READ=true export RUN_GEN_BE_MULTICOV=true export WRFVAR_DIR=/karri/users/xinzhang/support/WRFDA export FC_DIR= export STRIDE= #t46 45km: export START_DATE=2007010200 export END_DATE=2007013100 export NUM_LEVELS=28 export REGION=con200 export EXPT=expt export BIN_TYPE=5 export EXP_DIR=/karri/users/xinzhang/support/$REGION/$EXPT #Example of changes required for "be_method=ENS": #export BE_METHOD=ENS #export NE=56 #export FCST_RANGE=12 #[2] Run gen_be: ${WRFVAR_DIR}/var/scripts/gen_be/gen_be.ksh • WRFDA/var/scripts/gen_be>ls -l • gen_be.ksh • gen_be_cov2d.ksh • gen_be_cov3d.ksh • gen_be_ensrf.csh • gen_be_ep1.csh • gen_be_ep2.csh • gen_be_plot_wrapper.ksh • gen_be_set_defaults.ksh • gen_be_stage0_wrf.ksh • gen_be_stage4_global.ksh • gen_be_stage4_regional.ksh • gen_be_wrapper.ksh namelists Unused variables removed
%compile all_wrfvar da_wrfvar.exe Registry Mechanics WRFDA/Registry/Registry.wrfvar registry program: tools/registry Registry/Registry WRFDA/var/da/inc/*.inc CPP ____________ Fortran90 WRF-VAR source WRFDA/var/da/da_*/ *.f90
Before compilation WRFDA/var/da>ls -l total 56 -rw-r--r-- 1 1319 Aug 22 17:07 convertor.make -rw-r--r-- 1 11547 Aug 22 18:06 da.make drwxr-xr-x 13 442 Aug 22 17:13 da_airep drwxr-xr-x 14 476 Aug 22 17:13 da_airsr drwxr-xr-x 13 442 Aug 22 17:13 da_bogus drwxr-xr-x 13 442 Aug 22 17:13 da_buoy drwxr-xr-x 3 102 Aug 22 17:13 da_control drwxr-xr-x 15 510 Aug 22 17:13 da_define_structures drwxr-xr-x 21 714 Aug 22 17:13 da_dynamics drwxr-xr-x 8 272 Aug 22 17:13 da_etkf drwxr-xr-x 11 374 Aug 22 17:13 da_ffts drwxr-xr-x 16 544 Aug 22 17:13 da_gen_be drwxr-xr-x 13 442 Aug 22 17:13 da_geoamv drwxr-xr-x 16 544 Aug 22 17:13 da_gpspw drwxr-xr-x 13 442 Aug 22 17:13 da_gpsref drwxr-xr-x 8 272 Aug 22 17:13 da_grid_definitions drwxr-xr-x 11 374 Aug 22 17:13 da_interpolation drwxr-xr-x 19 646 Aug 22 17:13 da_main drwxr-xr-x 13 442 Aug 22 17:13 da_metar drwxr-xr-x 16 544 Aug 22 17:13 da_minimisation drwxr-xr-x 14 476 Aug 22 17:13 da_mtgirs drwxr-xr-x 18 612 Aug 22 17:13 da_obs drwxr-xr-x 24 816 Aug 22 17:13 da_obs_io drwxr-xr-x 36 1224 Aug 22 17:13 da_par_util drwxr-xr-x 69 2346 Aug 22 17:13 da_physics drwxr-xr-x 13 442 Aug 22 17:13 da_pilot drwxr-xr-x 13 442 Aug 22 17:13 da_polaramv drwxr-xr-x 13 442 Aug 22 17:13 da_profiler drwxr-xr-x 12 408 Aug 22 17:13 da_pseudo drwxr-xr-x 13 442 Aug 22 17:13 da_qscat drwxr-xr-x 17 578 Aug 22 17:13 da_radar drwxr-xr-x 10 340 Aug 22 17:13 da_radiance drwxr-xr-x 9 306 Aug 22 17:13 da_recursive_filter drwxr-xr-x 7 238 Aug 22 17:13 da_reporting drwxr-xr-x 13 442 Aug 22 17:14 da_satem drwxr-xr-x 28 952 Aug 22 17:14 da_setup_structures drwxr-xr-x 13 442 Aug 22 17:14 da_ships drwxr-xr-x 26 884 Aug 22 17:14 da_sound drwxr-xr-x 20 680 Aug 22 17:14 da_spectral drwxr-xr-x 84 2856 Aug 22 17:14 da_ssmi drwxr-xr-x 10 340 Aug 22 17:14 da_statistics drwxr-xr-x 14 476 Aug 22 17:14 da_synop drwxr-xr-x 46 1564 Aug 22 17:14 da_test drwxr-xr-x 74 2516 Aug 22 17:14 da_tools drwxr-xr-x 11 374 Aug 22 17:14 da_tracing drwxr-xr-x 12 408 Aug 22 17:14 da_transfer_model drwxr-xr-x 22 748 Aug 22 17:14 da_update_bc drwxr-xr-x 6 204 Aug 22 17:14 da_util drwxr-xr-x 3 102 Aug 22 17:14 da_varbc drwxr-xr-x 4 136 Aug 22 17:14 da_verif_anal drwxr-xr-x 5 170 Aug 22 17:14 da_verif_obs drwxr-xr-x 26 884 Aug 22 17:14 da_vtox_transforms -rwxr-xr-x 1 523 Aug 22 17:07 decode_l2_airs.make drwxr-xr-x 2 68 Aug 22 17:36 frame -rw-r--r-- 1 3969 Aug 22 17:07 gen_be.make drwxr-xr-x 2 68 Aug 22 17:36 inc drwxr-xr-x 40 1360 Aug 22 17:17 makedepf90-2.8.8 -rw-r--r-- 1 3150 Aug 22 17:17 makefile After compilation: a lot of files will appear in the directory WRFDA/var/da All source codes (*.F *.f90 and *.inc) are linked and *.f *.f90 *.o *.mod inc/*.inc *.exe are created
WRFDA / var / da / da_main / da_solve.inc B0 Namelist File xb yo WRF-Var START Setup Frame Read Namelist Setup Background Setup Background Errors Setup Observations Compute Analysis Minimize Cost Function Calculate O-B “Outer Loop” Calculate Diagnostics Output Analysis Tidy Up Diagnostics File xa WRF-Var END
Setup Frame • Reads grid dimensions from “namelist.input” file. • Use WRF framework’s distributed memory capability to initialize tile, memory, patch dimensions, etc. Read Namelist • Reads WRF-Var data assimilation options from “namelist.input” file. • Performs consistency checks between namelist options.
Setup Background (First-Guess) WRFDA/var/da/da_setup_structures/da_setup_firstguess_wrf.inc • Set up mapping information • Reads in the first-guess field. • Extracts necessary fields. • Creates background FORTRAN 90 derived data type “xb” e.g. xb % mix, xb % u(:,:,:), …. WRFDA/var/da/da_transfer_model/da_transfer_wrftoxb.inc
WRFDA/var/da/da_transfer_model/da_transfer_wrftoxb.inc Derived fields Vertical coordinate grid%xb%sigmaf(kte+1) = grid%znw(kte+1) grid%xb%znw(kte+1) = grid%znw(kte+1) grid%xb%znu(kte+1) = 0.0 do k=kts,kte grid%xb%sigmah(k) = grid%znu(k) grid%xb%sigmaf(k) = grid%znw(k) grid%xb%znu(k) = grid%znu(k) grid%xb%znw(k) = grid%znw(k) grid%xb%dn(k) = grid%dn(k) grid%xb%dnw(k) = grid%dnw(k) end do grid%xb % ptop = ptop cvpm = - (1.0 - gas_constant/cp) cpovcv = cp / (cp - gas_constant) do k=kts,kte do i=its,ite ! The base specific volume (from real.init.code) ppb = grid%znu(k) * grid%mub(i,j) + ptop ttb = (base_temp + base_lapse*log(ppb/base_pres)) * & (base_pres/ppb)**kappa albn = (gas_constant/base_pres) * ttb * (ppb/base_pres)**cvpm qvf1 = 1.0 + grid%moist(i,j,k,P_QV) / rd_over_rv aln = -1.0 / (grid%mub(i,j)+grid%mu_2(i,j)) * & (albn*grid%mu_2(i,j) + grid%rdnw(k) * & (grid%ph_2(i,j,k+1) - grid%ph_2(i,j,k))) ! total pressure: grid%xb%p(i,j,k) = base_pres * & ((gas_constant*(t0+grid%t_2(i,j,k))*qvf1) / & (base_pres*(aln+albn)))**cpovcv ! total density grid%xb%rho(i,j,k)= 1.0 / (albn+aln) ! pressure purtubation: grid%p(i,j,k) = grid%xb%p(i,j,k) - ppb end do end do Constant fields grid%xb%map_factor(i,j) = grid%msft(i,j) grid%xb%cori(i,j) = grid%f(i,j) grid%xb%tgrn(i,j) = grid%sst(i,j) if (grid%xb%tgrn(i,j) < 100.0) & grid%xb%tgrn(i,j) = grid%tmn(i,j) grid%xb%lat(i,j) = grid%xlat(i,j) grid%xb%lon(i,j) = grid%xlong(i,j) grid%xb%terr(i,j) = grid%ht(i,j) grid%xb%snow(i,j) = grid%snowc(i,j) grid%xb%lanu(i,j) = grid%lu_index(i,j) grid%xb%landmask(i,j) = grid%landmask(i,j) grid%xb%xland(i,j) = grid%xland(i,j)
WRFDA/var/da/da_transfer_model/da_transfer_wrftoxb.inc do k=kts,kte do i=its,ite grid%xb%u(i,j,k) = 0.5*(grid%xa%u(i,j,k)+grid%xa%u(i+1,j,k)) grid%xb%v(i,j,k) = 0.5*(grid%xa%v(i,j,k)+grid%xa%v(i,j+1,k)) grid%xb%wh(i,j,k)= 0.5*(grid%xb%w(i,j,k)+grid%xb%w(i,j,k+1)) grid%xb%h(i,j,k) = 0.5*(grid%xb%hf(i,j,k)+grid%xb%hf(i,j,k+1)) grid%xb%q(i,j,k) = grid%moist(i,j,k,P_QV) theta = t0 + grid%t_2(i,j,k) grid%xb%t(i,j,k) = theta*(grid%xb%p(i,j,k)/base_pres)**kappa ! Convert to specific humidity from mixing ratio of water vapor: grid%xb%q(i,j,k)=grid%xb%q(i,j,k)/(1.0+grid%xb%q(i,j,k)) if (grid%xb%q(i,j,k) < 1.0e-6) & grid%xb%q(i,j,k) = 1.0e-6 do i=its,ite grid%xb%psac(i,j) = grid%mub(i,j)+grid%mu_2(i,j) grid%xb%psfc(i,j) = grid%mub(i,j)+grid%p(i,j,kts)+grid%p_top if (grid%xb%tgrn(i,j) < 100.0) & grid%xb%tgrn(i,j) = grid%xb%t(i,j,kts)+ & 0.0065*(grid%xb%h(i,j,kts)-grid%xb%hf(i,j,kts)) end do end do Derived fields u10, v10, t2, q2 (used by sfc_assi_options=2) rh, td, slp
Setup Background Errors (BE) WRFDA/var/da/da_setup_structures/da_setup_be_regional.inc • Reads in background error statistics. • Extracts necessary quantities – eigenvectors, eigenvalues, lengthscales, regression coefficients, etc. • Creates background error FORTRAN 90 derived data type “be” e.g. be % v1 % evec(:,:), be % v2 % eval(:), etc, ….
Setup Observations WRFDA/var/da/da_setup_structures/da_setup_obs_structures_ascii.inc WRFDA/var/da/da_setup_structures/da_setup_obs_structures_bufr.inc WRFDA/var/da/da_obs_io/da_scan_obs_bufr.inc WRFDA/var/da/da_obs_io/da_read_obs_bufr.inc • Format depends on namelist variable “ob_format” 1 = BUFR, 2 = ASCII “WRF-Var” format. • Reads in observations. • Identifies Obs outside/inside the domain • Variable transforms • Creates observation FORTRAN 90 derived data type “ob” e.g. ob % metar(:), ob % sound(:) % u(:), etc, …. WRFDA/var/da/da_obs_io/da_scan_obs_ascii.inc WRFDA/var/da/da_obs_io/da_read_obs_ascii.inc
Calculate Innovation Vector (O-B) WRFDA/var/da/da_synop/da_get_innov_vector_synop.inc • Calculates “model equivalent” B of observation O through interpolation and change of variable. • Computes observation minus first guess (O-B) value. • Creates innovation vector FORTRAN 90 derived data type “iv” e.g. iv % metar(:), iv % qscat(:) % u, iv % sound(:) % u(:), etc ….
Minimize Cost Function • Conjugate Gradient • (a) Initializes analysis increments to zero. • (b) Computes cost function (if desired). • (c) Computes gradient of cost function. • (d) Uses cost function and gradient to calculate new value of analysis control variable (v) • Iterate (b) to (d)
!---------------------------------------------------------------------------!--------------------------------------------------------------------------- ! Purpose: Convert analysis increments into WRF increments ! ! The following WRF fields are modified: ! grid%u_2 ! grid%v_2 ! grid%w_2 ! grid%mu_2 ! grid%mu0 (NOTE: not clear that this is needed.) ! grid%ph_2 ! grid%t_2 ! grid%moist Compute Analysis • Once WRF-Var has found a converged control variable, convert control variable to model space analysis increments • Calculate: analysis = first-guess + analysis increment • Performs consistency checks e.g. remove negative humidity etc. WRFDA/var/da/da_transfer_model/da_transfer_xatowrf.inc
! To keep the background PH perturbation: do j=jts,jte do i=its,ite do k=kts, kte+1 ph_cgrid(i,j,k) = grid%ph_2(i,j,k) end do end do end do !--------------------------------------------------------------------------- ! [1.0] Get the mixing ratio of moisture first, as it its easy. !--------------------------------------------------------------------------- do k=kts,kte do j=jts,jte do i=its,ite if ((grid%xb%q(i,j,k)+grid%xa%q(i,j,k)) < 0.0) then q_cgrid(i,j,k) =-grid%xb%q(i,j,k)/(1.0 - grid%xb%q(i,j,k))**2 else q_cgrid(i,j,k) = grid%xa%q(i,j,k)/(1.0 - grid%xb%q(i,j,k))**2 end if end do end do end do !--------------------------------------------------------------------------- ! [2.0] compute increments of dry-column air mass per unit area !--------------------------------------------------------------------------- do j=jts,jte do i=its,ite sdmd=0.0 s1md=0.0 do k=kts,kte sdmd=sdmd+q_cgrid(i,j,k)*grid%dnw(k) s1md=s1md+(1.0+grid%moist(i,j,k,P_QV))*grid%dnw(k) end do mu_cgrid(i,j)=-(grid%xa%psfc(i,j)+grid%xb%psac(i,j)*sdmd)/s1md end do end do
!--------------------------------------------------------------------------- ! [3.0] compute pressure increments !--------------------------------------------------------------------------- ! Tangent linear code for grid%xa%p (based on WRF "real.init.code") ! developed by Y.-R. Guo 05/13/2004: do j=jts,jte do i=its,ite k = kte qvf1 = 0.5*(q_cgrid(i,j,k)+q_cgrid(i,j,k)) qvf1_b = 0.5*(grid%moist(i,j,k,P_QV)+grid%moist(i,j,k,P_QV)) qvf2 = - qvf1 / ((1.0+qvf1_b)*(1.0+qvf1_b)) qvf2_b = 1.0/(1.0+qvf1) qvf1 = qvf1*qvf2_b + qvf1_b*qvf2 qvf1_b = qvf1_b*qvf2_b grid%xa%p(i,j,k) = (-0.5/grid%rdnw(k)) * & ((mu_cgrid(i,j)+qvf1*grid%mub(i,j)) / qvf2_b & -(grid%mu_2(i,j)+qvf1_b*grid%mub(i,j))*qvf2/(qvf2_b*qvf2_b)) do k = kte-1,1,-1 qvf1 = 0.5*(q_cgrid(i,j,k)+q_cgrid(i,j,k+1)) qvf1_b = 0.5*(grid%moist(i,j,k,P_QV)+grid%moist(i,j,k+1,P_QV)) qvf2 = - qvf1 / ((1.0+qvf1_b)*(1.0+qvf1_b)) qvf2_b = 1.0/(1.0+qvf1_b) qvf1 = qvf1*qvf2_b + qvf1_b*qvf2 qvf1_b = qvf1_b*qvf2_b grid%xa%p(i,j,k) = grid%xa%p(i,j,k+1) & - (1.0/grid%rdn(k+1)) * & ((mu_cgrid(i,j)+qvf1*grid%mub(i,j)) / qvf2_b & -(grid%mu_2(i,j)+qvf1_b*grid%mub(i,j))*qvf2/(qvf2_b*qvf2_b)) end do end do end do ! Adjust grid%xa%q to makte grid%xb%q + grid%xa%q > 0.0 if (check_rh == check_rh_tpw) then ! Shu-Hua~s TPW conservation: call da_check_rh(grid) else if (check_rh == check_rh_simple) then ! Simple resetting to max/min values: call da_check_rh_simple(grid) end if do k=kts,kte do j=jts,jte do i=its,ite q_cgrid(i,j,k) = grid%xa%q(i,j,k)/(1.0 - grid%xb%q(i,j,k))**2 end do end do end do
!--------------------------------------------------------------------------- ! [4.0] Convert temperature increments into theta increments ! Evaluate also the increments of (1/rho) and geopotential !--------------------------------------------------------------------------- do j=jts,jte do i=its,ite ph_full = grid%ht(i,j) * gravity ph_xb_hd = grid%ht(i,j) * gravity do k = kts, kte ! To obtain all of the full fitelds: t, p, q(mixing ratio), rho t_full = grid%xa%t(i,j,k) + grid%xb%t(i,j,k) p_full = grid%xa%p(i,j,k) + grid%xb%p(i,j,k) q_full = grid%moist(i,j,k,P_QV) + q_cgrid(i,j,k) ! Note: According to WRF, thits its the dry air density used to ! compute the geopotential height: rho_full = p_full / (gas_constant*t_full*(1.0+q_full/rd_over_rv)) ! To compute the theta increment with the full fitelds: grid%t_2(i,j,k) = t_full*(base_pres/p_full)**kappa - t0 ! The full fiteld of analysis ph: ph_full = ph_full & - grid%xb%dnw(k) * (grid%xb%psac(i,j)+mu_cgrid(i,j)) / rho_full ! background hydrostatic phi: ph_xb_hd = ph_xb_hd & - grid%xb%dnw(k) * grid%xb%psac(i,j) / grid%xb%rho(i,j,k) ! The analysis perturbation = Hydro_ph - base_ph + nonhydro_xb_ph: grid%ph_2(i,j,k+1) = ph_full - grid%phb(i,j,k+1) & + (grid%xb%hf(i,j,k+1)*gravity - ph_xb_hd) end do end do end do ! To compute the geopotential height increment: do k=kts, kte+1 do j=jts,jte do i=its,ite ph_cgrid(i,j,k) = grid%ph_2(i,j,k) - ph_cgrid(i,j,k) end do end do end do
! ======================== ! Write out the increment: ! ======================== if (write_increments) then write(unit=stdout,fmt='(/"Write out increment for plotting......")') call da_write_increments (grid, q_cgrid, mu_cgrid, ph_cgrid) end if ! CONVERT FROM A-GRID TO C-GRID !--------------------------------------------------------------------------- ! [5.0] add increment to the original guess and update "grid" !--------------------------------------------------------------------------- do j=jts,jte do i=its,ite grid%mu_2(i,j) = grid%mu_2(i,j) + mu_cgrid(i,j) grid%mu0(i,j) = grid%mub(i,j) + grid%mu_2(i,j) grid%w_2(i,j,kte+1)= grid%w_2(i,j,kte+1) + grid%xa%w(i,j,kte+1) end do do k=kts,kte do i=its,ite grid%u_2(i,j,k) = grid%u_2(i,j,k) + u_cgrid(i,j,k) grid%v_2(i,j,k) = grid%v_2(i,j,k) + v_cgrid(i,j,k) grid%w_2(i,j,k) = grid%w_2(i,j,k) + grid%xa%w(i,j,k) grid%moist(i,j,k,P_QV) = grid%moist(i,j,k,P_QV) + q_cgrid(i,j,k) ! makte sure qv its positive. if (num_pseudo == 0 .and. grid%moist(i,j,k,P_QV) < 1.0e-6) & grid%moist(i,j,k,P_QV) = 1.0e-6 if (size(grid%moist,dim=4) >= 4) then grid%moist(i,j,k,p_qc) = grid%moist(i,j,k,p_qc) + grid%xa%qcw(i,j,k) grid%moist(i,j,k,p_qr) = grid%moist(i,j,k,p_qr) + grid%xa%qrn(i,j,k) if (grid%moist(i,j,k,p_qc) < 0.0) grid%moist(i,j,k,p_qc) = 0.0 if (grid%moist(i,j,k,p_qr) < 0.0) grid%moist(i,j,k,p_qr) = 0.0 end if if (size(grid%moist,dim=4) >= 6) then grid%moist(i,j,k,p_qi) = grid%moist(i,j,k,p_qi) + grid%xa%qci(i,j,k) grid%moist(i,j,k,p_qs) = grid%moist(i,j,k,p_qs) + grid%xa%qsn(i,j,k) if (grid%moist(i,j,k,p_qi) < 0.0) grid%moist(i,j,k,p_qi) = 0.0 if (grid%moist(i,j,k,p_qs) < 0.0) grid%moist(i,j,k,p_qs) = 0.0 end if if (size(grid%moist,dim=4) >= 7) then grid%moist(i,j,k,p_qg) = grid%moist(i,j,k,p_qg) + grid%xa%qgr(i,j,k) if (grid%moist(i,j,k,p_qg) < 0.0) grid%moist(i,j,k,p_qg) = 0.0 end if end do end do end do
Compute Diagnostics WRFDA/var/da/da_minimisation/da_write_diagnostics.inc • Compute O-B, O-A statistics for all observation types and variables. • Compute A-B (analysis increment) statistics for all model variables and levels. • Statistics include minimum, maximum (and their locations), mean and root mean square.