#!/usr/bin/env python3 ### ### Script to check water conservation in the IPSL coupled model ### ## Warning, to install, configure, run, use any of included software or ## to read the associated documentation you'll need at least one (1) ## brain in a reasonably working order. Lack of this implement will ## void any warranties (either express or implied). Authors assumes ## no responsability for errors, omissions, data loss, or any other ## consequences caused directly or indirectly by the usage of his ## software by incorrectly or partially configured personal ## ## ## SVN information # $Author$ # $Date$ # $Revision$ # $Id$ # $HeadURL$ ## Define Experiment if False : JobName="TEST-CM72-SIMPLE-ROUTING.12" ; TagName="IPSLCM7" ; SpaceName="DEVT" ; ExperimentName="piControl" ; User="p86caub" ; Project="gencmip6" Freq = 'MO' ; YearBegin = 1970 ; YearEnd = 1979 ; PackFrequency = 10 ORCA = 'eORCA1.2' ; NEMO=3.6 ; OCE_relax = False ; OCE_icb = False ATM = 'ICO40' ; Routing = 'SIMPLE' if False : JobName="TEST-CM72-SIMPLE-ROUTING.10" ; TagName="IPSLCM7" ; SpaceName="DEVT" ; ExperimentName="piControl" ; User="p86caub" ; Project="gencmip6" Freq = 'MO' ; YearBegin = 1860 ; YearEnd = 1869 ; PackFrequency = 10 ORCA = 'eORCA1.2' ; ATM = 'ICO40' ; Routing = 'SIMPLE' ; NEMO=3.6 ; OCE_relax = False ; OCE_icb = False if False : JobName="VALID-CM622-LR.01" ; TagName="IPSLCM6" ; SpaceName="DEVT" ; ExperimentName="piControl" ; User="p86caub" ; Project="gencmip6" Freq = 'MO' ; YearBegin = 1890 ; YearEnd = 1899 ; PackFrequency = 10 ORCA = 'eORCA1.2' ; ATM = 'LMD144142' ; Routing = 'ORCHIDEE' ; NEMO=3.6 ; OCE_relax = False ; OCE_icb = False if True : JobName="CM65v420-LR-SKL-pi-05" ; TagName="IPSLCM6" ; SpaceName="DEVT" ; ExperimentName="piControl" ; User="p48ethe" ; Project="gencmip6" #Freq = 'MO' ; YearBegin = 1890 ; YearEnd = 1899 ; PackFrequency = 10 Freq = 'MO' ; YearBegin = 2340 ; YearEnd = 2349 ; PackFrequency = 10 ORCA = 'eORCA1.2' ; ATM = 'LMD144142' ; Routing = 'ORCHIDEE' ; NEMO=4.2 ; OCE_relax = False ; OCE_icb = False ; Coupled = True Coupled = True import numpy as np ##-- Some physical constants #-- Earth Radius Ra = 40.e6 / (2. * np.pi) #-- Gravity g = 9.81 #-- Ice density (kg/m3) in LIM3 ICE_rho_ice = 917.0 #-- Snow density (kg/m3) in LIM3 ICE_rho_sno = 330.0 #-- Ocean water density (kg/m3) in NEMO OCE_rho_liq = 1026. #-- Water density in ice pounds in SI3 ICE_rho_pnd = 1000. ### ICO = False if 'ICO' in ATM : ICO = True LMDZ = False if 'LMD' in ATM : LMDZ = True ### ## Import system modules import sys, os, shutil, subprocess # Where do we run ? TGCC = False ; IDRIS = False SysName, NodeName, Release, Version, Machine = os.uname() if 'irene' in NodeName : TGCC = True if 'jeanzay' in NodeName : IDRIS = True ## Set site specific libIGCM directories, and other specific stuff if TGCC : CPU = subprocess.getoutput ( 'lscpu | grep "Model name"' ) if "Intel(R) Xeon(R) Platinum" in CPU : Machine = 'irene' if "AMD" in CPU : Machine = 'irene-amd' ARCHIVE = subprocess.getoutput ( f'ccc_home --cccstore -d {Project} -u {User}' ) STORAGE = subprocess.getoutput ( f'ccc_home --cccwork -d {Project} -u {User}' ) SCRATCHDIR = subprocess.getoutput ( f'ccc_home --cccscratch -d {Project} -u {User}' ) R_IN = os.path.join ( subprocess.getoutput ( f'ccc_home --cccwork -d igcmg -u igcmg' ), 'IGCM') rebuild = os.path.join ( subprocess.getoutput ( f'ccc_home --ccchome -d igcmg -u igcmg' ), 'Tools', Machine, 'rebuild_nemo', 'bin', 'rebuild_nemo' ) ## Specific to run at TGCC. # Needed before importing a NetCDF library (netCDF4, xarray, cmds, etc ...) import mpi4py mpi4py.rc.initialize = False ## Creates output directory #TmpDir = os.path.join ( subprocess.getoutput ( 'ccc_home --cccscratch' ), f'WATER_{JobName}_{YearBegin}_{YearEnd}' ) TmpDir = os.path.join ( '/ccc/scratch/cont003/drf/p86mart', f'WATER_{JobName}_{YearBegin}_{YearEnd}' ) if IDRIS : raise Exception("Pour IDRIS : repertoires et chemins a definir") ## Import specific module import nemo, lmdz ## Now import needed scientific modules import xarray as xr # Output file FileOut = f'CPL_waterbudget_{JobName}_{YearBegin}_{YearEnd}.out' f_out = open ( FileOut, mode = 'w' ) # Function to print to stdout *and* output file def echo (string) : print ( string ) f_out.write ( string + '\n' ) f_out.flush () return None ## Set libIGCM directories R_OUT = os.path.join ( ARCHIVE , 'IGCM_OUT') R_BUF = os.path.join ( SCRATCHDIR, 'IGCM_OUT') L_EXP = os.path.join (TagName, SpaceName, ExperimentName, JobName) R_SAVE = os.path.join ( R_OUT, L_EXP ) R_BUFR = os.path.join ( R_BUF, L_EXP ) POST_DIR = os.path.join ( R_BUF, L_EXP, 'Out' ) REBUILD_DIR = os.path.join ( R_BUF, L_EXP, 'REBUILD' ) R_BUF_KSH = os.path.join ( R_BUFR, 'Out' ) R_FIGR = os.path.join ( STORAGE, 'IGCM_OUT', L_EXP ) #if os.path.isdir (TmpDir) : shutil.rmtree ( TmpDir ) if not os.path.isdir (TmpDir) : os.mkdir (TmpDir) TmpDirOCE = os.path.join (TmpDir, 'OCE') TmpDirICE = os.path.join (TmpDir, 'ICE') if not os.path.exists (TmpDirOCE) : os.mkdir (TmpDirOCE ) if not os.path.exists (TmpDirICE) : os.mkdir (TmpDirICE ) echo ( f'Working in TMPDIR : {TmpDir}' ) echo ( f'\nDealing with {L_EXP}' ) #-- Model output directories if Freq == "MO" : FreqDir = os.path.join ('Output' , 'MO' ) if Freq == "SE" : FreqDir = os.path.join ('Analyse', 'SE' ) dir_ATM_his = os.path.join ( R_SAVE, "ATM", FreqDir ) dir_OCE_his = os.path.join ( R_SAVE, "OCE", FreqDir ) dir_ICE_his = os.path.join ( R_SAVE, "ICE", FreqDir ) dir_SRF_his = os.path.join ( R_SAVE, "SRF", FreqDir ) echo ( f'The analysis relies on files from the following model output directories : ' ) echo ( f'{dir_ATM_his}' ) echo ( f'{dir_OCE_his}' ) echo ( f'{dir_ICE_his}' ) echo ( f'{dir_SRF_his}' ) #-- Files Names if Freq == 'MO' : File = f'{JobName}_{YearBegin}0101_{YearEnd}1231_1M' if Freq == 'SE' : File = f'{JobName}_SE_{YearBegin}0101_{YearEnd}1231_1M' echo ('\nOpen history files' ) file_ATM_his = os.path.join ( dir_ATM_his, f'{File}_histmth.nc' ) file_OCE_his = os.path.join ( dir_OCE_his, f'{File}_grid_T.nc' ) file_OCE_sca = os.path.join ( dir_OCE_his, f'{File}_scalar.nc' ) file_ICE_his = os.path.join ( dir_ICE_his, f'{File}_icemod.nc' ) file_SRF_his = os.path.join ( dir_SRF_his, f'{File}_sechiba_history.nc' ) file_OCE_srf = os.path.join ( dir_OCE_his, f'{File}_grid_T.nc' ) d_ATM_his = xr.open_dataset ( file_ATM_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() d_OCE_his = xr.open_dataset ( file_OCE_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() d_OCE_sca = xr.open_dataset ( file_OCE_sca, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() d_ICE_his = xr.open_dataset ( file_ICE_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() if NEMO == 3.6 :d_ICE_his = d_ICE_his.rename ( {'y_grid_T':'y', 'x_grid_T':'x'} ) d_SRF_his = xr.open_dataset ( file_SRF_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() d_OCE_srf = xr.open_dataset ( file_OCE_srf, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() echo ( file_ATM_his ) echo ( file_OCE_his ) echo ( file_OCE_sca ) echo ( file_ICE_his ) echo ( file_SRF_his ) ## Compute run length dtime = ( d_ATM_his.time_counter_bounds.max() - d_ATM_his.time_counter_bounds.min() ) echo ('\nRun length : {:8.2f} days'.format ( (dtime/np.timedelta64(1, "D")).values ) ) dtime_sec = (dtime/np.timedelta64(1, "s")).values.item() # Convert in seconds ## Compute length of each period dtime_per = (d_ATM_his.time_counter_bounds[:,-1] - d_ATM_his.time_counter_bounds[:,0] ) echo ('\nPeriods lengths (days) : {:} days'.format ( (dtime_per/np.timedelta64(1, "D")).values ) ) dtime_per_sec = (dtime_per/np.timedelta64(1, "s")).values # In seconds dtime_per_sec = xr.DataArray (dtime_per_sec, dims=["time_counter", ], coords=[d_ATM_his.time_counter,] ) #-- Open restart files YearRes = YearBegin - 1 # Year of the restart of beginning of simulation YearPre = YearBegin - PackFrequency # Year to find the tarfile of the restart of beginning of simulation echo (f'Restart dates - Start : {YearRes}-12-31 / End : {YearEnd}-12-31 ') file_restart_beg = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{YearPre}0101_{YearRes}1231_restart.tar' ) file_restart_end = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{YearBegin}0101_{YearEnd}1231_restart.tar' ) echo ( f'{file_restart_beg}' ) echo ( f'{file_restart_end}' ) file_OCE_beg = f'OCE_{JobName}_{YearRes}1231_restart.nc' file_OCE_end = f'OCE_{JobName}_{YearEnd}1231_restart.nc' file_ICE_beg = f'ICE_{JobName}_{YearRes}1231_restart_icemod.nc' file_ICE_end = f'ICE_{JobName}_{YearEnd}1231_restart_icemod.nc' echo ( f'{file_OCE_beg}' ) echo ( f'{file_OCE_end}' ) echo ( f'{file_ICE_beg}' ) echo ( f'{file_ICE_end}' ) file_ATM_beg = f'ATM_{JobName}_{YearRes}1231_restartphy.nc' file_ATM_end = f'ATM_{JobName}_{YearEnd}1231_restartphy.nc' if LMDZ : file_DYN_beg = f'ATM_{JobName}_{YearRes}1231_restart.nc' file_DYN_end = f'ATM_{JobName}_{YearEnd}1231_restart.nc' if ICO : file_DYN_beg = f'ICO_{JobName}_{YearRes}1231_restart.nc' file_DYN_end = f'ICO_{JobName}_{YearEnd}1231_restart.nc' file_SRF_beg = f'SRF_{JobName}_{YearRes}1231_sechiba_rest.nc' file_SRF_end = f'SRF_{JobName}_{YearEnd}1231_sechiba_rest.nc' liste_beg = [file_ATM_beg, file_DYN_beg, file_SRF_beg, ] liste_end = [file_ATM_end, file_DYN_end, file_SRF_end, ] echo ( f'{file_ATM_beg}') echo ( f'{file_ATM_end}') echo ( f'{file_SRF_beg}') echo ( f'{file_SRF_end}') if Routing == 'SIMPLE' : file_RUN_beg = f'SRF_{JobName}_{YearRes}1231_routing_restart.nc' file_RUN_end = f'SRF_{JobName}_{YearEnd}1231_routing_restart.nc' liste_beg.append ( file_RUN_beg ) liste_end.append ( file_RUN_end ) echo ( f'{file_RUN_beg}') echo ( f'{file_RUN_end}') echo ('\nExtract restart files from tar : ATM, ICO and SRF') for resFile in liste_beg : if not os.path.exists ( os.path.join (TmpDir, resFile) ) : command = f'cd {TmpDir} ; tar xf {file_restart_beg} {resFile}' echo ( command ) os.system ( command ) for resFile in liste_end : if not os.path.exists ( os.path.join (TmpDir, resFile) ) : command = f'cd {TmpDir} ; tar xf {file_restart_end} {resFile}' echo ( command ) os.system ( command ) echo ('\nOpening ATM SRF and ICO restart files') d_ATM_beg = xr.open_dataset ( os.path.join (TmpDir, file_ATM_beg), decode_times=False, decode_cf=True).squeeze() d_ATM_end = xr.open_dataset ( os.path.join (TmpDir, file_ATM_end), decode_times=False, decode_cf=True).squeeze() d_SRF_beg = xr.open_dataset ( os.path.join (TmpDir, file_SRF_beg), decode_times=False, decode_cf=True).squeeze() d_SRF_end = xr.open_dataset ( os.path.join (TmpDir, file_SRF_end), decode_times=False, decode_cf=True).squeeze() d_DYN_beg = xr.open_dataset ( os.path.join (TmpDir, file_DYN_beg), decode_times=False, decode_cf=True).squeeze() d_DYN_end = xr.open_dataset ( os.path.join (TmpDir, file_DYN_end), decode_times=False, decode_cf=True).squeeze() for var in d_SRF_beg.variables : #d_SRF_beg[var].attrs['_FillValue'] = 1.e20 #d_SRF_end[var].attrs['_FillValue'] = 1.e20 d_SRF_beg[var] = d_SRF_beg[var].where ( d_SRF_beg[var]<1.e20, 0.) d_SRF_end[var] = d_SRF_end[var].where ( d_SRF_end[var]<1.e20, 0.) if ICO : d_RUN_beg = xr.open_dataset ( os.path.join (TmpDir, file_RUN_beg), decode_times=False, decode_cf=True).squeeze() d_RUN_end = xr.open_dataset ( os.path.join (TmpDir, file_RUN_end), decode_times=False, decode_cf=True).squeeze() echo ('\nExtract and rebuild OCE and ICE restarts') def get_ndomain (zfile) : #d_zfile = xr.open_dataset (zfile, decode_times=False).squeeze() #ndomain_opa = d_zfile.attrs['DOMAIN_number_total'] #d_zfile.close () ndomain_opa = subprocess.getoutput ( f'ls {zfile}_*.nc | wc -l' ).format() return int (ndomain_opa) if not os.path.exists ( os.path.join (TmpDir, file_OCE_beg) ) : if not os.path.exists ( os.path.join (TmpDirOCE, f'OCE_{JobName}_{YearRes}1231_restart_0000.nc') ): command = f'cd {TmpDirOCE} ; tar xf {file_restart_beg} OCE_{JobName}_{YearRes}1231_restart_*.nc' echo ( command ) os.system ( command ) ndomain_opa = get_ndomain ( os.path.join (TmpDirOCE, f'OCE_{JobName}_{YearRes}1231_restart') ) command = f'cd {TmpDirOCE} ; {rebuild} OCE_{JobName}_{YearRes}1231_restart {ndomain_opa} ; mv {file_OCE_beg} {TmpDir}' echo ( command ) os.system ( command ) echo ( f'Rebuild done : {file_OCE_beg}') if not os.path.exists ( os.path.join (TmpDir, file_OCE_end) ) : if not os.path.exists ( os.path.join (TmpDirOCE, f'OCE_{JobName}_{YearEnd}1231_restart_0000.nc') ): command = f'cd {TmpDirOCE} ; tar xf {file_restart_end} OCE_{JobName}_{YearEnd}1231_restart_*.nc' echo ( command ) os.system ( command ) ndomain_opa = get_ndomain ( os.path.join (TmpDirOCE, f'OCE_{JobName}_{YearEnd}1231_restart') ) command = f'cd {TmpDirOCE} ; {rebuild} OCE_{JobName}_{YearEnd}1231_restart {ndomain_opa} ; mv {file_OCE_end} {TmpDir}' echo ( command ) os.system ( command ) echo ( f'Rebuild done : {file_OCE_end}') if not os.path.exists ( os.path.join (TmpDir, file_ICE_beg) ) : if not os.path.exists ( os.path.join (TmpDirICE, f'ICE_{JobName}_{YearRes}1231_restart_icemod') ): command = f'cd {TmpDirICE} ; tar xf {file_restart_beg} ICE_{JobName}_{YearRes}1231_restart_icemod_*.nc' echo ( command ) os.system ( command ) ndomain_opa = get_ndomain ( os.path.join (TmpDirICE, f'ICE_{JobName}_{YearRes}1231_restart_icemod') ) command = f'cd {TmpDirICE} ; {rebuild} ICE_{JobName}_{YearRes}1231_restart_icemod {ndomain_opa} ; mv {file_ICE_beg} {TmpDir} ' echo ( command ) os.system ( command ) echo ( f'Rebuild done : {file_OCE_beg}') if not os.path.exists ( os.path.join (TmpDir, file_ICE_end) ) : if not os.path.exists ( os.path.join (TmpDirICE, f'ICE_{JobName}_{YearEnd}1231_restart_icemod') ): command = f'cd {TmpDirICE} ; tar xf {file_restart_end} ICE_{JobName}_{YearEnd}1231_restart_icemod_*.nc' echo ( command ) os.system ( command ) ndomain_opa = get_ndomain ( os.path.join (TmpDirICE, f'ICE_{JobName}_{YearRes}1231_restart_icemod') ) command = f'cd {TmpDirICE} ; {rebuild} ICE_{JobName}_{YearEnd}1231_restart_icemod {ndomain_opa} ; mv {file_ICE_end} {TmpDir}' echo ( command ) os.system ( command ) echo ( f'Rebuild done : {file_ICE_end}') echo ('Opening OCE and ICE restart files') if NEMO == 3.6 : d_OCE_beg = xr.open_dataset ( os.path.join (TmpDir, file_OCE_beg), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze() d_OCE_end = xr.open_dataset ( os.path.join (TmpDir, file_OCE_end), decode_times=False, decode_cf=True).squeeze() d_ICE_beg = xr.open_dataset ( os.path.join (TmpDir, file_ICE_beg), decode_times=False, decode_cf=True).squeeze() d_ICE_end = xr.open_dataset ( os.path.join (TmpDir, file_ICE_end), decode_times=False, decode_cf=True).squeeze() if NEMO == 4.0 or NEMO == 4.2 : d_OCE_beg = xr.open_dataset ( os.path.join (TmpDir, file_OCE_beg), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze() d_OCE_end = xr.open_dataset ( os.path.join (TmpDir, file_OCE_end), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze() d_ICE_beg = xr.open_dataset ( os.path.join (TmpDir, file_ICE_beg), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze() d_ICE_end = xr.open_dataset ( os.path.join (TmpDir, file_ICE_end), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze() echo ( file_ATM_beg ) echo ( file_ATM_end ) echo ( file_DYN_beg ) echo ( file_DYN_end ) echo ( file_SRF_beg ) echo ( file_SRF_end ) if Routing == 'SIMPLE' : echo ( file_RUN_beg ) echo ( file_RUN_end ) echo ( file_OCE_beg ) echo ( file_OCE_end ) echo ( file_ICE_beg ) echo ( file_ICE_end ) # ATM grid with cell surfaces if ICO : ATM_aire = d_ATM_his ['aire'][0] ATM_fsea = d_ATM_his ['fract_oce'][0] + d_ATM_his ['fract_sic'][0] ATM_flnd = d_ATM_his ['fract_ter'][0] + d_ATM_his ['fract_lic'][0] if LMDZ : ATM_aire = lmdz.geo2point ( d_ATM_his ['aire'][0], cumulPoles=True ) ATM_aire2 = lmdz.geo2point ( d_ATM_his ['aire'][0], cumulPoles=False ) ATM_fsea = lmdz.geo2point ( d_ATM_his ['fract_oce'][0] + d_ATM_his ['fract_sic'][0] ) ATM_flnd = lmdz.geo2point ( d_ATM_his ['fract_ter'][0] ) #ATM_aire[0] = np.sum ( d_ATM_his ['aire'][0, 0] ) #ATM_aire[-1] = np.sum ( d_ATM_his ['aire'][0,-1] ) SRF_aire = ATM_aire * ATM_flnd if ICO : # Area on icosahedron grid file_DYN_aire = os.path.join ( R_IN, 'ATM', 'GRID', ATM+'_grid.nc' ) d_DYN_aire = xr.open_dataset ( file_DYN_aire, decode_times=False).squeeze() d_DYN_aire = d_DYN_aire.rename ( {'cell':'cell_mesh'} ) DYN_aire = d_DYN_aire['aire'] DYN_fsea = d_DYN_aire ['fract_oce'] + d_DYN_aire ['fract_sic'] DYN_flnd = 1.0 - DYN_fsea if LMDZ : DYN_aire = ATM_aire DYN_fsea = ATM_fsea DYN_flnd = ATM_flnd #if LMDZ : # d_ATM_beg = d_ATM_beg.assign ( coords={'lon':d_ATM_beg.lon*180./np.pi} ) # Get mask and surfaces sos = d_OCE_his ['sos'][0].squeeze() OCE_msk = nemo.lbc_mask ( xr.where ( sos>0, 1., 0.0 ), cd_type = 'T' ) so = sos = d_OCE_his ['sos'][0].squeeze() OCE_msk3 = nemo.lbc_mask ( xr.where ( so>0., 1., 0. ), cd_type = 'T', sval = 0. ) #so = d_OCE_beg ['so'].squeeze() #OCE_msk3 = nemo.lbc_mask ( xr.where ( so>0., 1., 0. ), cd_type = 'T', sval = 0. ) #OCE_msk = OCE_msk3[0] # lbc_mask removes the duplicate points (periodicity and north fold) OCE_aire = nemo.lbc_mask ( d_OCE_his ['area'] * OCE_msk, cd_type = 'T', sval = 0.0 ) ICE_aire = OCE_aire ATM_aire_tot = np.sum (ATM_aire).values.item() OCE_aire_tot = np.sum (OCE_aire).values.item() ICE_aire_tot = np.sum (ICE_aire).values.item() echo ( '\n------------------------------------------------------------------------------------' ) echo ( '-- NEMO change in stores (for the records)' ) #-- Note that the total number of days of the run should be diagnosed rather than assumed #-- Here the result is in Sv # #-- Change in ocean volume in freshwater equivalent OCE_ssh_beg = d_OCE_beg['sshn'] OCE_ssh_end = d_OCE_end['sshn'] OCE_sum_ssh_beg = np.sum ( OCE_ssh_beg * OCE_aire ).values.item() OCE_sum_ssh_end = np.sum ( OCE_ssh_end * OCE_aire ).values.item() OCE_mas_wat_beg = OCE_sum_ssh_beg * OCE_rho_liq OCE_mas_wat_end = OCE_sum_ssh_end * OCE_rho_liq echo ( 'OCE_sum_ssh_beg = {:12.6e} m^3 - OCE_sum_ssh_end = {:12.6e} m^3'.format (OCE_sum_ssh_beg, OCE_sum_ssh_end) ) dOCE_vol_liq = ( OCE_sum_ssh_end - OCE_sum_ssh_beg ) dOCE_mas_liq = dOCE_vol_liq * OCE_rho_liq dOCE_mas_wat = dOCE_mas_liq echo ( 'dOCE vol = {:12.3e} m^3'.format (dOCE_vol_liq) ) echo ( 'dOCE ssh = {:12.3e} m '.format (dOCE_vol_liq/OCE_aire_tot) ) echo ( 'dOCE mass = {:12.3e} kg '.format (dOCE_mas_liq) ) echo ( 'dOCE mass = {:12.3e} Sv '.format (dOCE_mas_liq/dtime_sec*1E-6/OCE_rho_liq) ) ## Glace et neige if NEMO == 3.6 : ICE_ice_beg = d_ICE_beg['v_i_htc1']+d_ICE_beg['v_i_htc2']+d_ICE_beg['v_i_htc3']+d_ICE_beg['v_i_htc4']+d_ICE_beg['v_i_htc5'] ICE_ice_end = d_ICE_end['v_i_htc1']+d_ICE_end['v_i_htc2']+d_ICE_end['v_i_htc3']+d_ICE_end['v_i_htc4']+d_ICE_end['v_i_htc5'] ICE_sno_beg = d_ICE_beg['v_s_htc1']+d_ICE_beg['v_s_htc2']+d_ICE_beg['v_s_htc3']+d_ICE_beg['v_s_htc4']+d_ICE_beg['v_s_htc5'] ICE_sno_end = d_ICE_end['v_s_htc1']+d_ICE_end['v_s_htc2']+d_ICE_end['v_s_htc3']+d_ICE_end['v_s_htc4']+d_ICE_end['v_s_htc5'] ICE_pnd_beg = 0.0 ; ICE_pnd_end = 0.0 ICE_fzl_beg = 0.0 ; ICE_fzl_end = 0.0 ICE_mas_wat_beg = np.sum ( (ICE_ice_beg*ICE_rho_ice + ICE_sno_beg*ICE_rho_sno)*ICE_aire ).values.item() ICE_mas_wat_end = np.sum ( (ICE_ice_end*ICE_rho_ice + ICE_sno_end*ICE_rho_sno)*ICE_aire ).values.item() if NEMO == 4.0 or NEMO == 4.2 : ICE_ice_beg = d_ICE_beg ['v_i'] ; ICE_ice_end = d_ICE_end ['v_i'] ICE_sno_beg = d_ICE_beg ['v_s'] ; ICE_sno_end = d_ICE_end ['v_s'] ICE_pnd_beg = d_ICE_beg ['v_ip'] ; ICE_pnd_end = d_ICE_end ['v_ip'] ICE_fzl_beg = d_ICE_beg ['v_il'] ; ICE_fzl_end = d_ICE_end ['v_il'] ICE_mas_wat_beg = np.sum ( d_ICE_beg['snwice_mass']*ICE_aire ).values.item() ICE_mas_wat_end = np.sum ( d_ICE_end['snwice_mass']*ICE_aire ).values.item() ICE_vol_ice_beg = np.sum ( ICE_ice_beg*ICE_aire ).values.item() ICE_vol_ice_end = np.sum ( ICE_ice_end*ICE_aire ).values.item() ICE_vol_sno_beg = np.sum ( ICE_sno_beg*ICE_aire ).values.item() ICE_vol_sno_end = np.sum ( ICE_sno_end*ICE_aire ).values.item() ICE_vol_pnd_beg = np.sum ( ICE_pnd_beg*ICE_aire ).values.item() ICE_vol_pnd_end = np.sum ( ICE_pnd_end*ICE_aire ).values.item() ICE_vol_fzl_beg = np.sum ( ICE_fzl_beg*ICE_aire ).values.item() ICE_vol_fzl_end = np.sum ( ICE_fzl_end*ICE_aire ).values.item() #-- Converting to freswater volume dICE_vol_ice = ICE_vol_ice_end - ICE_vol_ice_beg dICE_mas_ice = dICE_vol_ice * ICE_rho_ice dICE_vol_sno = ICE_vol_sno_end - ICE_vol_sno_beg dICE_mas_sno = dICE_vol_sno * ICE_rho_sno dICE_vol_pnd = ICE_vol_pnd_end - ICE_vol_pnd_beg dICE_mas_pnd = dICE_vol_pnd * ICE_rho_pnd dICE_vol_fzl= ICE_vol_fzl_end - ICE_vol_fzl_beg dICE_mas_fzl = dICE_vol_fzl * ICE_rho_pnd if NEMO == 3.6 : dICE_mas_wat = dICE_mas_ice + dICE_mas_sno dSEA_mas_wat = dOCE_mas_wat + dICE_mas_ice + dICE_mas_sno if NEMO == 4.0 or NEMO == 4.2 : dICE_mas_wat = ICE_mas_wat_end - ICE_mas_wat_beg dSEA_mas_wat = dOCE_mas_wat + dICE_mas_wat echo ( 'ICE_vol_ice_beg = {:12.6e} m^3 - ICE_vol_ice_end = {:12.6e} m^3'.format (ICE_vol_ice_beg, ICE_vol_ice_end) ) echo ( 'ICE_vol_sno_beg = {:12.6e} m^3 - ICE_vol_sno_end = {:12.6e} m^3'.format (ICE_vol_sno_beg, ICE_vol_sno_end) ) echo ( 'ICE_vol_pnd_beg = {:12.6e} m^3 - ICE_vol_pnd_end = {:12.6e} m^3'.format (ICE_vol_pnd_beg, ICE_vol_pnd_end) ) echo ( 'ICE_vol_fzl_beg = {:12.6e} m^3 - ICE_vol_fzl_end = {:12.6e} m^3'.format (ICE_vol_fzl_beg, ICE_vol_fzl_end) ) echo ( 'dICE_vol_ice = {:12.3e} m^3'.format (dICE_vol_ice) ) echo ( 'dICE_vol_sno = {:12.3e} m^3'.format (dICE_vol_sno) ) echo ( 'dICE_vol_pnd = {:12.3e} m^3'.format (dICE_vol_pnd) ) echo ( 'dICE_mas_ice = {:12.3e} m^3'.format (dICE_mas_ice) ) echo ( 'dICE_mas_sno = {:12.3e} m^3'.format (dICE_mas_sno) ) echo ( 'dICE_mas_pnd = {:12.3e} m^3'.format (dICE_mas_pnd) ) echo ( 'dICE_mas_fzl = {:12.3e} m^3'.format (dICE_mas_fzl) ) echo ( 'dICE_mas_wat = {:12.3e} m^3'.format (dICE_mas_wat) ) SEA_mas_wat_beg = OCE_mas_wat_beg + ICE_mas_wat_beg SEA_mas_wat_end = OCE_mas_wat_end + ICE_mas_wat_end echo ( '\n------------------------------------------------------------') echo ( 'Variation du contenu en eau ocean + glace ' ) echo ( 'dMass(ocean) = {:12.6e} kg '.format(dSEA_mas_wat) ) echo ( 'dVol (ocean) = {:12.3e} Sv '.format(dSEA_mas_wat/dtime_sec*1E-6/OCE_rho_liq) ) echo ( 'dVol (ocean) = {:12.3e} m '.format(dSEA_mas_wat*1E-3/OCE_aire_tot) ) echo ( '\n------------------------------------------------------------------------------------' ) echo ( '-- ATM changes in stores ' ) #-- Change in precipitable water from the atmosphere daily and monthly files #-- Compute sum weighted by gridcell area (kg/m2) then convert to Sv # ATM vertical grid ATM_Ahyb = d_ATM_his['Ahyb'].squeeze() ATM_Bhyb = d_ATM_his['Bhyb'].squeeze() klevp1 = ATM_Ahyb.shape[0] # Surface pressure if ICO : DYN_ps_beg = d_DYN_beg['ps'] DYN_ps_end = d_DYN_end['ps'] if LMDZ : DYN_ps_beg = lmdz.geo2point ( d_DYN_beg['ps'].isel(rlonv=slice(0,-1)) ) DYN_ps_end = lmdz.geo2point ( d_DYN_end['ps'].isel(rlonv=slice(0,-1)) ) # 3D Pressure DYN_p_beg = ATM_Ahyb + ATM_Bhyb * DYN_ps_beg DYN_p_end = ATM_Ahyb + ATM_Bhyb * DYN_ps_end # Layer thickness DYN_sigma_beg = DYN_p_beg[0:-1]*0. DYN_sigma_end = DYN_p_end[0:-1]*0. for k in np.arange (klevp1-1) : DYN_sigma_beg[k,:] = (DYN_p_beg[k,:] - DYN_p_beg[k+1,:]) / g DYN_sigma_end[k,:] = (DYN_p_end[k,:] - DYN_p_end[k+1,:]) / g DYN_sigma_beg = DYN_sigma_beg.rename ( {'klevp1':'sigs'} ) DYN_sigma_end = DYN_sigma_end.rename ( {'klevp1':'sigs'} ) ##-- Vertical and horizontal integral, and sum of liquid, solid and vapor water phases if LMDZ : try : DYN_wat_beg = lmdz.geo3point ( (d_DYN_beg['H2Ov'] + d_DYN_beg['H2Ol'] + d_DYN_beg['H2Oi']).isel(rlonv=slice(0,-1) ) ) DYN_wat_end = lmdz.geo3point ( (d_DYN_end['H2Ov'] + d_DYN_end['H2Ol'] + d_DYN_end['H2Oi']).isel(rlonv=slice(0,-1) ) ) except : DYN_wat_beg = lmdz.geo3point ( (d_DYN_beg['H2O_g'] + d_DYN_beg['H2O_l'] + d_DYN_beg['H2O_s']).isel(rlonv=slice(0,-1) ) ) DYN_wat_end = lmdz.geo3point ( (d_DYN_end['H2O_g'] + d_DYN_end['H2O_l'] + d_DYN_end['H2O_s']).isel(rlonv=slice(0,-1) ) ) if ICO : DYN_wat_beg = ( d_DYN_beg['q'][0:4] ).sum (dim = ['nq',] ).rename ( {'lev':'sigs'} ) DYN_wat_end = ( d_DYN_end['q'][0:4] ).sum (dim = ['nq',] ).rename ( {'lev':'sigs'} ) ATM_mas_wat_beg = np.sum (DYN_sigma_beg * DYN_wat_beg * DYN_aire).values.item() ATM_mas_wat_end = np.sum (DYN_sigma_end * DYN_wat_end * DYN_aire).values.item() dATM_mas_wat = ATM_mas_wat_end - ATM_mas_wat_beg echo ( '\nVariation du contenu en eau atmosphere (dynamique) ' ) echo ( 'ATM_mas_beg = {:12.6e} kg - ATM_mas_end = {:12.6e} kg'.format (ATM_mas_wat_beg, ATM_mas_wat_end) ) echo ( 'dMass(atm) = {:12.3e} kg '.format (dATM_mas_wat) ) echo ( 'dMass(atm) = {:12.3e} Sv '.format (dATM_mas_wat/dtime_sec*1.E-9) ) echo ( 'dMass(atm) = {:12.3e}m '.format (dATM_mas_wat/OCE_aire_tot*1E-3) ) LIC_sno_beg = d_ATM_beg['SNOW01']*d_ATM_beg['FTER']+d_ATM_beg['SNOW02']*d_ATM_beg['FLIC']+d_ATM_beg['SNOW03']*d_ATM_beg['FOCE']+d_ATM_beg['SNOW04']*d_ATM_beg['FSIC'] LIC_sno_end = d_ATM_end['SNOW01']*d_ATM_end['FTER']+d_ATM_end['SNOW02']*d_ATM_end['FLIC']+d_ATM_end['SNOW03']*d_ATM_end['FOCE']+d_ATM_end['SNOW04']*d_ATM_end['FSIC'] if ICO : LIC_sno_beg = LIC_sno_beg.rename ( {'points_physiques':'cell_mesh'} ) LIC_sno_end = LIC_sno_end.rename ( {'points_physiques':'cell_mesh'} ) LIC_mas_sno_beg = np.sum ( LIC_sno_beg * DYN_aire ).values.item() LIC_mas_sno_end = np.sum ( LIC_sno_end * DYN_aire ).values.item() dLIC_mas_sno = LIC_mas_sno_end - LIC_mas_sno_beg echo ( '\nVariation du contenu en neige atmosphere (calottes)' ) echo ( 'LIC_mas_sno_beg = {:12.6e} kg - LIC_mas_sno_end = {:12.6e} kg'.format (LIC_mas_sno_beg, LIC_mas_sno_end) ) echo ( 'dMass(neige atm) = {:12.3e} kg '.format (dLIC_mas_sno ) ) echo ( 'dMass(neige atm) = {:12.3e} Sv '.format (dLIC_mas_sno/dtime_sec*1E-6/ICE_rho_ice) ) echo ( 'dMass(neige atm) = {:12.3e} m '.format (dLIC_mas_sno/OCE_aire_tot*1E-3) ) echo ( '\nVariation du contenu en eau+neige atmosphere ' ) echo ( 'dMass(eau + neige atm) = {:12.3e} kg '.format ( dATM_mas_wat + dLIC_mas_sno) ) echo ( 'dMass(eau + neige atm) = {:12.3e} Sv '.format ( (dATM_mas_wat + dLIC_mas_sno)/dtime_sec*1E-9) ) echo ( 'dMass(eau + neige atm) = {:12.3e} m '.format ( (dATM_mas_wat + dLIC_mas_sno)/OCE_aire_tot*1E-3) ) echo ( '\n------------------------------------------------------------------------------------' ) echo ( '-- SRF changes ' ) if Routing == 'SIMPLE' : RUN_mas_wat_beg = np.sum ( d_RUN_beg ['fast_reservoir'] + d_RUN_beg ['slow_reservoir'] + d_RUN_beg ['stream_reservoir']).values.item() RUN_mas_wat_end = np.sum ( d_RUN_end ['fast_reservoir'] + d_RUN_end ['slow_reservoir'] + d_RUN_end ['stream_reservoir']).values.item() if Routing == 'ORCHIDEE' : RUN_mas_wat_beg = np.sum ( d_SRF_beg['fastres'] + d_SRF_beg['slowres'] + d_SRF_beg['streamres'] \ + d_SRF_beg['floodres'] + d_SRF_beg['lakeres'] + d_SRF_beg['pondres'] ) .values.item() RUN_mas_wat_end = np.sum ( d_SRF_end['fastres'] + d_SRF_end['slowres'] + d_SRF_end['streamres'] \ + d_SRF_end['floodres'] + d_SRF_end['lakeres'] + d_SRF_end['pondres'] ) .values.item() dRUN_mas_wat = RUN_mas_wat_end - RUN_mas_wat_beg echo ( '\nWater content in routing ' ) echo ( 'RUN_mas_wat_beg = {:12.6e} kg - RUN_mas_wat_end = {:12.6e} kg '.format (RUN_mas_wat_end, RUN_mas_wat_end) ) echo ( 'dMass(routing) = {:12.3e} kg '.format(dRUN_mas_wat) ) echo ( 'dMass(routing) = {:12.3e} Sv '.format(dRUN_mas_wat/dtime_sec*1E-9) ) echo ( 'dMass(routing) = {:12.3e} m '.format(dRUN_mas_wat/OCE_aire_tot*1E-3) ) tot_watveg_beg = d_SRF_beg['tot_watveg_beg'] ; tot_watveg_beg = tot_watveg_beg .where (tot_watveg_beg < 1E10, 0.) tot_watsoil_beg = d_SRF_beg['tot_watsoil_beg'] ; tot_watsoil_beg = tot_watsoil_beg.where (tot_watsoil_beg< 1E10, 0.) snow_beg = d_SRF_beg['snow_beg'] ; snow_beg = snow_beg .where (snow_beg < 1E10, 0.) tot_watveg_end = d_SRF_end['tot_watveg_beg'] ; tot_watveg_end = tot_watveg_end .where (tot_watveg_end < 1E10, 0.) tot_watsoil_end = d_SRF_end['tot_watsoil_beg'] ; tot_watsoil_end = tot_watsoil_end.where (tot_watsoil_end< 1E10, 0.) snow_end = d_SRF_end['snow_beg'] ; snow_end = snow_end .where (snow_end < 1E10, 0.) SRF_wat_beg = tot_watveg_beg + tot_watsoil_beg + snow_beg SRF_wat_end = tot_watveg_end + tot_watsoil_end + snow_end #SRF_mas_wat_beg = d_SRF_beg['tot_watveg_beg']+d_SRF_beg['tot_watsoil_beg'] + d_SRF_beg['snow_beg'] #SRF_mas_wat_end = d_SRF_end['tot_watveg_beg']+d_SRF_end['tot_watsoil_beg'] + d_SRF_end['snow_beg'] if LMDZ : tot_watveg_beg = tot_watveg_beg .rename ( {'y':'points_phyiques'} ) tot_watsoil_beg = tot_watsoil_beg.rename ( {'y':'points_phyiques'} ) snow_beg = snow_beg .rename ( {'y':'points_phyiques'} ) tot_watveg_end = tot_watveg_end .rename ( {'y':'points_phyiques'} ) tot_watsoil_end = tot_watsoil_end.rename ( {'y':'points_phyiques'} ) snow_end = snow_end .rename ( {'y':'points_phyiques'} ) SRF_wat_beg = SRF_wat_beg .rename ( {'y':'points_phyiques'} ) SRF_wat_end = SRF_wat_end .rename ( {'y':'points_phyiques'} ) if ICO : tot_watveg_beg = tot_watveg_beg .rename ( {'y':'cell_mesh'} ) tot_watsoil_beg = tot_watsoil_beg.rename ( {'y':'cell_mesh'} ) snow_beg = snow_beg .rename ( {'y':'cell_mesh'} ) tot_watveg_end = tot_watveg_end .rename ( {'y':'cell_mesh'} ) tot_watsoil_end = tot_watsoil_end.rename ( {'y':'cell_mesh'} ) snow_end = snow_end .rename ( {'y':'cell_mesh'} ) SRF_wat_beg = SRF_wat_beg .rename ( {'y':'cell_mesh'} ) SRF_wat_end = SRF_wat_end .rename ( {'y':'cell_mesh'} ) SRF_mas_watveg_beg = np.sum ( tot_watveg_beg * SRF_aire).values.item() SRF_mas_watsoil_beg = np.sum ( tot_watsoil_beg * SRF_aire).values.item() SRF_mas_snow_beg = np.sum ( snow_beg * SRF_aire).values.item() SRF_mas_watveg_end = np.sum ( tot_watveg_end * SRF_aire).values.item() SRF_mas_watsoil_end = np.sum ( tot_watsoil_end * SRF_aire).values.item() SRF_mas_snow_end = np.sum ( snow_end * SRF_aire).values.item() dSRF_mas_watveg = SRF_mas_watveg_end - SRF_mas_watveg_beg dSRF_mas_watsoil = SRF_mas_watsoil_end - SRF_mas_watsoil_beg dSRF_mas_snow = SRF_mas_snow_end - SRF_mas_snow_beg echo ('\nLes differents reservoirs') echo ( 'SRF_mas_watveg_beg = {:12.6e} kg - SRF_mas_watveg_end = {:12.6e} kg '.format (SRF_mas_watveg_beg , SRF_mas_watveg_end) ) echo ( 'SRF_mas_watsoil_beg = {:12.6e} kg - SRF_mas_watsoil_end = {:12.6e} kg '.format (SRF_mas_watsoil_beg, SRF_mas_watsoil_end) ) echo ( 'SRF_mas_snow_beg = {:12.6e} kg - SRF_mas_snow_end = {:12.6e} kg '.format (SRF_mas_snow_beg , SRF_mas_snow_end) ) echo ( 'dMass(watveg) = {:12.3e} kg {:12.2e} Sv {:12.2e} m '.format (dSRF_mas_watveg , dSRF_mas_watveg /dtime_sec*1E-9, dSRF_mas_watveg /OCE_aire_tot*1E-3) ) echo ( 'dMass(watsoil) = {:12.3e} kg {:12.2e} Sv {:12.2e} m '.format (dSRF_mas_watsoil, dSRF_mas_watsoil/dtime_sec*1E-9, dSRF_mas_watsoil/OCE_aire_tot*1E-3) ) echo ( 'dMass(sno) = {:12.3e} kg {:12.2e} Sv {:12.2e} m '.format (dSRF_mas_snow , dSRF_mas_snow /dtime_sec*1E-9, dSRF_mas_snow /OCE_aire_tot*1E-3 ) ) SRF_mas_wat_beg = np.sum ( SRF_wat_beg * SRF_aire).values.item() SRF_mas_wat_end = np.sum ( SRF_wat_end * SRF_aire).values.item() dSRF_mas_wat = SRF_mas_wat_end - SRF_mas_wat_beg echo ( '\nWater content in surface ' ) echo ( 'SRF_mas_wat_beg = {:12.6e} kg - SRF_mas_wat_end = {:12.6e} kg '.format (SRF_mas_wat_beg, SRF_mas_wat_end) ) echo ( 'dMass(water srf) = {:12.3e} kg '.format (dSRF_mas_wat) ) echo ( 'dMass(water srf) = {:12.3e} Sv '.format (dSRF_mas_wat/dtime_sec*1E-9) ) echo ( 'dMass(water srf) = {:12.3e} m '.format (dSRF_mas_wat/OCE_aire_tot*1E-3) ) echo ( '\nWater content in ATM + SRF + RUN ' ) echo ( 'mas_wat_beg = {:12.6e} kg '.format (ATM_mas_wat_beg + LIC_mas_sno_beg + RUN_mas_wat_beg + SRF_mas_wat_beg) ) echo ( 'mas_wat_end = {:12.6e} kg '.format (ATM_mas_wat_end + LIC_mas_sno_end + RUN_mas_wat_end + SRF_mas_wat_end) ) echo ( 'dMass(water atm+srf+run) = {:12.6e} kg '.format ( dATM_mas_wat + dLIC_mas_sno + dRUN_mas_wat + dSRF_mas_wat) ) echo ( 'dMass(water atm+srf+run) = {:12.3e} Sv '.format ((dATM_mas_wat + dLIC_mas_sno + dRUN_mas_wat + dSRF_mas_wat)/dtime_sec*1E-9) ) echo ( 'dMass(water atm+srf+run) = {:12.3e} m '.format ((dATM_mas_wat + dLIC_mas_sno + dRUN_mas_wat + dSRF_mas_wat)/OCE_aire_tot*1E-3) ) echo ( '\n------------------------------------------------------------------------------------' ) echo ( '-- Change in all components' ) echo ( 'mas_wat_beg = {:12.6e} kg '.format (SEA_mas_wat_beg + ATM_mas_wat_beg + LIC_mas_sno_beg + RUN_mas_wat_beg + SRF_mas_wat_beg) ) echo ( 'mas_wat_end = {:12.6e} kg '.format (SEA_mas_wat_end + ATM_mas_wat_end + LIC_mas_sno_end + RUN_mas_wat_end + SRF_mas_wat_end) ) echo ( 'dMass(water CPL) = {:12.3e} kg '.format ( dSEA_mas_wat + dATM_mas_wat + dLIC_mas_sno + dRUN_mas_wat + dSRF_mas_wat) ) echo ( 'dMass(water CPL) = {:12.3e} Sv '.format ((dSEA_mas_wat + dATM_mas_wat + dLIC_mas_sno + dRUN_mas_wat + dSRF_mas_wat)/dtime_sec*1E-9) ) echo ( 'dMass(water CPL) = {:12.3e} m '.format ((dSEA_mas_wat + dATM_mas_wat + dLIC_mas_sno + dRUN_mas_wat + dSRF_mas_wat)/OCE_aire_tot*1E-3) )