Changeset 13719
- Timestamp:
- 2020-11-03T12:02:23+01:00 (4 years ago)
- Location:
- NEMO/branches/2020/dev_r13648_ASINTER-04_laurent_bulk_ice
- Files:
-
- 18 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
NEMO/branches/2020/dev_r13648_ASINTER-04_laurent_bulk_ice/src/ABL/ablmod.F90
r13655 r13719 19 19 USE sbc_oce, ONLY : ght_abl, ghw_abl, e3t_abl, e3w_abl, jpka, jpkam1, rhoa 20 20 USE sbcblk ! use rn_efac, cdn_oce 21 USE sbc_phy ! use some physical constants for flux computation21 USE sbc_phy ! Catalog of functions for physical/meteorological parameters in the marine boundary layer 22 22 ! 23 23 USE prtctl ! Print control (prt_ctl routine) … … 252 252 & + rDt_abl * fft_abl(ji, jj) * v_abl( ji, jj, jk, nt_n ) ) & 253 253 & / (1._wp + gamma_Cor*gamma_Cor*zcff) 254 254 255 255 v_abl( ji, jj, jk, nt_a ) = e3t_abl(jk) *( & 256 256 & (1._wp-gamma_Cor*(1._wp-gamma_Cor)*zcff) * v_abl( ji, jj, jk, nt_n ) & … … 590 590 591 591 DO_2D( 0, 1, 0, 1 ) 592 zwnd_i(ji,jj) = u_abl(ji ,jj,2,nt_a) - 0.5_wp * ( pssu(ji ,jj) + pssu(ji-1,jj) ) 593 zwnd_j(ji,jj) = v_abl(ji,jj ,2,nt_a) - 0.5_wp * ( pssv(ji,jj ) + pssv(ji,jj-1) ) 592 zwnd_i(ji,jj) = u_abl(ji ,jj,2,nt_a) - 0.5_wp * ( pssu(ji ,jj) + pssu(ji-1,jj) ) 593 zwnd_j(ji,jj) = v_abl(ji,jj ,2,nt_a) - 0.5_wp * ( pssv(ji,jj ) + pssv(ji,jj-1) ) 594 594 END_2D 595 595 ! … … 633 633 ! Wind stress relative to the moving ice ( U10m - U_ice ) ! 634 634 ! ------------------------------------------------------------ ! 635 DO_2D( 0, 0, 0, 0 ) 635 DO_2D( 0, 0, 0, 0 ) 636 636 ptaui_ice(ji,jj) = 0.5_wp * ( rhoa(ji+1,jj) * pCd_du_ice(ji+1,jj) + rhoa(ji,jj) * pCd_du_ice(ji,jj) ) & 637 637 & * ( 0.5_wp * ( u_abl(ji+1,jj,2,nt_a) + u_abl(ji,jj,2,nt_a) ) - pssu_ice(ji,jj) ) -
NEMO/branches/2020/dev_r13648_ASINTER-04_laurent_bulk_ice/src/ABL/sbcabl.F90
r13655 r13719 22 22 USE sbc_oce ! Surface boundary condition: ocean fields 23 23 USE sbcblk ! Surface boundary condition: bulk formulae 24 USE sbc_phy ! Surface boundary condition: bulk formulae24 USE sbc_phy ! Catalog of functions for physical/meteorological parameters in the marine boundary layer 25 25 USE dom_oce, ONLY : tmask 26 26 ! … … 175 175 IF(nn_amxl==0) WRITE(numout,*) 'Deardorff 80 length-scale ' 176 176 IF(nn_amxl==1) WRITE(numout,*) 'Modified Deardorff 80 length-scale ' 177 IF(nn_amxl==2) WRITE(numout,*) 'Bougeault and Lacarrere length-scale ' 178 IF(nn_amxl==3) WRITE(numout,*) 'Rodier et al. length-scale ' 177 IF(nn_amxl==2) WRITE(numout,*) 'Bougeault and Lacarrere length-scale ' 178 IF(nn_amxl==3) WRITE(numout,*) 'Rodier et al. length-scale ' 179 179 WRITE(numout,*) ' Minimum value of atmospheric TKE = ',tke_min,' m^2 s^-2' 180 180 WRITE(numout,*) ' Minimum value of atmospheric mixing length = ',mxl_min,' m' … … 356 356 !! 3 - Advance ABL variables from now (n) to after (n+1) 357 357 !!------------------------------------------------------------------------------------------- 358 358 359 359 CALL abl_stp( kt, tsk_m, ssu_m, ssv_m, zssq, & ! <<= in 360 360 & sf(jp_wndi)%fnow(:,:,:), sf(jp_wndj)%fnow(:,:,:), & ! <<= in -
NEMO/branches/2020/dev_r13648_ASINTER-04_laurent_bulk_ice/src/ICE/icesbc.F90
r13655 r13719 71 71 ! 72 72 SELECT CASE( ksbc ) 73 ! 74 CASE( jp_usr ) 75 CALL usrdef_sbc_ice_tau( kt ) ! user defined formulation 76 ! 73 CASE( jp_usr ) ; CALL usrdef_sbc_ice_tau( kt ) ! user defined formulation 77 74 CASE( jp_blk ) 78 75 CALL blk_ice_1( sf(jp_wndi)%fnow(:,:,1), sf(jp_wndj)%fnow(:,:,1), & … … 80 77 & sf(jp_slp )%fnow(:,:,1), u_ice, v_ice, tm_su , & ! inputs 81 78 & putaui = utau_ice, pvtaui = vtau_ice ) ! outputs 82 ! CASE( jp_abl ) utau_ice & vtau_ice are computed in ablmod 83 CASE( jp_purecpl ) 84 CALL sbc_cpl_ice_tau( utau_ice , vtau_ice ) ! Coupled formulation 79 ! CASE( jp_abl ) utau_ice & vtau_ice are computed in ablmod 80 CASE( jp_purecpl ) ; CALL sbc_cpl_ice_tau( utau_ice , vtau_ice ) ! Coupled formulation 85 81 END SELECT 86 82 ! 87 83 IF( ln_mixcpl) THEN ! Case of a mixed Bulk/Coupled formulation 88 CALL sbc_cpl_ice_tau( zutau_ice , zvtau_ice )84 CALL sbc_cpl_ice_tau( zutau_ice , zvtau_ice ) 89 85 DO_2D( 0, 0, 0, 0 ) 90 utau_ice(ji,jj) = utau_ice(ji,jj) * xcplmask(ji,jj,0) + zutau_ice(ji,jj) * ( 1. - xcplmask(ji,jj,0) )91 vtau_ice(ji,jj) = vtau_ice(ji,jj) * xcplmask(ji,jj,0) + zvtau_ice(ji,jj) * ( 1. - xcplmask(ji,jj,0) )86 utau_ice(ji,jj) = utau_ice(ji,jj) * xcplmask(ji,jj,0) + zutau_ice(ji,jj) * ( 1. - xcplmask(ji,jj,0) ) 87 vtau_ice(ji,jj) = vtau_ice(ji,jj) * xcplmask(ji,jj,0) + zvtau_ice(ji,jj) * ( 1. - xcplmask(ji,jj,0) ) 92 88 END_2D 93 89 CALL lbc_lnk_multi( 'icesbc', utau_ice, 'U', -1.0_wp, vtau_ice, 'V', -1.0_wp ) … … 143 139 ! 144 140 SELECT CASE( ksbc ) !== fluxes over sea ice ==! 145 141 ! 146 142 CASE( jp_usr ) !--- user defined formulation 147 CALL usrdef_sbc_ice_flx( kt, h_s, h_i ) 148 ! 143 CALL usrdef_sbc_ice_flx( kt, h_s, h_i ) 149 144 CASE( jp_blk, jp_abl ) !--- bulk formulation & ABL formulation 150 CALL blk_ice_2 ( t_su, h_s, h_i, alb_ice, & 151 & theta_air_zt(:,:), q_air_zt(:,:), & ! #LB: known from "sbc_oce" module... 152 & sf(jp_slp)%fnow(:,:,1), sf(jp_qlw)%fnow(:,:,1), & 153 & sf(jp_prec)%fnow(:,:,1), sf(jp_snow)%fnow(:,:,1) ) 154 ! 145 CALL blk_ice_2 ( t_su, h_s, h_i, alb_ice, & 146 & theta_air_zt(:,:), q_air_zt(:,:), & ! #LB: known from "sbc_oce" module... 147 & sf(jp_slp)%fnow(:,:,1), sf(jp_qlw)%fnow(:,:,1), & 148 & sf(jp_prec)%fnow(:,:,1), sf(jp_snow)%fnow(:,:,1) ) 155 149 IF( ln_mixcpl ) CALL sbc_cpl_ice_flx( picefr=at_i_b, palbi=alb_ice, psst=sst_m, pist=t_su, phs=h_s, phi=h_i ) 156 150 IF( nn_flxdist /= -1 ) CALL ice_flx_dist ( t_su, alb_ice, qns_ice, qsr_ice, dqns_ice, evap_ice, devap_ice, nn_flxdist ) … … 159 153 & CALL blk_ice_qcn ( ln_virtual_itd, t_su, t_bo, h_s, h_i ) 160 154 CASE ( jp_purecpl ) !--- coupled formulation 161 CALL sbc_cpl_ice_flx( picefr=at_i_b, palbi=alb_ice, psst=sst_m, pist=t_su, phs=h_s, phi=h_i )155 CALL sbc_cpl_ice_flx( picefr=at_i_b, palbi=alb_ice, psst=sst_m, pist=t_su, phs=h_s, phi=h_i ) 162 156 IF( nn_flxdist /= -1 ) CALL ice_flx_dist ( t_su, alb_ice, qns_ice, qsr_ice, dqns_ice, evap_ice, devap_ice, nn_flxdist ) 163 157 END SELECT … … 228 222 !!---------------------------------------------------------------------- 229 223 ! 230 WHERE ( at_i (:,:) > 0._wp ) 231 z1_at_i(:,:) = 1._wp / at_i (:,:) 232 ELSEWHERE 233 z1_at_i(:,:) = 0._wp 224 WHERE ( at_i (:,:) > 0._wp ) ; z1_at_i(:,:) = 1._wp / at_i (:,:) 225 ELSEWHERE ; z1_at_i(:,:) = 0._wp 234 226 END WHERE 235 227 236 228 SELECT CASE( k_flxdist ) !== averaged on all ice categories ==! 237 229 ! 238 230 CASE( 0 , 1 ) 239 231 ! … … 258 250 ! 259 251 SELECT CASE( k_flxdist ) !== redistribution on all ice categories ==! 260 252 ! 261 253 CASE( 1 , 2 ) 262 254 ! -
NEMO/branches/2020/dev_r13648_ASINTER-04_laurent_bulk_ice/src/ICE/icetab.F90
r10069 r13719 17 17 USE par_oce 18 18 USE ice, ONLY : jpl 19 19 20 20 IMPLICIT NONE 21 21 PRIVATE … … 40 40 INTEGER , DIMENSION(ndim1d) , INTENT(in ) :: tab_ind ! input index 41 41 REAL(wp), DIMENSION(jpi,jpj,jpl), INTENT(in ) :: tab2d ! input 2D field 42 REAL(wp), DIMENSION(ndim1d,jpl) , INTENT( 42 REAL(wp), DIMENSION(ndim1d,jpl) , INTENT(inout) :: tab1d ! output 1D field 43 43 ! 44 44 INTEGER :: jl, jn, jid, jjd … … 61 61 INTEGER , DIMENSION(ndim1d) , INTENT(in ) :: tab_ind ! input index 62 62 REAL(wp), DIMENSION(jpi,jpj), INTENT(in ) :: tab2d ! input 2D field 63 REAL(wp), DIMENSION(ndim1d) , INTENT( 63 REAL(wp), DIMENSION(ndim1d) , INTENT(inout) :: tab1d ! output 1D field 64 64 ! 65 65 INTEGER :: jn , jid, jjd … … 80 80 INTEGER , DIMENSION(ndim1d) , INTENT(in ) :: tab_ind ! input index 81 81 REAL(wp), DIMENSION(ndim1d,jpl) , INTENT(in ) :: tab1d ! input 1D field 82 REAL(wp), DIMENSION(jpi,jpj,jpl), INTENT( 82 REAL(wp), DIMENSION(jpi,jpj,jpl), INTENT(inout) :: tab2d ! output 2D field 83 83 ! 84 84 INTEGER :: jl, jn, jid, jjd … … 101 101 INTEGER , DIMENSION(ndim1d) , INTENT(in ) :: tab_ind ! input index 102 102 REAL(wp), DIMENSION(ndim1d) , INTENT(in ) :: tab1d ! input 1D field 103 REAL(wp), DIMENSION(jpi,jpj), INTENT( 103 REAL(wp), DIMENSION(jpi,jpj), INTENT(inout) :: tab2d ! output 2D field 104 104 ! 105 105 INTEGER :: jn , jid, jjd -
NEMO/branches/2020/dev_r13648_ASINTER-04_laurent_bulk_ice/src/OCE/SBC/sbcblk.F90
r13655 r13719 62 62 USE prtctl ! Print control 63 63 64 USE sbc_phy ! a catalog of functions for physical/meteorological parameters in the marine boundary layer, rho_air, q_sat, etc...64 USE sbc_phy ! Catalog of functions for physical/meteorological parameters in the marine boundary layer 65 65 66 66 -
NEMO/branches/2020/dev_r13648_ASINTER-04_laurent_bulk_ice/src/OCE/SBC/sbcblk_algo_andreas.F90
r13655 r13719 35 35 USE dom_oce ! ocean space and time domain 36 36 USE phycst ! physical constants 37 USE sbc_phy ! all thermodynamics functions, rho_air, q_sat, etc... !LB37 USE sbc_phy ! Catalog of functions for physical/meteorological parameters in the marine boundary layer 38 38 39 39 IMPLICIT NONE -
NEMO/branches/2020/dev_r13648_ASINTER-04_laurent_bulk_ice/src/OCE/SBC/sbcblk_algo_coare3p0.F90
r13655 r13719 37 37 38 38 USE sbc_oce ! Surface boundary condition: ocean fields 39 USE sbc_phy ! all thermodynamics functions, rho_air, q_sat, etc... !LB39 USE sbc_phy ! Catalog of functions for physical/meteorological parameters in the marine boundary layer 40 40 USE sbcblk_skin_coare ! cool-skin/warm layer scheme (CSWL_ECMWF) !LB 41 41 -
NEMO/branches/2020/dev_r13648_ASINTER-04_laurent_bulk_ice/src/OCE/SBC/sbcblk_algo_coare3p6.F90
r13655 r13719 27 27 USE lib_mpp, ONLY: ctl_stop ! distribued memory computing library 28 28 USE in_out_manager, ONLY: nit000 ! I/O manager 29 USE sbc_phy ! all thermodynamics functions, rho_air, q_sat, etc... !LB29 USE sbc_phy ! Catalog of functions for physical/meteorological parameters in the marine boundary layer 30 30 USE sbcblk_skin_coare ! cool-skin/warm layer scheme (CSWL_ECMWF) !LB 31 31 -
NEMO/branches/2020/dev_r13648_ASINTER-04_laurent_bulk_ice/src/OCE/SBC/sbcblk_algo_ecmwf.F90
r13655 r13719 28 28 USE lib_mpp, ONLY: ctl_stop ! distribued memory computing library 29 29 USE in_out_manager, ONLY: nit000 ! I/O manager 30 USE sbc_phy ! all thermodynamics functions, rho_air, q_sat, etc... !LB30 USE sbc_phy ! Catalog of functions for physical/meteorological parameters in the marine boundary layer 31 31 USE sbcblk_skin_ecmwf ! cool-skin/warm layer scheme !LB 32 32 -
NEMO/branches/2020/dev_r13648_ASINTER-04_laurent_bulk_ice/src/OCE/SBC/sbcblk_algo_ice_cdn.F90
r13655 r13719 15 15 USE par_oce, ONLY: jpi, jpj, Nis0, Nie0, Njs0, Nje0, nn_hls 16 16 USE phycst ! physical constants 17 USE sbc_phy ! all thermodynamics functions, rho_air, q_sat, etc... !LB17 USE sbc_phy ! Catalog of functions for physical/meteorological parameters in the marine boundary layer 18 18 19 19 IMPLICIT NONE -
NEMO/branches/2020/dev_r13648_ASINTER-04_laurent_bulk_ice/src/OCE/SBC/sbcblk_algo_ice_lg15.F90
r13655 r13719 23 23 USE par_oce, ONLY: jpi, jpj 24 24 USE phycst ! physical constants 25 USE sbc_phy ! all thermodynamics functions, rho_air, q_sat, etc... !LB25 USE sbc_phy ! Catalog of functions for physical/meteorological parameters in the marine boundary layer 26 26 USE sbcblk_algo_ice_cdn 27 27 -
NEMO/branches/2020/dev_r13648_ASINTER-04_laurent_bulk_ice/src/OCE/SBC/sbcblk_algo_ice_lu12.F90
r13655 r13719 22 22 USE par_oce, ONLY: jpi, jpj 23 23 USE phycst ! physical constants 24 USE sbc_phy ! all thermodynamics functions, rho_air, q_sat, etc... !LB24 USE sbc_phy ! Catalog of functions for physical/meteorological parameters in the marine boundary layer 25 25 USE sbcblk_algo_ice_cdn 26 26 -
NEMO/branches/2020/dev_r13648_ASINTER-04_laurent_bulk_ice/src/OCE/SBC/sbcblk_algo_ncar.F90
r13655 r13719 27 27 USE sbcwave, ONLY: cdn_wave ! wave module 28 28 USE phycst ! physical constants 29 USE sbc_phy ! all thermodynamics functions, rho_air, q_sat, etc... !LB29 USE sbc_phy ! Catalog of functions for physical/meteorological parameters in the marine boundary layer 30 30 31 31 IMPLICIT NONE -
NEMO/branches/2020/dev_r13648_ASINTER-04_laurent_bulk_ice/src/OCE/SBC/sbcblk_skin_coare.F90
r13655 r13719 20 20 USE sbc_oce ! Surface boundary condition: ocean fields 21 21 22 USE sbc_phy ! misc. functions for marine ABL physics (rho_air, q_sat, bulk_formula, etc)22 USE sbc_phy ! Catalog of functions for physical/meteorological parameters in the marine boundary layer 23 23 24 24 USE sbcdcy !#LB: to know hour of dawn and dusk: rdawn_dcy and rdusk_dcy (needed in WL_COARE) -
NEMO/branches/2020/dev_r13648_ASINTER-04_laurent_bulk_ice/src/OCE/SBC/sbcblk_skin_ecmwf.F90
r13655 r13719 35 35 USE sbc_oce ! Surface boundary condition: ocean fields 36 36 37 USE sbc_phy ! misc. functions for marine ABL physics (rho_air, q_sat, bulk_formula, etc)37 USE sbc_phy ! Catalog of functions for physical/meteorological parameters in the marine boundary layer 38 38 39 39 USE lib_mpp ! distribued memory computing library -
NEMO/branches/2020/dev_r13648_ASINTER-04_laurent_bulk_ice/tests/STATION_ASF/EXPREF/launch_sasf.sh
r13690 r13719 15 15 16 16 # Atmo + SSX forcing to use and sea-ice support? 17 # => NFORC: name of forcing17 # => FORCING: name of forcing 18 18 # => i_sea_ice: whether to compute fluxes over sea-ice as well 19 19 # => SFORC: string sufficient to copy relevant files as in "*${SFORC}*.nc" 20 # NFORC="PAPA" ; i_sea_ice=0 ; SFORC="Station_PAPA_50N-145W"21 #NFORC="ERA5_arctic" ; i_sea_ice=1 ; SFORC="ERA5_arctic_surface_81N_36p75E_1h" ; # "ERA5_arctic" WITH ice/air flux computation22 NFORC="ERA5_arctic" ; i_sea_ice=0 ; SFORC="ERA5_arctic_surface_81N_36p75E_1h" ; # "ERA5_arctic" WITHOUT ice/air flux computation20 #FORCING="PAPA" ; i_sea_ice=0 ; SFORC="Station_PAPA_50N-145W" 21 FORCING="ERA5_arctic" ; i_sea_ice=1 ; SFORC="ERA5_arctic_surface_81N_36p75E_1h" ; # "ERA5_arctic" WITH ice/air flux computation 22 #FORCING="ERA5_arctic" ; i_sea_ice=0 ; SFORC="ERA5_arctic_surface_81N_36p75E_1h" ; # "ERA5_arctic" WITHOUT ice/air flux computation 23 23 24 24 … … 81 81 LIST_OA_ALGOS="ECMWF" ; # list of air-sea algorithms to test 82 82 LIST_IA_ALGOS="LG15 LU12 CSTC" ; # list of air-ice algorithms to test 83 DIR_NL=${ NFORC}/oce+ice ; # where to fetch the namelists from...83 DIR_NL=${FORCING}/oce+ice ; # where to fetch the namelists from... 84 84 else 85 85 # Only OPEN-OCEAN/AIR flux computation 86 86 LIST_OA_ALGOS="NCAR ECMWF COARE3p6 ANDREAS"; # list of air-sea algorithms to test 87 87 LIST_IA_ALGOS="" 88 DIR_NL=${ NFORC}/oce ; # where to fetch the namelists from...89 fi 90 if [ ! -d ${DIR_NL} ]; then echo " Mhhh, seems like forcing ${ NFORC} is not meant to be used with sea-ice/air flux computation !"; exit; fi88 DIR_NL=${FORCING}/oce ; # where to fetch the namelists from... 89 fi 90 if [ ! -d ${DIR_NL} ]; then echo " Mhhh, seems like forcing ${FORCING} is not meant to be used with sea-ice/air flux computation !"; exit; fi 91 91 92 92 … … 176 176 echo ; echo 177 177 echo "=======================================================================" 178 echo " Going for experiment: ${CASE} bulk param. with ${ NFORC} forcing "178 echo " Going for experiment: ${CASE} bulk param. with ${FORCING} forcing " 179 179 echo "=======================================================================" 180 180 echo … … 205 205 # Moving output files: 206 206 mkdir -p output 207 mv -f ${CONFIG}-${CASE}_${ NFORC}_*_grid*.nc output/208 if [ ${i_sea_ice} -eq 1 ]; then mv -f ${CONFIG}-${CASE}_${ NFORC}_*_icemod.nc output/; fi207 mv -f ${CONFIG}-${CASE}_${FORCING}_*_grid*.nc output/ 208 if [ ${i_sea_ice} -eq 1 ]; then mv -f ${CONFIG}-${CASE}_${FORCING}_*_icemod.nc output/; fi 209 209 210 210 # Saving logs: 211 mkdir -p ${CASE}_${ NFORC}_log212 mv -f *.out *.err ocean.output output.namelist.dyn ${CASE}_${ NFORC}_log/211 mkdir -p ${CASE}_${FORCING}_log 212 mv -f *.out *.err ocean.output output.namelist.dyn ${CASE}_${FORCING}_log/ 213 213 214 214 # Making 3x3 to 1 ! 215 215 cd output/ 216 list=`\ls ${CONFIG}*${CASE}_${ NFORC}_*.nc | grep -v '_restart_'| grep -v '_1p.nc'`216 list=`\ls ${CONFIG}*${CASE}_${FORCING}_*.nc | grep -v '_restart_'| grep -v '_1p.nc'` 217 217 for ff in ${list}; do 218 218 echo -
NEMO/branches/2020/dev_r13648_ASINTER-04_laurent_bulk_ice/tests/STATION_ASF/EXPREF/plot_station_asf_ICE.py
r13718 r13719 10 10 import sys 11 11 from os import path as path 12 import math 12 import argparse as ap 13 from math import floor, ceil, copysign, log 13 14 import numpy as nmp 14 15 from netCDF4 import Dataset,num2date … … 18 19 import matplotlib.dates as mdates 19 20 20 CONFIG='STATION_ASF'21 22 cforcing = 'PAPA' ; # name of forcing ('PAPA', 'ERA5_arctic', etc...)23 24 # (files are: output/3x3/'+CONFIG+'-'+algo+'_1h_'+year+'0101_'+year+'1231_gridT_'+cforcing+'.nc' )25 cstation = 'ERA5 81N, 36.75E'26 27 cy1 = '2018' ; # First year28 cy2 = '2018' ; # Last year29 30 jt0 = 031 32 21 dir_figs='.' 33 size_fig=(13,8 )22 size_fig=(13,8.5) 34 23 size_fig0=(12,10) 35 fig_ext='png'36 24 37 25 clr_red = '#AD0000' 38 clr_sat = '#ffed00'39 26 clr_mod = '#008ab8' 40 27 41 28 rDPI=100. 42 29 43 L_ALGOS = [ 'ECMWF-LG15', 'ECMWF-LU12', 'ECMWF-CSTC' ] 44 l_color = [ '#ffed00' , '#008ab8' , '0.4' ] ; # colors to differentiate algos on the plot 45 l_width = [ 3 , 2 , 1 ] ; # line-width to differentiate algos on the plot 46 l_style = [ '-' , '-' , '--' ] ; # line-style 47 48 49 # Variables to compare for A GIVEN algorithm 50 ############################################### 51 #L_VNEM0 = [ 52 53 30 L_ALGOS = [ 'ECMWF-CSTC', 'ECMWF-LG15', 'ECMWF-LU12' ] 31 l_color = [ '0.4' , '#ffed00' , '#008ab8' ] ; # colors to differentiate algos on the plot 32 l_width = [ 3 , 3 , 2 ] ; # line-width to differentiate algos on the plot 33 l_style = [ '--' , '-' , '-' ] ; # line-style 34 35 nb_algos = len(L_ALGOS) ; print(nb_algos) 54 36 55 37 # Variables to compare between algorithms … … 59 41 L_VARL = [ r'$C_{D}$', r'$C_{E}$', r'$Q_{lat}$', r'$Q_{sens}$' , r'$Q_{net}$' , r'$Q_{lw}$' , r'$Q_{sw}$' , r'$|\tau|$' ] 60 42 L_VUNT = [ '' , '' , r'$W/m^2$' , r'$W/m^2$' , r'$W/m^2$' , r'$W/m^2$' , r'$W/m^2$' , r'$N/m^2$' ] 61 L_ VMAX = [ 0.003 , 0.003 , 75. , 75. , 800. , 200. , 200. , 1.2]62 L_ VMIN = [ 0. , 0. , -250. , -125. , -400. , -200. , 0. , 0.]43 L_BASE = [ 0.0005 , 0.0005 , 5. , 5. , 5. , 5. , 5. , 0.05 ] 44 L_PREC = [ 3 , 3 , 0 , 0 , 0 , 0 , 0 , 2 ] 63 45 L_ANOM = [ False , False , True , True , True , True , True , True ] 64 46 65 47 66 nb_algos = len(L_ALGOS) 67 68 # Getting arguments: 69 narg = len(sys.argv) 70 if narg != 2: 71 print('Usage: '+sys.argv[0]+' <DIR_OUT_SASF>'); sys.exit(0) 72 cdir_data = sys.argv[1] 48 49 ################## ARGUMENT PARSING / USAGE ################################################################################################ 50 parser = ap.ArgumentParser(description='Generate pixel maps of a given scalar.') 51 # 52 requiredNamed = parser.add_argument_group('required arguments') 53 requiredNamed.add_argument('-d', '--dirout' , required=True, help='Path to (production) directory where STATION_ASF was run') 54 requiredNamed.add_argument('-f', '--forcing', required=True, default="PAPA", help='Name of forcing (ex: PAPA, ERA5_arctic') 55 # 56 parser.add_argument('-C', '--conf', default="STATION_ASF", help='specify NEMO config (ex: STATION_ASF)') 57 parser.add_argument('-s', '--ystart', default="2018", help='specify first year of experiment (ex: 2018)') 58 parser.add_argument('-e', '--yend', default="2018", help='specify last year of experiment (ex: 2018)') 59 # 60 parser.add_argument('-t', '--itype', default="png", help='specify the type of image you want to create (ex: png, svg, etc.)') 61 #parser.add_argument('-l', '--lev' , type=int, default=0, help='specify the level to use if 3D field (default: 0 => 2D)') 62 #parser.add_argument('-I', '--ice' , action='store_true', help='draw sea-ice concentration layer onto the field') 63 # 64 args = parser.parse_args() 65 # 66 cdir_data = args.dirout 67 cforcing = args.forcing 68 # 69 CONF = args.conf 70 cy1 = args.ystart 71 cy2 = args.yend 72 # 73 fig_ext = args.itype 74 #jk = args.lev 75 #lshow_ice = args.ice 76 # 77 #print(''); print(' *** cdir_data = ', cdir_data); print(' *** cforcing = ', cforcing) 78 #print(' *** CONF = ', CONF); print(' *** cy1 = ', cy1); print(' *** cy2 = ', cy2) 79 ############################################################################################################################################### 73 80 74 81 … … 83 90 cf_in = [] 84 91 for ja in range(nb_algos): 85 cfi = cdir_data+'/output/ 3x3/'+CONFIG+'-'+L_ALGOS[ja]+'_1h_'+cy1+'0101_'+cy2+'1231_icemod_'+cforcing+'.nc'92 cfi = cdir_data+'/output/'+CONF+'-'+L_ALGOS[ja]+'_'+cforcing+'_1h_'+cy1+'0101_'+cy2+'1231_icemod.nc' 86 93 chck4f(cfi) 87 94 cf_in.append(cfi) … … 90 97 #----------------------------------------------------------------- 91 98 99 100 def round_bounds( x1, x2, base=5, prec=3 ): 101 rmin = base * round( floor(float(x1)/base), prec ) 102 rmax = base * round( ceil(float(x2)/base), prec ) 103 return rmin, rmax 104 105 92 106 # Getting time array from the first file: 93 107 id_in = Dataset(cf_in[0]) 94 vt = id_in.variables['time_counter'][ jt0:]108 vt = id_in.variables['time_counter'][:] 95 109 cunit_t = id_in.variables['time_counter'].units ; print(' "time_counter" is in "'+cunit_t+'"') 96 110 id_in.close() 97 111 Nt = len(vt) 98 112 99 vtime = num2date(vt, units=cunit_t) ; # something understandable!113 vtime = num2date(vt, units=cunit_t) ; # something human! 100 114 vtime = vtime.astype(dtype='datetime64[D]') 101 115 … … 131 145 # 132 146 id_in = Dataset(cf_in[ja]) 133 xF[:,ja] = id_in.variables[L_VNEM[jv]][ jt0:,1,1] # only the center point of the 3x3 spatial domain!147 xF[:,ja] = id_in.variables[L_VNEM[jv]][:,1,1] # only the center point of the 3x3 spatial domain! 134 148 if ja == 0: cvar_lnm = id_in.variables[L_VNEM[jv]].long_name 135 149 id_in.close() 136 150 151 idx_okay = nmp.where( nmp.abs(xF) < 1.e+10 ) 152 137 153 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 138 154 fig = plt.figure(num = jv, figsize=size_fig, facecolor='w', edgecolor='k') 139 ax1 = plt.axes([0.08 , 0.25, 0.9, 0.7])155 ax1 = plt.axes([0.083, 0.23, 0.9, 0.7]) 140 156 ax1.set_xticks(vtime[::xticks_d]) 141 157 ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d %H:%M:%S')) … … 143 159 144 160 for ja in range(nb_algos): 145 plt.plot(vtime, xF[:,ja], '-', color=l_color[ja], linestyle=l_style[ja], linewidth=l_width[ja], label=L_ALGOS[ja], zorder=10+ja) 146 147 ax1.set_ylim(L_VMIN[jv], L_VMAX[jv]) ; ax1.set_xlim(vtime[0],vtime[Nt-1]) 161 fplot = nmp.ma.masked_where( xF[:,ja]==0., xF[:,ja] ) 162 plt.plot(vtime, fplot, '-', color=l_color[ja], \ 163 linestyle=l_style[ja], linewidth=l_width[ja], label=L_ALGOS[ja], zorder=10+ja) 164 165 fmin, fmax = round_bounds( nmp.min(xF[idx_okay]) , nmp.max(xF[idx_okay]), base=L_BASE[jv], prec=L_PREC[jv]) 166 ax1.set_ylim(fmin, fmax) ; ax1.set_xlim(vtime[0],vtime[Nt-1]) 148 167 plt.ylabel(L_VARL[jv]+' ['+L_VUNT[jv]+']') 149 168 150 169 ax1.grid(color='k', linestyle='-', linewidth=0.3) 151 170 plt.legend(loc='best', ncol=1, shadow=True, fancybox=True) 152 ax1.annotate(cvar_lnm+', station: '+cstation, xy=(0.3, 1.), xycoords='axes fraction', bbox={'facecolor':'w', 'alpha':1., 'pad':10}, zorder=50, **font_inf) 153 plt.savefig(L_VARO[jv]+'.'+fig_ext, dpi=int(rDPI), transparent=False) 171 ax1.annotate(cvar_lnm+', station: '+cforcing, xy=(0.5, 1.04), xycoords='axes fraction', \ 172 ha='center', bbox={'facecolor':'w', 'alpha':1., 'pad':10}, \ 173 zorder=50, **font_inf) 174 plt.savefig(L_VARO[jv]+'_'+cforcing+'.'+fig_ext, dpi=int(rDPI), transparent=False) 154 175 plt.close(jv) 155 176 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 177 178 179 156 180 157 181 def symetric_range( pmin, pmax ): … … 164 188 return frng 165 189 166 167 190 168 191 if L_ANOM[jv]: … … 180 203 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 181 204 fig = plt.figure(num = 10+jv, figsize=size_fig, facecolor='w', edgecolor='k') 182 ax1 = plt.axes([0.08 , 0.25, 0.9, 0.7])205 ax1 = plt.axes([0.083, 0.23, 0.9, 0.7]) 183 206 ax1.set_xticks(vtime[::xticks_d]) 184 207 ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d %H:%M:%S')) … … 186 209 187 210 for ja in range(nb_algos): 188 plt.plot(vtime, xFa[:,ja], '-', color=l_color[ja], linewidth=l_width[ja], label=L_ALGOS[ja], zorder=10+ja) 211 fplot = nmp.ma.masked_where( xF[:,ja]==0., xF[:,ja] ) 212 plt.plot(vtime, fplot, '-', color=l_color[ja], linewidth=l_width[ja], \ 213 label=L_ALGOS[ja], zorder=10+ja) 189 214 190 215 ax1.set_ylim(-yrng,yrng) ; ax1.set_xlim(vtime[0],vtime[Nt-1]) … … 192 217 ax1.grid(color='k', linestyle='-', linewidth=0.3) 193 218 plt.legend(bbox_to_anchor=(0.45, 0.2), ncol=1, shadow=True, fancybox=True) 194 ax1.annotate('Anomaly of '+cvar_lnm, xy=(0.3, 0.97), xycoords='axes fraction', bbox={'facecolor':'w', 'alpha':1., 'pad':10}, zorder=50, **font_inf) 219 ax1.annotate('Anomaly of '+cvar_lnm+', station: '+cforcing, xy=(0.5, 1.04), xycoords='axes fraction', \ 220 ha='center', bbox={'facecolor':'w', 'alpha':1., 'pad':10}, \ 221 zorder=50, **font_inf) 195 222 plt.savefig(L_VARO[jv]+'_anomaly.'+fig_ext, dpi=int(rDPI), transparent=False) 196 223 plt.close(10+jv) 197 224 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 198 199 200 201 -
NEMO/branches/2020/dev_r13648_ASINTER-04_laurent_bulk_ice/tests/STATION_ASF/EXPREF/plot_station_asf_OCE.py
r13691 r13719 33 33 l_style = [ '-' , '-' , '-' , '--' ] ; # line-style 34 34 35 nb_algos = len(L_ALGOS) ; print(nb_algos) 35 36 36 37 # Variables to compare between algorithms 37 38 ############################################ 38 L_VNEM = [ 'Cd_oce' , 'Ce_oce' , 'qla_oce' , 'qsb_oce' , 'qt_oce' , 'qlw_oce' , 'taum' , 'dt_skin' ] 39 L_VARO = [ 'Cd' , 'Ce' , 'Qlat' , 'Qsen' , 'Qnet' , 'Qlw' , 'Tau' , 'dT_skin' ] ; # name of variable on figure 40 L_VARL = [ r'$C_{D}$' , r'$C_{E}$' , r'$Q_{lat}$', r'$Q_{sens}$' , r'$Q_{net}$' , r'$Q_{lw}$' , r'$|\tau|$' , r'$\Delta T_{skin}$' ] ; # name of variable in latex mode 41 L_VUNT = [ '' , '' , r'$W/m^2$' , r'$W/m^2$' , r'$W/m^2$' , r'$W/m^2$' , r'$N/m^2$' , 'K' ] 42 L_BASE = [ 0.005 , 0.005 , 5. , 5. , 5 , 5. , 0.05 , 0.05 ] 43 L_PREC = [ 3 , 3 , 0 , 0 , 0 , 0 , 2 , 3 ] 44 L_ANOM = [ False , False , True , True , True , True , True , False ] 45 46 47 nb_algos = len(L_ALGOS) ; print(nb_algos) 48 39 L_VNEM = [ 'Cd_oce' , 'Ce_oce' , 'qla_oce' , 'qsb_oce' , 'qt_oce' , 'qlw_oce' , 'taum' , 'dt_skin' ] 40 L_VARO = [ 'Cd' , 'Ce' , 'Qlat' , 'Qsen' , 'Qnet' , 'Qlw' , 'Tau' , 'dT_skin' ] ; # name of variable on figure 41 L_VARL = [ r'$C_{D}$' , r'$C_{E}$' , r'$Q_{lat}$', r'$Q_{sens}$' , r'$Q_{net}$' , r'$Q_{lw}$' , r'$|\tau|$' , r'$\Delta T_{skin}$' ] ; # name of variable in latex mode 42 L_VUNT = [ '' , '' , r'$W/m^2$' , r'$W/m^2$' , r'$W/m^2$' , r'$W/m^2$' , r'$N/m^2$' , 'K' ] 43 L_BASE = [ 0.005 , 0.005 , 5. , 5. , 5 , 5. , 0.05 , 0.05 ] 44 L_PREC = [ 3 , 3 , 0 , 0 , 0 , 0 , 2 , 3 ] 45 L_ANOM = [ False , False , True , True , True , True , True , False ] 49 46 50 47 … … 91 88 if not path.exists(cf): print(cmesg) ; sys.exit(0) 92 89 93 ###cf_in = nmp.empty((), dtype="S10")94 90 cf_in = [] 95 91 for ja in range(nb_algos): … … 108 104 109 105 110 111 106 # Getting time array from the first file: 112 107 id_in = Dataset(cf_in[0]) … … 114 109 cunit_t = id_in.variables['time_counter'].units ; print(' "time_counter" is in "'+cunit_t+'"') 115 110 id_in.close() 116 nbr= len(vt)117 118 vtime = num2date(vt, units=cunit_t) ; # something understandable!111 Nt = len(vt) 112 113 vtime = num2date(vt, units=cunit_t) ; # something human! 119 114 vtime = vtime.astype(dtype='datetime64[D]') 120 115 121 ii= nbr/300116 ii=Nt/300 122 117 ib=max(ii-ii%10,1) 123 118 xticks_d=int(30*ib) 124 125 119 126 120 rat = 100./float(rDPI) … … 140 134 141 135 142 # First for each algorithm we compare some input vs out put variables: 136 # First for each algorithm we compare some input vs out put variables: 143 137 144 138 # t_skin … … 150 144 ntemp = len(vtemp_in) 151 145 152 xxx = nmp.zeros(( nbr,ntemp))146 xxx = nmp.zeros((Nt,ntemp)) 153 147 154 148 for ja in range(nb_algos): … … 171 165 idx_okay = nmp.where( nmp.abs(xxx) < 1.e+10 ) 172 166 fmin, fmax = round_bounds( nmp.min(xxx[idx_okay]) , nmp.max(xxx[idx_okay]), base=5, prec=0 ) 173 ax1.set_ylim(fmin, fmax) ; ax1.set_xlim(vtime[0],vtime[ nbr-1])167 ax1.set_ylim(fmin, fmax) ; ax1.set_xlim(vtime[0],vtime[Nt-1]) 174 168 plt.ylabel(r'Temperature [$^{\circ}$C]') 175 169 … … 189 183 nb_var = len(L_VNEM) 190 184 191 xF = nmp.zeros(( nbr,nb_algos))192 xFa = nmp.zeros(( nbr,nb_algos))185 xF = nmp.zeros((Nt,nb_algos)) 186 xFa = nmp.zeros((Nt,nb_algos)) 193 187 194 188 … … 204 198 205 199 idx_okay = nmp.where( nmp.abs(xF) < 1.e+10 ) 206 200 201 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 207 202 fig = plt.figure(num = jv, figsize=size_fig, facecolor='w', edgecolor='k') 208 ax1 = plt.axes([0.08 , 0.23, 0.9, 0.7])203 ax1 = plt.axes([0.083, 0.23, 0.9, 0.7]) 209 204 ax1.set_xticks(vtime[::xticks_d]) 210 205 ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d %H:%M:%S')) … … 212 207 213 208 for ja in range(nb_algos): 214 plt.plot(vtime, xF[:,ja], '-', color=l_color[ja], linestyle=l_style[ja], linewidth=l_width[ja], label=L_ALGOS[ja], zorder=10+ja) 215 209 fplot = nmp.ma.masked_where( xF[:,ja]==0., xF[:,ja] ) 210 plt.plot(vtime, fplot, '-', color=l_color[ja], \ 211 linestyle=l_style[ja], linewidth=l_width[ja], label=L_ALGOS[ja], zorder=10+ja) 212 216 213 fmin, fmax = round_bounds( nmp.min(xF[idx_okay]) , nmp.max(xF[idx_okay]), base=L_BASE[jv], prec=L_PREC[jv]) 217 #print("LOLO: fmin, fmax =",nmp.min(xF[idx_okay]), nmp.max(xF[idx_okay]) ); print("LOLO: fmin, fmax =",fmin, fmax) ; #sys.exit(0) 218 219 ax1.set_ylim(fmin, fmax) ; ax1.set_xlim(vtime[0],vtime[nbr-1]) 214 ax1.set_ylim(fmin, fmax) ; ax1.set_xlim(vtime[0],vtime[Nt-1]) 220 215 plt.ylabel(L_VARL[jv]+' ['+L_VUNT[jv]+']') 221 216 222 217 ax1.grid(color='k', linestyle='-', linewidth=0.3) 223 218 plt.legend(loc='best', ncol=1, shadow=True, fancybox=True) 224 ax1.annotate(cvar_lnm+', station: '+cforcing, xy=(0.5, 1.04), xycoords='axes fraction', ha='center', bbox={'facecolor':'w', 'alpha':1., 'pad':10}, \ 219 ax1.annotate(cvar_lnm+', station: '+cforcing, xy=(0.5, 1.04), xycoords='axes fraction', \ 220 ha='center', bbox={'facecolor':'w', 'alpha':1., 'pad':10}, \ 225 221 zorder=50, **font_inf) 226 222 plt.savefig(L_VARO[jv]+'_'+cforcing+'.'+fig_ext, dpi=int(rDPI), transparent=False) 227 223 plt.close(jv) 224 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 225 226 227 228 229 def symetric_range( pmin, pmax ): 230 # Returns a symetric f-range that makes sense for the anomaly of "f" we're looking at... 231 from math import floor, copysign, log, ceil 232 zmax = max( abs(pmax) , abs(pmin) ) 233 romagn = floor(log(zmax, 10)) ; # order of magnitude of the anomaly we're dealing with 234 rmlt = 10.**(int(romagn)) / 2. 235 frng = copysign( ceil(abs(zmax)/rmlt)*rmlt , zmax) 236 return frng 237 228 238 229 239 if L_ANOM[jv]: … … 231 241 for ja in range(nb_algos): xFa[:,ja] = xF[:,ja] - nmp.mean(xF,axis=1) 232 242 233 if nmp.sum( xFa[:,:]) == 0.0:243 if nmp.sum(nmp.abs(xFa[:,:])) == 0.0: 234 244 print(' Well! Seems that for variable '+L_VARO[jv]+', choice of algo has no impact a all!') 235 245 print(' ==> skipping anomaly plot...') … … 237 247 else: 238 248 239 # Want a symetric y-range that makes sense for the anomaly we're looking at: 240 rmax = nmp.max(xFa) ; rmin = nmp.min(xFa) 241 rmax = max( abs(rmax) , abs(rmin) ) 242 romagn = floor(log(rmax, 10)) ; # order of magnitude of the anomaly we're dealing with 243 rmlt = 10.**(int(romagn)) / 2. 244 yrng = copysign( ceil(abs(rmax)/rmlt)*rmlt , rmax) 245 249 yrng = symetric_range( nmp.min(xFa) , nmp.max(xFa) ) 250 251 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 246 252 fig = plt.figure(num = 10+jv, figsize=size_fig, facecolor='w', edgecolor='k') 247 ax1 = plt.axes([0.0 8, 0.25, 0.9, 0.7])253 ax1 = plt.axes([0.09, 0.25, 0.9, 0.7]) 248 254 ax1.set_xticks(vtime[::xticks_d]) 249 255 ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d %H:%M:%S')) … … 253 259 plt.plot(vtime, xFa[:,ja], '-', color=l_color[ja], linewidth=l_width[ja], label=L_ALGOS[ja], zorder=10+ja) 254 260 255 ax1.set_ylim(-yrng,yrng) ; ax1.set_xlim(vtime[0],vtime[ nbr-1])261 ax1.set_ylim(-yrng,yrng) ; ax1.set_xlim(vtime[0],vtime[Nt-1]) 256 262 plt.ylabel(L_VARL[jv]+' ['+L_VUNT[jv]+']') 257 263 ax1.grid(color='k', linestyle='-', linewidth=0.3) … … 260 266 plt.savefig(L_VARO[jv]+'_'+cforcing+'.'+fig_ext, dpi=int(rDPI), transparent=False) 261 267 plt.close(10+jv) 262 263 264 265 -
NEMO/branches/2020/dev_r13648_ASINTER-04_laurent_bulk_ice/tests/STATION_ASF/EXPREF/sbcblk_sanity_check.sh
r13690 r13719 25 25 26 26 # Atmo + SSX forcing to use and sea-ice support? 27 NFORC="IDEALIZED" ; i_sea_ice=0 ; SFORC="input_output_VALIDATION_IDEALIZED.nc"27 FORCING="IDEALIZED" ; i_sea_ice=0 ; SFORC="input_output_VALIDATION_IDEALIZED.nc" 28 28 29 29 … … 86 86 87 87 88 DIR_NL=${ NFORC}/oce ; # directory where to find the namelists...88 DIR_NL=${FORCING}/oce ; # directory where to find the namelists... 89 89 90 90 # NEMO executable to use is: … … 162 162 echo ; echo 163 163 echo "=======================================================================" 164 echo " Going for experiment: ${CASE} bulk param. with ${ NFORC} forcing "164 echo " Going for experiment: ${CASE} bulk param. with ${FORCING} forcing " 165 165 echo "=======================================================================" 166 166 echo … … 187 187 # Moving output files: 188 188 mkdir -p output 189 mv -f ${CONFIG}-${CASE}_${ NFORC}_*_grid*.nc output/189 mv -f ${CONFIG}-${CASE}_${FORCING}_*_grid*.nc output/ 190 190 191 191 # Saving logs: 192 mkdir -p ${CASE}_${ NFORC}_log193 mv -f *.out *.err ocean.output output.namelist.dyn ${CASE}_${ NFORC}_log/192 mkdir -p ${CASE}_${FORCING}_log 193 mv -f *.out *.err ocean.output output.namelist.dyn ${CASE}_${FORCING}_log/ 194 194 195 195 done
Note: See TracChangeset
for help on using the changeset viewer.