123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433 |
- #!/usr/bin/env python
- # B a r a K u d a
- #
- # Budget and other stuffs on rectangular boxes!
- #
- # L. Brodeau, 2013
- import sys
- import numpy as nmp
- from netCDF4 import Dataset
- from os.path import basename
- import barakuda_tool as bt
- import barakuda_ncio as bnc
- from barakuda_physics import sigma0
- #next = 10
- next = 10
- # The density of seawater is about 1025 kg/m^3 and the specific heat is about 3850 J/(kg C)
- #rho0 = 1025. ; # kg/m^3
- #rCp = 3850. ; # 3850 J/kg/deg.C
- rho0 = 1000. ; # kg/m^3 => to stay consistent with cdftransportiz.f90 of CDFTOOLS...
- rCp = 4000. ; # 3850 J/kg/deg.C => to stay consistent with cdftransportiz.f90 of CDFTOOLS...
- #l_plot_debug = True
- l_plot_debug = False
- venv_needed = {'ORCA','EXP','CPREF','DIAG_D','MM_FILE','FILE_DEF_BOXES','NN_T','NN_S', \
- 'NN_SST','NN_SSS','NN_SSH'}
- vdic = bt.check_env_var(sys.argv[0], venv_needed)
- corca = vdic['ORCA']
- CONFEXP = corca+'-'+vdic['EXP']
- cname_script = basename(sys.argv[0])
- print '\n'+cname_script
- narg = len(sys.argv)
- if narg < 3 or narg > 4:
- print 'Usage: '+cname_script+' <year> <depth for surface properties> (uv)'
- print ' by specifying "uv" as 3rd argument, budget will be extended to'
- print ' some variables found in grid_U and grid_V files such as wind stress\n'
- sys.exit(0)
- cy = sys.argv[1] ; jy=int(cy)
- czs= sys.argv[2] ; zs = float(int(czs))
- # Shall we need U and V files???
- luv = False
- if narg == 4 and sys.argv[3] == 'uv':
- luv = True
- venv_uv = {'NN_TAUX','NN_TAUY'}
- vdic_uv = bt.check_env_var(sys.argv[0], venv_uv)
- path_fig = vdic['DIAG_D']+'/'
- # Image type? eps, png, jpg...
- #FIG_FORM = 'pdf'
- FIG_FORM = 'png'
- # First will read name and coordinates of rectangular boxes to treat into file FILE_DEF_BOXES
- ##############################################################################################
- vboxes, vi1, vj1, vi2, vj2 = bt.read_coor(vdic['FILE_DEF_BOXES'])
- nbb = len(vboxes)
- print ''
- # Checking presence of NEMO files:
- cfroot = vdic['CPREF']+cy+'0101_'+cy+'1231'
- cf_in_T = cfroot+'_grid_T.nc'; bt.chck4f(cf_in_T, script_name=cname_script)
- if luv:
- cf_in_U = cfroot+'_grid_U.nc'; bt.chck4f(cf_in_U, script_name=cname_script)
- cf_in_V = cfroot+'_grid_V.nc'; bt.chck4f(cf_in_V, script_name=cname_script)
-
- # Coordinates, mask and metrics:
- bt.chck4f(vdic['MM_FILE'], script_name=cname_script)
- id_mm = Dataset(vdic['MM_FILE'])
- Xmask = id_mm.variables['tmask'] [0,:,:,:]
- ze1t = id_mm.variables['e1t'] [0,:,:]
- ze2t = id_mm.variables['e2t'] [0,:,:]
- ve3t = id_mm.variables['e3t_1d'] [0,:]
- zlon = id_mm.variables['nav_lon'] [:,:]
- zlat = id_mm.variables['nav_lat'] [:,:]
- vzt = id_mm.variables['gdept_1d'][0,:]
- vzw = id_mm.variables['gdepw_1d'][0,:]
- id_mm.close()
- lqnet = False ; lqsw = False ; lpme = False; ltau = False
- # NEMO output, Grid T
- # ~~~~~~~~~~~~~~~~~~~
- id_in_T = Dataset(cf_in_T)
- list_variables = id_in_T.variables.keys()
- Vtime = id_in_T.variables['time_counter'][:]
- if vdic['NN_SST'] == 'thetao':
- Zsst = id_in_T.variables[vdic['NN_SST']][:,0,:,:]
- else:
- Zsst = id_in_T.variables[vdic['NN_SST']][:,:,:]
-
- if vdic['NN_SSS'] == 'so':
- Zsss = id_in_T.variables[vdic['NN_SSS']][:,0,:,:]
- else:
- Zsss = id_in_T.variables[vdic['NN_SSS']][:,:,:]
-
- Zssh = id_in_T.variables[vdic['NN_SSH']][:,:,:]
- Xtemp = id_in_T.variables[vdic['NN_T']][:,:,:,:]
- Xsali = id_in_T.variables[vdic['NN_S']][:,:,:,:]
- if 'sohefldo' in list_variables[:]:
- Zqnet = id_in_T.variables['sohefldo'] [:,:,:] ; # Net Downward Heat Flux
- lqnet = True
- if 'tohfls' in list_variables[:]:
- Zqnet = id_in_T.variables['tohfls'] [:,:,:] ; # Net Downward Heat Flux
- lqnet = True
-
- if 'soshfldo' in list_variables[:]:
- Zqsw = id_in_T.variables['soshfldo'] [:,:,:] ; # Shortwave Radiation
- lqsw = True
- if 'rsntds' in list_variables[:]:
- Zqsw = id_in_T.variables['rsntds'] [:,:,:] ; # Shortwave Radiation
- lqsw = True
- # Want PmE (positive when ocean gains FW), in NEMO files its the oposite EmP...
- if 'wfo' in list_variables[:]:
- Zpme = -id_in_T.variables['wfo'] [:,:,:] ; # wfo same as below = EmP, > 0 when ocean losing water
- lpme = True
- if 'sowaflup' in list_variables[:]:
- Zpme = -id_in_T.variables['sowaflup'] [:,:,:] ; # Net Downward Heat Flux
- # # sowaflup = EmP (>0 if more evaporation than P)
- lpme = True
-
- print '(has ',Xtemp.shape[0],' time snapshots)\n'
- id_in_T.close()
- [ Nt, nk, nj, ni ] = Xtemp.shape ; print 'Nt, nk, nj, ni =', Nt, nk, nj, ni
- Zss0 = sigma0( Zsst, Zsss )
- print len(ve3t[:])
- if len(ve3t[:]) != nk: print 'Problem with nk!!!'; sys.exit(0)
- # NEMO output, Grid U and V
- # ~~~~~~~~~~~~~~~~~~~~~~~~~
- if luv:
- id_in_U = Dataset(cf_in_U)
- list_variables = id_in_U.variables.keys()
- if vdic_uv['NN_TAUX'] in list_variables[:]:
- Ztaux = id_in_U.variables[vdic_uv['NN_TAUX']][:,:,:] ; # Net Downward Heat Flux
- ltau = True
- print vdic_uv['NN_TAUX']+' found in '+cf_in_U
- else:
- print vdic_uv['NN_TAUX']+' NOT found in '+cf_in_U
- id_in_U.close()
- id_in_V = Dataset(cf_in_V)
- list_variables = id_in_V.variables.keys()
- if ltau and vdic_uv['NN_TAUY'] in list_variables[:]:
- Ztauy = id_in_V.variables[vdic_uv['NN_TAUY']][:,:,:] ; # Net Downward Heat Flux
- print vdic_uv['NN_TAUY']+' found in '+cf_in_V+'\n'
- else:
- print vdic_uv['NN_TAUY']+' NOT found in '+cf_in_V
- ltau = False
- id_in_V.close()
- if ltau:
- # Must interpolate Taux and Tauy on T-grid:
- Ztau = nmp.zeros(Nt*nj*ni) ; Ztau.shape = [ Nt, nj, ni ]
- xtmp1 = nmp.zeros(nj*ni) ; xtmp1.shape = [ nj, ni ]
- xtmp2 = nmp.zeros(nj*ni) ; xtmp2.shape = [ nj, ni ]
- for jm in range(Nt):
- xtmp1[:,1:] = 0.5*(Ztaux[jm,:,1:]+Ztaux[jm,:,:ni-1]) ; # u on Tgrid
- xtmp2[1:,:] = 0.5*(Ztauy[jm,1:,:]+Ztauy[jm,:nj-1,:]) ; # v on Tgrid
- Ztau[jm,:,:] = nmp.sqrt(xtmp1*xtmp1 + xtmp2*xtmp2)
- #print Ztau[3,100,:]
- #del Ztaux, Ztaux, xtmp1, xtmp2
- jks = 0
- for jk in range(nk-1):
- if zs >= vzw[jk] and zs < vzw[jk+1]: jks = jk+1
- czs = str(int(round(vzw[jks],0))) ; print czs
- print ' *** for depth '+czs+': jks = '+str(jks)+', depthw = '+str(vzw[jks])+' => '+czs+'m'
- print ' => will average from jk=0 to jk='+str(jks)+'-1 on T-points => X[:jks-1]'
- jks = jks - 1
- print ' => that\'s on T-points from jk=0 to jk='+str(jks)+' (depth of deepest T-point used ='+str(vzt[jks])+'m)'
- # Loop along boxes:
- for jb in range(nbb):
- cbox = vboxes[jb]
- i1 = vi1[jb]
- j1 = vj1[jb]
- i2 = vi2[jb]+1
- j2 = vj2[jb]+1
-
- print '\n *** Treating box '+cbox+' => ', i1, j1, i2-1, j2-1
- # Filling box arrays:
- # ~~~~~~~~~~~~~~~~~~~
- nx_b = i2 - i1
- ny_b = j2 - j1
- shape_array = [ Nt, nk, ny_b, nx_b ]
- XVolu = nmp.zeros(nk*ny_b*nx_b) ; XVolu.shape = [ nk, ny_b, nx_b ]
- ZArea = nmp.zeros( ny_b*nx_b) ; ZArea.shape = [ ny_b, nx_b ]
- Ztmp = nmp.zeros( ny_b*nx_b) ; Ztmp.shape = [ ny_b, nx_b ]
- Xs0 = nmp.zeros(nk*ny_b*nx_b) ; Xs0.shape = [ nk, ny_b, nx_b ]
- ssh_m = nmp.zeros(Nt) ; ssh_m.shape = [ Nt ]
- sst_m = nmp.zeros(Nt) ; sst_m.shape = [ Nt ]
- sss_m = nmp.zeros(Nt) ; sss_m.shape = [ Nt ]
- ss0_m = nmp.zeros(Nt) ; ss0_m.shape = [ Nt ]
- surf_T_m = nmp.zeros(Nt) ; surf_T_m.shape = [ Nt ]
- surf_S_m = nmp.zeros(Nt) ; surf_S_m.shape = [ Nt ]
- surf_s0_m = nmp.zeros(Nt) ; surf_s0_m.shape = [ Nt ]
- T_m = nmp.zeros(Nt) ; T_m.shape = [ Nt ]
- Tau_m = nmp.zeros(Nt) ; Tau_m.shape = [ Nt ]
- Qnet_m = nmp.zeros(Nt) ; Qnet_m.shape = [ Nt ]
- Qnet_x_S_m = nmp.zeros(Nt) ; Qnet_x_S_m.shape = [ Nt ]
- Qsw_m = nmp.zeros(Nt) ; Qsw_m.shape = [ Nt ]
- Qsw_x_S_m = nmp.zeros(Nt) ; Qsw_x_S_m.shape = [ Nt ]
- PmE_m = nmp.zeros(Nt) ; PmE_m.shape = [ Nt ]
- H_m = nmp.zeros(Nt) ; H_m.shape = [ Nt ] ; # Heat coNtent
- S_m = nmp.zeros(Nt) ; S_m.shape = [ Nt ]
- Vol_m = nmp.zeros(Nt) ; Vol_m.shape = [ Nt ] ; # Volume derived from SSH!
-
-
-
-
- # On the sea of the box only:
-
- ZArea[:,:] = ze1t[j1:j2, i1:i2]*ze2t[j1:j2, i1:i2]
-
- for jk in range(nk): XVolu[jk,:,:] = Xmask[jk, j1:j2, i1:i2]*ZArea[:,:]*ve3t[jk]
- ZArea[:,:] = Xmask[0, j1:j2, i1:i2]*ZArea[:,:]
- #if l_plot_debug: bp.check_with_fig_2(ZArea, ZArea*0.+1., 'ZArea', fig_type=FIG_FORM)
-
- Tot_area = nmp.sum(ZArea) ; print 'Total area of '+cbox+' (m^2): ', Tot_area
-
- Tot_vol = nmp.sum(XVolu)
-
- Tot_vol_jks = nmp.sum(XVolu[:jks,:,:])
-
-
- for jm in range(Nt):
-
-
- # 3D sigma0 density for current month
- Xs0[:,:,:] = 0.
- Xs0[:,:,:] = sigma0( Xtemp[jm,:, j1:j2, i1:i2], Xsali[jm,:, j1:j2, i1:i2] )
- # Mean SSH
- ssh_m[jm] = nmp.sum(Zssh[jm, j1:j2, i1:i2]*ZArea) / Tot_area
- # Mean SST
- sst_m[jm] = nmp.sum(Zsst[jm, j1:j2, i1:i2]*ZArea) / Tot_area
- # Mean SSS
- sss_m[jm] = nmp.sum(Zsss[jm, j1:j2, i1:i2]*ZArea) / Tot_area
- # Mean SS0
- ss0_m[jm] = nmp.sum(Zss0[jm, j1:j2, i1:i2]*ZArea) / Tot_area
-
- # Mean surface temp (first Xm)
- surf_T_m[jm] = nmp.sum(Xtemp[jm, :jks, j1:j2, i1:i2]*XVolu[:jks,:,:]) / Tot_vol_jks
-
- # Mean temperature
- T_m[jm] = nmp.sum(Xtemp[jm, : , j1:j2, i1:i2]*XVolu[:,:,:]) / Tot_vol
-
- # Heat content in Peta Joules:
- H_m[jm] = nmp.sum(Xtemp[jm,:, j1:j2, i1:i2]*(XVolu/1.E6))*rho0*rCp * 1.E-9 ; # => PJ (E15)
- # Mean surface salinity (first Xm)
- surf_S_m[jm] = nmp.sum(Xsali[jm,:jks, j1:j2, i1:i2]*XVolu[:jks,:,:]) / Tot_vol_jks
- # Mean salinity
- S_m[jm] = nmp.sum(Xsali[jm,:, j1:j2, i1:i2]*XVolu) / Tot_vol
-
-
- # Mean surface sigma0 density (first Xm)
- surf_s0_m[jm] = nmp.sum(Xs0[:jks,:,:]*XVolu[:jks,:,:]) / Tot_vol_jks
-
-
- # Sea-ice area
- #Aice_m[jm] = nmp.sum(Zicec[jm,:,:]*ZArea) * 1.E-12; # Million km^2
-
-
- # For open-sea:
- #Ztmp[:,:] = 1. - Zicec[jm,:,:] ; # 1 => 100% open sea / 0 => 100% ice
- Ztmp[:,:] = 1.
-
-
- # ZArea is in m^2
- if ltau:
- # Surface wind stress:
- Tau_m[jm] = nmp.sum(Ztau[jm, j1:j2, i1:i2]*ZArea) / Tot_area
-
- # Surface heat flux
- if lqnet:
- rr = nmp.sum(Zqnet[jm, j1:j2, i1:i2]*ZArea)
- Qnet_m[jm] = rr / Tot_area # W/m^2
- Qnet_x_S_m[jm] = rr * 1.E-15 # PW
-
- # Shortwave heat flux
- if lqsw:
- rr = nmp.sum(Zqsw[jm, j1:j2, i1:i2]*ZArea)
- Qsw_m[jm] = rr / Tot_area # W/m^2
- Qsw_x_S_m[jm] = rr * 1.E-15 # PW
-
- # PmE
- if lpme: PmE_m[jm] = nmp.sum( Zpme[jm, j1:j2, i1:i2]*ZArea) * 1.E-9; # (Sv) 1 kg/m^2/s x S => 1E-3 m^3/s
- # # 1 Sv = 1E6 m^3
-
- # Volume associated with SSH
- Vol_m[jm] = nmp.sum(Zssh[jm, j1:j2, i1:i2]*ZArea) * 1.E-9; # km^3
-
-
-
- if l_plot_debug:
- VMN = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]
- print ' *** month ', str(jm+1), '***'
- print 'Mean sst = ', sst_m[jm]
- print 'Mean ssh = ', ssh_m[jm]
- print 'Mean sss (0-'+czs+'m) = ', sss_m[jm]
- print 'Mean ss0 (0-'+czs+'m) = ', ss0_m[jm]
- print 'Mean T = ', T_m[jm]
- print 'Heat content (PJ) / ref T=0C => ', H_m[jm]
- if jm>0: print 'Volume heat flux (PW) / ref T=0C => ', (H_m[jm] - H_m[jm-1]) / (VMN[jm-1]*24.*3600.)
- print 'Mean S = ', S_m[jm]
- #print 'Sea-ice (10^6 km^2) = ', Aice_m[jm]
- print 'Shortwave Radiation (PW) = ', Qsw_m[jm]
- print 'Net surface heat flux (PW) = ', Qnet_m[jm], '\n'
- print 'Surface freshwater flux (Sv) = ', PmE_m[jm], '\n'
- print 'Volume associated with SSH (km^3) = ', Vol_m[jm], '\n'
-
- Vtime = nmp.zeros(Nt)
- for jm in range(Nt): Vtime[jm] = float(jy) + (float(jm)+0.5)/12.
-
- cc = 'Box-averaged '
- cf_out = vdic['DIAG_D']+'/budget_'+CONFEXP+'_box_'+cbox+'.nc'
-
- bnc.wrt_appnd_1d_series(Vtime, ssh_m, cf_out, 'ssh', cu_t='year', cu_d='m', cln_d=cc+'sea surface height',
- vd2=sst_m, cvar2='sst', cln_d2=cc+'sea surface temperature', cun2='deg.C',
- vd3=sss_m, cvar3='sss', cln_d3=cc+'sea surface salinity', cun3='PSU',
- vd4=surf_T_m, cvar4='surf_T', cln_d4=cc+'Temperature (first '+czs+'m)', cun4='deg.C',
- vd5=T_m, cvar5='theta', cln_d5=cc+'potential temperature', cun5='deg.C',
- vd6=H_m, cvar6='HC', cln_d6=cc+'heat content', cun6='PJ',
- vd7=surf_S_m, cvar7='surf_S', cln_d7=cc+'salinity (first '+czs+'m)', cun7='PSU',
- vd8=S_m, cvar8='S', cln_d8=cc+'salinity', cun8='PSU',
- vd9=ss0_m, cvar9='SSs0', cln_d9=cc+'sea surface sigma0 (sst&sss)', cun9='',
- vd10=surf_s0_m,cvar10='surf_s0', cln_d10=cc+'surface sigma0 (first '+czs+'m)', cun10=''
- )
-
- cf_out = vdic['DIAG_D']+'/budget_srf_flx_'+CONFEXP+'_box_'+cbox+'.nc'
-
- bnc.wrt_appnd_1d_series(Vtime, Qnet_m, cf_out, 'Qnet', cu_t='year', cu_d='W/m^2', cln_d=cc+'net heat flux',
- vd2=Qnet_x_S_m, cvar2='Qnet_x_S', cln_d2=cc+'net heat flux x Surface', cun2='PW',
- vd3=Qsw_m, cvar3='Qsw', cln_d3=cc+'solar radiation', cun3='W/m^2',
- vd4=Qsw_x_S_m, cvar4='Qsw_x_S', cln_d4=cc+'solar radiation x Surface', cun4='PW',
- vd5=PmE_m, cvar5='PmE', cln_d5=cc+'net freshwater flux', cun5='Sv',
- vd6=Tau_m, cvar6='Tau', cln_d6=cc+'wind stress module', cun6='N/m^2'
- )
|