- Timestamp:
- 10/10/23 12:58:04 (7 months ago)
- Location:
- TOOLS/WATER_BUDGET
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
TOOLS/WATER_BUDGET/ATM_waterbudget.py
r6620 r6647 34 34 raise Exception ( "Minimum Python version is 3.8" ) 35 35 36 ## Import local module 36 ## Import local modules 37 37 import WaterUtils as wu 38 38 import libIGCM_sys 39 39 import nemo, lmdz 40 41 from WaterUtils import VarInt, Rho, Ra, Grav, ICE_rho_ice, ICE_rho_sno, OCE_rho_liq, ATM_rho, SRF_rho, RUN_rho, ICE_rho_pnd, YearLength 40 42 41 43 ## Creates parser for reading .ini input file … … 47 49 ## --------------------- 48 50 ATM=None ; ATM_HIS='latlon' ; SRF_HIS='latlon' ; RUN_HIS='latlon' ; ORCA=None ; NEMO=None ; OCE_relax=False 49 OCE_icb=False ; Coupled=False ; Routing=None 51 OCE_icb=False ; Coupled=False ; Routing=None ; TestInterp=None 50 52 TarRestartPeriod_beg=None ; TarRestartPeriod_end=None ; Comment=None ; Period=None ; Title=None 53 YearBegin=None ; YearEnd=None ; DateBegin=None ; DateEnd=None 51 54 52 55 ## … … 66 69 tar_restart_end_RUN=None ; tar_restart_end_OCE=None ; tar_restart_end_ICE=None 67 70 ContinueOnError=False ; ErrorCount=0 ; SortIco = False 71 72 ## 73 ## Precision of history file reading 74 ## --------------------------------- 75 # Default is float (full precision). Degrade the precision by using np.float32 76 # Restart file are always read at the full precision 77 readPrec=float 68 78 69 79 ## Read command line arguments … … 138 148 print ( f'\nConfig file readed : {IniFile} ' ) 139 149 150 ## 151 ## Reading prec 152 if wu.unDefined ( 'readPrec' ) : 153 readPrec = np.float64 154 else : 155 if readPrec in ["float", "float64", "r8", "double", "<class 'float'>" ] : readPrec = float 156 if readPrec in [ "float32", "r4", "single", "<class 'numpy.float32'>" ] : readPrec = np.float32 157 if readPrec in [ "float16", "r2", "half" , "<class 'numpy.float16'>" ] : readPrec = np.float16 158 140 159 ## Some physical constants 141 160 ## ======================= … … 155 174 if not 'Files' in config.keys () : config['Files'] = {} 156 175 157 config['Physics'] = { 'Ra': Ra, 'Grav':Grav, 'ICE_rho_ice':ICE_rho_ice, 'ICE_rho_sno':ICE_rho_sno,158 'OCE_rho_liq': OCE_rho_liq, 'ATM_rho':ATM_rho, 'SRF_rho':SRF_rho, 'RUN_rho':RUN_rho}159 160 config['Config'] = { 'ContinueOnError': ContinueOnError, 'SortIco':SortIco}176 config['Physics'] = { 'Ra':str(Ra), 'Grav':str(Grav), 'ICE_rho_ice':str(ICE_rho_ice), 'ICE_rho_sno':str(ICE_rho_sno), 177 'OCE_rho_liq':str(OCE_rho_liq), 'ATM_rho':str(ATM_rho), 'SRF_rho':str(SRF_rho), 'RUN_rho':str(RUN_rho)} 178 179 config['Config'] = { 'ContinueOnError':str(ContinueOnError), 'SortIco':str(SortIco), 'TestInterp':str(TestInterp), 'readPrec':str(readPrec) } 161 180 162 181 ## -------------------------- … … 176 195 if wu.unDefined ( 'DateBegin' ) : 177 196 DateBegin = f'{YearBegin}0101' 178 config['Experiment']['DateBegin'] = DateBegin197 config['Experiment']['DateBegin'] = str(DateBegin) 179 198 else : 180 YearBegin, MonthBegin, DayBegin = wu. DateSplit( DateBegin )181 DateBegin = wu.FormatToGregorian ( 182 config['Experiment']['YearBegin'] = YearBegin199 YearBegin, MonthBegin, DayBegin = wu.SplitDate ( DateBegin ) 200 DateBegin = wu.FormatToGregorian (DateBegin) 201 config['Experiment']['YearBegin'] = str(YearBegin) 183 202 184 203 if wu.unDefined ( 'DateEnd' ) : 185 204 DateEnd = f'{YearEnd}1231' 186 config['Experiment']['DateEnd'] = DateEnd205 config['Experiment']['DateEnd'] = str(DateEnd) 187 206 else : 188 YearEnd, MonthEnd, DayEnd = wu.DateSplit ( DateEnd ) 189 DateEnd = wu.FormatToGregorian ( DateEnd) 207 YearEnd, MonthEnd, DayEnd = wu.SplitDate ( DateEnd ) 208 DateEnd = wu.FormatToGregorian (DateEnd) 209 config['Experiment']['DateEnd'] = str(DateEnd) 190 210 191 211 if wu.unDefined ( 'PackFrequency' ) : … … 200 220 ## Output file with water budget diagnostics 201 221 ## ----------------------------------------- 202 if wu.unDefined ( 'FileOut' ) : FileOut = f'ATM_waterbudget_{JobName}_{DateBegin}_{DateEnd}.out' 222 if wu.unDefined ( 'FileOut' ) : 223 FileOut = f'ATM_waterbudget_{JobName}_{YearBegin}_{YearEnd}' 224 if ICO : 225 if ATM_HIS == 'latlon' : FileOut = f'{FileOut}_LATLON' 226 if ATM_HIS == 'ico' : FileOut = f'{FileOut}_ICO' 227 if readPrec == np.float32 : FileOut = f'{FileOut}_float32' 228 FileOut = f'{FileOut}.out' 229 203 230 config['Files']['FileOut'] = FileOut 204 231 … … 207 234 ## Useful functions 208 235 ## ---------------- 236 if readPrec == float : 237 def rprec (tab) : return tab 238 else : 239 def rprec (tab) : return tab.astype(readPrec).astype(float) 240 209 241 def kg2Sv (val, rho=ATM_rho) : 210 242 '''From kg to Sverdrup''' … … 216 248 217 249 def var2prt (var, small=False, rho=ATM_rho) : 218 if small : return var , kg2Sv(var, rho=rho)*1000., kg2myear(var, rho=rho)*100 #250 if small : return var , kg2Sv(var, rho=rho)*1000., kg2myear(var, rho=rho)*1000 219 251 else : return var , kg2Sv(var, rho=rho) , kg2myear(var, rho=rho) 220 252 … … 236 268 f_out.flush () 237 269 return None 238 270 271 echo ( f'{ContinueOnError = }' ) 272 echo ( f'{SortIco = }' ) 273 echo ( f'{readPrec = }' ) 274 275 echo ( f'{JobName = }' ) 276 echo ( f'{ConfigCard = }' ) 277 echo ( f'{libIGCM = }' ) 278 echo ( f'{User = }' ) 279 echo ( f'{Group = }' ) 280 echo ( f'{Freq = }' ) 281 echo ( f'{YearBegin = }' ) 282 echo ( f'{YearEnd = }' ) 283 echo ( f'{DateBegin = }' ) 284 echo ( f'{DateEnd = }' ) 285 echo ( f'{PackFrequency = }' ) 286 echo ( f'{ATM = }' ) 287 echo ( f'{Routing = }' ) 288 echo ( f'{ORCA = }' ) 289 echo ( f'{NEMO = }' ) 290 echo ( f'{Coupled = }' ) 291 echo ( f'{ATM_HIS = }' ) 292 echo ( f'{SRF_HIS = }' ) 293 echo ( f'{RUN_HIS = }' ) 294 239 295 ## Set libIGCM directories 240 296 ## ----------------------- … … 266 322 267 323 echo (' ') 268 echo ( f'JobName : {JobName}')269 echo ( f'Comment : {Comment}')270 echo ( f'TmpDir : {TmpDir}')324 echo ( f'JobName : {JobName}' ) 325 echo ( f'Comment : {Comment}' ) 326 echo ( f'TmpDir : {TmpDir}' ) 271 327 echo ( f'FileDir : {FileDir}' ) 272 328 echo ( f'FileDirOCE : {FileDirOCE}' ) … … 598 654 # ATM grid with cell surfaces 599 655 if LMDZ : 600 ATM_lat = lmdz.geo2point ( d_ATM_his ['lat']+0*d_ATM_his ['lon'], dim1D='cell_latlon' ) 601 ATM_lon = lmdz.geo2point ( 0*d_ATM_his ['lat']+ d_ATM_his ['lon'], dim1D='cell_latlon' ) 602 ATM_aire = lmdz.geo2point ( d_ATM_his ['aire'] [0], cumulPoles=True, dim1D='cell_latlon' ) 603 ATM_fter = lmdz.geo2point ( d_ATM_his ['fract_ter'][0], dim1D='cell_latlon' ) 604 ATM_foce = lmdz.geo2point ( d_ATM_his ['fract_oce'][0], dim1D='cell_latlon' ) 605 ATM_fsic = lmdz.geo2point ( d_ATM_his ['fract_sic'][0], dim1D='cell_latlon' ) 606 ATM_flic = lmdz.geo2point ( d_ATM_his ['fract_lic'][0], dim1D='cell_latlon' ) 607 SRF_lat = lmdz.geo2point ( d_SRF_his ['lat']+0*d_SRF_his ['lon'], dim1D='cell_latlon' ) 608 SRF_lon = lmdz.geo2point ( 0*d_SRF_his ['lat']+ d_SRF_his ['lon'], dim1D='cell_latlon' ) 609 SRF_aire = lmdz.geo2point ( d_SRF_his ['Areas'] * d_SRF_his ['Contfrac'], dim1D='cell_latlonl', cumulPoles=True ) 610 SRF_areas = lmdz.geo2point ( d_SRF_his ['Areas'], dim1D='cell_latlonl', cumulPoles=True ) 611 SRF_contfrac = lmdz.geo2point ( d_SRF_his ['Contfrac'], dim1D='cell_latlonl' ) 612 613 #SRF_res_aire = SRF_aire 614 656 echo ('ATM grid with cell surfaces : LMDZ') 657 ATM_lat = lmdz.geo2point ( rprec (d_ATM_his ['lat'])+0*rprec (d_ATM_his ['lon']), dim1D='cell' ) 658 ATM_lon = lmdz.geo2point ( 0*rprec (d_ATM_his ['lat'])+ rprec (d_ATM_his ['lon']), dim1D='cell' ) 659 ATM_aire = lmdz.geo2point ( rprec (d_ATM_his ['aire'] ) [0], cumulPoles=True, dim1D='cell' ) 660 ATM_fter = lmdz.geo2point ( rprec (d_ATM_his ['fract_ter'][0]), dim1D='cell' ) 661 ATM_foce = lmdz.geo2point ( rprec (d_ATM_his ['fract_oce'][0]), dim1D='cell' ) 662 ATM_fsic = lmdz.geo2point ( rprec (d_ATM_his ['fract_sic'][0]), dim1D='cell' ) 663 ATM_flic = lmdz.geo2point ( rprec (d_ATM_his ['fract_lic'][0]), dim1D='cell' ) 664 SRF_lat = lmdz.geo2point ( rprec (d_SRF_his ['lat'])+0*rprec (d_SRF_his ['lon']), dim1D='cell' ) 665 SRF_lon = lmdz.geo2point ( 0*rprec (d_SRF_his ['lat'])+ rprec (d_SRF_his ['lon']), dim1D='cell' ) 666 SRF_aire = lmdz.geo2point ( rprec (d_SRF_his ['Areas']) * rprec (d_SRF_his ['Contfrac']), dim1D='cell', cumulPoles=True ) 667 SRF_areas = lmdz.geo2point ( rprec (d_SRF_his ['Areas']) , dim1D='cell', cumulPoles=True ) 668 SRF_contfrac = lmdz.geo2point ( rprec (d_SRF_his ['Contfrac']), dim1D='cell' ) 669 615 670 if ICO : 616 671 if ATM_HIS == 'latlon' : 617 jpja, jpia = d_ATM_his['aire'][0].shape 618 if wu.unDefined ( 'file_ATM_aire' ) : 619 file_ATM_aire = os.path.join ( R_IN, 'ATM', 'GRID', f'aire_{ATM}_to_{jpia}x{jpja}.nc' ) 620 config['Files']['file_ATM_aire'] = file_ATM_aire 621 echo ( f'Aire sur grille reguliere : {file_ATM_aire = }' ) 622 d_ATM_aire = xr.open_dataset ( file_ATM_aire, decode_times=False ).squeeze() 623 try : 624 ATM_lat = lmdz.geo2point ( d_ATM_his ['lat']+0*d_ATM_his ['lon'], dim1D='cell_latlon' ) 625 ATM_lon = lmdz.geo2point ( 0*d_ATM_his ['lat']+ d_ATM_his ['lon'], dim1D='cell_latlon' ) 626 except : 627 ATM_lat = lmdz.geo2point ( d_ATM_his ['lat_dom_out']+0*d_ATM_his ['lon_dom_out'], dim1D='cell_latlon' ) 628 ATM_lon = lmdz.geo2point ( 0*d_ATM_his ['lat_dom_out']+ d_ATM_his ['lon_dom_out'], dim1D='cell_latlon' ) 629 ATM_aire = lmdz.geo2point ( d_ATM_aire ['aire'].squeeze(), cumulPoles=True, dim1D='cell_latlon' ) 630 ATM_fter = lmdz.geo2point ( d_ATM_his ['fract_ter'][0], dim1D='cell_latlon' ) 631 ATM_foce = lmdz.geo2point ( d_ATM_his ['fract_oce'][0], dim1D='cell_latlon' ) 632 ATM_fsic = lmdz.geo2point ( d_ATM_his ['fract_sic'][0], dim1D='cell_latlon' ) 633 ATM_flic = lmdz.geo2point ( d_ATM_his ['fract_lic'][0], dim1D='cell_latlon' ) 672 echo ( 'ATM areas and fractions on latlon grid' ) 673 if 'lat_dom_out' in d_ATM_his.variables : 674 ATM_lat = lmdz.geo2point ( rprec (d_ATM_his ['lat_dom_out'])+0*rprec (d_ATM_his ['lon_dom_out']), dim1D='cell' ) 675 ATM_lon = lmdz.geo2point ( 0*rprec (d_ATM_his ['lat_dom_out'])+ rprec (d_ATM_his ['lon_dom_out']), dim1D='cell' ) 676 else : 677 ATM_lat = lmdz.geo2point ( rprec (d_ATM_his ['lat'])+0*rprec (d_ATM_his ['lon']), dim1D='cell' ) 678 ATM_lon = lmdz.geo2point ( 0*rprec (d_ATM_his ['lat'])+ rprec (d_ATM_his ['lon']), dim1D='cell' ) 679 ATM_aire = lmdz.geo2point ( rprec (d_ATM_his ['aire'][0]).squeeze(), cumulPoles=True, dim1D='cell' ) 680 ATM_fter = lmdz.geo2point ( rprec (d_ATM_his ['fract_ter'][0]), dim1D='cell' ) 681 ATM_foce = lmdz.geo2point ( rprec (d_ATM_his ['fract_oce'][0]), dim1D='cell' ) 682 ATM_fsic = lmdz.geo2point ( rprec (d_ATM_his ['fract_sic'][0]), dim1D='cell' ) 683 ATM_flic = lmdz.geo2point ( rprec (d_ATM_his ['fract_lic'][0]), dim1D='cell' ) 684 685 if ATM_HIS == 'ico' : 686 echo ( 'ATM areas and fractions on ICO grid' ) 687 ATM_aire = rprec (d_ATM_his ['aire'] [0])[ATM_his_keysort].squeeze() 688 ATM_lat = rprec (d_ATM_his ['lat'] )[ATM_his_keysort] 689 ATM_lon = rprec (d_ATM_his ['lon'] )[ATM_his_keysort] 690 ATM_fter = rprec (d_ATM_his ['fract_ter'][0])[ATM_his_keysort] 691 ATM_foce = rprec (d_ATM_his ['fract_oce'][0])[ATM_his_keysort] 692 ATM_fsic = rprec (d_ATM_his ['fract_sic'][0])[ATM_his_keysort] 693 ATM_flic = rprec (d_ATM_his ['fract_lic'][0])[ATM_his_keysort] 634 694 635 695 if SRF_HIS == 'latlon' : 636 try : 637 SRF_lat = lmdz.geo2point ( d_SRF_his ['lat']+0*d_SRF_his ['lon'], dim1D='cell_latlon' ) 638 SRF_lon = lmdz.geo2point ( 0*d_SRF_his ['lat']+ d_SRF_his ['lon'], dim1D='cell_latlon' ) 639 except : 640 try : 641 SRF_lat = lmdz.geo2point ( d_SRF_his ['lat_dom_out']+0*d_SRF_his ['lon_dom_out'], dim1D='cell_latlon' ) 642 SRF_lon = lmdz.geo2point ( 0*d_SRF_his ['lat_dom_out']+ d_SRF_his ['lon_dom_out'], dim1D='cell_latlon' ) 643 except : 644 SRF_lat = lmdz.geo2point ( d_SRF_his ['lat_domain_landpoints_out']+0*d_SRF_his ['lon_domain_landpoints_out'], dim1D='cell_latlon' ) 645 SRF_lon = lmdz.geo2point ( 0*d_SRF_his ['lat_domain_landpoints_out']+ d_SRF_his ['lon_domain_landpoints_out'], dim1D='cell_latlon' ) 646 SRF_areas = d_SRF_his ['Areas'].values 647 SRF_areafrac = d_SRF_his ['AreaFrac'].values 648 SRF_areas = xr.DataArray ( SRF_areas , coords=d_SRF_his ['Contfrac'].coords, dims=d_SRF_his ['Contfrac'].dims) 649 SRF_areafrac = xr.DataArray ( SRF_areafrac, coords=d_SRF_his ['Contfrac'].coords, dims=d_SRF_his ['Contfrac'].dims) 650 651 SRF_areas = lmdz.geo2point ( SRF_areas , dim1D='cell_latlon', cumulPoles=True ) 652 SRF_areafrac = lmdz.geo2point ( SRF_areafrac, dim1D='cell_latlon', cumulPoles=True ) 653 SRF_contfrac = SRF_areafrac / SRF_areas 654 SRF_aire = SRF_areafrac 655 656 if ATM_HIS == 'ico' : 657 echo ( f'Grille icosaedre' ) 658 ATM_aire = d_ATM_his ['aire'] [0][ATM_his_keysort].squeeze() 659 ATM_lat = d_ATM_his ['lat'] [ATM_his_keysort] 660 ATM_lon = d_ATM_his ['lon'] [ATM_his_keysort] 661 ATM_fter = d_ATM_his ['fract_ter'][0][ATM_his_keysort] 662 ATM_foce = d_ATM_his ['fract_oce'][0][ATM_his_keysort] 663 ATM_fsic = d_ATM_his ['fract_sic'][0][ATM_his_keysort] 664 ATM_flic = d_ATM_his ['fract_lic'][0][ATM_his_keysort] 665 666 if SRF_HIS == 'ico' : 667 SRF_lat = d_SRF_his ['lat'] [SRF_his_keysort] 668 SRF_lon = d_SRF_his ['lon'] [SRF_his_keysort] 669 SRF_areas = d_SRF_his ['Areas'] [SRF_his_keysort] 670 #SRF_areafrac = d_SRF_his ['AreaFrac'] [SRF_his_keysort] 671 SRF_contfrac = d_SRF_his ['Contfrac'][SRF_his_keysort] 696 echo ( 'SRF areas and fractions on latlon grid' ) 697 if 'lat_domain_landpoints_out' in d_SRF_his : 698 SRF_lat = lmdz.geo2point ( rprec (d_SRF_his ['lat_domain_landpoints_out'])+0*rprec (d_SRF_his ['lon_domain_landpoints_out']), dim1D='cell' ) 699 SRF_lon = lmdz.geo2point ( 0*rprec (d_SRF_his ['lat_domain_landpoints_out'])+ rprec (d_SRF_his ['lon_domain_landpoints_out']), dim1D='cell' ) 700 else : 701 if 'lat_domain_landpoints_out' in d_SRF_his : 702 SRF_lat = lmdz.geo2point ( rprec (d_SRF_his ['lat_dom_out'])+0*rprec (d_SRF_his ['lon_dom_out']), dim1D='cell' ) 703 SRF_lon = lmdz.geo2point ( 0*rprec (d_SRF_his ['lat_dom_out'])+ rprec (d_SRF_his ['lon_dom_out']), dim1D='cell' ) 704 else : 705 SRF_lat = lmdz.geo2point ( rprec (d_SRF_his ['lat'])+0*rprec (d_SRF_his ['lon']), dim1D='cell' ) 706 SRF_lon = lmdz.geo2point ( 0*rprec (d_SRF_his ['lat'])+ rprec (d_SRF_his ['lon']), dim1D='cell' ) 707 708 SRF_areas = lmdz.geo2point ( rprec (d_SRF_his ['Areas'] ) , dim1D='cell', cumulPoles=True ) 709 SRF_areafrac = lmdz.geo2point ( rprec (d_SRF_his ['AreaFrac']) , dim1D='cell', cumulPoles=True ) 710 SRF_contfrac = lmdz.geo2point ( rprec (d_SRF_his ['Contfrac']) , dim1D='cell', cumulPoles=True ) 711 SRF_aire = SRF_areafrac 712 713 if SRF_HIS == 'ico' : 714 echo ( 'SRF areas and fractions on latlon grid' ) 715 SRF_lat = rprec (d_SRF_his ['lat'] ) [SRF_his_keysort] 716 SRF_lon = rprec (d_SRF_his ['lon'] ) [SRF_his_keysort] 717 SRF_areas = rprec (d_SRF_his ['Areas'] ) [SRF_his_keysort] 718 SRF_contfrac = rprec (d_SRF_his ['Contfrac']) [SRF_his_keysort] 672 719 SRF_aire = SRF_areas * SRF_contfrac 673 720 … … 681 728 ATM_aire_fsea = ATM_aire * ATM_fsea 682 729 683 SRF_aire = SRF_aire.where ( np.abs (SRF_aire) < 1E15, 0. )730 #SRF_aire = SRF_aire.where ( np.abs (SRF_aire) < 1E15, 0. ) 684 731 685 732 ## Write the full configuration … … 713 760 DYN_fsea = ATM_fsea 714 761 DYN_flnd = ATM_flnd 715 DYN_fter = d_ATM_beg['FTER']716 DYN_flic = d_ATM_beg['FLIC']762 DYN_fter = rprec (d_ATM_beg['FTER']) 763 DYN_flic = rprec (d_ATM_beg['FLIC']) 717 764 DYN_aire_fter = DYN_aire * DYN_fter 718 765 … … 728 775 return ATM_flux_int 729 776 777 def LIC_flux_int (flux) : 778 '''Integrate (* time * surface) flux on land ice grid''' 779 LIC_flux_int = wu.Psum ( (flux * dtime_per_sec * ATM_aire_flic).to_masked_array().ravel() ) 780 return LIC_flux_int 781 730 782 def SRF_stock_int (stock) : 731 783 '''Integrate (* surface) stock on land grid''' … … 749 801 return ONE_flux_int 750 802 803 def Sprec ( tlist ) : 804 '''Accurate sum of list of scalar elements''' 805 return wu.Psum ( np.array ( tlist) ) 806 751 807 ATM_aire_sea = ATM_aire * ATM_fsea 808 752 809 ATM_aire_tot = ONE_stock_int (ATM_aire) 753 ATM_aire_sea_tot = ONE_stock_int (ATM_aire*ATM_fsea) 754 755 DYN_aire_tot = ONE_stock_int ( DYN_aire ) 756 SRF_aire_tot = ONE_stock_int ( SRF_aire ) 810 ATM_aire_sea_tot = ONE_stock_int (ATM_aire_fsea) 811 ATM_aire_ter_tot = ONE_stock_int (ATM_aire_fter) 812 ATM_aire_lic_tot = ONE_stock_int (ATM_aire_flic) 813 814 DYN_aire_tot = ONE_stock_int ( DYN_aire ) 815 SRF_aire_tot = ONE_stock_int ( SRF_aire ) 757 816 758 817 echo ('') 759 echo ( f'ATM DYN : Area of atmosphere : {DYN_aire_tot:18.9e}' ) 760 echo ( f'ATM HIS : Area of atmosphere : {ATM_aire_tot:18.9e}' ) 761 echo ( f'ATM SRF : Area of atmosphere : {SRF_aire_tot:18.9e}' ) 818 echo ( f'ATM DYN : Area of atmosphere : {DYN_aire_tot:18.9e}' ) 819 echo ( f'ATM HIS : Area of atmosphere : {ATM_aire_tot:18.9e}' ) 820 echo ( f'ATM HIS : Area of ter in atmosphere : {ATM_aire_ter_tot:18.9e}' ) 821 echo ( f'ATM HIS : Area of lic in atmosphere : {ATM_aire_lic_tot:18.9e}' ) 822 echo ( f'ATM SRF : Area of atmosphere : {SRF_aire_tot:18.9e}' ) 762 823 echo ('') 763 echo ( 'ATM DYN : Area of atmosphere/(4pi R^2) : {:18.9f}'.format(DYN_aire_tot/(Ra*Ra*4*np.pi) ) ) 764 echo ( 'ATM HIS : Area of atmosphere/(4pi R^2) : {:18.9f}'.format(ATM_aire_tot/(Ra*Ra*4*np.pi) ) ) 765 echo ( 'ATM SRF : Area of atmosphere/(4pi R^2) : {:18.9f}'.format(SRF_aire_tot/(Ra*Ra*4*np.pi) ) ) 824 echo ( 'ATM DYN : Area of atmosphere/(4pi R^2) : {:18.9f}'.format(DYN_aire_tot/(Ra*Ra*4*np.pi) ) ) 825 echo ( 'ATM HIS : Area of atmosphere/(4pi R^2) : {:18.9f}'.format(ATM_aire_tot/(Ra*Ra*4*np.pi) ) ) 826 echo ( 'ATM HIS : Area of ter in atmosphere/(4pi R^2) : {:18.9f}'.format(ATM_aire_ter_tot/(Ra*Ra*4*np.pi) ) ) 827 echo ( 'ATM SRF : Area of atmosphere/(4pi R^2) : {:18.9f}'.format(SRF_aire_tot/(Ra*Ra*4*np.pi) ) ) 766 828 echo ('') 767 829 echo ( f'ATM SRF : Area of atmosphere (no contfrac): {ONE_stock_int (SRF_areas):18.9e}' ) … … 786 848 DYN_psol_end = d_DYN_end['ps'][DYN_end_keysort] 787 849 if LMDZ : 788 DYN_psol_beg = lmdz.geo2point ( d_DYN_beg['ps'].isel(rlonv=slice(0,-1)), dim1D='cell _latlon' )789 DYN_psol_end = lmdz.geo2point ( d_DYN_end['ps'].isel(rlonv=slice(0,-1)), dim1D='cell _latlon' )850 DYN_psol_beg = lmdz.geo2point ( d_DYN_beg['ps'].isel(rlonv=slice(0,-1)), dim1D='cell' ) 851 DYN_psol_end = lmdz.geo2point ( d_DYN_end['ps'].isel(rlonv=slice(0,-1)), dim1D='cell' ) 790 852 791 853 echo ( '3D Pressure at the interface layers (not scalar points)' ) … … 793 855 DYN_pres_end = ATM_Ahyb + ATM_Bhyb * DYN_psol_end 794 856 857 echo ( 'Check computation of pressure levels' ) 858 859 ind = np.empty (8) 860 861 ind[0] = (DYN_pres_beg[ 0]-DYN_psol_beg).min().item() 862 ind[1] = (DYN_pres_beg[ 0]-DYN_psol_beg).max().item() 863 ind[2] = (DYN_pres_beg[-1]).min().item() 864 ind[3] = (DYN_pres_beg[-1]).max().item() 865 ind[4] = (DYN_pres_end[ 0]-DYN_psol_end).min().item() 866 ind[5] = (DYN_pres_end[ 0]-DYN_psol_end).max().item() 867 ind[6] = (DYN_pres_end[-1]).min().item() 868 ind[7] = (DYN_pres_end[-1]).max().item() 869 870 if any ( ind != 0) : 871 echo ( 'All values should be zero' ) 872 echo ( f'(DYN_pres_beg[ 0]-DYN_psol_beg).min().item() = {ind[0]}' ) 873 echo ( f'(DYN_pres_beg[ 0]-DYN_psol_beg).max().item() = {ind[1]}' ) 874 echo ( f'(DYN_pres_beg[-1]).min().item() = {ind[2]}' ) 875 echo ( f'(DYN_pres_beg[-1]).max().item() = {ind[3]}' ) 876 echo ( f'(DYN_pres_end[ 0]-DYN_psol_end).min().item() = {ind[4]}' ) 877 echo ( f'(DYN_pres_end[ 0]-DYN_psol_end).max().item() = {ind[5]}' ) 878 echo ( f'(DYN_pres_end[-1]).min().item() = {ind[6]}' ) 879 echo ( f'(DYN_pres_end[-1]).max().item() = {ind[7]}' ) 880 raise Exception 881 795 882 klevp1 = ATM_Bhyb.shape[-1] 796 883 cell = DYN_psol_beg.shape[-1] … … 798 885 799 886 echo ( 'Layer thickness (pressure)' ) 800 DYN_dpres_beg = xr.DataArray ( np.empty( (klev, cell )), dims = ('sigs', 'cell'), coords=(np.arange(klev), np.arange(cell) ) ) 801 DYN_dpres_end = xr.DataArray ( np.empty( (klev, cell )), dims = ('sigs', 'cell'), coords=(np.arange(klev), np.arange(cell) ) ) 802 803 for k in np.arange (klevp1-1) : 804 DYN_dpres_beg[k,:] = DYN_pres_beg[k,:] - DYN_pres_beg[k+1,:] 805 DYN_dpres_end[k,:] = DYN_pres_end[k,:] - DYN_pres_end[k+1,:] 887 DYN_mass_beg = xr.DataArray ( np.empty( (klev, cell)), dims = ('sigs', 'cell'), coords=(np.arange(klev), np.arange(cell) ) ) 888 DYN_mass_end = xr.DataArray ( np.empty( (klev, cell)), dims = ('sigs', 'cell'), coords=(np.arange(klev), np.arange(cell) ) ) 889 890 for k in np.arange (klev) : 891 DYN_mass_beg[k,:] = ( DYN_pres_beg[k,:] - DYN_pres_beg[k+1,:] ) / Grav 892 DYN_mass_end[k,:] = ( DYN_pres_end[k,:] - DYN_pres_end[k+1,:] ) / Grav 893 894 DYN_mass_beg_2D = DYN_mass_beg.sum (dim='sigs') 895 DYN_mass_end_2D = DYN_mass_end.sum (dim='sigs') 896 897 DYN_mas_air_beg = DYN_stock_int ( DYN_mass_beg_2D ) 898 DYN_mas_air_end = DYN_stock_int ( DYN_mass_end_2D ) 806 899 807 900 echo ( 'Vertical and horizontal integral, and sum of liquid, solid and vapor water phases' ) 808 901 if LMDZ : 809 try : 810 DYN_wat_beg = lmdz.geo3point ( (d_DYN_beg['H2Ov'] + d_DYN_beg['H2Ol'] + d_DYN_beg['H2Oi'] ).isel(rlonv=slice(0,-1) ), dim1D='cell' ) 811 DYN_wat_end = lmdz.geo3point ( (d_DYN_end['H2Ov'] + d_DYN_end['H2Ol'] + d_DYN_end['H2Oi'] ).isel(rlonv=slice(0,-1) ), dim1D='cell' ) 812 except : 902 if 'H2Ov' in d_DYN_beg.variables : 903 echo ('reading LATLON : H2Ov, H2Ol, H2Oi' ) 904 DYN_wat_beg = lmdz.geo3point ( d_DYN_beg['H2Ov'] + d_DYN_beg['H2Ol'] + d_DYN_beg['H2Oi'].isel(rlonv=slice(0,-1) ), dim1D='cell' ) 905 DYN_wat_end = lmdz.geo3point ( d_DYN_end['H2Ov'] + d_DYN_end['H2Ol'] + d_DYN_end['H2Oi'].isel(rlonv=slice(0,-1) ), dim1D='cell' ) 906 if 'H2Ov_g' in d_DYN_beg.variables : 907 echo ('reading LATLON : H2O_g, H2O_l, H2O_s' ) 813 908 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) ), dim1D='cell' ) 814 909 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) ), dim1D='cell' ) 815 910 if ICO : 816 try : 911 if 'H2Ov_g' in d_DYN_beg.variables : 912 echo ('reading ICO : H2O_g, H2O_l, H2O_s' ) 817 913 DYN_wat_beg = (d_DYN_beg['H2O_g'] + d_DYN_beg['H2O_l'] + d_DYN_beg['H2O_s'])[..., DYN_beg_keysort] 818 914 DYN_wat_end = (d_DYN_end['H2O_g'] + d_DYN_end['H2O_l'] + d_DYN_end['H2O_s'])[..., DYN_beg_keysort] 819 820 except : 915 elif 'H2O_g' in d_DYN_beg.variables : 916 echo ('reading ICO : H2O_g, H2O_l, H2O_s' ) 917 DYN_wat_beg = (d_DYN_beg['H2O_g'] + d_DYN_beg['H2O_l'] + d_DYN_beg['H2O_s'])[..., DYN_beg_keysort] 918 DYN_wat_end = (d_DYN_end['H2O_g'] + d_DYN_end['H2O_l'] + d_DYN_end['H2O_s'])[..., DYN_beg_keysort] 919 elif 'q' in d_DYN_beg.variables : 920 echo ('reading ICO : q' ) 821 921 DYN_wat_beg = (d_DYN_beg['q'].isel(nq=0) + d_DYN_beg['q'].isel(nq=1) + d_DYN_beg['q'].isel(nq=2) )[..., DYN_beg_keysort] 822 922 DYN_wat_end = (d_DYN_end['q'].isel(nq=0) + d_DYN_end['q'].isel(nq=1) + d_DYN_end['q'].isel(nq=2) )[..., DYN_beg_keysort] 823 923 924 if 'lev' in DYN_wat_beg.dims : 824 925 DYN_wat_beg = DYN_wat_beg.rename ( {'lev':'sigs'} ) 825 DYN_wat_ beg= DYN_wat_end.rename ( {'lev':'sigs'} )926 DYN_wat_end = DYN_wat_end.rename ( {'lev':'sigs'} ) 826 927 827 928 echo ( 'Compute water content : vertical and horizontal integral' ) 828 DYN_mas_wat_beg = DYN_stock_int ( (DYN_dpres_beg * DYN_wat_beg).sum (dim='sigs') ) / Grav 829 DYN_mas_wat_end = DYN_stock_int ( (DYN_dpres_end * DYN_wat_end).sum (dim='sigs') ) / Grav 929 930 DYN_wat_beg_2D = (DYN_mass_beg * DYN_wat_beg).sum (dim='sigs') 931 DYN_wat_end_2D = (DYN_mass_end * DYN_wat_end).sum (dim='sigs') 932 933 DYN_mas_wat_beg = DYN_stock_int ( DYN_wat_beg_2D ) 934 DYN_mas_wat_end = DYN_stock_int ( DYN_wat_end_2D ) 830 935 831 936 echo ( 'Variation of water content' ) 832 937 dDYN_mas_wat = DYN_mas_wat_end - DYN_mas_wat_beg 833 938 834 # \([a-z,A-Z,_]*\)/dtime_sec\*1e-9 kg2Sv(\1)835 # \([a-z,A-Z,_]*\)\/ATM_aire_sea_tot\/ATM_rho\/NbYear kg2myear(\1)836 837 939 echo ( f'\nChange of atmosphere water content (dynamics) -- {Title} ' ) 838 940 echo ( '------------------------------------------------------------------------------------' ) 839 echo ( 'DYN_mas_beg = {:12.6e} kg | DYN_mas_end = {:12.6e} kg'.format (DYN_mas_wat_beg, DYN_mas_wat_end) ) 941 echo ( 'DYN_mas_air_beg = {:12.6e} kg | DYN_mas_air_end = {:12.6e} kg'.format (DYN_mas_air_beg, DYN_mas_air_end) ) 942 echo ( 'DYN_mas_wat_beg = {:12.6e} kg | DYN_mas_wat_end = {:12.6e} kg'.format (DYN_mas_wat_beg, DYN_mas_wat_end) ) 840 943 prtFlux ( 'dMass (atm) ', dDYN_mas_wat, 'e', True ) 841 944 … … 850 953 d_ATM_end['QS03'] *d_ATM_end['FOCE'] + d_ATM_end['QS04'] *d_ATM_end['FSIC'] 851 954 852 ATM_qsol_beg = d_ATM_beg['QSOL']853 ATM_qsol_end = d_ATM_end['QSOL']955 ATM_qsol_beg = d_ATM_beg['QSOL'] 956 ATM_qsol_end = d_ATM_end['QSOL'] 854 957 855 958 LIC_sno_beg = d_ATM_beg['SNOW02']*d_ATM_beg['FLIC'] … … 859 962 LIC_runlic0_end = d_ATM_end['RUNOFFLIC0'] 860 963 861 ATM_qs01_beg = d_ATM_beg['QS01'] * d_ATM_beg['FTER'] 862 ATM_qs01_end = d_ATM_end['QS01'] * d_ATM_end['FTER'] 863 ATM_qs02_beg = d_ATM_beg['QS02'] * d_ATM_beg['FLIC'] 864 ATM_qs02_end = d_ATM_end['QS02'] * d_ATM_end['FLIC'] 865 ATM_qs03_beg = d_ATM_beg['QS03'] * d_ATM_beg['FOCE'] 866 ATM_qs03_end = d_ATM_end['QS03'] * d_ATM_end['FOCE'] 867 ATM_qs04_beg = d_ATM_beg['QS04'] * d_ATM_beg['FSIC'] 868 ATM_qs04_end = d_ATM_end['QS04'] * d_ATM_end['FSIC'] 964 ATM_qs01_beg = d_ATM_beg['QS01'] * d_ATM_beg['FTER'] 965 ATM_qs02_beg = d_ATM_beg['QS02'] * d_ATM_beg['FLIC'] 966 ATM_qs03_beg = d_ATM_beg['QS03'] * d_ATM_beg['FOCE'] 967 ATM_qs04_beg = d_ATM_beg['QS04'] * d_ATM_beg['FSIC'] 968 969 ATM_qs01_end = d_ATM_end['QS01'] * d_ATM_end['FTER'] 970 ATM_qs02_end = d_ATM_end['QS02'] * d_ATM_end['FLIC'] 971 ATM_qs03_end = d_ATM_end['QS03'] * d_ATM_end['FOCE'] 972 ATM_qs04_end = d_ATM_end['QS04'] * d_ATM_end['FSIC'] 869 973 870 974 if ICO : 871 ATM_sno_beg 872 ATM_sno_end 873 ATM_qs_beg 874 ATM_qs_end 875 ATM_qsol_beg 876 ATM_qs ol_end = ATM_qsol_end [ATM_end_keysort]877 ATM_qs0 1_beg = ATM_qs01_beg [ATM_beg_keysort]878 ATM_qs0 1_end = ATM_qs01_end [ATM_end_keysort]879 ATM_qs0 2_beg = ATM_qs02_beg [ATM_beg_keysort]880 ATM_qs 02_end = ATM_qs02_end [ATM_end_keysort]881 ATM_qs0 3_beg = ATM_qs03_beg [ATM_beg_keysort]882 ATM_qs0 3_end = ATM_qs03_end [ATM_end_keysort]883 ATM_qs0 4_beg = ATM_qs04_beg [ATM_beg_keysort]884 ATM_qs04_end 885 LIC_sno_beg 886 LIC_sno_end 887 LIC_runlic0_beg 888 LIC_runlic0_end 975 ATM_sno_beg = ATM_sno_beg [ATM_beg_keysort] 976 ATM_sno_end = ATM_sno_end [ATM_end_keysort] 977 ATM_qs_beg = ATM_qs_beg [ATM_beg_keysort] 978 ATM_qs_end = ATM_qs_end [ATM_end_keysort] 979 ATM_qsol_beg = ATM_qsol_beg [ATM_beg_keysort] 980 ATM_qs01_beg = ATM_qs01_beg [ATM_beg_keysort] 981 ATM_qs02_beg = ATM_qs02_beg [ATM_beg_keysort] 982 ATM_qs03_beg = ATM_qs03_beg [ATM_beg_keysort] 983 ATM_qs04_beg = ATM_qs04_beg [ATM_beg_keysort] 984 ATM_qsol_end = ATM_qsol_end [ATM_end_keysort] 985 ATM_qs01_end = ATM_qs01_end [ATM_end_keysort] 986 ATM_qs02_end = ATM_qs02_end [ATM_end_keysort] 987 ATM_qs03_end = ATM_qs03_end [ATM_end_keysort] 988 ATM_qs04_end = ATM_qs04_end [ATM_end_keysort] 989 LIC_sno_beg = LIC_sno_beg [ATM_beg_keysort] 990 LIC_sno_end = LIC_sno_end [ATM_end_keysort] 991 LIC_runlic0_beg = LIC_runlic0_beg[ATM_beg_keysort] 992 LIC_runlic0_end = LIC_runlic0_end[ATM_end_keysort] 889 993 890 994 LIC_qs_beg = ATM_qs02_beg … … 897 1001 ATM_mas_qs_end = DYN_stock_int ( ATM_qs_end ) 898 1002 ATM_mas_qsol_beg = DYN_stock_int ( ATM_qsol_beg ) 1003 ATM_mas_qs01_beg = DYN_stock_int ( ATM_qs01_beg ) 1004 ATM_mas_qs02_beg = DYN_stock_int ( ATM_qs02_beg ) 1005 ATM_mas_qs03_beg = DYN_stock_int ( ATM_qs03_beg ) 1006 ATM_mas_qs04_beg = DYN_stock_int ( ATM_qs04_beg ) 899 1007 ATM_mas_qsol_end = DYN_stock_int ( ATM_qsol_end ) 900 ATM_mas_qs01_beg = DYN_stock_int ( ATM_qs01_beg )901 1008 ATM_mas_qs01_end = DYN_stock_int ( ATM_qs01_end ) 902 ATM_mas_qs02_beg = DYN_stock_int ( ATM_qs02_beg )903 1009 ATM_mas_qs02_end = DYN_stock_int ( ATM_qs02_end ) 904 ATM_mas_qs03_beg = DYN_stock_int ( ATM_qs03_beg )905 1010 ATM_mas_qs03_end = DYN_stock_int ( ATM_qs03_end ) 906 ATM_mas_qs04_beg = DYN_stock_int ( ATM_qs04_beg )907 1011 ATM_mas_qs04_end = DYN_stock_int ( ATM_qs04_end ) 908 1012 … … 929 1033 dLIC_mas_sno = LIC_mas_sno_end - LIC_mas_sno_beg 930 1034 dLIC_mas_runlic0 = LIC_mas_runlic0_end - LIC_mas_runlic0_beg 931 dLIC_mas_wat = dLIC_mas_qs + dLIC_mas_sno 1035 1036 dLIC_mas_wat = dLIC_mas_qs + dLIC_mas_sno # + dLIC_mas_runlic0 932 1037 933 1038 echo ( f'\nChange of atmosphere snow content (Land ice) -- {Title} ' ) … … 980 1085 RUN_mas_wat_pond_end = ONE_stock_int ( d_SRF_end ['pondres'] ) 981 1086 982 RUN_mas_wat_beg = RUN_mas_wat_fast_beg + RUN_mas_wat_slow_beg + RUN_mas_wat_stream_beg + \ 983 RUN_mas_wat_flood_beg + RUN_mas_wat_lake_beg + RUN_mas_wat_pond_beg 984 RUN_mas_wat_end = RUN_mas_wat_fast_end + RUN_mas_wat_slow_end + RUN_mas_wat_stream_end + \ 985 RUN_mas_wat_flood_end + RUN_mas_wat_lake_end + RUN_mas_wat_pond_end 1087 RUN_mas_wat_beg = Sprec ( [RUN_mas_wat_fast_beg , RUN_mas_wat_slow_beg, RUN_mas_wat_stream_beg, 1088 RUN_mas_wat_flood_beg, RUN_mas_wat_lake_beg, RUN_mas_wat_pond_beg] ) 1089 1090 RUN_mas_wat_end = Sprec ( [RUN_mas_wat_fast_end , RUN_mas_wat_slow_end , RUN_mas_wat_stream_end, 1091 RUN_mas_wat_flood_end , RUN_mas_wat_lake_end , RUN_mas_wat_pond_end] ) 986 1092 987 1093 dRUN_mas_wat_fast = RUN_mas_wat_fast_end - RUN_mas_wat_fast_beg … … 1032 1138 1033 1139 if LMDZ : 1034 SRF_tot_watveg_beg = lmdz.geo2point (SRF_tot_watveg_beg , dim1D='cell _latlon')1035 SRF_tot_watsoil_beg = lmdz.geo2point (SRF_tot_watsoil_beg, dim1D='cell _latlon')1036 SRF_snow_beg = lmdz.geo2point (SRF_snow_beg , dim1D='cell _latlon')1037 SRF_lakeres_beg = lmdz.geo2point (SRF_lakeres_beg , dim1D='cell _latlon')1038 SRF_tot_watveg_end = lmdz.geo2point (SRF_tot_watveg_end , dim1D='cell _latlon')1039 SRF_tot_watsoil_end = lmdz.geo2point (SRF_tot_watsoil_end, dim1D='cell _latlon')1040 SRF_snow_end = lmdz.geo2point (SRF_snow_end , dim1D='cell _latlon')1041 SRF_lakeres_end = lmdz.geo2point (SRF_lakeres_end , dim1D='cell _latlon')1140 SRF_tot_watveg_beg = lmdz.geo2point (SRF_tot_watveg_beg , dim1D='cell') 1141 SRF_tot_watsoil_beg = lmdz.geo2point (SRF_tot_watsoil_beg, dim1D='cell') 1142 SRF_snow_beg = lmdz.geo2point (SRF_snow_beg , dim1D='cell') 1143 SRF_lakeres_beg = lmdz.geo2point (SRF_lakeres_beg , dim1D='cell') 1144 SRF_tot_watveg_end = lmdz.geo2point (SRF_tot_watveg_end , dim1D='cell') 1145 SRF_tot_watsoil_end = lmdz.geo2point (SRF_tot_watsoil_end, dim1D='cell') 1146 SRF_snow_end = lmdz.geo2point (SRF_snow_end , dim1D='cell') 1147 SRF_lakeres_end = lmdz.geo2point (SRF_lakeres_end , dim1D='cell') 1042 1148 1043 1149 if ICO : … … 1053 1159 # Stock dSoilHum dInterce dSWE dStream dFastR dSlowR dLake dPond dFlood 1054 1160 1055 SRF_wat_beg = SRF_tot_watveg_beg + SRF_tot_watsoil_beg + SRF_snow_beg 1161 SRF_wat_beg = SRF_tot_watveg_beg + SRF_tot_watsoil_beg + SRF_snow_beg 1056 1162 SRF_wat_end = SRF_tot_watveg_end + SRF_tot_watsoil_end + SRF_snow_end 1057 1163 … … 1079 1185 print (' -- ') ; sys.stdout.flush () 1080 1186 1081 dSRF_mas_watveg = S RF_mas_watveg_end - SRF_mas_watveg_beg1082 dSRF_mas_watsoil = S RF_mas_watsoil_end - SRF_mas_watsoil_beg1083 dSRF_mas_snow = S RF_mas_snow_end - SRF_mas_snow_beg1084 dSRF_mas_lake = S RF_mas_lake_end - SRF_mas_lake_beg1187 dSRF_mas_watveg = Sprec ( [SRF_mas_watveg_end , -SRF_mas_watveg_beg] ) 1188 dSRF_mas_watsoil = Sprec ( [SRF_mas_watsoil_end, -SRF_mas_watsoil_beg] ) 1189 dSRF_mas_snow = Sprec ( [SRF_mas_snow_end , -SRF_mas_snow_beg] ) 1190 dSRF_mas_lake = Sprec ( [SRF_mas_lake_end , -SRF_mas_lake_beg] ) 1085 1191 1086 1192 echo ( '------------------------------------------------------------------------------------' ) … … 1096 1202 prtFlux ( 'dMass (lake) ', dSRF_mas_lake , 'e' , True ) 1097 1203 1098 SRF_mas_wat_beg = SRF_mas_watveg_beg + SRF_mas_watsoil_beg + SRF_mas_snow_beg 1099 SRF_mas_wat_end = SRF_mas_watveg_end + SRF_mas_watsoil_end + SRF_mas_snow_end 1100 dSRF_mas_wat = SRF_mas_wat_end - SRF_mas_wat_beg 1204 SRF_mas_wat_beg = Sprec ( [SRF_mas_watveg_beg , SRF_mas_watsoil_beg, SRF_mas_snow_beg] ) 1205 SRF_mas_wat_end = Sprec ( [SRF_mas_watveg_end , SRF_mas_watsoil_end, SRF_mas_snow_end] ) 1206 1207 dSRF_mas_wat = Sprec ( [+SRF_mas_watveg_end , +SRF_mas_watsoil_end, +SRF_mas_snow_end, 1208 -SRF_mas_watveg_beg , -SRF_mas_watsoil_beg, -SRF_mas_snow_beg] ) 1101 1209 1102 1210 echo ( '------------------------------------------------------------------------------------' ) … … 1115 1223 echo ( f'-- ATM Fluxes -- {Title} ' ) 1116 1224 1117 Step=11118 print ( 'Step {Step}', end='' ) ; Step += 11119 1225 if ATM_HIS == 'latlon' : 1120 ATM_wbilo_oce = lmdz.geo2point ( d_ATM_his ['wbilo_oce'], dim1D='cell_latlon' ) 1121 ATM_wbilo_sic = lmdz.geo2point ( d_ATM_his ['wbilo_sic'], dim1D='cell_latlon' ) 1122 ATM_wbilo_ter = lmdz.geo2point ( d_ATM_his ['wbilo_ter'], dim1D='cell_latlon' ) 1123 ATM_wbilo_lic = lmdz.geo2point ( d_ATM_his ['wbilo_lic'], dim1D='cell_latlon' ) 1124 ATM_runofflic = lmdz.geo2point ( d_ATM_his ['runofflic'], dim1D='cell_latlon' ) 1125 ATM_fqcalving = lmdz.geo2point ( d_ATM_his ['fqcalving'], dim1D='cell_latlon' ) 1126 ATM_fqfonte = lmdz.geo2point ( d_ATM_his ['fqfonte'] , dim1D='cell_latlon' ) 1127 ATM_precip = lmdz.geo2point ( d_ATM_his ['precip'] , dim1D='cell_latlon' ) 1128 ATM_snowf = lmdz.geo2point ( d_ATM_his ['snow'] , dim1D='cell_latlon' ) 1129 ATM_evap = lmdz.geo2point ( d_ATM_his ['evap'] , dim1D='cell_latlon' ) 1130 ATM_wevap_ter = lmdz.geo2point ( d_ATM_his ['wevap_ter'], dim1D='cell_latlon' ) 1131 ATM_wevap_oce = lmdz.geo2point ( d_ATM_his ['wevap_oce'], dim1D='cell_latlon' ) 1132 ATM_wevap_lic = lmdz.geo2point ( d_ATM_his ['wevap_lic'], dim1D='cell_latlon' ) 1133 ATM_wevap_sic = lmdz.geo2point ( d_ATM_his ['wevap_sic'], dim1D='cell_latlon' ) 1134 1135 ATM_wrain_ter = lmdz.geo2point ( d_ATM_his ['wrain_ter'], dim1D='cell_latlon' ) 1136 ATM_wrain_oce = lmdz.geo2point ( d_ATM_his ['wrain_oce'], dim1D='cell_latlon' ) 1137 ATM_wrain_lic = lmdz.geo2point ( d_ATM_his ['wrain_lic'], dim1D='cell_latlon' ) 1138 ATM_wrain_sic = lmdz.geo2point ( d_ATM_his ['wrain_sic'], dim1D='cell_latlon' ) 1139 1140 ATM_wsnow_ter = lmdz.geo2point ( d_ATM_his ['wsnow_ter'], dim1D='cell_latlon' ) 1141 ATM_wsnow_oce = lmdz.geo2point ( d_ATM_his ['wsnow_oce'], dim1D='cell_latlon' ) 1142 ATM_wsnow_lic = lmdz.geo2point ( d_ATM_his ['wsnow_lic'], dim1D='cell_latlon' ) 1143 ATM_wsnow_sic = lmdz.geo2point ( d_ATM_his ['wsnow_sic'], dim1D='cell_latlon' ) 1144 1145 ATM_wevap_ter = lmdz.geo2point ( d_ATM_his ['wevap_ter'], dim1D='cell_latlon' ) 1146 ATM_wevap_oce = lmdz.geo2point ( d_ATM_his ['wevap_oce'], dim1D='cell_latlon' ) 1147 ATM_wevap_lic = lmdz.geo2point ( d_ATM_his ['wevap_lic'], dim1D='cell_latlon' ) 1148 ATM_wevap_sic = lmdz.geo2point ( d_ATM_his ['wevap_sic'], dim1D='cell_latlon' ) 1149 1150 ATM_runofflic = lmdz.geo2point ( d_ATM_his ['runofflic'], dim1D='cell_latlon' ) 1151 1152 print ( 'Step {Step}', end='' ) ; Step += 1 1226 echo ( ' latlon case' ) 1227 ATM_wbilo_oce = lmdz.geo2point ( rprec (d_ATM_his ['wbilo_oce']), dim1D='cell' ) 1228 ATM_wbilo_sic = lmdz.geo2point ( rprec (d_ATM_his ['wbilo_sic']), dim1D='cell' ) 1229 ATM_wbilo_ter = lmdz.geo2point ( rprec (d_ATM_his ['wbilo_ter']), dim1D='cell' ) 1230 ATM_wbilo_lic = lmdz.geo2point ( rprec (d_ATM_his ['wbilo_lic']), dim1D='cell' ) 1231 ATM_runofflic = lmdz.geo2point ( rprec (d_ATM_his ['runofflic']), dim1D='cell' ) 1232 ATM_fqcalving = lmdz.geo2point ( rprec (d_ATM_his ['fqcalving']), dim1D='cell' ) 1233 ATM_fqfonte = lmdz.geo2point ( rprec (d_ATM_his ['fqfonte'] ), dim1D='cell' ) 1234 ATM_precip = lmdz.geo2point ( rprec (d_ATM_his ['precip'] ), dim1D='cell' ) 1235 ATM_snowf = lmdz.geo2point ( rprec (d_ATM_his ['snow'] ), dim1D='cell' ) 1236 ATM_evap = lmdz.geo2point ( rprec (d_ATM_his ['evap'] ), dim1D='cell' ) 1237 ATM_wevap_ter = lmdz.geo2point ( rprec (d_ATM_his ['wevap_ter']), dim1D='cell' ) 1238 ATM_wevap_oce = lmdz.geo2point ( rprec (d_ATM_his ['wevap_oce']), dim1D='cell' ) 1239 ATM_wevap_lic = lmdz.geo2point ( rprec (d_ATM_his ['wevap_lic']), dim1D='cell' ) 1240 ATM_wevap_sic = lmdz.geo2point ( rprec (d_ATM_his ['wevap_sic']), dim1D='cell' ) 1241 ATM_wrain_ter = lmdz.geo2point ( rprec (d_ATM_his ['wrain_ter']), dim1D='cell' ) 1242 ATM_wrain_oce = lmdz.geo2point ( rprec (d_ATM_his ['wrain_oce']), dim1D='cell' ) 1243 ATM_wrain_lic = lmdz.geo2point ( rprec (d_ATM_his ['wrain_lic']), dim1D='cell' ) 1244 ATM_wrain_sic = lmdz.geo2point ( rprec (d_ATM_his ['wrain_sic']), dim1D='cell' ) 1245 ATM_wsnow_ter = lmdz.geo2point ( rprec (d_ATM_his ['wsnow_ter']), dim1D='cell' ) 1246 ATM_wsnow_oce = lmdz.geo2point ( rprec (d_ATM_his ['wsnow_oce']), dim1D='cell' ) 1247 ATM_wsnow_lic = lmdz.geo2point ( rprec (d_ATM_his ['wsnow_lic']), dim1D='cell' ) 1248 ATM_wsnow_sic = lmdz.geo2point ( rprec (d_ATM_his ['wsnow_sic']), dim1D='cell' ) 1249 ATM_runofflic = lmdz.geo2point ( rprec (d_ATM_his ['runofflic']), dim1D='cell' ) 1250 echo ( f'End of LATLON case') 1251 1153 1252 if ATM_HIS == 'ico' : 1154 ATM_wbilo_oce = d_ATM_his ['wbilo_oce'][..., ATM_his_keysort] 1155 ATM_wbilo_sic = d_ATM_his ['wbilo_sic'][..., ATM_his_keysort] 1156 ATM_wbilo_ter = d_ATM_his ['wbilo_ter'][..., ATM_his_keysort] 1157 ATM_wbilo_lic = d_ATM_his ['wbilo_lic'][..., ATM_his_keysort] 1158 ATM_runofflic = d_ATM_his ['runofflic'][..., ATM_his_keysort] 1159 ATM_fqcalving = d_ATM_his ['fqcalving'][..., ATM_his_keysort] 1160 ATM_fqfonte = d_ATM_his ['fqfonte'] [..., ATM_his_keysort] 1161 ATM_precip = d_ATM_his ['precip'] [..., ATM_his_keysort] 1162 ATM_snowf = d_ATM_his ['snow'] [..., ATM_his_keysort] 1163 ATM_evap = d_ATM_his ['evap'] [..., ATM_his_keysort] 1164 ATM_wevap_ter = d_ATM_his ['wevap_ter'][..., ATM_his_keysort] 1165 ATM_wevap_oce = d_ATM_his ['wevap_oce'][..., ATM_his_keysort] 1166 ATM_wevap_lic = d_ATM_his ['wevap_lic'][..., ATM_his_keysort] 1167 ATM_wevap_sic = d_ATM_his ['wevap_sic'][..., ATM_his_keysort] 1168 ATM_runofflic = d_ATM_his ['runofflic'][..., ATM_his_keysort] 1169 1170 ATM_wevap_ter = d_ATM_his ['wevap_ter'][..., ATM_his_keysort] 1171 ATM_wevap_oce = d_ATM_his ['wevap_oce'][..., ATM_his_keysort] 1172 ATM_wevap_lic = d_ATM_his ['wevap_lic'][..., ATM_his_keysort] 1173 ATM_wevap_sic = d_ATM_his ['wevap_sic'][..., ATM_his_keysort] 1174 1175 ATM_wrain_ter = d_ATM_his ['wrain_ter'][..., ATM_his_keysort] 1176 ATM_wrain_oce = d_ATM_his ['wrain_oce'][..., ATM_his_keysort] 1177 ATM_wrain_lic = d_ATM_his ['wrain_lic'][..., ATM_his_keysort] 1178 ATM_wrain_sic = d_ATM_his ['wrain_sic'][..., ATM_his_keysort] 1179 1180 ATM_wsnow_ter = d_ATM_his ['wsnow_ter'][..., ATM_his_keysort] 1181 ATM_wsnow_oce = d_ATM_his ['wsnow_oce'][..., ATM_his_keysort] 1182 ATM_wsnow_lic = d_ATM_his ['wsnow_lic'][..., ATM_his_keysort] 1183 ATM_wsnow_sic = d_ATM_his ['wsnow_sic'][..., ATM_his_keysort] 1184 1185 print ( 'Step {Step}', end='' ) ; Step += 1 1186 1253 echo (' ico case') 1254 ATM_wbilo_oce = rprec (d_ATM_his ['wbilo_oce'])[..., ATM_his_keysort] 1255 ATM_wbilo_sic = rprec (d_ATM_his ['wbilo_sic'])[..., ATM_his_keysort] 1256 ATM_wbilo_ter = rprec (d_ATM_his ['wbilo_ter'])[..., ATM_his_keysort] 1257 ATM_wbilo_lic = rprec (d_ATM_his ['wbilo_lic'])[..., ATM_his_keysort] 1258 ATM_runofflic = rprec (d_ATM_his ['runofflic'])[..., ATM_his_keysort] 1259 ATM_fqcalving = rprec (d_ATM_his ['fqcalving'])[..., ATM_his_keysort] 1260 ATM_fqfonte = rprec (d_ATM_his ['fqfonte'] )[..., ATM_his_keysort] 1261 ATM_precip = rprec (d_ATM_his ['precip'] )[..., ATM_his_keysort] 1262 ATM_snowf = rprec (d_ATM_his ['snow'] )[..., ATM_his_keysort] 1263 ATM_evap = rprec (d_ATM_his ['evap'] )[..., ATM_his_keysort] 1264 ATM_wevap_ter = rprec (d_ATM_his ['wevap_ter'])[..., ATM_his_keysort] 1265 ATM_wevap_oce = rprec (d_ATM_his ['wevap_oce'])[..., ATM_his_keysort] 1266 ATM_wevap_lic = rprec (d_ATM_his ['wevap_lic'])[..., ATM_his_keysort] 1267 ATM_wevap_sic = rprec (d_ATM_his ['wevap_sic'])[..., ATM_his_keysort] 1268 ATM_runofflic = rprec (d_ATM_his ['runofflic'])[..., ATM_his_keysort] 1269 ATM_wevap_ter = rprec (d_ATM_his ['wevap_ter'])[..., ATM_his_keysort] 1270 ATM_wevap_oce = rprec (d_ATM_his ['wevap_oce'])[..., ATM_his_keysort] 1271 ATM_wevap_lic = rprec (d_ATM_his ['wevap_lic'])[..., ATM_his_keysort] 1272 ATM_wevap_sic = rprec (d_ATM_his ['wevap_sic'])[..., ATM_his_keysort] 1273 ATM_wrain_ter = rprec (d_ATM_his ['wrain_ter'])[..., ATM_his_keysort] 1274 ATM_wrain_oce = rprec (d_ATM_his ['wrain_oce'])[..., ATM_his_keysort] 1275 ATM_wrain_lic = rprec (d_ATM_his ['wrain_lic'])[..., ATM_his_keysort] 1276 ATM_wrain_sic = rprec (d_ATM_his ['wrain_sic'])[..., ATM_his_keysort] 1277 ATM_wsnow_ter = rprec (d_ATM_his ['wsnow_ter'])[..., ATM_his_keysort] 1278 ATM_wsnow_oce = rprec (d_ATM_his ['wsnow_oce'])[..., ATM_his_keysort] 1279 ATM_wsnow_lic = rprec (d_ATM_his ['wsnow_lic'])[..., ATM_his_keysort] 1280 ATM_wsnow_sic = rprec (d_ATM_his ['wsnow_sic'])[..., ATM_his_keysort] 1281 echo ( f'End of ico case ') 1282 1283 echo ( 'ATM wprecip_oce' ) 1187 1284 ATM_wprecip_oce = ATM_wrain_oce + ATM_wsnow_oce 1188 1285 ATM_wprecip_ter = ATM_wrain_ter + ATM_wsnow_ter … … 1190 1287 ATM_wprecip_lic = ATM_wrain_lic + ATM_wsnow_lic 1191 1288 1192 ATM_wbilo = ATM_wbilo_oce + ATM_wbilo_sic + ATM_wbilo_ter + ATM_wbilo_lic 1193 ATM_emp = ATM_evap - ATM_precip 1289 ATM_wbilo = ATM_wbilo_oce + ATM_wbilo_sic + ATM_wbilo_ter + ATM_wbilo_lic 1290 ATM_wevap = ATM_wevap_oce + ATM_wevap_sic + ATM_wevap_ter + ATM_wevap_lic 1291 ATM_wprecip = ATM_wprecip_oce + ATM_wprecip_sic + ATM_wprecip_ter + ATM_wprecip_lic 1292 ATM_wsnow = ATM_wsnow_oce + ATM_wsnow_sic + ATM_wsnow_ter + ATM_wsnow_lic 1293 ATM_wrain = ATM_wrain_oce + ATM_wrain_sic + ATM_wrain_ter + ATM_wrain_lic 1294 ATM_wemp = ATM_wevap - ATM_wprecip 1295 ATM_emp = ATM_evap - ATM_precip 1296 1194 1297 ATM_wprecip_sea = ATM_wprecip_oce + ATM_wprecip_sic 1195 1298 ATM_wsnow_sea = ATM_wsnow_oce + ATM_wsnow_sic … … 1198 1301 ATM_wevap_sea = ATM_wevap_sic + ATM_wevap_oce 1199 1302 1200 #ATM_wemp_ter = ATM_wevap_ter - ATM_precip * ATM_fter 1201 #ATM_wemp_oce = ATM_wevap_oce - ATM_precip * ATM_foce 1202 #ATM_wemp_sic = ATM_wevap_sic - ATM_precip * ATM_fsic 1203 #ATM_wemp_lic = ATM_wevap_lic - ATM_precip * ATM_flic 1204 #ATM_wemp_sea = ATM_wevap_sic + ATM_wevap_oce - ATM_precip * ATM_fsea 1205 1206 ATM_wemp_ter = ATM_wevap_ter - ATM_wprecip_ter 1207 ATM_wemp_oce = ATM_wevap_oce - ATM_wprecip_oce 1208 ATM_wemp_sic = ATM_wevap_sic - ATM_wprecip_sic 1209 ATM_wemp_lic = ATM_wevap_lic - ATM_wprecip_lic 1210 ATM_wemp_sea = ATM_wevap_sic - ATM_wprecip_oce 1211 1212 print ( 'Step {Step}', end='' ) ; Step += 1 1213 if RUN_HIS == 'latlon' : 1214 RUN_coastalflow = lmdz.geo2point ( d_RUN_his ['coastalflow'], dim1D='cell_latlon' ) 1215 RUN_riverflow = lmdz.geo2point ( d_RUN_his ['riverflow'] , dim1D='cell_latlon' ) 1216 RUN_runoff = lmdz.geo2point ( d_RUN_his ['runoff'] , dim1D='cell_latlon' ) 1217 RUN_drainage = lmdz.geo2point ( d_RUN_his ['drainage'] , dim1D='cell_latlon' ) 1218 RUN_riversret = lmdz.geo2point ( d_RUN_his ['riversret'] , dim1D='cell_latlon' ) 1219 1220 RUN_coastalflow_cpl = lmdz.geo2point ( d_RUN_his ['coastalflow_cpl'], dim1D='cell_latlon' ) 1221 RUN_riverflow_cpl = lmdz.geo2point ( d_RUN_his ['riverflow_cpl'] , dim1D='cell_latlon' ) 1222 1223 print ( 'Step {Step}', end='' ) ; Step += 1 1303 ATM_wemp_ter = ATM_wevap_ter - ATM_wprecip_ter 1304 ATM_wemp_oce = ATM_wevap_oce - ATM_wprecip_oce 1305 ATM_wemp_sic = ATM_wevap_sic - ATM_wprecip_sic 1306 ATM_wemp_lic = ATM_wevap_lic - ATM_wprecip_lic 1307 ATM_wemp_sea = ATM_wevap_sic - ATM_wprecip_oce 1308 1309 if RUN_HIS == 'latlon' : 1310 echo ( f'RUN costalflow Grille LATLON' ) 1311 if TestInterp : 1312 echo ( f'RUN runoff TestInterp' ) 1313 RUN_runoff = lmdz.geo2point ( rprec (d_RUN_his ['runoff_contfrac_interp'] ) , dim1D='cell' ) 1314 RUN_drainage = lmdz.geo2point ( rprec (d_RUN_his ['drainage_contfrac_interp']) , dim1D='cell' ) 1315 else : 1316 echo ( f'RUN runoff' ) 1317 RUN_runoff = lmdz.geo2point ( rprec (d_RUN_his ['runoff'] ), dim1D='cell' ) 1318 RUN_drainage = lmdz.geo2point ( rprec (d_RUN_his ['drainage'] ), dim1D='cell' ) 1319 1320 RUN_coastalflow = lmdz.geo2point ( rprec (d_RUN_his ['coastalflow'] ), dim1D='cell' ) 1321 RUN_riverflow = lmdz.geo2point ( rprec (d_RUN_his ['riverflow'] ), dim1D='cell' ) 1322 RUN_riversret = lmdz.geo2point ( rprec (d_RUN_his ['riversret'] ), dim1D='cell' ) 1323 RUN_coastalflow_cpl = lmdz.geo2point ( rprec (d_RUN_his ['coastalflow_cpl']), dim1D='cell' ) 1324 RUN_riverflow_cpl = lmdz.geo2point ( rprec (d_RUN_his ['riverflow_cpl'] ), dim1D='cell' ) 1325 1224 1326 if RUN_HIS == 'ico' : 1225 RUN_coastalflow = d_RUN_his ['coastalflow'][..., RUN_his_keysort] 1226 RUN_riverflow = d_RUN_his ['riverflow'] [..., RUN_his_keysort] 1227 RUN_runoff = d_RUN_his ['runoff'] [..., RUN_his_keysort] 1228 RUN_drainage = d_RUN_his ['drainage'] [..., RUN_his_keysort] 1229 RUN_riversret = d_RUN_his ['riversret'] [..., RUN_his_keysort] 1230 1231 RUN_coastalflow_cpl = d_RUN_his ['coastalflow_cpl'][..., RUN_his_keysort] 1232 RUN_riverflow_cpl = d_RUN_his ['riverflow_cpl'] [..., RUN_his_keysort] 1233 1234 print ( 'Step {Step}', end='' ) ; Step += 1 1327 echo ( f'RUN costalflow Grille ICO' ) 1328 RUN_coastalflow = rprec (d_RUN_his ['coastalflow'])[..., RUN_his_keysort] 1329 RUN_riverflow = rprec (d_RUN_his ['riverflow'] )[..., RUN_his_keysort] 1330 RUN_runoff = rprec (d_RUN_his ['runoff'] )[..., RUN_his_keysort] 1331 RUN_drainage = rprec (d_RUN_his ['drainage'] )[..., RUN_his_keysort] 1332 RUN_riversret = rprec (d_RUN_his ['riversret'] )[..., RUN_his_keysort] 1333 1334 RUN_coastalflow_cpl = rprec (d_RUN_his ['coastalflow_cpl'])[..., RUN_his_keysort] 1335 RUN_riverflow_cpl = rprec (d_RUN_his ['riverflow_cpl'] )[..., RUN_his_keysort] 1336 1337 Step = 0 1338 1235 1339 if SRF_HIS == 'latlon' : 1236 SRF_rain = lmdz.geo2point ( d_SRF_his ['rain'] , dim1D='cell_latlon') 1237 SRF_evap = lmdz.geo2point ( d_SRF_his ['evap'] , dim1D='cell_latlon') 1238 SRF_snowf = lmdz.geo2point ( d_SRF_his ['snowf'] , dim1D='cell_latlon') 1239 SRF_subli = lmdz.geo2point ( d_SRF_his ['subli'] , dim1D='cell_latlon') 1240 SRF_transpir = lmdz.geo2point ( np.sum (d_SRF_his ['transpir'], axis=1), dim1D='cell_latlon' ) 1241 1242 print ( 'Step {Step}', end='' ) ; Step += 1 1340 if TestInterp : 1341 echo ( f'SRF rain TestInterp' ) 1342 SRF_rain = lmdz.geo2point ( rprec (d_SRF_his ['rain_contfrac_interp'] ), dim1D='cell') 1343 SRF_evap = lmdz.geo2point ( rprec (d_SRF_his ['evap_contfrac_interp'] ), dim1D='cell') 1344 SRF_snowf = lmdz.geo2point ( rprec (d_SRF_his ['snow_contfrac_interp'] ), dim1D='cell') 1345 SRF_subli = lmdz.geo2point ( rprec (d_SRF_his ['subli_contfrac_interp']), dim1D='cell') 1346 SRF_transpir = lmdz.geo2point ( rprec (d_SRF_his ['transpir_contfrac_interp']).sum(dim='veget'), dim1D='cell' ) 1347 SRF_rain.attrs = d_SRF_his ['rain_contfrac_interp'].attrs 1348 SRF_evap.attrs = d_SRF_his ['evap_contfrac_interp'].attrs 1349 SRF_snowf.attrs = d_SRF_his ['snow_contfrac_interp'].attrs 1350 SRF_subli.attrs = d_SRF_his ['subli_contfrac_interp'].attrs 1351 SRF_transpir.attrs = d_SRF_his ['transpir_contfrac_interp'].attrs 1352 else : 1353 echo ( f'SRF rain' ) 1354 SRF_rain = lmdz.geo2point ( rprec (d_SRF_his ['rain'] ) , dim1D='cell') 1355 SRF_evap = lmdz.geo2point ( rprec (d_SRF_his ['evap'] ) , dim1D='cell') 1356 SRF_snowf = lmdz.geo2point ( rprec (d_SRF_his ['snowf']) , dim1D='cell') 1357 SRF_subli = lmdz.geo2point ( rprec (d_SRF_his ['subli']) , dim1D='cell') 1358 SRF_transpir = lmdz.geo2point ( rprec (d_SRF_his ['transpir']).sum(dim='veget'), dim1D='cell' ) 1359 1243 1360 if SRF_HIS == 'ico' : 1244 SRF_rain = d_SRF_his ['rain'] [..., SRF_his_keysort] 1245 SRF_evap = d_SRF_his ['evap'] [..., SRF_his_keysort] 1246 SRF_snowf = d_SRF_his ['snowf'][..., SRF_his_keysort] 1247 SRF_subli = d_SRF_his ['subli'][..., SRF_his_keysort] 1248 SRF_transpir = np.sum (d_SRF_his ['transpir'], axis=1)[..., SRF_his_keysort] 1249 1250 print ( 'Step {Step}', end='' ) ; Step += 1 1361 echo ( f'SRF rain') 1362 SRF_rain = rprec (d_SRF_his ['rain'] )[..., SRF_his_keysort] 1363 SRF_evap = rprec (d_SRF_his ['evap'] )[..., SRF_his_keysort] 1364 SRF_snowf = rprec (d_SRF_his ['snowf'])[..., SRF_his_keysort] 1365 SRF_subli = rprec (d_SRF_his ['subli'])[..., SRF_his_keysort] 1366 SRF_transpir = rprec (d_SRF_his ['transpir']).sum(dim='veget')[..., SRF_his_keysort] 1367 1368 echo ( f'SRF emp' ) 1251 1369 SRF_transpir.attrs['units'] = d_SRF_his ['transpir'].attrs['units'] 1252 1370 SRF_emp = SRF_evap - SRF_rain - SRF_snowf ; SRF_emp.attrs['units'] = SRF_rain.attrs['units'] … … 1271 1389 mmd2SI (VarT) 1272 1390 1273 print ( 'Step {Step}', end='' ) ; Step += 1 1391 echo ( f'RUN input' ) 1274 1392 RUN_input = RUN_runoff + RUN_drainage 1275 1393 RUN_output = RUN_coastalflow + RUN_riverflow 1276 1394 1277 print ( 'Step {Step}', end='' ) ; Step += 1 1395 echo ( f'ATM flw_wbilo' ) 1278 1396 ATM_flx_wbilo = ATM_flux_int ( ATM_wbilo ) 1397 ATM_flx_wevap = ATM_flux_int ( ATM_wevap ) 1398 ATM_flx_wprecip = ATM_flux_int ( ATM_wprecip ) 1399 ATM_flx_wsnow = ATM_flux_int ( ATM_wsnow ) 1400 ATM_flx_wrain = ATM_flux_int ( ATM_wrain ) 1401 ATM_flx_wemp = ATM_flux_int ( ATM_wemp ) 1402 1279 1403 ATM_flx_wbilo_lic = ATM_flux_int ( ATM_wbilo_lic ) 1280 1404 ATM_flx_wbilo_oce = ATM_flux_int ( ATM_wbilo_oce ) … … 1285 1409 ATM_flx_fqfonte = ATM_flux_int ( ATM_fqfonte ) 1286 1410 1287 print ( 'Step {Step}', end='' ) ; Step += 1 1411 LIC_flx_calving = LIC_flux_int ( ATM_fqcalving ) 1412 LIC_flx_fqfonte = LIC_flux_int ( ATM_fqfonte ) 1413 1414 echo ( f'ATM flx precip' ) 1288 1415 ATM_flx_precip = ATM_flux_int ( ATM_precip ) 1289 1416 ATM_flx_snowf = ATM_flux_int ( ATM_snowf ) … … 1291 1418 ATM_flx_runlic = ATM_flux_int ( ATM_runofflic ) 1292 1419 1293 print ( 'Step {Step}', end='' ) ; Step += 1 1420 LIC_flx_precip = LIC_flux_int ( ATM_precip ) 1421 LIC_flx_snowf = LIC_flux_int ( ATM_snowf ) 1422 LIC_flx_evap = LIC_flux_int ( ATM_evap ) 1423 LIC_flx_runlic = LIC_flux_int ( ATM_runofflic ) 1424 1425 echo ( f'ATM flx_wrain_ter' ) 1294 1426 ATM_flx_wrain_ter = ATM_flux_int ( ATM_wrain_ter ) 1295 1427 ATM_flx_wrain_oce = ATM_flux_int ( ATM_wrain_oce ) … … 1303 1435 ATM_flx_wsnow_sic = ATM_flux_int ( ATM_wsnow_sic ) 1304 1436 ATM_flx_wsnow_sea = ATM_flux_int ( ATM_wsnow_sea ) 1305 print ( 'Step {Step}', end='' ) ; Step += 1 1306 ATM_flx_wrain_ter = ATM_flux_int ( ATM_wrain_ter ) 1307 ATM_flx_wrain_oce = ATM_flux_int ( ATM_wrain_oce ) 1308 ATM_flx_wrain_lic = ATM_flux_int ( ATM_wrain_lic ) 1309 ATM_flx_wrain_sic = ATM_flux_int ( ATM_wrain_sic ) 1310 ATM_flx_wrain_sea = ATM_flux_int ( ATM_wrain_sea ) 1437 1438 echo ( f'ATM flx_evap_ter' ) 1311 1439 ATM_flx_wevap_ter = ATM_flux_int ( ATM_wevap_ter ) 1312 1440 ATM_flx_wevap_oce = ATM_flux_int ( ATM_wevap_oce ) … … 1325 1453 ATM_flx_wemp_sea = ATM_flux_int ( ATM_wemp_sea ) 1326 1454 1327 ATM_flx_emp = ATM_flux_int ( ATM_emp )1328 1329 print ( 'Step {Step}', end='' ) ; Step += 1 1455 ATM_flx_emp = ATM_flux_int ( ATM_emp ) 1456 1457 echo ( f'RUN flx_coastal' ) 1330 1458 RUN_flx_coastal = ONE_flux_int ( RUN_coastalflow) 1459 echo ( f'RUN flx_river' ) 1331 1460 RUN_flx_river = ONE_flux_int ( RUN_riverflow ) 1461 echo ( f'RUN flx_coastal_cpl' ) 1332 1462 RUN_flx_coastal_cpl = ONE_flux_int ( RUN_coastalflow_cpl) 1463 echo ( f'RUN flx_river_cpl' ) 1333 1464 RUN_flx_river_cpl = ONE_flux_int ( RUN_riverflow_cpl ) 1465 echo ( f'RUN flx_drainage' ) 1334 1466 RUN_flx_drainage = SRF_flux_int ( RUN_drainage ) 1467 echo ( f'RUN flx_riversset' ) 1335 1468 RUN_flx_riversret = SRF_flux_int ( RUN_riversret ) 1469 echo ( f'RUN flx_runoff' ) 1336 1470 RUN_flx_runoff = SRF_flux_int ( RUN_runoff ) 1471 echo ( f'RUN flx_input' ) 1337 1472 RUN_flx_input = SRF_flux_int ( RUN_input ) 1473 echo ( f'RUN flx_output' ) 1338 1474 RUN_flx_output = ONE_flux_int ( RUN_output ) 1339 1475 1340 print ( 'Step {Step}', end='' ) ; Step += 1 1341 RUN_flx_bil = RUN_flx_input - RUN_flx_output 1342 RUN_flx_rivcoa = RUN_flx_coastal + RUN_flx_river 1343 1344 prtFlux ('wbilo_oce ', ATM_flx_wbilo_oce , 'f' ) 1345 prtFlux ('wbilo_sic ', ATM_flx_wbilo_sic , 'f' ) 1346 prtFlux ('wbilo_sic+oce ', ATM_flx_wbilo_sea , 'f' ) 1347 prtFlux ('wbilo_ter ', ATM_flx_wbilo_ter , 'f' ) 1348 prtFlux ('wbilo_lic ', ATM_flx_wbilo_lic , 'f' ) 1349 prtFlux ('Sum wbilo_* ', ATM_flx_wbilo , 'f', True) 1350 prtFlux ('E-P ', ATM_flx_emp , 'f', True) 1351 prtFlux ('calving ', ATM_flx_calving , 'f' ) 1352 prtFlux ('fqfonte ', ATM_flx_fqfonte , 'f' ) 1353 prtFlux ('precip ', ATM_flx_precip , 'f' ) 1354 prtFlux ('snowf ', ATM_flx_snowf , 'f' ) 1355 prtFlux ('evap ', ATM_flx_evap , 'f' ) 1356 prtFlux ('runoff lic ', ATM_flx_runlic , 'f' ) 1357 1358 prtFlux ('ATM_flx_wemp_lic ', ATM_flx_wemp_lic , 'f' ) 1359 prtFlux ('ATM_flx_wemp_oce ', ATM_flx_wemp_oce , 'f' ) 1360 prtFlux ('ATM_flx_wemp_sic ', ATM_flx_wemp_sic , 'f' ) 1361 prtFlux ('ATM_flx_wemp_ter ', ATM_flx_wemp_ter , 'f' ) 1362 1363 prtFlux ('ATM_flx_wprecip_lic ', ATM_flx_wprecip_lic , 'f' ) 1364 prtFlux ('ATM_flx_wprecip_oce ', ATM_flx_wprecip_oce , 'f' ) 1365 prtFlux ('ATM_flx_wprecip_sic ', ATM_flx_wprecip_sic , 'f' ) 1366 prtFlux ('ATM_flx_wprecip_ter ', ATM_flx_wprecip_ter , 'f' ) 1367 1368 prtFlux ('ATM_flx_wrain_lic ', ATM_flx_wrain_lic , 'f' ) 1369 prtFlux ('ATM_flx_wrain_oce ', ATM_flx_wrain_oce , 'f' ) 1370 prtFlux ('ATM_flx_wrain_sic ', ATM_flx_wrain_sic , 'f' ) 1371 prtFlux ('ATM_flx_wrain_ter ', ATM_flx_wrain_ter , 'f' ) 1372 1373 prtFlux ('ATM_flx_wsnow_lic ', ATM_flx_wsnow_lic , 'f' ) 1374 prtFlux ('ATM_flx_wsnow_oce ', ATM_flx_wsnow_oce , 'f' ) 1375 prtFlux ('ATM_flx_wsnow_sic ', ATM_flx_wsnow_sic , 'f' ) 1376 prtFlux ('ATM_flx_wsnow_ter ', ATM_flx_wsnow_ter , 'f' ) 1377 1378 prtFlux ('ATM_flx_wevap_lic ', ATM_flx_wevap_lic , 'f' ) 1379 prtFlux ('ATM_flx_wevap_oce ', ATM_flx_wevap_oce , 'f' ) 1380 prtFlux ('ATM_flx_wevap_sic ', ATM_flx_wevap_sic , 'f' ) 1381 prtFlux ('ATM_flx_wevap_ter ', ATM_flx_wevap_ter , 'f' ) 1382 1383 prtFlux ('ATM_flx_wevap_lic ', ATM_flx_wevap_lic , 'f' ) 1384 prtFlux ('ATM_flx_wevap_oce ', ATM_flx_wevap_oce , 'f' ) 1385 prtFlux ('ATM_flx_wevap_sic ', ATM_flx_wevap_sic , 'f' ) 1386 prtFlux ('ATM_flx_wevap_ter ', ATM_flx_wevap_ter , 'f' ) 1476 echo ( f'RUN flx_bil' ) ; Step += 1 1477 #RUN_flx_bil = RUN_flx_input - RUN_flx_output 1478 #RUN_flx_rivcoa = RUN_flx_coastal + RUN_flx_river 1479 1480 RUN_flx_bil = ONE_flux_int ( RUN_input - RUN_output) 1481 RUN_flx_rivcoa = ONE_flux_int ( RUN_coastalflow + RUN_riverflow) 1482 1483 prtFlux ('wbilo_oce ', ATM_flx_wbilo_oce , 'f' ) 1484 prtFlux ('wbilo_sic ', ATM_flx_wbilo_sic , 'f' ) 1485 prtFlux ('wbilo_sic+oce ', ATM_flx_wbilo_sea , 'f' ) 1486 prtFlux ('wbilo_ter ', ATM_flx_wbilo_ter , 'f' ) 1487 prtFlux ('wbilo_lic ', ATM_flx_wbilo_lic , 'f' ) 1488 prtFlux ('Sum wbilo_* ', ATM_flx_wbilo , 'f', True) 1489 prtFlux ('E-P ', ATM_flx_emp , 'f', True) 1490 prtFlux ('calving ', ATM_flx_calving , 'f' ) 1491 prtFlux ('fqfonte ', ATM_flx_fqfonte , 'f' ) 1492 prtFlux ('precip ', ATM_flx_precip , 'f' ) 1493 prtFlux ('snowf ', ATM_flx_snowf , 'f' ) 1494 prtFlux ('evap ', ATM_flx_evap , 'f' ) 1495 prtFlux ('runoff lic ', ATM_flx_runlic , 'f' ) 1496 1497 prtFlux ('ATM_flx_wevap* ', ATM_flx_wevap , 'f' ) 1498 prtFlux ('ATM_flx_wrain* ', ATM_flx_wrain , 'f' ) 1499 prtFlux ('ATM_flx_wsnow* ', ATM_flx_wsnow , 'f' ) 1500 prtFlux ('ATM_flx_wprecip* ', ATM_flx_wprecip , 'f' ) 1501 prtFlux ('ATM_flx_wemp* ', ATM_flx_wemp , 'f', True ) 1502 1503 prtFlux ('ERROR evap ', ATM_flx_wevap - ATM_flx_evap , 'e', True ) 1504 prtFlux ('ERROR precip ', ATM_flx_wprecip - ATM_flx_precip, 'e', True ) 1505 prtFlux ('ERROR snow ', ATM_flx_wsnow - ATM_flx_snowf , 'e', True ) 1506 prtFlux ('ERROR emp ', ATM_flx_wemp - ATM_flx_emp , 'e', True ) 1507 1387 1508 1388 1509 echo ( '\n====================================================================================' ) … … 1401 1522 1402 1523 ATM_flx_budget = -ATM_flx_wbilo + ATM_flx_calving + ATM_flx_runlic #+ ATM_flx_fqfonte + RUN_flx_river 1524 1525 1403 1526 echo ('') 1404 1527 #echo (' Global {:12.3e} kg | {:12.4f} Sv | {:12.4f} m '.format ( ATM_flx_budget , ATM_flx_budget / dtime_sec*1E-9, ATM_flx_budget /ATM_aire_sea_tot/ATM_rho )) … … 1427 1550 echo ( '\n====================================================================================' ) 1428 1551 1429 ATM_flx_runofflic_lic = ATM_flux_int ( ATM_runofflic * ATM_flic ) 1430 1431 LIC_flx_budget1 = -ATM_flx_wemp_lic - ATM_flx_calving - ATM_flx_fqfonte 1432 LIC_flx_budget2 = -ATM_flx_wbilo_lic - ATM_flx_calving - ATM_flx_fqfonte 1433 LIC_flx_budget3 = -ATM_flx_wbilo_lic - ATM_flx_runofflic_lic 1552 LIC_flx_budget1 = Sprec ( [-ATM_flx_wemp_lic , -LIC_flx_calving , -LIC_flx_fqfonte] ) 1553 LIC_flx_budget2 = Sprec ( [-ATM_flx_wbilo_lic , -LIC_flx_calving , -LIC_flx_fqfonte] ) 1554 LIC_flx_budget3 = Sprec ( [-ATM_flx_wbilo_lic , -LIC_flx_runlic] ) 1555 LIC_flx_budget4 = Sprec ( [-ATM_flx_wemp_lic , -LIC_flx_runlic] ) 1434 1556 1435 1557 echo ( f'-- LIC -- {Title} ' ) … … 1438 1560 echo ( f'Mass qs begin = {LIC_mas_qs_beg :12.6e} kg | Mass end = {LIC_mas_qs_end :12.6e} kg' ) 1439 1561 echo ( f'Mass runlic0 begin = {LIC_mas_runlic0_beg:12.6e} kg | Mass end = {LIC_mas_runlic0_end:12.6e} kg' ) 1440 prtFlux ( 'dmass (LIC sno) ', dLIC_mas_sno , 'f', True, width=65 ) 1441 prtFlux ( 'dmass (LIC qs) ', dLIC_mas_qs , 'e', True, width=65 ) 1442 prtFlux ( 'dmass (LIC wat) ', dLIC_mas_wat , 'f', True, width=65 ) 1443 prtFlux ( 'dmass (LIC runlic0) ', dLIC_mas_runlic0 , 'e', True, width=65 ) 1444 prtFlux ( 'dmass (LIC total) ', dLIC_mas_wat , 'e', True, width=65 ) 1445 prtFlux ( 'LIC ATM_flx_wemp_lic ', ATM_flx_wemp_lic , 'f', True, width=65 ) 1446 prtFlux ( 'LIC ATM_flx_fqfonte ', ATM_flx_fqfonte , 'f', True, width=65 ) 1447 prtFlux ( 'LIC ATM_flx_calving ', ATM_flx_calving , 'f', True, width=65 ) 1448 prtFlux ( 'LIC ATM_flx_runofflic ', ATM_flx_runofflic_lic , 'f', True, width=65 ) 1449 prtFlux ( 'LIC fqfonte + calving ', ATM_flx_calving+ATM_flx_fqfonte , 'f', True, width=65 ) 1450 prtFlux ( 'LIC fluxes 1 (wevap - precip*frac_lic - fqcalving - fqfonte) ', LIC_flx_budget1 , 'f', True, width=65 ) 1451 prtFlux ( 'LIC fluxes 2 (-wbilo_lic - fqcalving - fqfonte) ', LIC_flx_budget2 , 'f', True, width=65 ) 1452 prtFlux ( 'LIC fluxes 3 (-wbilo_lic - runofflic*frac_lic) ', LIC_flx_budget3 , 'f', True, width=65 ) 1453 prtFlux ( 'LIC error 1 ', LIC_flx_budget1-dLIC_mas_wat , 'e', True, width=65 ) 1454 prtFlux ( 'LIC error 2 ', LIC_flx_budget2-dLIC_mas_wat , 'e', True, width=65 ) 1455 prtFlux ( 'LIC error 3 ', LIC_flx_budget3-dLIC_mas_wat , 'e', True, width=65 ) 1562 prtFlux ( 'dmass (LIC sno) ', dLIC_mas_sno , 'f', True, width=45 ) 1563 prtFlux ( 'dmass (LIC qs) ', dLIC_mas_qs , 'e', True, width=45 ) 1564 prtFlux ( 'dmass (LIC wat) ', dLIC_mas_wat , 'f', True, width=45 ) 1565 prtFlux ( 'dmass (LIC runlic0) ', dLIC_mas_runlic0 , 'e', True, width=45 ) 1566 prtFlux ( 'dmass (LIC total) ', dLIC_mas_wat , 'e', True, width=45 ) 1567 prtFlux ( 'LIC ATM_flx_wemp_lic ', ATM_flx_wemp_lic , 'f', True, width=45 ) 1568 prtFlux ( 'LIC LIC_flx_fqfonte ', LIC_flx_fqfonte , 'f', True, width=45 ) 1569 prtFlux ( 'LIC LIC_flx_calving ', LIC_flx_calving , 'f', True, width=45 ) 1570 prtFlux ( 'LIC LIC_flx_runofflic ', LIC_flx_runlic , 'f', True, width=45 ) 1571 prtFlux ( 'LIC fqfonte + calving ', LIC_flx_calving+LIC_flx_fqfonte , 'f', True, width=45 ) 1572 prtFlux ( 'LIC fluxes 1 ( wemp_lic - fqcalving - fqfonte)) ', LIC_flx_budget1 , 'f', True, width=45 ) 1573 prtFlux ( 'LIC fluxes 2 (-wbilo_lic - fqcalving - fqfonte) ', LIC_flx_budget2 , 'f', True, width=45 ) 1574 prtFlux ( 'LIC fluxes 3 (-wbilo_lic - runofflic*frac_lic) ', LIC_flx_budget3 , 'f', True, width=45 ) 1575 prtFlux ( 'LIC fluxes 3 ( wemp_lic - runofflic*frac_lic) ', LIC_flx_budget4 , 'f', True, width=45 ) 1576 prtFlux ( 'LIC error 1 ', LIC_flx_budget1-dLIC_mas_wat , 'e', True, width=45 ) 1577 prtFlux ( 'LIC error 2 ', LIC_flx_budget2-dLIC_mas_wat , 'e', True, width=45 ) 1578 prtFlux ( 'LIC error 3 ', LIC_flx_budget3-dLIC_mas_wat , 'e', True, width=45 ) 1456 1579 echo ( 'LIC error (wevap - precip*frac_lic - fqcalving - fqfonte) = {:12.4e} (rel) '.format ( (LIC_flx_budget1-dLIC_mas_wat)/dLIC_mas_wat) ) 1457 1580 echo ( 'LIC error (-wbilo_lic - fqcalving - fqfonte) = {:12.4e} (rel) '.format ( (LIC_flx_budget2-dLIC_mas_wat)/dLIC_mas_wat) ) … … 1468 1591 SRF_flx_emp = SRF_flux_int ( SRF_emp ) 1469 1592 1470 RUN_flx_torouting = RUN_flx_runoff + RUN_flx_drainage1471 RUN_flx_fromrouting = RUN_flx_coastal + RUN_flx_river1472 1473 SRF_flx_all = SRF_flx_rain + SRF_flx_snowf - SRF_flx_evap - RUN_flx_runoff - RUN_flx_drainage1593 RUN_flx_torouting = SRF_flux_int ( RUN_runoff + RUN_drainage) 1594 RUN_flx_fromrouting = ONE_flux_int ( RUN_coastalflow + RUN_riverflow ) 1595 1596 SRF_flx_all = SRF_flux_int ( SRF_rain + SRF_snowf - SRF_evap - RUN_runoff - RUN_drainage ) 1474 1597 1475 1598 prtFlux ('rain ', SRF_flx_rain , 'f' ) -
TOOLS/WATER_BUDGET/CPL_waterbudget.py
r6508 r6647 12 12 ## 13 13 ## 14 # #SVN information14 # SVN information 15 15 # $Author$ 16 16 # $Date$ … … 19 19 # $HeadURL$ 20 20 21 21 # SVN Information 22 SVN = { 23 'Author' : "$Author$", 24 'Date' : "$Date$", 25 'Revision': "$Revision$", 26 'Id' : "$Id$", 27 'HeadURL' : "$HeadUrl: $" 28 } 22 29 ### 23 30 ## Import system modules … … 27 34 from pathlib import Path 28 35 36 ### 37 ## Import system modules 38 import sys, os, shutil#, subprocess, platform 39 import configparser, re 40 41 ## Import needed scientific modules 42 import numpy as np, xarray as xr 43 29 44 # Check python version 30 45 if sys.version_info < (3, 8, 0) : … … 32 47 raise Exception ( "Minimum Python version is 3.8" ) 33 48 34 ## Import local module 49 ## Import local modules 35 50 import WaterUtils as wu 51 import libIGCM_sys 52 import nemo, lmdz 53 54 from WaterUtils import VarInt, Rho, Ra, Grav, ICE_rho_ice, ICE_rho_sno, OCE_rho_liq, ATM_rho, SRF_rho, RUN_rho, ICE_rho_pnd, YearLength 36 55 37 56 ## Creates parser for reading .ini input file 38 config = configparser.ConfigParser (interpolation=configparser.ExtendedInterpolation() ) 57 ## ------------------------------------------- 58 config = configparser.ConfigParser ( interpolation=configparser.ExtendedInterpolation() ) 39 59 config.optionxform = str # To keep capitals 40 60 41 61 ## Experiment parameters 42 ATM=None ; ATM_HIS='latlon' ; SRF_HIS='latlon' ; ORCA=None ; NEMO=None ; OCE_relax=False ; OCE_icb=False ; Coupled=False ; Routing=None ; TarRestartPeriod_beg=None ; TarRestartPeriod_end=None ; Comment=None ; Period=None ; Title=None 62 ## --------------------- 63 ATM=None ; ATM_HIS='latlon' ; SRF_HIS='latlon' ; RUN_HIS='latlon' ; ORCA=None ; NEMO=None ; OCE_relax=False 64 OCE_icb=False ; Coupled=False ; Routing=None ; TestInterp=None 65 TarRestartPeriod_beg=None ; TarRestartPeriod_end=None ; Comment=None ; Period=None ; Title=None 66 YearBegin=None ; YearEnd=None ; DateBegin=None ; DateEnd=None 43 67 44 68 ## 45 ARCHIVE=None ; STORAGE=None ; SCRATCHDIR=None ; R_IN=None ; rebuild=None 46 TmpDir=None ; RunDir=None ; FileOut=None ; dir_ATM_his=None ; dir_SRF_his=None ; dir_OCE_his=None ; dir_ICE_his=None ; FileCommon=None 47 file_ATM_his=None ; file_SRF_his=None ; file_RUN_his=None ; file_OCE_his=None ; file_ICE_his=None ; file_OCE_sca=None 48 tar_restart_beg=None ; tar_restart_end=None ; file_ATM_beg=None ; file_ATM_end=None ; file_DYN_beg=None ; file_DYN_end=None ; file_SRF_beg=None ; file_SRF_end=None 49 file_RUN_beg=None ; file_RUN_end=None ; file_RUN_end=None ; file_OCE_beg=None ; file_ICE_beg=None ; file_OCE_beg=None ; file_OCE_end=None ; file_OCE_srf=None ; file_OCE_sca=None ; file_ICE_beg=None ; file_OCE_end=None ; file_ICE_end=None 50 51 # Read command line arguments 69 ARCHIVE=None ; STORAGE=None ; SCRATCHDIR=None ; R_IN=None ; rebuild=None ; TmpDir=None 70 FileDir=None ; FileOut=None 71 dir_ATM_his=None ; dir_SRF_his=None ; dir_OCE_his=None ; dir_ICE_his=None 72 FileCommon=None ; file_ATM_his=None ; file_SRF_his=None ; file_RUN_his=None 73 file_OCE_his=None ; file_ICE_his=None ; file_OCE_sca=None ; file_OCE_srf=None 74 tar_restart_beg=None ; tar_restart_end=None ; file_ATM_beg=None ; file_ATM_end=None ; file_DYN_beg=None 75 file_DYN_end=None ; file_SRF_beg=None ; file_SRF_end=None 76 file_RUN_beg=None ; file_RUN_end=None ; file_RUN_end=None ; file_OCE_beg=None 77 file_ICE_beg=None ; file_OCE_beg=None 78 file_OCE_end=None ; file_ICE_beg=None ; file_OCE_end=None ; file_ICE_end=None 79 tar_restart_beg_ATM=None ; tar_restart_beg_DYN=None ; tar_restart_beg_SRF=None 80 tar_restart_beg_RUN=None ; tar_restart_beg_OCE=None ; tar_restart_beg_ICE=None 81 tar_restart_end_ATM=None ; tar_restart_end_DYN=None ; tar_restart_end_SRF=None 82 tar_restart_end_RUN=None ; tar_restart_end_OCE=None ; tar_restart_end_ICE=None 83 ContinueOnError=False ; ErrorCount=0 ; SortIco = False 84 85 ## 86 ## Precision of history file reading 87 ## --------------------------------- 88 # Default is float (full precision). Degrade the precision by using np.float32 89 # Restart file are always read at the full precision 90 readPrec=float 91 92 ## Read command line arguments 93 ## --------------------------- 52 94 print ( "Name of Python script:", sys.argv[0] ) 53 95 IniFile = sys.argv[1] 54 # Text existence of IniFile 96 97 # Test existence of IniFile 55 98 if not os.path.exists (IniFile ) : 56 99 raise FileExistsError ( f"File not found : {IniFile = }" ) … … 63 106 FullIniFile = 'full_' + IniFile 64 107 108 ## Reading config.card if possible 109 ## ------------------------------- 110 ConfigCard = None 111 112 if 'Experiment' in config.keys () : ## Read Experiment on Config file if possible 113 if 'ConfigCard' in config['Experiment'].keys () : 114 ConfigCard = config['Experiment']['ConfigCard'] 115 print ( f'{ConfigCard=}' ) 116 117 if ConfigCard : ## Read config card if it exists 118 # Text existence of ConfigCard 119 if os.path.exists ( ConfigCard ) : 120 print ( f'Reading Config Card : {ConfigCard}' ) 121 ## Creates parser for reading .ini input file 122 MyReader = configparser.ConfigParser (interpolation=configparser.ExtendedInterpolation() ) 123 MyReader.optionxform = str # To keep capitals 124 125 MyReader.read (ConfigCard) 126 127 for VarName in ['JobName', 'ExperimentName', 'SpaceName', 'LongName', 'ModelName', 'TagName'] : 128 if VarName in MyReader['UserChoices'].keys() : 129 locals()[VarName] = MyReader['UserChoices'][VarName] 130 exec ( f'{VarName} = wu.setBool ({VarName})' ) 131 exec ( f'{VarName} = wu.setNum ({VarName})' ) 132 exec ( f'{VarName} = wu.setNone ({VarName})' ) 133 exec ( f'wu.{VarName} = {VarName}' ) 134 print ( f' {VarName:21} set to : {locals()[VarName]:}' ) 135 136 for VarName in ['PackFrequency'] : 137 if VarName in MyReader['Post'].keys() : 138 locals()[VarName] = MyReader['Post'][VarName] 139 exec ( f'{VarName} = wu.setBool ({VarName})' ) 140 exec ( f'{VarName} = wu.setNum ({VarName})' ) 141 exec ( f'{VarName} = wu.setNone ({VarName})' ) 142 exec ( f'wu.{VarName} = {VarName}' ) 143 print ( f' {VarName:21} set to : {locals()[VarName]:}' ) 144 else : 145 raise FileExistsError ( f"File not found : {ConfigCard = }" ) 146 147 65 148 ## Reading config file 66 for Section in ['Experiment', 'libIGCM', 'Files', 'Physics' ] : 149 ## ------------------- 150 for Section in ['Config', 'Experiment', 'libIGCM', 'Files', 'Physics' ] : 67 151 if Section in config.keys () : 68 print ( f' Reading [{Section}]' )152 print ( f'\nReading [{Section}]' ) 69 153 for VarName in config[Section].keys() : 70 154 locals()[VarName] = config[Section][VarName] 71 exec ( f'{VarName} = wu.setBool ({VarName})' )72 exec ( f'{VarName} = wu.setNum ({VarName})' )73 exec ( f'{VarName} = wu.setNone ({VarName})' )74 exec (f'wu.{VarName} = {VarName}' )75 print ( '{:25} set to : {:}'.format (VarName, locals()[VarName]))155 exec ( f'{VarName} = wu.setBool ({VarName})' ) 156 exec ( f'{VarName} = wu.setNum ({VarName})' ) 157 exec ( f'{VarName} = wu.setNone ({VarName})' ) 158 exec ( f'wu.{VarName} = {VarName}' ) 159 print ( f' {VarName:21} set to : {locals()[VarName]}' ) 76 160 #exec ( f'del {VarName}' ) 77 161 78 #-- Some physical constants 79 if wu.unDefined ( 'Ra' ) : Ra = 6366197.7236758135 #-- Earth Radius (m) 80 if wu.unDefined ( 'Grav' ) : Grav = 9.81 #-- Gravity (m^2/s 81 if wu.unDefined ( 'ICE_rho_ice' ) : ICE_rho_ice = 917.0 #-- Ice volumic mass (kg/m3) in LIM3 82 if wu.unDefined ( 'ICE_rho_sno') : ICE_rho_sno = 330.0 #-- Snow volumic mass (kg/m3) in LIM3 83 if wu.unDefined ( 'OCE_rho_liq' ) : OCE_rho_liq = 1026.0 #-- Ocean water volumic mass (kg/m3) in NEMO 84 if wu.unDefined ( 'ATM_rho' ) : ATM_rho = 1000.0 #-- Water volumic mass in atmosphere (kg/m^3) 85 if wu.unDefined ( 'SRF_rho' ) : SRF_rho = 1000.0 #-- Water volumic mass in surface reservoir (kg/m^3) 86 if wu.unDefined ( 'RUN_rho' ) : RUN_rho = 1000.0 #-- Water volumic mass of rivers (kg/m^3) 87 if wu.unDefined ( 'ICE_rho_pnd' ) : ICE_rho_pnd = 1000. #-- Water volumic mass in ice ponds (kg/m^3) 88 if wu.unDefined ( 'YearLength' ) : YearLength = 365.25 * 24. * 60. * 60. #-- Year length (s) - Use only to compute drif in approximate unit 89 90 # Set libIGCM and machine dependant values 91 if not 'Files' in config.keys() : config['Files'] = {} 92 93 config['Physics'] = { 'Ra':Ra, 'Grav':Grav, 'ICE_rho_ice':ICE_rho_ice, 'ICE_rho_sno':ICE_rho_sno, 'OCE_rho_liq':OCE_rho_liq, 'ATM_rho':ATM_rho, 'SRF_rho':SRF_rho, 'RUN_rho':RUN_rho} 162 print ( f'\nConfig file readed : {IniFile} ' ) 163 164 ## 165 ## Reading prec 166 if wu.unDefined ( 'readPrec' ) : 167 readPrec = np.float64 168 else : 169 if readPrec in ["float", "float64", "r8", "double", "<class 'float'>" ] : readPrec = float 170 if readPrec in [ "float32", "r4", "single", "<class 'numpy.float32'>" ] : readPrec = np.float32 171 if readPrec in [ "float16", "r2", "half" , "<class 'numpy.float16'>" ] : readPrec = np.float16 172 173 ## Some physical constants 174 ## ======================= 175 if wu.unDefined ( 'Ra' ) : Ra = wu.Ra #-- Earth Radius (m) 176 if wu.unDefined ( 'Grav' ) : Grav = wu.Grav #-- Gravity (m^2/s 177 if wu.unDefined ( 'ICE_rho_ice' ) : ICE_rho_ice = wu.ICE_rho_ice #-- Ice volumic mass (kg/m3) in LIM3 178 if wu.unDefined ( 'ICE_rho_sno') : ICE_rho_sno = wu.ICE_rho_sno #-- Snow volumic mass (kg/m3) in LIM3 179 if wu.unDefined ( 'OCE_rho_liq' ) : OCE_rho_liq = wu.OCE_rho_liq #-- Ocean water volumic mass (kg/m3) in NEMO 180 if wu.unDefined ( 'ATM_rho' ) : ATM_rho = wu.ATM_rho #-- Water volumic mass in atmosphere (kg/m^3) 181 if wu.unDefined ( 'SRF_rho' ) : SRF_rho = wu.SRF_rho #-- Water volumic mass in surface reservoir (kg/m^3) 182 if wu.unDefined ( 'RUN_rho' ) : RUN_rho = wu.RUN_rho #-- Water volumic mass of rivers (kg/m^3) 183 if wu.unDefined ( 'ICE_rho_pnd' ) : ICE_rho_pnd = wu.ICE_rho_pnd #-- Water volumic mass in ice ponds (kg/m^3) 184 if wu.unDefined ( 'YearLength' ) : YearLength = wu.YearLength #-- Year length (s) 185 186 ## Set libIGCM and machine dependant values 187 ## ---------------------------------------- 188 if not 'Files' in config.keys () : config['Files'] = {} 189 190 config['Physics'] = { 'Ra':str(Ra), 'Grav':str(Grav), 'ICE_rho_ice':str(ICE_rho_ice), 'ICE_rho_sno':str(ICE_rho_sno), 191 'OCE_rho_liq':str(OCE_rho_liq), 'ATM_rho':str(ATM_rho), 'SRF_rho':str(SRF_rho), 'RUN_rho':str(RUN_rho)} 192 193 config['Config'] = { 'ContinueOnError':str(ContinueOnError), 'SortIco':str(SortIco), 'TestInterp':str(TestInterp), 'readPrec':str(readPrec) } 94 194 95 195 ## -------------------------- … … 97 197 LMDZ = ( 'LMD' in wu.ATM ) 98 198 99 with open ('SetLibIGCM.py') as f: exec ( f.read() ) 199 mm = libIGCM_sys.config ( TagName=TagName, SpaceName=SpaceName, ExperimentName=ExperimentName, JobName=JobName, User=User, Group=Group, 200 ARCHIVE=None, SCRATCHDIR=None, STORAGE=None, R_IN=None, R_OUT=None, R_FIG=None, rebuild=None, TmpDir=None, 201 R_SAVE=None, R_FIGR=None, R_BUFR=None, R_BUF_KSH=None, REBUILD_DIR=None, POST_DIR=None ) 202 globals().update(mm) 203 100 204 config['Files']['TmpDir'] = TmpDir 101 102 if libIGCM : 103 config['libIGCM'] = {'ARCHIVE':ARCHIVE, 'STORAGE':STORAGE, 'SCRATCHDIR':SCRATCHDIR, 'R_IN':R_IN, 'rebuild':rebuild } 104 105 # Import specific module 106 import nemo, lmdz 107 ## Now import needed scientific modules 108 import xarray as xr 109 110 # Output file with water budget diagnostics 111 if wu.unDefined ( 'FileOut' ) : FileOut = f'CPL_waterbudget_{JobName}_{YearBegin}_{YearEnd}.out' 205 config['libIGCM'] = { 'ARCHIVE':ARCHIVE, 'STORAGE':STORAGE, 'TmpDir':TmpDir, 'R_IN':R_IN, 'rebuild':rebuild } 206 207 ## Defines begining and end of experiment 208 ## -------------------------------------- 209 if wu.unDefined ( 'DateBegin' ) : 210 DateBegin = f'{YearBegin}0101' 211 config['Experiment']['DateBegin'] = str(DateBegin) 212 else : 213 YearBegin, MonthBegin, DayBegin = wu.SplitDate ( DateBegin ) 214 DateBegin = wu.FormatToGregorian (DateBegin) 215 config['Experiment']['YearBegin'] = str(YearBegin) 216 217 if wu.unDefined ( 'DateEnd' ) : 218 DateEnd = f'{YearEnd}1231' 219 config['Experiment']['DateEnd'] = str(DateEnd) 220 else : 221 YearEnd, MonthEnd, DayEnd = wu.SplitDate ( DateEnd ) 222 DateEnd = wu.FormatToGregorian (DateEnd) 223 config['Experiment']['DateEnd'] = str(DateEnd) 224 225 if wu.unDefined ( 'PackFrequency' ) : 226 PackFrequency = YearEnd - YearBegin + 1 227 config['Experiment']['PackFrequency'] = f'{PackFrequency}' 228 229 if type ( PackFrequency ) == str : 230 if 'Y' in PackFrequency : PackFrequency = PackFrequency.replace ( 'Y', '') 231 if 'M' in PackFrequency : PackFrequency = PackFrequency.replace ( 'M', '') 232 PackFrequency = int ( PackFrequency ) 233 234 ## Output file with water budget diagnostics 235 ## ----------------------------------------- 236 if wu.unDefined ( 'FileOut' ) : 237 FileOut = f'CPL_waterbudget_{JobName}_{YearBegin}_{YearEnd}' 238 if ICO : 239 if ATM_HIS == 'latlon' : FileOut = f'{FileOut}_LATLON' 240 if ATM_HIS == 'ico' : FileOut = f'{FileOut}_ICO' 241 if readPrec == np.float32 : FileOut = f'{FileOut}_float32' 242 FileOut = f'{FileOut}.out' 243 112 244 config['Files']['FileOut'] = FileOut 113 245 114 246 f_out = open ( FileOut, mode = 'w' ) 115 247 116 # Useful functions 248 ## Useful functions 249 ## ---------------- 250 if readPrec == float : 251 def rprec (tab) : return tab 252 else : 253 def rprec (tab) : return tab.astype(readPrec).astype(float) 254 117 255 def kg2Sv (val, rho=ATM_rho) : 118 256 '''From kg to Sverdrup''' … … 124 262 125 263 def var2prt (var, small=False, rho=ATM_rho) : 126 if small : return var , kg2Sv(var, rho=rho)*1000., kg2myear(var, rho=rho)*1000 .264 if small : return var , kg2Sv(var, rho=rho)*1000., kg2myear(var, rho=rho)*1000 127 265 else : return var , kg2Sv(var, rho=rho) , kg2myear(var, rho=rho) 128 266 129 267 def prtFlux (Desc, var, Form='F', small=False, rho=ATM_rho, width=15) : 130 268 if small : 131 if Form in ['f', 'F'] : ff=" {:1 2.4e} kg | {:12.4f} mSv | {:12.4f} mm/year "132 if Form in ['e', 'E'] : ff=" {:1 2.4e} kg | {:12.4e} mSv | {:12.4e} mm/year "269 if Form in ['f', 'F'] : ff=" {:14.6e} kg | {:12.4f} mSv | {:12.4f} mm/year " 270 if Form in ['e', 'E'] : ff=" {:14.6e} kg | {:12.4e} mSv | {:12.4e} mm/year " 133 271 else : 134 if Form in ['f', 'F'] : ff=" {:1 2.4e} kg | {:12.4f} Sv | {:12.4f} m/year "135 if Form in ['e', 'E'] : ff=" {:1 2.4e} kg | {:12.4e} Sv | {:12.4e} m/year "136 echo ( (' {:>{width}} = ' +ff).format (Desc, *var2prt(var, small , rho=rho), width=width ) )272 if Form in ['f', 'F'] : ff=" {:14.6e} kg | {:12.4f} Sv | {:12.4f} m/year " 273 if Form in ['e', 'E'] : ff=" {:14.6e} kg | {:12.4e} Sv | {:12.4e} m/year " 274 echo ( (' {:>{width}} = ' +ff).format (Desc, *var2prt(var, small=small, rho=rho), width=width ) ) 137 275 return None 138 276 … … 144 282 f_out.flush () 145 283 return None 146 284 285 echo ( f'{ContinueOnError = }' ) 286 echo ( f'{SortIco = }' ) 287 echo ( f'{readPrec = }' ) 288 289 echo ( f'{JobName = }' ) 290 echo ( f'{ConfigCard = }' ) 291 echo ( f'{libIGCM = }' ) 292 echo ( f'{User = }' ) 293 echo ( f'{Group = }' ) 294 echo ( f'{Freq = }' ) 295 echo ( f'{YearBegin = }' ) 296 echo ( f'{YearEnd = }' ) 297 echo ( f'{DateBegin = }' ) 298 echo ( f'{DateEnd = }' ) 299 echo ( f'{PackFrequency = }' ) 300 echo ( f'{ATM = }' ) 301 echo ( f'{Routing = }' ) 302 echo ( f'{ORCA = }' ) 303 echo ( f'{NEMO = }' ) 304 echo ( f'{Coupled = }' ) 305 echo ( f'{ATM_HIS = }' ) 306 echo ( f'{SRF_HIS = }' ) 307 echo ( f'{RUN_HIS = }' ) 308 147 309 ## Set libIGCM directories 310 ## ----------------------- 148 311 if wu.unDefined ('R_OUT' ) : R_OUT = os.path.join ( ARCHIVE , 'IGCM_OUT' ) 149 312 if wu.unDefined ('R_BUF' ) : R_BUF = os.path.join ( SCRATCHDIR, 'IGCM_OUT' ) … … 156 319 if wu.unDefined ('R_FIGR' ) : R_FIGR = os.path.join ( STORAGE, 'IGCM_OUT', L_EXP ) 157 320 158 config['libIGCM'] = { 'R_OUT':R_OUT, 'R_BUF':R_BUF, 'L_EXP':L_EXP, 'R_BUFR':R_BUFR, 'POST_DIR':POST_DIR, 'REBUILD_DIR':REBUILD_DIR, 'R_BUF_KSH':R_BUF_KSH, 'R_FIGR':R_FIGR } 159 160 # Set directory to extract filesa 161 if RunDir == None : RunDir = os.path.join ( TmpDir, f'WATER_{JobName}_{YearBegin}_{YearEnd}' ) 162 config['Files']['RunDir'] = RunDir 163 164 if not os.path.isdir ( RunDir ) : os.makedirs ( RunDir ) 165 166 # Set directories to rebuild ocean and ice restart files 167 RunDirOCE = os.path.join ( RunDir, 'OCE' ) 168 RunDirICE = os.path.join ( RunDir, 'ICE' ) 169 #RunDirATM = os.path.join ( RunDir, 'ATM' ) 170 #RunDirSRF = os.path.join ( RunDir, 'SRF' ) 171 #RunDirRUN = os.path.join ( RunDir, 'RUN' ) 172 #RunDirDYN = os.path.join ( RunDir, 'DYN' ) 173 if not os.path.exists ( RunDirOCE ) : os.mkdir ( RunDirOCE ) 174 if not os.path.exists ( RunDirICE ) : os.mkdir ( RunDirICE ) 321 config['libIGCM'].update ( { 'R_OUT':R_OUT, 'R_BUF':R_BUF, 'L_EXP':L_EXP, 'R_BUFR':R_BUFR, 'POST_DIR':POST_DIR, 322 'REBUILD_DIR':REBUILD_DIR, 'R_BUF_KSH':R_BUF_KSH, 'R_FIGR':R_FIGR, 'rebuild':rebuild } ) 323 324 ## Set directory to extract files 325 ## ------------------------------ 326 if wu.unDefined ( 'FileDir' ) : FileDir = os.path.join ( TmpDir, f'WATER_{JobName}' ) 327 config['Files']['FileDir'] = FileDir 328 329 if not os.path.isdir ( FileDir ) : os.makedirs ( FileDir ) 330 331 ##- Set directories to rebuild ocean and ice restart files 332 if wu.unDefined ( 'FileDirOCE' ) : FileDirOCE = os.path.join ( FileDir, 'OCE' ) 333 if wu.unDefined ( 'FileDirICE' ) : FileDirICE = os.path.join ( FileDir, 'ICE' ) 334 if not os.path.exists ( FileDirOCE ) : os.mkdir ( FileDirOCE ) 335 if not os.path.exists ( FileDirICE ) : os.mkdir ( FileDirICE ) 336 337 echo (' ') 338 echo ( f'JobName : {JobName}' ) 339 echo ( f'Comment : {Comment}' ) 340 echo ( f'TmpDir : {TmpDir}' ) 341 echo ( f'FileDir : {FileDir}' ) 342 echo ( f'FileDirOCE : {FileDirOCE}' ) 343 echo ( f'FileDirICE : {FileDirICE}' ) 344 345 echo ( f'\nDealing with {L_EXP}' ) 175 346 176 347 echo (' ') … … 178 349 echo ( f'Comment : {Comment}' ) 179 350 echo ( f'TmpDir : {TmpDir}' ) 180 echo ( f'RunDirOCE : {RunDirOCE}' )181 echo ( f'RunDirICE : {RunDirICE}' )182 351 183 352 echo ( f'\nDealing with {L_EXP}' ) 184 353 185 #-- Model output directories 354 ## Creates model output directory names 355 ## ------------------------------------ 186 356 if Freq == "MO" : FreqDir = os.path.join ('Output' , 'MO' ) 187 357 if Freq == "SE" : FreqDir = os.path.join ('Analyse', 'SE' ) … … 205 375 echo ( f'{dir_SRF_his}' ) 206 376 207 # -- Creates files names208 if Period == None:209 if Freq == 'MO' : Period = f'{ YearBegin}0101_{YearEnd}1231_1M'210 if Freq == 'SE' : Period = f'SE_{ YearBegin}0101_{YearEnd}1231_1M'377 ##-- Creates files names 378 if wu.unDefined ( 'Period' ) : 379 if Freq == 'MO' : Period = f'{DateBegin}_{DateEnd}_1M' 380 if Freq == 'SE' : Period = f'SE_{DateBegin}_{DateEnd}_1M' 211 381 config['Files']['Period'] = Period 212 if FileCommon == None : 382 383 config['Files']['DateBegin'] = DateBegin 384 config['Files']['DateBegin'] = DateEnd 385 386 echo ( f'Period : {Period}' ) 387 388 if wu.unDefined ( 'FileCommon' ) : 213 389 FileCommon = f'{JobName}_{Period}' 214 390 config['Files']['FileCommon'] = FileCommon 215 391 216 if Title == None:217 Title = f'{JobName} : {Freq} : { YearBegin}-01-01 - {YearEnd}-12-31'392 if wu.unDefined ( 'Title' ) : 393 Title = f'{JobName} : {Freq} : {DateBegin} - {DateEnd}' 218 394 config['Files']['Title'] = Title 219 220 395 echo ('\nOpen history files' ) 221 if file_ATM_his == None : 222 file_ATM_his = os.path.join ( dir_ATM_his, f'{FileCommon}_histmth.nc' ) 396 if wu.unDefined ( 'file_ATM_his' ) : 397 if ATM_HIS == 'latlon' : 398 file_ATM_his = os.path.join ( dir_ATM_his, f'{FileCommon}_histmth.nc' ) 399 if ATM_HIS == 'ico' : 400 file_ATM_his = os.path.join ( dir_ATM_his, f'{FileCommon}_histmth_ico.nc' ) 223 401 config['Files']['file_ATM_his'] = file_ATM_his 224 if file_SRF_his == None : 225 file_SRF_his = os.path.join ( dir_SRF_his, f'{FileCommon}_sechiba_history.nc' ) 402 if wu.unDefined ( 'file_SRF_his' ) : 403 if ATM_HIS == 'latlon' : 404 file_SRF_his = os.path.join ( dir_SRF_his, f'{FileCommon}_sechiba_history.nc' ) 405 if ATM_HIS == 'ico' : 406 file_SRF_his = os.path.join ( dir_SRF_his, f'{FileCommon}_sechiba_history_ico.nc' ) 226 407 config['Files']['file_SRF_his'] = file_SRF_his 227 #if Routing == 'SECHIBA' : 228 # file_RUN_his = os.path.join ( dir_SRF_his, f'{FileCommon}_sechiba_history.nc' ) 408 229 409 if Routing == 'SIMPLE' : 230 if file_RUN_his == None : 231 file_RUN_his = os.path.join ( dir_SRF_his, f'{FileCommon}_sechiba_history.nc' ) 410 if file_RUN_his == None : 411 if ATM_HIS == 'latlon' : 412 file_RUN_his = os.path.join ( dir_SRF_his, f'{FileCommon}_sechiba_history.nc' ) 413 if ATM_HIS == 'ico' : 414 file_RUN_his = os.path.join ( dir_SRF_his, f'{FileCommon}_sechiba_history_ico.nc' ) 232 415 config['Files']['file_RUN_his'] = file_RUN_his 233 if file_OCE_his == None : 234 file_OCE_his = os.path.join ( dir_OCE_his, f'{FileCommon}_grid_T.nc' ) 235 config['Files']['file_OCE_his'] = file_OCE_his 236 if file_OCE_sca == None : 237 file_OCE_sca = os.path.join ( dir_OCE_his, f'{FileCommon}_scalar.nc' ) 238 config['Files']['file_OCE_sca'] = file_OCE_sca 239 if file_ICE_his == None : 240 file_ICE_his = os.path.join ( dir_ICE_his, f'{FileCommon}_icemod.nc' ) 241 config['Files']['file_ICE_his'] = file_ICE_his 242 if file_OCE_srf == None : 243 file_OCE_srf = os.path.join ( dir_OCE_his, f'{FileCommon}_grid_T.nc' ) 244 config['Files']['file_OCE_srf'] = file_OCE_srf 245 246 d_ATM_his = xr.open_dataset ( file_ATM_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() 247 d_OCE_his = xr.open_dataset ( file_OCE_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() 248 d_OCE_sca = xr.open_dataset ( file_OCE_sca, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() 249 d_ICE_his = xr.open_dataset ( file_ICE_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() 250 if NEMO == '3.6' :d_ICE_his = d_ICE_his.rename ( {'y_grid_T':'y', 'x_grid_T':'x'} ) 251 d_SRF_his = xr.open_dataset ( file_SRF_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() 252 d_OCE_srf = xr.open_dataset ( file_OCE_srf, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() 253 if Routing == 'SECHIBA' : d_RUN_his = d_SRF_his 254 if Routing == 'SIMPLE' : d_RUN_his = xr.open_dataset ( file_RUN_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() 255 256 416 257 417 echo ( f'{file_ATM_his = }' ) 258 418 echo ( f'{file_SRF_his = }' ) 259 419 if Routing == 'SIMPLE' : echo ( f'{file_RUN_his = }' ) 420 421 d_ATM_his = xr.open_dataset ( file_ATM_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() 422 d_SRF_his = xr.open_dataset ( file_SRF_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() 423 if Routing == 'SECHIBA' : d_RUN_his = d_SRF_his 424 if Routing == 'SIMPLE' : d_RUN_his = xr.open_dataset ( file_RUN_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() 425 426 if wu.unDefined ('file_OCE_his' ) : 427 file_OCE_his = os.path.join ( dir_OCE_his, f'{FileCommon}_grid_T.nc' ) 428 file_OCE_his = file_OCE_his 429 if wu.unDefined ('file_OCE_sca' ) : 430 file_OCE_sca = os.path.join ( dir_OCE_his, f'{FileCommon}_scalar.nc' ) 431 config['Files']['file_OCE_sca'] = file_OCE_sca 432 if wu.unDefined ('file_OCE_srf' ) : 433 file_OCE_srf = os.path.join ( dir_OCE_his, f'{FileCommon}_sbc.nc' ) 434 config['Files']['file_OCE_srf'] = file_OCE_srf 435 if wu.unDefined ( 'file_ICE_hi' ) : 436 file_ICE_his = os.path.join ( dir_ICE_his, f'{FileCommon}_icemod.nc' ) 437 config['Files']['file_ICE_his'] = file_ICE_his 438 439 d_OCE_his = xr.open_dataset ( file_OCE_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() 440 d_OCE_sca = xr.open_dataset ( file_OCE_sca, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() 441 #d_OCE_srf = xr.open_dataset ( file_OCE_srf, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() 442 d_ICE_his = xr.open_dataset ( file_ICE_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() 443 if NEMO == '3.6' :d_ICE_his = d_ICE_his.rename ( {'y_grid_T':'y', 'x_grid_T':'x'} ) 444 260 445 echo ( f'{file_OCE_his = }' ) 261 446 echo ( f'{file_ICE_his = }' ) … … 264 449 265 450 ## Compute run length 451 ## ------------------ 266 452 dtime = ( d_ATM_his.time_counter_bounds.max() - d_ATM_his.time_counter_bounds.min() ) 267 453 echo ('\nRun length : {:8.2f} days'.format ( (dtime/np.timedelta64(1, "D")).values ) ) … … 278 464 NbYear = dtime_sec / YearLength 279 465 280 #-- Open restart files281 YearRes = YearBegin - 1 # Year of the restart of beginning of simulation282 YearPre = YearBegin - PackFrequency # Year to find the tarfile of the restart of beginning of simulation283 284 config['Files']['YearPre'] = f'{YearBegin}'285 286 echo (f'Restart dates - Start : {YearRes}-12-31 / End : {YearEnd}-12-31 ')287 288 if TarRestartPeriod_beg == None :289 echo (f'Restart dates - Start : {YearRes}-12-31 / End : {YearEnd}-12-31 ')290 TarRestartPeriod_beg = f'{YearPre}0101_{YearRes}1231'291 config['Files']['TarRestartPeriod_beg'] = TarRestartPeriod_beg292 293 if TarRestartPeriod_end == None :294 YearPre = YearBegin - PackFrequency # Year to find the tarfile of the restart of beginning of simulation295 echo (f'Restart dates - Start : {YearRes}-12-31 / End : {YearEnd}-12-31 ')296 TarRestartPeriod_end = f'{YearBegin}0101_{YearEnd}1231'297 config['Files']['TarRestartPeriod_end'] = TarRestartPeriod_end298 299 if tar_restart_beg == None :300 tar_restart_beg = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{TarRestartPeriod_beg}_restart.tar' )301 config['Files']['tar_restart_beg'] = tar_restart_beg302 if tar_restart_end == None :303 tar_restart_end = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{TarRestartPeriod_end}_restart.tar' )304 config['Files']['tar_restart_end'] = tar_restart_end305 306 echo ( f'{tar_restart_beg}' )307 echo ( f'{tar_restart_end}' )308 309 if file_ATM_beg == None :310 file_ATM_beg = f'{RunDir}/ATM_{JobName}_{YearRes}1231_restartphy.nc'311 config['Files']['file_ATM_beg'] = file_ATM_beg312 if file_ATM_end == None :313 file_ATM_end = f'{RunDir}/ATM_{JobName}_{YearEnd}1231_restartphy.nc'314 config['Files']['file_ATM_end'] = file_ATM_end315 316 if file_DYN_beg == None :317 if LMDZ : file_DYN_beg = f'{RunDir}/ATM_{JobName}_{YearRes}1231_restart.nc'318 if ICO : file_DYN_beg = f'{RunDir}/ICO_{JobName}_{YearRes}1231_restart.nc'319 config['Files']['file_DYN_beg'] = file_DYN_beg320 321 if file_DYN_end == None :322 if LMDZ : file_DYN_end = f'{RunDir}/ATM_{JobName}_{YearEnd}1231_restart.nc'323 if ICO : file_DYN_end = f'{RunDir}/ICO_{JobName}_{YearEnd}1231_restart.nc'324 config['Files']['file_DYN_end'] = file_DYN_end325 326 if file_SRF_beg == None :327 file_SRF_beg = f'{RunDir}/SRF_{JobName}_{YearRes}1231_sechiba_rest.nc'328 config['Files']['file_SRF_beg'] = file_SRF_beg329 if file_SRF_end == None :330 file_SRF_end = f'{RunDir}/SRF_{JobName}_{YearEnd}1231_sechiba_rest.nc'331 config['Files']['file_SRF_end'] = file_SRF_end332 333 if file_OCE_beg == None :334 file_OCE_beg = f'{RunDir}/OCE_{JobName}_{YearRes}1231_restart.nc'335 config['Files']['file_OCE_beg'] = file_OCE_beg336 if file_OCE_end == None :337 file_OCE_end = f'{RunDir}/OCE_{JobName}_{YearEnd}1231_restart.nc'338 config['Files']['file_OCE_end'] = file_OCE_end339 if file_ICE_beg == None :340 file_ICE_beg = f'{RunDir}/ICE_{JobName}_{YearRes}1231_restart_icemod.nc'341 config['Files']['file_ICE_beg'] = file_ICE_beg342 if file_ICE_end == None :343 file_ICE_end = f'{RunDir}/ICE_{JobName}_{YearEnd}1231_restart_icemod.nc'344 config['Files']['file_ICE_end'] = file_ICE_end345 346 liste_beg = [file_ATM_beg, file_DYN_beg, file_SRF_beg]347 liste_end = [file_ATM_end, file_DYN_end, file_SRF_end]348 349 if Routing == 'SIMPLE' :350 if file_RUN_beg == None :351 file_RUN_beg = f'{RunDir}/SRF_{JobName}_{YearRes}1231_routing_restart.nc'352 config['Files']['file_RUN_beg'] = file_RUN_beg353 if file_RUN_end == None :354 file_RUN_end = f'{RunDir}/SRF_{JobName}_{YearEnd}1231_routing_restart.nc'355 config['Files']['file_RUN_end'] = file_RUN_end356 357 liste_beg.append ( file_RUN_beg )358 liste_end.append ( file_RUN_end )359 echo ( f'{file_RUN_beg = }' )360 echo ( f'{file_RUN_end = }' )361 362 echo ( f'{file_ATM_beg = }' )363 echo ( f'{file_ATM_end = }' )364 echo ( f'{file_DYN_beg = }' )365 echo ( f'{file_DYN_end = }' )366 echo ( f'{file_SRF_beg = }' )367 echo ( f'{file_SRF_end = }' )368 echo ( f'{file_RUN_beg = }' )369 echo ( f'{file_RUN_end = }' )370 echo ( f'{file_OCE_beg = }' )371 echo ( f'{file_OCE_end = }' )372 echo ( f'{file_ICE_beg = }' )373 echo ( f'{file_ICE_end = }' )374 375 echo ('\nExtract restart files from tar : ATM, ICO and SRF')376 for resFile in liste_beg + liste_end :377 if os.path.exists ( os.path.join (RunDir, resFile) ) :378 echo ( f'file found : {resFile = }' )379 else :380 base_file = Path (file_name).stem # basename, and remove suffix381 command = f'cd {RunDir} ; tar xf {tar_restart_beg} {base_resFile}.nc'382 echo ( command )383 ierr = os.system ( command )384 if ierr == 0 : echo ( f'tar done : {base_resFile}')385 else : raise Exception ( f'command failed : {command}' )386 387 echo ('\nOpening ATM SRF and ICO restart files')388 d_ATM_beg = xr.open_dataset ( os.path.join (RunDir, file_ATM_beg), decode_times=False, decode_cf=True).squeeze()389 d_ATM_end = xr.open_dataset ( os.path.join (RunDir, file_ATM_end), decode_times=False, decode_cf=True).squeeze()390 d_SRF_beg = xr.open_dataset ( os.path.join (RunDir, file_SRF_beg), decode_times=False, decode_cf=True).squeeze()391 d_SRF_end = xr.open_dataset ( os.path.join (RunDir, file_SRF_end), decode_times=False, decode_cf=True).squeeze()392 d_DYN_beg = xr.open_dataset ( os.path.join (RunDir, file_DYN_beg), decode_times=False, decode_cf=True).squeeze()393 d_DYN_end = xr.open_dataset ( os.path.join (RunDir, file_DYN_end), decode_times=False, decode_cf=True).squeeze()394 395 echo ('\nExtract and rebuild OCE and ICE restarts')396 def get_ndomain (zfile) :397 #d_zfile = xr.open_dataset (zfile, decode_times=False).squeeze()398 #ndomain_opa = d_zfile.attrs['DOMAIN_number_total']399 #d_zfile.close ()400 ndomain_opa = subprocess.getoutput ( f'ls {zfile}_*.nc | wc -l' ) #.format()401 return int (ndomain_opa)402 403 def extract_and_rebuild ( file_name=file_OCE_beg, tar_restart=tar_restart_end, RunDirComp=RunDirOCE ) :404 '''Extract restart file from tar. Rebuild ocean files if needed'''405 echo ( f'file to extract : {file_name} ' )406 if os.path.exists ( file_name ) :407 echo ( f'-- File ready : {file_name}' )408 else :409 echo ( f'-- Extracting {file_name}' )410 base_resFile = Path (file_name).stem # basename, and remove suffix411 # Try to extract the rebuilded file412 command = f'cd {RunDirComp} ; tar xf {tar_restart} {base_resFile}.nc'413 echo ( command )414 ierr = os.system ( command )415 if ierr == 0 :416 echo ( f'tar done : {base_resFile}')417 command = f'cd {RunDirComp} ; mv {base_resFile}.nc {RunDir}'418 ierr = os.system ( command )419 if ierr == 0 : echo ( f'command done : {command}' )420 else : raise Exception ( f'command failed : {command}' )421 else :422 if not os.path.exists ( os.path.join (RunDir, f'{base_resFile}_0000.nc') ):423 command = f'cd {RunDirComp} ; tar xf {tar_restart_end} {base_resFile}_*.nc'424 echo ( command )425 ierr = os.system ( command )426 if ierr == 0 : echo ( f'tar done : {file_OCE_beg}')427 else : raise Exception ( f'command failed : {command}' )428 echo ('extract ndomain' )429 ndomain_opa = get_ndomain ( os.path.join (RunDir, f'{base_resFile}') )430 command = f'cd {RunDirComp} ; {rebuild} {base_resFile} {ndomain_opa} ; mv {base_resFile}.nc {RunDir}'431 echo ( command )432 ierr = os.system ( command )433 if ierr == 0 : echo ( f'Rebuild done : {base_resFile}.nc')434 else : raise Exception ( f'command failed : {command}' )435 436 extract_and_rebuild ( file_name=file_OCE_beg, tar_restart=tar_restart_beg, RunDirComp=RunDirOCE )437 extract_and_rebuild ( file_name=file_OCE_end, tar_restart=tar_restart_end, RunDirComp=RunDirOCE )438 extract_and_rebuild ( file_name=file_ICE_beg, tar_restart=tar_restart_beg, RunDirComp=RunDirICE )439 extract_and_rebuild ( file_name=file_ICE_end, tar_restart=tar_restart_end, RunDirComp=RunDirICE )440 441 echo ('Opening OCE and ICE restart files')442 if NEMO == 3.6 :443 d_OCE_beg = xr.open_dataset ( os.path.join (RunDir, file_OCE_beg), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze()444 d_OCE_end = xr.open_dataset ( os.path.join (RunDir, file_OCE_end), decode_times=False, decode_cf=True).squeeze()445 d_ICE_beg = xr.open_dataset ( os.path.join (RunDir, file_ICE_beg), decode_times=False, decode_cf=True).squeeze()446 d_ICE_end = xr.open_dataset ( os.path.join (RunDir, file_ICE_end), decode_times=False, decode_cf=True).squeeze()447 if NEMO == 4.0 or NEMO == 4.2 :448 d_OCE_beg = xr.open_dataset ( os.path.join (RunDir, file_OCE_beg), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze()449 d_OCE_end = xr.open_dataset ( os.path.join (RunDir, file_OCE_end), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze()450 d_ICE_beg = xr.open_dataset ( os.path.join (RunDir, file_ICE_beg), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze()451 d_ICE_end = xr.open_dataset ( os.path.join (RunDir, file_ICE_end), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze()452 453 466 ## Write the full configuration 454 467 config_out = open (FullIniFile, 'w') … … 456 469 config_out.close () 457 470 458 for var in d_SRF_beg.variables :459 d_SRF_beg[var] = d_SRF_beg[var].where ( d_SRF_beg[var]<1.e20, 0.)460 d_SRF_end[var] = d_SRF_end[var].where ( d_SRF_end[var]<1.e20, 0.)461 462 if ICO :463 d_RUN_beg = xr.open_dataset ( os.path.join (RunDir, file_RUN_beg), decode_times=False, decode_cf=True).squeeze()464 d_RUN_end = xr.open_dataset ( os.path.join (RunDir, file_RUN_end), decode_times=False, decode_cf=True).squeeze()465 466 def kg2Sv (val, rho=OCE_rho_liq) :467 '''From kg to Sverdrup'''468 return val/dtime_sec*1.0e-6/rho469 470 def kg2myear (val, rho=OCE_rho_liq) :471 '''From kg to m/year'''472 return val/OCE_aire_tot/rho/NbYear473 474 def var2prt (var, small=False) :475 if small : return var , kg2Sv(var)*1000., kg2myear(var)*1000.476 else : return var , kg2Sv(var) , kg2myear(var)477 478 def prtFlux (Desc, var, Form='F', small=False) :479 if small :480 if Form in ['f', 'F'] : ff=" {:12.4e} kg | {:12.4f} mSv | {:12.4f} mm/year "481 if Form in ['e', 'E'] : ff=" {:12.4e} kg | {:12.4e} mSv | {:12.4e} mm/year "482 else :483 if Form in ['f', 'F'] : ff=" {:12.4e} kg | {:12.4f} Sv | {:12.4f} m/year "484 if Form in ['e', 'E'] : ff=" {:12.4e} kg | {:12.4e} Sv | {:12.4e} m/year "485 echo ( (' {:>15} = ' +ff).format (Desc, *var2prt(var, small) ) )486 return None487 488 489 490 471 # ATM grid with cell surfaces 472 if LMDZ : 473 echo ('ATM grid with cell surfaces : LMDZ') 474 ATM_lat = lmdz.geo2point ( rprec (d_ATM_his ['lat'])+0*rprec (d_ATM_his ['lon']), dim1D='cell' ) 475 ATM_lon = lmdz.geo2point ( 0*rprec (d_ATM_his ['lat'])+ rprec (d_ATM_his ['lon']), dim1D='cell' ) 476 ATM_aire = lmdz.geo2point ( rprec (d_ATM_his ['aire'] ) [0], cumulPoles=True, dim1D='cell' ) 477 ATM_fter = lmdz.geo2point ( rprec (d_ATM_his ['fract_ter'][0]), dim1D='cell' ) 478 ATM_foce = lmdz.geo2point ( rprec (d_ATM_his ['fract_oce'][0]), dim1D='cell' ) 479 ATM_fsic = lmdz.geo2point ( rprec (d_ATM_his ['fract_sic'][0]), dim1D='cell' ) 480 ATM_flic = lmdz.geo2point ( rprec (d_ATM_his ['fract_lic'][0]), dim1D='cell' ) 481 SRF_lat = lmdz.geo2point ( rprec (d_SRF_his ['lat'])+0*rprec (d_SRF_his ['lon']), dim1D='cell' ) 482 SRF_lon = lmdz.geo2point ( 0*rprec (d_SRF_his ['lat'])+ rprec (d_SRF_his ['lon']), dim1D='cell' ) 483 SRF_aire = lmdz.geo2point ( rprec (d_SRF_his ['Areas']) * rprec (d_SRF_his ['Contfrac']), dim1D='cell', cumulPoles=True ) 484 SRF_areas = lmdz.geo2point ( rprec (d_SRF_his ['Areas']) , dim1D='cell', cumulPoles=True ) 485 SRF_contfrac = lmdz.geo2point ( rprec (d_SRF_his ['Contfrac']), dim1D='cell' ) 491 486 if ICO : 492 487 if ATM_HIS == 'latlon' : 493 jpja, jpia = d_ATM_his['aire'][0].shape494 file_ATM_aire = os.path.join ( R_IN, 'ATM', 'GRID', f'aire_{ATM}_to_{jpia}x{jpja}.nc' )495 config['Files']['file_ATM_aire'] = file_ATM_aire496 echo ( f'Aire sur grille reguliere : {file_ATM_aire = }' )497 d_ATM_aire = xr.open_dataset ( file_ATM_aire, decode_times=False ).squeeze()498 ATM_aire = lmdz.geo2point ( d_ATM_aire ['aire'].squeeze(), cumulPoles=True)499 ATM_fter = lmdz.geo2point ( d_ATM_his ['fract_ter'][0])500 ATM_ foce = lmdz.geo2point ( d_ATM_his ['fract_oce'][0])501 ATM_f sic = lmdz.geo2point ( d_ATM_his ['fract_sic'][0])502 ATM_f lic = lmdz.geo2point ( d_ATM_his ['fract_lic'][0])503 SRF_aire = lmdz.geo2point ( d_SRF_his ['Areas'] * d_SRF_his ['Contfrac'])504 #SRF_aire = ATM_aire * lmdz.geo2point (d_SRF_his ['Contfrac'])505 #SRF_aire = ATM_aire * ATM_fter 488 echo ( 'ATM areas and fractions on latlon grid' ) 489 if 'lat_dom_out' in d_ATM_his.variables : 490 ATM_lat = lmdz.geo2point ( rprec (d_ATM_his ['lat_dom_out'])+0*rprec (d_ATM_his ['lon_dom_out']), dim1D='cell' ) 491 ATM_lon = lmdz.geo2point ( 0*rprec (d_ATM_his ['lat_dom_out'])+ rprec (d_ATM_his ['lon_dom_out']), dim1D='cell' ) 492 else : 493 ATM_lat = lmdz.geo2point ( rprec (d_ATM_his ['lat'])+0*rprec (d_ATM_his ['lon']), dim1D='cell' ) 494 ATM_lon = lmdz.geo2point ( 0*rprec (d_ATM_his ['lat'])+ rprec (d_ATM_his ['lon']), dim1D='cell' ) 495 ATM_aire = lmdz.geo2point ( rprec (d_ATM_his ['aire'][0]).squeeze(), cumulPoles=True, dim1D='cell' ) 496 ATM_fter = lmdz.geo2point ( rprec (d_ATM_his ['fract_ter'][0]), dim1D='cell' ) 497 ATM_foce = lmdz.geo2point ( rprec (d_ATM_his ['fract_oce'][0]), dim1D='cell' ) 498 ATM_fsic = lmdz.geo2point ( rprec (d_ATM_his ['fract_sic'][0]), dim1D='cell' ) 499 ATM_flic = lmdz.geo2point ( rprec (d_ATM_his ['fract_lic'][0]), dim1D='cell' ) 500 506 501 if ATM_HIS == 'ico' : 507 echo ( f'Aire sur grille icosaedre : {file_ATM_aire = }' ) 508 509 if LMDZ : 510 ATM_aire = lmdz.geo2point ( d_ATM_his ['aire'][0], cumulPoles=True ) 511 ATM_fter = lmdz.geo2point ( d_ATM_his ['fract_ter'][0] ) 512 ATM_foce = lmdz.geo2point ( d_ATM_his ['fract_oce'][0] ) 513 ATM_fsic = lmdz.geo2point ( d_ATM_his ['fract_sic'][0] ) 514 ATM_flic = lmdz.geo2point ( d_ATM_his ['fract_lic'][0] ) 515 #SRF_aire = lmdz.geo2point ( d_SRF_his['Areas'] * d_SRF_his['Contfrac'] ) 516 SRF_aire = ATM_aire * lmdz.geo2point ( d_SRF_his['Contfrac'] ) 517 502 echo ( 'ATM areas and fractions on ICO grid' ) 503 ATM_aire = rprec (d_ATM_his ['aire'] [0]).squeeze() 504 ATM_lat = rprec (d_ATM_his ['lat'] ) 505 ATM_lon = rprec (d_ATM_his ['lon'] ) 506 ATM_fter = rprec (d_ATM_his ['fract_ter'][0]) 507 ATM_foce = rprec (d_ATM_his ['fract_oce'][0]) 508 ATM_fsic = rprec (d_ATM_his ['fract_sic'][0]) 509 ATM_flic = rprec (d_ATM_his ['fract_lic'][0]) 510 511 if SRF_HIS == 'latlon' : 512 echo ( 'SRF areas and fractions on latlon grid' ) 513 if 'lat_domain_landpoints_out' in d_SRF_his : 514 SRF_lat = lmdz.geo2point ( rprec (d_SRF_his ['lat_domain_landpoints_out'])+0*rprec (d_SRF_his ['lon_domain_landpoints_out']), dim1D='cell' ) 515 SRF_lon = lmdz.geo2point ( 0*rprec (d_SRF_his ['lat_domain_landpoints_out'])+ rprec (d_SRF_his ['lon_domain_landpoints_out']), dim1D='cell' ) 516 else : 517 if 'lat_domain_landpoints_out' in d_SRF_his : 518 SRF_lat = lmdz.geo2point ( rprec (d_SRF_his ['lat_dom_out'])+0*rprec (d_SRF_his ['lon_dom_out']), dim1D='cell' ) 519 SRF_lon = lmdz.geo2point ( 0*rprec (d_SRF_his ['lat_dom_out'])+ rprec (d_SRF_his ['lon_dom_out']), dim1D='cell' ) 520 else : 521 SRF_lat = lmdz.geo2point ( rprec (d_SRF_his ['lat'])+0*rprec (d_SRF_his ['lon']), dim1D='cell' ) 522 SRF_lon = lmdz.geo2point ( 0*rprec (d_SRF_his ['lat'])+ rprec (d_SRF_his ['lon']), dim1D='cell' ) 523 524 SRF_areas = lmdz.geo2point ( rprec (d_SRF_his ['Areas'] ) , dim1D='cell', cumulPoles=True ) 525 SRF_areafrac = lmdz.geo2point ( rprec (d_SRF_his ['AreaFrac']) , dim1D='cell', cumulPoles=True ) 526 SRF_contfrac = lmdz.geo2point ( rprec (d_SRF_his ['Contfrac']) , dim1D='cell', cumulPoles=True ) 527 SRF_aire = SRF_areafrac 528 529 if SRF_HIS == 'ico' : 530 echo ( 'SRF areas and fractions on latlon grid' ) 531 SRF_lat = rprec (d_SRF_his ['lat'] ) 532 SRF_lon = rprec (d_SRF_his ['lon'] ) 533 SRF_areas = rprec (d_SRF_his ['Areas'] ) 534 SRF_contfrac = rprec (d_SRF_his ['Contfrac']) 535 SRF_aire = SRF_areas * SRF_contfrac 518 536 ATM_fsea = ATM_foce + ATM_fsic 519 537 ATM_flnd = ATM_fter + ATM_flic … … 525 543 ATM_aire_fsea = ATM_aire * ATM_fsea 526 544 527 SRF_aire = SRF_aire.where ( SRF_aire < 1E15, 0.) 528 529 if ICO : 530 # Area on icosahedron grid 531 file_DYN_aire = os.path.join ( R_IN, 'ATM', 'GRID', ATM+'_grid.nc' ) 532 d_DYN_aire = xr.open_dataset ( file_DYN_aire, decode_times=False).squeeze() 533 d_DYN_aire = d_DYN_aire.rename ( {'cell':'cell_mesh'} ) 534 DYN_aire = d_DYN_aire['aire'] 535 536 DYN_fsea = d_DYN_aire ['fract_oce'] + d_DYN_aire ['fract_sic'] 537 DYN_flnd = 1.0 - DYN_fsea 538 539 if LMDZ : 540 # Area on lon/lat grid 541 DYN_aire = ATM_aire 542 DYN_fsea = ATM_fsea 543 DYN_flnd = ATM_flnd 544 DYN_fter = d_ATM_beg['FTER'] 545 DYN_flic = d_ATM_beg['FTER'] 546 547 def ATM_stock_int (stock) : 548 '''Integrate (* surface) stock on atmosphere grid''' 549 ATM_stock_int = wu.Psum ( (stock * DYN_aire).to_masked_array().ravel() ) 550 return ATM_stock_int 545 #SRF_aire = SRF_aire.where ( SRF_aire < 1E15, 0.) 546 547 # if ICO : 548 # if wu.unDefined ('file_DYN_aire') : file_DYN_aire = os.path.join ( R_IN, 'ATM', 'GRID', ATM+'_grid.nc' ) 549 # config['Files']['file_DYN_aire'] = file_DYN_aire 550 551 # if ICO : 552 # # Area on icosahedron grid 553 # d_DYN_aire = xr.open_dataset ( file_DYN_aire, decode_times=False ).squeeze() 554 555 # DYN_lat = d_DYN_aire['lat'] 556 # DYN_lon = d_DYN_aire['lon'] 557 558 # DYN_aire = d_DYN_aire['aire'] 559 # DYN_fsea = d_DYN_aire['fract_oce'] + d_DYN_aire['fract_sic'] 560 # DYN_flnd = 1.0 - DYN_fsea 561 # DYN_fter = d_ATM_beg['FTER'] 562 # DYN_flic = d_ATM_beg['FLIC'] 563 # DYN_aire_fter = DYN_aire * DYN_fter 564 565 # if LMDZ : 566 # # Area on lon/lat grid 567 # DYN_aire = ATM_aire 568 # DYN_fsea = ATM_fsea 569 # DYN_flnd = ATM_flnd 570 # DYN_fter = rprec (d_ATM_beg['FTER']) 571 # DYN_flic = rprec (d_ATM_beg['FLIC']) 572 # DYN_aire_fter = DYN_aire * DYN_fter 573 574 # Functions computing integrals and sum 575 # def ATM_stock_int (stock) : 576 # '''Integrate (* surface) stock on atmosphere grid''' 577 # ATM_stock_int = wu.Psum ( (stock * DYN_aire).to_masked_array().ravel() ) 578 # return ATM_stock_int 551 579 552 580 def ATM_flux_int (flux) : … … 555 583 return ATM_flux_int 556 584 557 def SRF_stock_int (stock) :558 '''Integrate (* surface) stock on land grid'''559 ATM_stock_int = wu.Ksum ( ( (stock * DYN_aire_fter).to_masked_array().ravel()) )560 return ATM_stock_int585 # def SRF_stock_int (stock) : 586 # '''Integrate (* surface) stock on land grid''' 587 # ATM_stock_int = wu.Ksum ( ( (stock * DYN_aire_fter).to_masked_array().ravel()) ) 588 # return ATM_stock_int 561 589 562 590 def SRF_flux_int (flux) : … … 565 593 return SRF_flux_int 566 594 567 def OCE_stock_int (stock) : 568 '''Integrate stock on ocean grid''' 569 OCE_stock_int = np.sum ( np.sort ( (stock * OCE_aire ).to_masked_array().ravel()) ) 570 return OCE_stock_int 595 def LIC_flux_int (flux) : 596 '''Integrate (* time * surface) flux on land ice grid''' 597 LIC_flux_int = wu.Psum ( (flux * dtime_per_sec * ATM_aire_flic).to_masked_array().ravel() ) 598 return LIC_flux_int 599 600 # def OCE_stock_int (stock) : 601 # '''Integrate stock on ocean grid''' 602 # OCE_stock_int = np.sum ( np.sort ( (stock * OCE_aire ).to_masked_array().ravel()) ) 603 # return OCE_stock_int 571 604 572 605 def ONE_stock_int (stock) : … … 584 617 OCE_flux_int = np.sum ( np.sort ( (flux * dtime_per_sec).to_masked_array().ravel()) ) 585 618 return OCE_flux_int 586 587 #if LMDZ :588 # d_ATM_beg = d_ATM_beg.assign ( coords={'lon':d_ATM_beg.lon*180./np.pi} )589 619 590 620 # Get mask and surfaces … … 607 637 608 638 echo ( '\n====================================================================================' ) 609 echo ( '-- NEMO change in stores (for the records)' ) 610 #-- Note that the total number of days of the run should be diagnosed rather than assumed 611 #-- Here the result is in Sv 612 # 613 #-- Change in ocean volume in freshwater equivalent 614 615 OCE_ssh_beg = d_OCE_beg['sshn'] 616 OCE_ssh_end = d_OCE_end['sshn'] 617 OCE_sum_ssh_beg = OCE_stock_int ( OCE_ssh_beg ) 618 OCE_sum_ssh_end = OCE_stock_int ( OCE_ssh_end ) 619 620 OCE_mas_wat_beg = OCE_sum_ssh_beg * OCE_rho_liq 621 OCE_mas_wat_end = OCE_sum_ssh_end * OCE_rho_liq 622 623 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) ) 624 dOCE_vol_liq = ( OCE_sum_ssh_end - OCE_sum_ssh_beg ) 625 dOCE_mas_liq = dOCE_vol_liq * OCE_rho_liq 626 dOCE_mas_wat = dOCE_mas_liq 627 628 echo ( 'dOCE vol = {:12.3e} m^3'.format (dOCE_vol_liq) ) 629 echo ( 'dOCE ssh = {:12.3e} m '.format (dOCE_vol_liq/OCE_aire_tot) ) 630 echo ( 'dOCE mass = {:12.3e} kg '.format (dOCE_mas_liq) ) 631 echo ( 'dOCE mass = {:12.3e} Sv '.format (dOCE_mas_liq/dtime_sec*1E-6/OCE_rho_liq) ) 632 633 ## Glace et neige 639 echo ( f'-- ATM Fluxes -- {Title} ' ) 640 641 if ATM_HIS == 'latlon' : 642 echo ( ' latlon case' ) 643 ATM_wbilo_oce = lmdz.geo2point ( rprec (d_ATM_his ['wbilo_oce']), dim1D='cell' ) 644 ATM_wbilo_sic = lmdz.geo2point ( rprec (d_ATM_his ['wbilo_sic']), dim1D='cell' ) 645 ATM_wbilo_ter = lmdz.geo2point ( rprec (d_ATM_his ['wbilo_ter']), dim1D='cell' ) 646 ATM_wbilo_lic = lmdz.geo2point ( rprec (d_ATM_his ['wbilo_lic']), dim1D='cell' ) 647 ATM_runofflic = lmdz.geo2point ( rprec (d_ATM_his ['runofflic']), dim1D='cell' ) 648 ATM_fqcalving = lmdz.geo2point ( rprec (d_ATM_his ['fqcalving']), dim1D='cell' ) 649 ATM_fqfonte = lmdz.geo2point ( rprec (d_ATM_his ['fqfonte'] ), dim1D='cell' ) 650 ATM_precip = lmdz.geo2point ( rprec (d_ATM_his ['precip'] ), dim1D='cell' ) 651 ATM_snowf = lmdz.geo2point ( rprec (d_ATM_his ['snow'] ), dim1D='cell' ) 652 ATM_evap = lmdz.geo2point ( rprec (d_ATM_his ['evap'] ), dim1D='cell' ) 653 ATM_wevap_ter = lmdz.geo2point ( rprec (d_ATM_his ['wevap_ter']), dim1D='cell' ) 654 ATM_wevap_oce = lmdz.geo2point ( rprec (d_ATM_his ['wevap_oce']), dim1D='cell' ) 655 ATM_wevap_lic = lmdz.geo2point ( rprec (d_ATM_his ['wevap_lic']), dim1D='cell' ) 656 ATM_wevap_sic = lmdz.geo2point ( rprec (d_ATM_his ['wevap_sic']), dim1D='cell' ) 657 ATM_wrain_ter = lmdz.geo2point ( rprec (d_ATM_his ['wrain_ter']), dim1D='cell' ) 658 ATM_wrain_oce = lmdz.geo2point ( rprec (d_ATM_his ['wrain_oce']), dim1D='cell' ) 659 ATM_wrain_lic = lmdz.geo2point ( rprec (d_ATM_his ['wrain_lic']), dim1D='cell' ) 660 ATM_wrain_sic = lmdz.geo2point ( rprec (d_ATM_his ['wrain_sic']), dim1D='cell' ) 661 ATM_wsnow_ter = lmdz.geo2point ( rprec (d_ATM_his ['wsnow_ter']), dim1D='cell' ) 662 ATM_wsnow_oce = lmdz.geo2point ( rprec (d_ATM_his ['wsnow_oce']), dim1D='cell' ) 663 ATM_wsnow_lic = lmdz.geo2point ( rprec (d_ATM_his ['wsnow_lic']), dim1D='cell' ) 664 ATM_wsnow_sic = lmdz.geo2point ( rprec (d_ATM_his ['wsnow_sic']), dim1D='cell' ) 665 ATM_runofflic = lmdz.geo2point ( rprec (d_ATM_his ['runofflic']), dim1D='cell' ) 666 echo ( f'End of LATLON case') 667 668 if ATM_HIS == 'ico' : 669 echo (' ico case') 670 ATM_wbilo_oce = rprec (d_ATM_his ['wbilo_oce']) 671 ATM_wbilo_sic = rprec (d_ATM_his ['wbilo_sic']) 672 ATM_wbilo_ter = rprec (d_ATM_his ['wbilo_ter']) 673 ATM_wbilo_lic = rprec (d_ATM_his ['wbilo_lic']) 674 ATM_runofflic = rprec (d_ATM_his ['runofflic']) 675 ATM_fqcalving = rprec (d_ATM_his ['fqcalving']) 676 ATM_fqfonte = rprec (d_ATM_his ['fqfonte'] ) 677 ATM_precip = rprec (d_ATM_his ['precip'] ) 678 ATM_snowf = rprec (d_ATM_his ['snow'] ) 679 ATM_evap = rprec (d_ATM_his ['evap'] ) 680 ATM_wevap_ter = rprec (d_ATM_his ['wevap_ter']) 681 ATM_wevap_oce = rprec (d_ATM_his ['wevap_oce']) 682 ATM_wevap_lic = rprec (d_ATM_his ['wevap_lic']) 683 ATM_wevap_sic = rprec (d_ATM_his ['wevap_sic']) 684 ATM_runofflic = rprec (d_ATM_his ['runofflic']) 685 ATM_wevap_ter = rprec (d_ATM_his ['wevap_ter']) 686 ATM_wevap_oce = rprec (d_ATM_his ['wevap_oce']) 687 ATM_wevap_lic = rprec (d_ATM_his ['wevap_lic']) 688 ATM_wevap_sic = rprec (d_ATM_his ['wevap_sic']) 689 ATM_wrain_ter = rprec (d_ATM_his ['wrain_ter']) 690 ATM_wrain_oce = rprec (d_ATM_his ['wrain_oce']) 691 ATM_wrain_lic = rprec (d_ATM_his ['wrain_lic']) 692 ATM_wrain_sic = rprec (d_ATM_his ['wrain_sic']) 693 ATM_wsnow_ter = rprec (d_ATM_his ['wsnow_ter']) 694 ATM_wsnow_oce = rprec (d_ATM_his ['wsnow_oce']) 695 ATM_wsnow_lic = rprec (d_ATM_his ['wsnow_lic']) 696 ATM_wsnow_sic = rprec (d_ATM_his ['wsnow_sic']) 697 echo ( f'End of ico case ') 698 699 700 701 echo ( 'ATM wprecip_oce' ) 702 ATM_wprecip_oce = ATM_wrain_oce + ATM_wsnow_oce 703 ATM_wprecip_ter = ATM_wrain_ter + ATM_wsnow_ter 704 ATM_wprecip_sic = ATM_wrain_sic + ATM_wsnow_sic 705 ATM_wprecip_lic = ATM_wrain_lic + ATM_wsnow_lic 706 707 ATM_wbilo = ATM_wbilo_oce + ATM_wbilo_sic + ATM_wbilo_ter + ATM_wbilo_lic 708 ATM_wevap = ATM_wevap_oce + ATM_wevap_sic + ATM_wevap_ter + ATM_wevap_lic 709 ATM_wprecip = ATM_wprecip_oce + ATM_wprecip_sic + ATM_wprecip_ter + ATM_wprecip_lic 710 ATM_wsnow = ATM_wsnow_oce + ATM_wsnow_sic + ATM_wsnow_ter + ATM_wsnow_lic 711 ATM_wrain = ATM_wrain_oce + ATM_wrain_sic + ATM_wrain_ter + ATM_wrain_lic 712 ATM_wemp = ATM_wevap - ATM_wprecip 713 ATM_emp = ATM_evap - ATM_precip 714 715 ATM_wprecip_sea = ATM_wprecip_oce + ATM_wprecip_sic 716 ATM_wsnow_sea = ATM_wsnow_oce + ATM_wsnow_sic 717 ATM_wrain_sea = ATM_wrain_oce + ATM_wrain_sic 718 ATM_wbilo_sea = ATM_wbilo_oce + ATM_wbilo_sic 719 ATM_wevap_sea = ATM_wevap_sic + ATM_wevap_oce 720 721 ATM_wemp_ter = ATM_wevap_ter - ATM_wprecip_ter 722 ATM_wemp_oce = ATM_wevap_oce - ATM_wprecip_oce 723 ATM_wemp_sic = ATM_wevap_sic - ATM_wprecip_sic 724 ATM_wemp_lic = ATM_wevap_lic - ATM_wprecip_lic 725 ATM_wemp_sea = ATM_wevap_sic - ATM_wprecip_oce 726 727 if RUN_HIS == 'latlon' : 728 echo ( f'RUN costalflow Grille LATLON' ) 729 if TestInterp : 730 echo ( f'RUN runoff TestInterp' ) 731 RUN_runoff = lmdz.geo2point ( rprec (d_RUN_his ['runoff_contfrac_interp'] ) , dim1D='cell' ) 732 RUN_drainage = lmdz.geo2point ( rprec (d_RUN_his ['drainage_contfrac_interp']) , dim1D='cell' ) 733 else : 734 echo ( f'RUN runoff' ) 735 RUN_runoff = lmdz.geo2point ( rprec (d_RUN_his ['runoff'] ), dim1D='cell' ) 736 RUN_drainage = lmdz.geo2point ( rprec (d_RUN_his ['drainage'] ), dim1D='cell' ) 737 738 RUN_coastalflow = lmdz.geo2point ( rprec (d_RUN_his ['coastalflow'] ), dim1D='cell' ) 739 RUN_riverflow = lmdz.geo2point ( rprec (d_RUN_his ['riverflow'] ), dim1D='cell' ) 740 RUN_riversret = lmdz.geo2point ( rprec (d_RUN_his ['riversret'] ), dim1D='cell' ) 741 RUN_coastalflow_cpl = lmdz.geo2point ( rprec (d_RUN_his ['coastalflow_cpl']), dim1D='cell' ) 742 RUN_riverflow_cpl = lmdz.geo2point ( rprec (d_RUN_his ['riverflow_cpl'] ), dim1D='cell' ) 743 744 if RUN_HIS == 'ico' : 745 echo ( f'RUN costalflow Grille ICO' ) 746 RUN_coastalflow = rprec (d_RUN_his ['coastalflow']) 747 RUN_riverflow = rprec (d_RUN_his ['riverflow'] ) 748 RUN_runoff = rprec (d_RUN_his ['runoff'] ) 749 RUN_drainage = rprec (d_RUN_his ['drainage'] ) 750 RUN_riversret = rprec (d_RUN_his ['riversret'] ) 751 752 RUN_coastalflow_cpl = rprec (d_RUN_his ['coastalflow_cpl']) 753 RUN_riverflow_cpl = rprec (d_RUN_his ['riverflow_cpl'] ) 754 755 ## Correcting units of SECHIBA variables 756 def mmd2SI ( Var ) : 757 '''Change unit from mm/d or m^3/s to kg/s if needed''' 758 if 'units' in VarT.attrs : 759 if VarT.attrs['units'] in ['m^3/s', 'm3/s', 'm3.s-1',] : 760 VarT.values = VarT.values * ATM_rho ; VarT.attrs['units'] = 'kg/s' 761 if VarT.attrs['units'] == 'mm/d' : 762 VarT.values = VarT.values * ATM_rho * (1e-3/86400.) ; VarT.attrs['units'] = 'kg/s' 763 if VarT.attrs['units'] in ['m^3', 'm3', ] : 764 VarT.values = VarT.values * ATM_rho ; VarT.attrs['units'] = 'kg' 765 766 for var in [ 'runoff', 'drainage', 'riversret', 'coastalflow', 'riverflow', 'coastalflow_cpl', 'riverflow_cpl' ] : 767 VarT = locals()['RUN_' + var] 768 mmd2SI (VarT) 769 770 #for var in ['evap', 'snowf', 'subli', 'transpir', 'rain', 'emp' ] : 771 # VarT = locals()['SRF_' + var] 772 # mmd2SI (VarT) 773 echo ( f'RUN input' ) 774 RUN_input = RUN_runoff + RUN_drainage 775 RUN_output = RUN_coastalflow + RUN_riverflow 776 777 echo ( f'ATM flw_wbilo' ) 778 ATM_flx_wbilo = ATM_flux_int ( ATM_wbilo ) 779 ATM_flx_wevap = ATM_flux_int ( ATM_wevap ) 780 ATM_flx_wprecip = ATM_flux_int ( ATM_wprecip ) 781 ATM_flx_wsnow = ATM_flux_int ( ATM_wsnow ) 782 ATM_flx_wrain = ATM_flux_int ( ATM_wrain ) 783 ATM_flx_wemp = ATM_flux_int ( ATM_wemp ) 784 785 ATM_flx_wbilo_lic = ATM_flux_int ( ATM_wbilo_lic ) 786 ATM_flx_wbilo_oce = ATM_flux_int ( ATM_wbilo_oce ) 787 ATM_flx_wbilo_sea = ATM_flux_int ( ATM_wbilo_sea ) 788 ATM_flx_wbilo_sic = ATM_flux_int ( ATM_wbilo_sic ) 789 ATM_flx_wbilo_ter = ATM_flux_int ( ATM_wbilo_ter ) 790 ATM_flx_calving = ATM_flux_int ( ATM_fqcalving ) 791 ATM_flx_fqfonte = ATM_flux_int ( ATM_fqfonte ) 792 793 LIC_flx_calving = LIC_flux_int ( ATM_fqcalving ) 794 LIC_flx_fqfonte = LIC_flux_int ( ATM_fqfonte ) 795 796 ATM_flx_precip = ATM_flux_int ( ATM_precip ) 797 ATM_flx_snowf = ATM_flux_int ( ATM_snowf ) 798 ATM_flx_evap = ATM_flux_int ( ATM_evap ) 799 ATM_flx_runlic = ATM_flux_int ( ATM_runofflic ) 800 801 LIC_flx_precip = LIC_flux_int ( ATM_precip ) 802 LIC_flx_snowf = LIC_flux_int ( ATM_snowf ) 803 LIC_flx_evap = LIC_flux_int ( ATM_evap ) 804 LIC_flx_runlic = LIC_flux_int ( ATM_runofflic ) 805 806 ATM_flx_wrain_ter = ATM_flux_int ( ATM_wrain_ter ) 807 ATM_flx_wrain_oce = ATM_flux_int ( ATM_wrain_oce ) 808 ATM_flx_wrain_lic = ATM_flux_int ( ATM_wrain_lic ) 809 ATM_flx_wrain_sic = ATM_flux_int ( ATM_wrain_sic ) 810 ATM_flx_wrain_sea = ATM_flux_int ( ATM_wrain_sea ) 811 812 ATM_flx_wsnow_ter = ATM_flux_int ( ATM_wsnow_ter ) 813 ATM_flx_wsnow_oce = ATM_flux_int ( ATM_wsnow_oce ) 814 ATM_flx_wsnow_lic = ATM_flux_int ( ATM_wsnow_lic ) 815 ATM_flx_wsnow_sic = ATM_flux_int ( ATM_wsnow_sic ) 816 ATM_flx_wsnow_sea = ATM_flux_int ( ATM_wsnow_sea ) 817 818 ATM_flx_wevap_ter = ATM_flux_int ( ATM_wevap_ter ) 819 ATM_flx_wevap_oce = ATM_flux_int ( ATM_wevap_oce ) 820 ATM_flx_wevap_lic = ATM_flux_int ( ATM_wevap_lic ) 821 ATM_flx_wevap_sic = ATM_flux_int ( ATM_wevap_sic ) 822 ATM_flx_wevap_sea = ATM_flux_int ( ATM_wevap_sea ) 823 ATM_flx_wprecip_lic = ATM_flux_int ( ATM_wprecip_lic ) 824 ATM_flx_wprecip_oce = ATM_flux_int ( ATM_wprecip_oce ) 825 ATM_flx_wprecip_sic = ATM_flux_int ( ATM_wprecip_sic ) 826 ATM_flx_wprecip_ter = ATM_flux_int ( ATM_wprecip_ter ) 827 ATM_flx_wprecip_sea = ATM_flux_int ( ATM_wprecip_sea ) 828 ATM_flx_wemp_lic = ATM_flux_int ( ATM_wemp_lic ) 829 ATM_flx_wemp_oce = ATM_flux_int ( ATM_wemp_oce ) 830 ATM_flx_wemp_sic = ATM_flux_int ( ATM_wemp_sic ) 831 ATM_flx_wemp_ter = ATM_flux_int ( ATM_wemp_ter ) 832 ATM_flx_wemp_sea = ATM_flux_int ( ATM_wemp_sea ) 833 834 ATM_flx_emp = ATM_flux_int ( ATM_emp ) 835 836 RUN_flx_coastal = ONE_flux_int ( RUN_coastalflow) 837 RUN_flx_river = ONE_flux_int ( RUN_riverflow ) 838 RUN_flx_coastal_cpl = ONE_flux_int ( RUN_coastalflow_cpl) 839 RUN_flx_river_cpl = ONE_flux_int ( RUN_riverflow_cpl ) 840 RUN_flx_drainage = SRF_flux_int ( RUN_drainage ) 841 RUN_flx_riversret = SRF_flux_int ( RUN_riversret ) 842 RUN_flx_runoff = SRF_flux_int ( RUN_runoff ) 843 RUN_flx_input = SRF_flux_int ( RUN_input ) 844 RUN_flx_output = ONE_flux_int ( RUN_output ) 845 846 RUN_flx_bil = ONE_flux_int ( RUN_input - RUN_output) 847 RUN_flx_rivcoa = ONE_flux_int ( RUN_coastalflow + RUN_riverflow) 848 849 prtFlux ('wbilo_oce ', ATM_flx_wbilo_oce , 'f' ) 850 prtFlux ('wbilo_sic ', ATM_flx_wbilo_sic , 'f' ) 851 prtFlux ('wbilo_sic+oce ', ATM_flx_wbilo_sea , 'f' ) 852 prtFlux ('wbilo_ter ', ATM_flx_wbilo_ter , 'f' ) 853 prtFlux ('wbilo_lic ', ATM_flx_wbilo_lic , 'f' ) 854 prtFlux ('Sum wbilo_* ', ATM_flx_wbilo , 'f', True) 855 prtFlux ('E-P ', ATM_flx_emp , 'f', True) 856 prtFlux ('calving ', ATM_flx_calving , 'f' ) 857 prtFlux ('fqfonte ', ATM_flx_fqfonte , 'f' ) 858 prtFlux ('precip ', ATM_flx_precip , 'f' ) 859 prtFlux ('snowf ', ATM_flx_snowf , 'f' ) 860 prtFlux ('evap ', ATM_flx_evap , 'f' ) 861 prtFlux ('runoff lic ', ATM_flx_runlic , 'f' ) 862 863 prtFlux ('ATM_flx_wevap* ', ATM_flx_wevap , 'f' ) 864 prtFlux ('ATM_flx_wrain* ', ATM_flx_wrain , 'f' ) 865 prtFlux ('ATM_flx_wsnow* ', ATM_flx_wsnow , 'f' ) 866 prtFlux ('ATM_flx_wprecip* ', ATM_flx_wprecip , 'f' ) 867 prtFlux ('ATM_flx_wemp* ', ATM_flx_wemp , 'f', True ) 868 869 prtFlux ('ERROR evap ', ATM_flx_wevap - ATM_flx_evap , 'e', True ) 870 prtFlux ('ERROR precip ', ATM_flx_wprecip - ATM_flx_precip, 'e', True ) 871 prtFlux ('ERROR snow ', ATM_flx_wsnow - ATM_flx_snowf , 'e', True ) 872 prtFlux ('ERROR emp ', ATM_flx_wemp - ATM_flx_emp , 'e', True ) 873 874 875 echo ( '\n====================================================================================' ) 876 echo ( f'-- RUNOFF Fluxes -- {Title} ' ) 877 prtFlux ('coastalflow ', RUN_flx_coastal , 'f' ) 878 prtFlux ('riverflow ', RUN_flx_river , 'f' ) 879 prtFlux ('coastal_cpl ', RUN_flx_coastal_cpl, 'f' ) 880 prtFlux ('riverf_cpl ', RUN_flx_river_cpl , 'f' ) 881 prtFlux ('river+coastal ', RUN_flx_rivcoa , 'f' ) 882 prtFlux ('drainage ', RUN_flx_drainage , 'f' ) 883 prtFlux ('riversret ', RUN_flx_riversret , 'f' ) 884 prtFlux ('runoff ', RUN_flx_runoff , 'f' ) 885 prtFlux ('river in ', RUN_flx_input , 'f' ) 886 prtFlux ('river out ', RUN_flx_output , 'f' ) 887 prtFlux ('river bil ', RUN_flx_bil , 'f' ) 888 889 echo ( '\n====================================================================================' ) 890 echo ( f'-- OCE Fluxes -- {Title} ' ) 891 892 # Read variable and computes integral over space and time 893 OCE_empmr = rprec (d_OCE_his['wfo'] ) ; OCE_mas_empmr = OCE_flux_int ( OCE_empmr ) 894 OCE_wfob = rprec (d_OCE_his['wfob'] ) ; OCE_mas_wfob = OCE_flux_int ( OCE_wfob ) 895 OCE_emp_oce = rprec (d_OCE_his['emp_oce'] ) ; OCE_mas_emp_oce = OCE_flux_int ( OCE_emp_oce ) 896 OCE_emp_ice = rprec (d_OCE_his['emp_ice'] ) ; OCE_mas_emp_ice = OCE_flux_int ( OCE_emp_ice ) 897 OCE_iceshelf = rprec (d_OCE_his['iceshelf']) ; OCE_mas_iceshelf = OCE_flux_int ( OCE_iceshelf ) 898 OCE_calving = rprec (d_OCE_his['calving'] ) ; OCE_mas_calving = OCE_flux_int ( OCE_calving ) 899 OCE_iceberg = rprec (d_OCE_his['iceberg'] ) ; OCE_mas_iceberg = OCE_flux_int ( OCE_iceberg ) 900 OCE_friver = rprec (d_OCE_his['friver'] ) ; OCE_mas_friver = OCE_flux_int ( OCE_friver ) 901 OCE_runoffs = rprec (d_OCE_his['runoffs'] ) ; OCE_mas_runoffs = OCE_flux_int ( OCE_runoffs ) 902 if NEMO == 4.0 or NEMO == 4.2 : 903 OCE_wfxice = rprec (d_OCE_his['vfxice']) ; OCE_mas_wfxice = OCE_flux_int ( OCE_wfxice ) 904 OCE_wfxsnw = rprec (d_OCE_his['vfxsnw']) ; OCE_mas_wfxsnw = OCE_flux_int ( OCE_wfxsnw ) 905 OCE_wfxsub = rprec (d_OCE_his['vfxsub']) ; OCE_mas_wfxsub = OCE_flux_int ( OCE_wfxsub ) 634 906 if NEMO == 3.6 : 635 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'] 636 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'] 637 638 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'] 639 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'] 640 641 ICE_pnd_beg = 0.0 ; ICE_pnd_end = 0.0 642 ICE_fzl_beg = 0.0 ; ICE_fzl_end = 0.0 643 644 ICE_mas_wat_beg = OCE_stock_int ( (ICE_ice_beg*ICE_rho_ice + ICE_sno_beg*ICE_rho_sno) ) 645 ICE_mas_wat_end = OCE_stock_int ( (ICE_ice_end*ICE_rho_ice + ICE_sno_end*ICE_rho_sno) ) 646 907 OCE_wfxice = rprec (d_OCE_his['vfxice'])/86400.*ICE_rho_ice ; OCE_mas_wfxice = OCE_flux_int ( OCE_wfxice ) 908 OCE_wfxsnw = rprec (d_OCE_his['vfxsnw'])/86400.*ICE_rho_sno ; OCE_mas_wfxsnw = OCE_flux_int ( OCE_wfxsnw ) 909 OCE_wfxsub = rprec (d_OCE_his['vfxsub'])/86400.*ICE_rho_sno ; OCE_mas_wfxsub = OCE_flux_int ( OCE_wfxsub ) 910 # Additional checks 911 OCE_evap_oce = rprec (d_OCE_his['evap_ao_cea']) ; OCE_mas_evap_oce = OCE_flux_int ( OCE_evap_oce ) 912 ICE_evap_ice = rprec (d_OCE_his['subl_ai_cea']) ; ICE_mas_evap_ice = OCE_flux_int ( ICE_evap_ice ) 913 OCE_snow_oce = rprec (d_OCE_his['snow_ao_cea']) ; OCE_mas_snow_oce = OCE_flux_int ( OCE_snow_oce ) 914 OCE_snow_ice = rprec (d_OCE_his['snow_ai_cea']) ; OCE_mas_snow_ice = OCE_flux_int ( OCE_snow_ice ) 915 OCE_rain = rprec (d_OCE_his['rain'] ) ; OCE_mas_rain = OCE_flux_int ( OCE_rain ) 916 ICE_wfxsub_err = rprec (d_ICE_his['vfxsub_err'] ) ; ICE_mas_wfxsub_err = OCE_flux_int ( ICE_wfxsub_err ) 647 917 if NEMO == 4.0 or NEMO == 4.2 : 648 ICE_ice_beg = d_ICE_beg ['v_i'] ; ICE_ice_end = d_ICE_end ['v_i'] 649 ICE_sno_beg = d_ICE_beg ['v_s'] ; ICE_sno_end = d_ICE_end ['v_s'] 650 ICE_pnd_beg = d_ICE_beg ['v_ip'] ; ICE_pnd_end = d_ICE_end ['v_ip'] 651 ICE_fzl_beg = d_ICE_beg ['v_il'] ; ICE_fzl_end = d_ICE_end ['v_il'] 652 653 ICE_mas_wat_beg = OCE_stock_int ( d_ICE_beg['snwice_mass'] ) 654 ICE_mas_wat_end = OCE_stock_int ( d_ICE_end['snwice_mass'] ) 655 656 657 ICE_vol_ice_beg = OCE_stock_int ( ICE_ice_beg ) 658 ICE_vol_ice_end = OCE_stock_int ( ICE_ice_end ) 659 660 ICE_vol_sno_beg = OCE_stock_int ( ICE_sno_beg ) 661 ICE_vol_sno_end = OCE_stock_int ( ICE_sno_end ) 662 663 ICE_vol_pnd_beg = OCE_stock_int ( ICE_pnd_beg ) 664 ICE_vol_pnd_end = OCE_stock_int ( ICE_pnd_end ) 665 666 ICE_vol_fzl_beg = OCE_stock_int ( ICE_fzl_beg ) 667 ICE_vol_fzl_end = OCE_stock_int ( ICE_fzl_end ) 668 669 #-- Converting to freswater volume 670 dICE_vol_ice = ICE_vol_ice_end - ICE_vol_ice_beg 671 dICE_mas_ice = dICE_vol_ice * ICE_rho_ice 672 673 dICE_vol_sno = ICE_vol_sno_end - ICE_vol_sno_beg 674 dICE_mas_sno = dICE_vol_sno * ICE_rho_sno 675 676 dICE_vol_pnd = ICE_vol_pnd_end - ICE_vol_pnd_beg 677 dICE_mas_pnd = dICE_vol_pnd * ICE_rho_pnd 678 679 dICE_vol_fzl= ICE_vol_fzl_end - ICE_vol_fzl_beg 680 dICE_mas_fzl = dICE_vol_fzl * ICE_rho_pnd 681 918 ICE_wfxpnd = rprec (d_ICE_his['vfxpnd'] ) ; ICE_mas_wfxpnd = OCE_flux_int ( ICE_wfxpnd ) 919 ICE_wfxsnw_sub = rprec (d_ICE_his['vfxsnw_sub']) ; ICE_mas_wfxsnw_sub = OCE_flux_int ( ICE_wfxsnw_sub ) 920 ICE_wfxsnw_pre = rprec (d_ICE_his['vfxsnw_pre']) ; ICE_mas_wfxsnw_pre = OCE_flux_int ( ICE_wfxsnw_pre ) 682 921 if NEMO == 3.6 : 683 dICE_mas_wat = dICE_mas_ice + dICE_mas_sno 684 dSEA_mas_wat = dOCE_mas_wat + dICE_mas_ice + dICE_mas_sno 685 686 if NEMO == 4.0 or NEMO == 4.2 : 687 dICE_mas_wat = ICE_mas_wat_end - ICE_mas_wat_beg 688 dSEA_mas_wat = dOCE_mas_wat + dICE_mas_wat 689 690 echo ( f'ICE_vol_ice_beg = {ICE_vol_ice_beg:12.6e} m^3 | ICE_vol_ice_end = {ICE_vol_ice_end:12.6e} m^3' ) 691 echo ( f'ICE_vol_sno_beg = {ICE_vol_sno_beg:12.6e} m^3 | ICE_vol_sno_end = {ICE_vol_sno_end:12.6e} m^3' ) 692 echo ( f'ICE_vol_pnd_beg = {ICE_vol_pnd_beg:12.6e} m^3 | ICE_vol_pnd_end = {ICE_vol_pnd_end:12.6e} m^3' ) 693 echo ( f'ICE_vol_fzl_beg = {ICE_vol_fzl_beg:12.6e} m^3 | ICE_vol_fzl_end = {ICE_vol_fzl_end:12.6e} m^3' ) 694 695 echo ( f'dICE_vol_ice = {dICE_vol_ice:12.3e} m^3' ) 696 echo ( f'dICE_vol_sno = {dICE_vol_sno:12.3e} m^3' ) 697 echo ( f'dICE_vol_pnd = {dICE_vol_pnd:12.3e} m^3' ) 698 echo ( f'dICE_mas_ice = {dICE_mas_ice:12.3e} m^3' ) 699 echo ( f'dICE_mas_sno = {dICE_mas_sno:12.3e} m^3' ) 700 echo ( f'dICE_mas_pnd = {dICE_mas_pnd:12.3e} m^3' ) 701 echo ( f'dICE_mas_fzl = {dICE_mas_fzl:12.3e} m^3' ) 702 echo ( f'dICE_mas_wat = {dICE_mas_wat:12.3e} m^3' ) 703 704 705 SEA_mas_wat_beg = OCE_mas_wat_beg + ICE_mas_wat_beg 706 SEA_mas_wat_end = OCE_mas_wat_end + ICE_mas_wat_end 707 708 echo ( '\n------------------------------------------------------------') 709 echo ( 'Variation du contenu en eau ocean + glace ' ) 710 echo ( 'dMass (ocean) = {:12.6e} kg '.format(dSEA_mas_wat) ) 711 echo ( 'dVol (ocean) = {:12.3e} Sv '.format(dSEA_mas_wat/dtime_sec*1E-6/OCE_rho_liq) ) 712 echo ( 'dVol (ocean) = {:12.3e} m '.format(dSEA_mas_wat*1E-3/OCE_aire_tot) ) 713 714 715 echo ( '\n------------------------------------------------------------------------------------' ) 716 echo ( '-- ATM changes in stores ' ) 717 718 #-- Change in precipitable water from the atmosphere daily and monthly files 719 #-- Compute sum weighted by gridcell area (kg/m2) then convert to Sv 720 721 # ATM vertical grid 722 ATM_Ahyb = d_ATM_his['Ahyb'].squeeze() 723 ATM_Bhyb = d_ATM_his['Bhyb'].squeeze() 724 klevp1 = ATM_Ahyb.shape[0] 725 726 # Surface pressure 727 if ICO : 728 DYN_ps_beg = d_DYN_beg['ps'] 729 DYN_ps_end = d_DYN_end['ps'] 730 731 if LMDZ : 732 DYN_ps_beg = lmdz.geo2point ( d_DYN_beg['ps'].isel(rlonv=slice(0,-1)) ) 733 DYN_ps_end = lmdz.geo2point ( d_DYN_end['ps'].isel(rlonv=slice(0,-1)) ) 734 735 # 3D Pressure 736 DYN_p_beg = ATM_Ahyb + ATM_Bhyb * DYN_ps_beg 737 DYN_p_end = ATM_Ahyb + ATM_Bhyb * DYN_ps_end 738 739 # Layer thickness 740 DYN_sigma_beg = DYN_p_beg[0:-1]*0. 741 DYN_sigma_end = DYN_p_end[0:-1]*0. 742 743 for k in np.arange (klevp1-1) : 744 DYN_sigma_beg[k,:] = (DYN_p_beg[k,:] - DYN_p_beg[k+1,:]) / Grav 745 DYN_sigma_end[k,:] = (DYN_p_end[k,:] - DYN_p_end[k+1,:]) / Grav 746 747 DYN_sigma_beg = DYN_sigma_beg.rename ( {'klevp1':'sigs'} ) 748 DYN_sigma_end = DYN_sigma_end.rename ( {'klevp1':'sigs'} ) 749 750 ##-- Vertical and horizontal integral, and sum of liquid, solid and vapor water phases 751 if LMDZ : 752 try : 753 DYN_wat_beg = lmdz.geo3point ( (d_DYN_beg['H2Ov'] + d_DYN_beg['H2Ol'] + d_DYN_beg['H2Oi']).isel(rlonv=slice(0,-1) ) ) 754 DYN_wat_end = lmdz.geo3point ( (d_DYN_end['H2Ov'] + d_DYN_end['H2Ol'] + d_DYN_end['H2Oi']).isel(rlonv=slice(0,-1) ) ) 755 except : 756 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) ) ) 757 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) ) ) 758 if ICO : 759 try : 760 DYN_wat_beg = (d_DYN_beg['H2O_g'] + d_DYN_beg['H2O_l'] + d_DYN_beg['H2O_s']).rename ( {'lev':'sigs'} ) 761 DYN_wat_end = (d_DYN_end['H2O_g'] + d_DYN_end['H2O_l'] + d_DYN_end['H2O_s']).rename ( {'lev':'sigs'} ) 762 except : 763 DYN_wat_beg = (d_DYN_beg['q'].isel(nq=0) + d_DYN_beg['q'].isel(nq=1) + d_DYN_beg['q'].isel(nq=2) ).rename ( {'lev':'sigs'} ) 764 DYN_wat_end = (d_DYN_end['q'].isel(nq=0) + d_DYN_end['q'].isel(nq=1) + d_DYN_end['q'].isel(nq=2) ).rename ( {'lev':'sigs'} ) 765 766 DYN_mas_wat_beg = ATM_stock_int (DYN_sigma_beg * DYN_wat_beg) 767 DYN_mas_wat_end = ATM_stock_int (DYN_sigma_end * DYN_wat_end) 768 769 dDYN_mas_wat = DYN_mas_wat_end - DYN_mas_wat_beg 770 771 echo ( '\nVariation du contenu en eau atmosphere (dynamique) ' ) 772 echo ( 'DYN_mas_beg = {:12.6e} kg | DYN_mas_end = {:12.6e} kg'.format (DYN_mas_wat_beg, DYN_mas_wat_end) ) 773 echo ( 'dMass (atm) = {:12.3e} kg '.format (dDYN_mas_wat) ) 774 echo ( 'dMass (atm) = {:12.3e} Sv '.format (dDYN_mas_wat/dtime_sec*1.e-6/ATM_rho) ) 775 echo ( 'dMass (atm) = {:12.3e} m '.format (dDYN_mas_wat/ATM_aire_sea_tot/ATM_rho) ) 776 777 ATM_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'] 778 ATM_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'] 779 780 ATM_qs_beg = d_ATM_beg['QS01']*d_ATM_beg['FTER']+d_ATM_beg['QS02']*d_ATM_beg['FLIC']+d_ATM_beg['QS03']*d_ATM_beg['FOCE']+d_ATM_beg['QS04']*d_ATM_beg['FSIC'] 781 ATM_qs_end = d_ATM_end['QS01']*d_ATM_end['FTER']+d_ATM_end['QS02']*d_ATM_end['FLIC']+d_ATM_end['QS03']*d_ATM_end['FOCE']+d_ATM_end['QS04']*d_ATM_end['FSIC'] 782 783 ATM_qsol_beg = d_ATM_beg['QSOL'] 784 ATM_qsol_end = d_ATM_end['QSOL'] 785 786 ATM_qs01_beg = d_ATM_beg['QS01'] * d_ATM_beg['FTER'] 787 ATM_qs01_end = d_ATM_end['QS01'] * d_ATM_end['FTER'] 788 ATM_qs02_beg = d_ATM_beg['QS02'] * d_ATM_beg['FLIC'] 789 ATM_qs02_end = d_ATM_end['QS02'] * d_ATM_end['FLIC'] 790 ATM_qs03_beg = d_ATM_beg['QS03'] * d_ATM_beg['FOCE'] 791 ATM_qs03_end = d_ATM_end['QS03'] * d_ATM_end['FOCE'] 792 ATM_qs04_beg = d_ATM_beg['QS04'] * d_ATM_beg['FSIC'] 793 ATM_qs04_end = d_ATM_end['QS04'] * d_ATM_end['FSIC'] 794 795 if ICO : 796 ATM_sno_beg = ATM_sno_beg .rename ( {'points_physiques':'cell_mesh'} ) 797 ATM_sno_end = ATM_sno_end .rename ( {'points_physiques':'cell_mesh'} ) 798 ATM_qs_beg = ATM_qs_beg .rename ( {'points_physiques':'cell_mesh'} ) 799 ATM_qs_end = ATM_qs_end .rename ( {'points_physiques':'cell_mesh'} ) 800 ATM_qsol_beg = ATM_qsol_beg.rename ( {'points_physiques':'cell_mesh'} ) 801 ATM_qsol_end = ATM_qsol_end.rename ( {'points_physiques':'cell_mesh'} ) 802 ATM_qs01_beg = ATM_qs01_beg.rename ( {'points_physiques':'cell_mesh'} ) 803 ATM_qs01_end = ATM_qs01_end.rename ( {'points_physiques':'cell_mesh'} ) 804 ATM_qs02_beg = ATM_qs02_beg.rename ( {'points_physiques':'cell_mesh'} ) 805 ATM_qs02_end = ATM_qs02_end.rename ( {'points_physiques':'cell_mesh'} ) 806 ATM_qs03_beg = ATM_qs03_beg.rename ( {'points_physiques':'cell_mesh'} ) 807 ATM_qs03_end = ATM_qs03_end.rename ( {'points_physiques':'cell_mesh'} ) 808 ATM_qs04_beg = ATM_qs04_beg.rename ( {'points_physiques':'cell_mesh'} ) 809 ATM_qs04_end = ATM_qs04_end.rename ( {'points_physiques':'cell_mesh'} ) 810 811 echo ('Computing atmosphere integrals') 812 ATM_mas_sno_beg = ATM_stock_int ( ATM_sno_beg ) 813 ATM_mas_sno_end = ATM_stock_int ( ATM_sno_end ) 814 ATM_mas_qs_beg = ATM_stock_int ( ATM_qs_beg ) 815 ATM_mas_qs_end = ATM_stock_int ( ATM_qs_end ) 816 ATM_mas_qsol_beg = ATM_stock_int ( ATM_qsol_beg ) 817 ATM_mas_qsol_end = ATM_stock_int ( ATM_qsol_end ) 818 ATM_mas_qs01_beg = ATM_stock_int ( ATM_qs01_beg ) 819 ATM_mas_qs01_end = ATM_stock_int ( ATM_qs01_end ) 820 ATM_mas_qs02_beg = ATM_stock_int ( ATM_qs02_beg ) 821 ATM_mas_qs02_end = ATM_stock_int ( ATM_qs02_end ) 822 ATM_mas_qs03_beg = ATM_stock_int ( ATM_qs03_beg ) 823 ATM_mas_qs03_end = ATM_stock_int ( ATM_qs03_end ) 824 ATM_mas_qs04_beg = ATM_stock_int ( ATM_qs04_beg ) 825 ATM_mas_qs04_end = ATM_stock_int ( ATM_qs04_end ) 826 827 dATM_mas_sno = ATM_mas_sno_end - ATM_mas_sno_beg 828 dATM_mas_qs = ATM_mas_qs_end - ATM_mas_qs_beg 829 dATM_mas_qsol = ATM_mas_qsol_end - ATM_mas_qsol_beg 830 831 dATM_mas_qs01 = ATM_mas_qs01_end - ATM_mas_qs01_beg 832 dATM_mas_qs02 = ATM_mas_qs02_end - ATM_mas_qs02_beg 833 dATM_mas_qs03 = ATM_mas_qs03_end - ATM_mas_qs03_beg 834 dATM_mas_qs04 = ATM_mas_qs04_end - ATM_mas_qs04_beg 835 836 echo ( '\nVariation du contenu en neige atmosphere (calottes)' ) 837 echo ( 'ATM_mas_sno_beg = {:12.6e} kg | ATM_mas_sno_end = {:12.6e} kg'.format (ATM_mas_sno_beg, ATM_mas_sno_end) ) 838 echo ( 'dMass (neige atm) = {:12.3e} kg '.format (dATM_mas_sno ) ) 839 echo ( 'dMass (neige atm) = {:12.3e} Sv '.format (dATM_mas_sno/dtime_sec*1e-6/ICE_rho_ice) ) 840 echo ( 'dMass (neige atm) = {:12.3e} m '.format (dATM_mas_sno/ATM_aire_sea_tot/ATM_rho) ) 841 842 echo ( '\nVariation du contenu humidite du sol' ) 843 echo ( 'ATM_mas_qs_beg = {:12.6e} kg | ATM_mas_qs_end = {:12.6e} kg'.format (ATM_mas_qs_beg, ATM_mas_qs_end) ) 844 echo ( 'dMass (neige atm) = {:12.3e} kg '.format (dATM_mas_qs ) ) 845 echo ( 'dMass (neige atm) = {:12.3e} Sv '.format (dATM_mas_qs/dtime_sec*1e-6/ATM_rho) ) 846 echo ( 'dMass (neige atm) = {:12.3e} m '.format (dATM_mas_qs/ATM_aire_sea_tot/ATM_rho) ) 847 848 echo ( '\nVariation du contenu en eau+neige atmosphere ' ) 849 echo ( 'dMass (eau + neige atm) = {:12.3e} kg '.format ( dDYN_mas_wat + dATM_mas_sno) ) 850 echo ( 'dMass (eau + neige atm) = {:12.3e} Sv '.format ( (dDYN_mas_wat + dATM_mas_sno)/dtime_sec*1E-6/ATM_rho) ) 851 echo ( 'dMass (eau + neige atm) = {:12.3e} m '.format ( (dDYN_mas_wat + dATM_mas_sno)/ATM_aire_sea_tot/ATM_rho) ) 852 853 echo ( '\n------------------------------------------------------------------------------------' ) 854 echo ( '-- SRF changes ' ) 855 856 if Routing == 'SIMPLE' : 857 RUN_mas_wat_beg = ONE_stock_int ( d_RUN_beg ['fast_reservoir'] + d_RUN_beg ['slow_reservoir'] + d_RUN_beg ['stream_reservoir']) 858 RUN_mas_wat_end = ONE_stock_int ( d_RUN_end ['fast_reservoir'] + d_RUN_end ['slow_reservoir'] + d_RUN_end ['stream_reservoir']) 859 860 if Routing == 'SECHIBA' : 861 RUN_mas_wat_beg = ONE_stock_int ( d_SRF_beg['fastres'] + d_SRF_beg['slowres'] + d_SRF_beg['streamres'] \ 862 + d_SRF_beg['floodres'] + d_SRF_beg['lakeres'] + d_SRF_beg['pondres'] ) 863 RUN_mas_wat_end = ONE_stock_int ( d_SRF_end['fastres'] + d_SRF_end['slowres'] + d_SRF_end['streamres'] \ 864 + d_SRF_end['floodres'] + d_SRF_end['lakeres'] + d_SRF_end['pondres'] ) 865 866 dRUN_mas_wat = RUN_mas_wat_end - RUN_mas_wat_beg 867 868 echo ( '\nWater content in routing ' ) 869 echo ( 'RUN_mas_wat_beg = {:12.6e} kg | RUN_mas_wat_end = {:12.6e} kg '.format (RUN_mas_wat_end, RUN_mas_wat_end) ) 870 echo ( 'dMass (routing) = {:12.3e} kg '.format(dRUN_mas_wat) ) 871 echo ( 'dMass (routing) = {:12.3e} Sv '.format(dRUN_mas_wat/dtime_sec*1E-9) ) 872 echo ( 'dMass (routing) = {:12.3e} m '.format(dRUN_mas_wat/OCE_aire_tot*1E-3) ) 873 874 print ('Reading SRF restart') 875 tot_watveg_beg = d_SRF_beg['tot_watveg_beg'] ; tot_watveg_beg = tot_watveg_beg .where (tot_watveg_beg < 1E10, 0.) 876 tot_watsoil_beg = d_SRF_beg['tot_watsoil_beg'] ; tot_watsoil_beg = tot_watsoil_beg.where (tot_watsoil_beg< 1E10, 0.) 877 snow_beg = d_SRF_beg['snow_beg'] ; snow_beg = snow_beg .where (snow_beg < 1E10, 0.) 878 879 tot_watveg_end = d_SRF_end['tot_watveg_beg'] ; tot_watveg_end = tot_watveg_end .where (tot_watveg_end < 1E10, 0.) 880 tot_watsoil_end = d_SRF_end['tot_watsoil_beg'] ; tot_watsoil_end = tot_watsoil_end.where (tot_watsoil_end< 1E10, 0.) 881 snow_end = d_SRF_end['snow_beg'] ; snow_end = snow_end .where (snow_end < 1E10, 0.) 882 883 if LMDZ : 884 tot_watveg_beg = lmdz.geo2point (tot_watveg_beg) 885 tot_watsoil_beg = lmdz.geo2point (tot_watsoil_beg) 886 snow_beg = lmdz.geo2point (snow_beg) 887 tot_watveg_end = lmdz.geo2point (tot_watveg_end) 888 tot_watsoil_end = lmdz.geo2point (tot_watsoil_end) 889 snow_end = lmdz.geo2point (snow_end) 890 891 SRF_wat_beg = tot_watveg_beg + tot_watsoil_beg + snow_beg 892 SRF_wat_end = tot_watveg_end + tot_watsoil_end + snow_end 893 894 #SRF_mas_wat_beg = d_SRF_beg['tot_watveg_beg']+d_SRF_beg['tot_watsoil_beg'] + d_SRF_beg['snow_beg'] 895 #SRF_mas_wat_end = d_SRF_end['tot_watveg_beg']+d_SRF_end['tot_watsoil_beg'] + d_SRF_end['snow_beg'] 896 897 #if LMDZ : 898 # tot_watveg_beg = tot_watveg_beg .rename ( {'y':'points_phyiques'} ) 899 # tot_watsoil_beg = tot_watsoil_beg.rename ( {'y':'points_phyiques'} ) 900 # snow_beg = snow_beg .rename ( {'y':'points_phyiques'} ) 901 # tot_watveg_end = tot_watveg_end .rename ( {'y':'points_phyiques'} ) 902 # tot_watsoil_end = tot_watsoil_end.rename ( {'y':'points_phyiques'} ) 903 # snow_end = snow_end .rename ( {'y':'points_phyiques'} ) 904 # SRF_wat_beg = SRF_wat_beg .rename ( {'y':'points_phyiques'} ) 905 # SRF_wat_end = SRF_wat_end .rename ( {'y':'points_phyiques'} ) 906 if ICO : 907 tot_watveg_beg = tot_watveg_beg .rename ( {'y':'cell_mesh'} ) 908 tot_watsoil_beg = tot_watsoil_beg.rename ( {'y':'cell_mesh'} ) 909 snow_beg = snow_beg .rename ( {'y':'cell_mesh'} ) 910 tot_watveg_end = tot_watveg_end .rename ( {'y':'cell_mesh'} ) 911 tot_watsoil_end = tot_watsoil_end.rename ( {'y':'cell_mesh'} ) 912 snow_end = snow_end .rename ( {'y':'cell_mesh'} ) 913 SRF_wat_beg = SRF_wat_beg .rename ( {'y':'cell_mesh'} ) 914 SRF_wat_end = SRF_wat_end .rename ( {'y':'cell_mesh'} ) 915 916 print ('Computing integrals') 917 918 print ( ' 1/6', end='' ) ; sys.stdout.flush () 919 SRF_mas_watveg_beg = ATM_stock_int ( tot_watveg_beg ) 920 print ( ' 2/6', end='' ) ; sys.stdout.flush () 921 SRF_mas_watsoil_beg = ATM_stock_int ( tot_watsoil_beg ) 922 print ( ' 3/6', end='' ) ; sys.stdout.flush () 923 SRF_mas_snow_beg = ATM_stock_int ( snow_beg ) 924 print ( ' 4/6', end='' ) ; sys.stdout.flush () 925 SRF_mas_watveg_end = ATM_stock_int ( tot_watveg_end ) 926 print ( ' 5/6', end='' ) ; sys.stdout.flush () 927 SRF_mas_watsoil_end = ATM_stock_int ( tot_watsoil_end ) 928 print ( ' 6/6', end='' ) ; sys.stdout.flush () 929 SRF_mas_snow_end = ATM_stock_int ( snow_end ) 930 print (' -- ') ; sys.stdout.flush () 931 932 dSRF_mas_watveg = SRF_mas_watveg_end - SRF_mas_watveg_beg 933 dSRF_mas_watsoil = SRF_mas_watsoil_end - SRF_mas_watsoil_beg 934 dSRF_mas_snow = SRF_mas_snow_end - SRF_mas_snow_beg 935 936 echo ('\nLes differents reservoirs') 937 echo ( f'SRF_mas_watveg_beg = {SRF_mas_watveg_beg :12.6e} kg | SRF_mas_watveg_end = {SRF_mas_watveg_end :12.6e} kg ' ) 938 echo ( f'SRF_mas_watsoil_beg = {SRF_mas_watsoil_beg:12.6e} kg | SRF_mas_watsoil_end = {SRF_mas_watsoil_end:12.6e} kg ' ) 939 echo ( f'SRF_mas_snow_beg = {SRF_mas_snow_beg :12.6e} kg | SRF_mas_snow_end = {SRF_mas_snow_end :12.6e} kg ' ) 940 941 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) ) 942 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) ) 943 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 ) ) 944 945 SRF_mas_wat_beg = SRF_mas_watveg_beg + SRF_mas_watsoil_beg + SRF_mas_snow_beg 946 SRF_mas_wat_end = SRF_mas_watveg_end + SRF_mas_watsoil_end + SRF_mas_snow_end 947 dSRF_mas_wat = SRF_mas_wat_end - SRF_mas_wat_beg 948 949 echo ( '\nWater content in surface ' ) 950 echo ( 'SRF_mas_wat_beg = {:12.6e} kg | SRF_mas_wat_end = {:12.6e} kg '.format (SRF_mas_wat_beg, SRF_mas_wat_end) ) 951 echo ( 'dMass (water srf) = {:12.3e} kg '.format (dSRF_mas_wat) ) 952 echo ( 'dMass (water srf) = {:12.3e} Sv '.format (dSRF_mas_wat/dtime_sec*1E-6/ATM_rho) ) 953 echo ( 'dMass (water srf) = {:12.3e} m '.format (dSRF_mas_wat/ATM_aire_sea_tot/ATM_rho) ) 954 955 echo ( '\nWater content in ATM + SRF + RUN ' ) 956 echo ( 'mas_wat_beg = {:12.6e} kg | mas_wat_end = {:12.6e} kg '. 957 format (DYN_mas_wat_beg + ATM_mas_sno_beg + RUN_mas_wat_beg + SRF_mas_wat_beg, 958 DYN_mas_wat_end + ATM_mas_sno_end + RUN_mas_wat_end + SRF_mas_wat_end) ) 959 echo ( 'dMass (water atm+srf+run) = {:12.6e} kg '.format ( dDYN_mas_wat + dATM_mas_sno + dRUN_mas_wat + dSRF_mas_wat) ) 960 echo ( 'dMass (water atm+srf+run) = {:12.3e} Sv '.format ((dDYN_mas_wat + dATM_mas_sno + dRUN_mas_wat + dSRF_mas_wat)/dtime_sec*1E-6/ATM_rho) ) 961 echo ( 'dMass (water atm+srf+run) = {:12.3e} m '.format ((dDYN_mas_wat + dATM_mas_sno + dRUN_mas_wat + dSRF_mas_wat)/ATM_aire_sea_tot/ATM_rho) ) 962 963 echo ( '\n------------------------------------------------------------------------------------' ) 964 echo ( '-- Change in all components' ) 965 echo ( 'mas_wat_beg = {:12.6e} kg | mas_wat_end = {:12.6e} kg'. 966 format (SEA_mas_wat_beg + DYN_mas_wat_beg + ATM_mas_sno_beg + RUN_mas_wat_beg + SRF_mas_wat_beg, 967 SEA_mas_wat_end + DYN_mas_wat_end + ATM_mas_sno_end + RUN_mas_wat_end + SRF_mas_wat_end) ) 968 echo ( 'dMass (water CPL) = {:12.3e} kg '.format ( dSEA_mas_wat + dDYN_mas_wat + dATM_mas_sno + dRUN_mas_wat + dSRF_mas_wat) ) 969 echo ( 'dMass (water CPL) = {:12.3e} Sv '.format ((dSEA_mas_wat + dDYN_mas_wat + dATM_mas_sno + dRUN_mas_wat + dSRF_mas_wat)/dtime_sec*1E-9) ) 970 echo ( 'dMass (water CPL) = {:12.3e} m '.format ((dSEA_mas_wat + dDYN_mas_wat + dATM_mas_sno + dRUN_mas_wat + dSRF_mas_wat)/OCE_aire_tot*1E-3) ) 971 972 922 ICE_wfxpnd = 0.0 ; ICE_mas_wfxpnd = 0.0 923 ICE_wfxsnw_sub = rprec (d_ICE_his['vfxsub'])/86400.*ICE_rho_sno ; ICE_mas_wfxsnw_sub = OCE_flux_int ( ICE_wfxsnw_sub ) 924 ICE_wfxsnw_pre = rprec (d_ICE_his['vfxspr'])/86400.*ICE_rho_sno ; ICE_mas_wfxsnw_pre = OCE_flux_int ( ICE_wfxsnw_pre ) 925 926 OCE_wfcorr = rprec (d_OCE_his['wfcorr']) ; OCE_mas_wfcorr = OCE_flux_int ( OCE_wfcorr ) 927 if OCE_relax : 928 # ssr and fwb are included in emp=>empmr but not in emp_oce (outputed by sea-ice) 929 OCE_vflx_fwb = rprec (d_OCE_his['vflx_fwb']) ; OCE_mas_vflx_fwb = OCE_flux_int ( OCE_vflx_fwb ) 930 OCE_vflx_ssr = rprec (d_OCE_his['vflx_ssr']) ; OCE_mas_vflx_ssr = OCE_flux_int ( OCE_vflx_ssr ) 931 else : 932 OCE_fwb = 0.0 ; OCE_mas_fwb = 0.0 933 OCE_ssr = 0.0 ; OCE_mas_ssr = 0.0 934 if OCE_icb : 935 OCE_berg_icb = rprec (d_OCE_his['berg_floating_melt']) ; OCE_mas_berg_icb = OCE_flux_int ( OCE_berg_icb ) 936 OCE_calving_icb = rprec (d_OCE_his['calving_icb'] ) ; OCE_mas_calv_icb = OCE_flux_int ( OCE_calving_icb ) 937 else : 938 OCE_berg_icb = 0. ; OCE_mas_berg_icb = 0. 939 OCE_calv_icb = 0. ; OCE_mas_calv_icb = 0. 940 941 OCE_mas_emp = OCE_mas_emp_oce - OCE_mas_wfxice - OCE_mas_wfxsnw - ICE_mas_wfxpnd - ICE_mas_wfxsub_err 942 OCE_mas_all = OCE_mas_emp_oce + OCE_mas_emp_ice - OCE_mas_runoffs - OCE_mas_iceshelf 943 944 prtFlux ('OCE+ICE budget ', OCE_mas_all , 'e', True) 945 prtFlux (' EMPMR ', OCE_mas_empmr , 'e', True) 946 prtFlux (' WFOB ', OCE_mas_wfob , 'e', True) 947 prtFlux (' EMP_OCE ', OCE_mas_emp_oce , 'e', True) 948 prtFlux (' EMP_ICE ', OCE_mas_emp_ice , 'e', True) 949 prtFlux (' EMP ', OCE_mas_emp , 'e', True) 950 prtFlux (' ICEBERG ', OCE_mas_iceberg , 'e', ) 951 prtFlux (' ICESHELF ', OCE_mas_iceshelf , 'e', True) 952 prtFlux (' CALVING ', OCE_mas_calving , 'e', True) 953 prtFlux (' FRIVER ', OCE_mas_friver , 'e', ) 954 prtFlux (' RUNOFFS ', OCE_mas_runoffs , 'e', True) 955 prtFlux (' WFXICE ', OCE_mas_wfxice , 'e', True) 956 prtFlux (' WFXSNW ', OCE_mas_wfxsnw , 'e', True) 957 prtFlux (' WFXSUB ', OCE_mas_wfxsub , 'e', True) 958 prtFlux (' WFXPND ', ICE_mas_wfxpnd , 'e', True) 959 prtFlux (' WFXSNW_SUB ', ICE_mas_wfxsnw_sub, 'e', True) 960 prtFlux (' WFXSNW_PRE ', ICE_mas_wfxsnw_pre, 'e', True) 961 prtFlux (' WFXSUB_ERR ', ICE_mas_wfxsub_err, 'e', True) 962 prtFlux (' EVAP_OCE ', OCE_mas_evap_oce , 'e' ) 963 prtFlux (' EVAP_ICE ', ICE_mas_evap_ice , 'e', True) 964 prtFlux (' SNOW_OCE ', OCE_mas_snow_oce , 'e', True) 965 prtFlux (' SNOW_ICE ', OCE_mas_snow_ice , 'e', True) 966 prtFlux (' RAIN ', OCE_mas_rain , 'e' ) 967 prtFlux (' FWB ', OCE_mas_fwb , 'e', True) 968 prtFlux (' SSR ', OCE_mas_ssr , 'e', True) 969 prtFlux (' WFCORR ', OCE_mas_wfcorr , 'e', True) 970 prtFlux (' BERG_ICB ', OCE_mas_berg_icb , 'e', True) 971 prtFlux (' CALV_ICB ', OCE_mas_calv_icb , 'e', True) 972 973 974 echo (' ') 975 976 prtFlux ( 'wbilo sea ', ATM_flux_int (ATM_wbilo_sea), 'e', ) 977 prtFlux ( 'costalflow ', ONE_flux_int (RUN_coastalflow), 'e', ) 978 prtFlux ( 'riverflow ', RUN_flx_river , 'e', ) 979 prtFlux ( 'costalflow ', RUN_flx_coastal, 'e', ) 980 prtFlux ( 'runoff ', RUN_flx_river+RUN_flx_coastal, 'e', ) 981 982 ATM_to_OCE = ATM_flux_int (ATM_wbilo_sea) - RUN_flx_river - RUN_flx_coastal - ATM_flx_calving 983 #OCE_from_ATM = -OCE_mas_emp_oce - OCE_mas_emp_ice + OCE_mas_runoffs + OCE_mas_iceberg + OCE_mas_calving + OCE_mas_iceshelf 984 OCE_from_ATM = OCE_mas_all 985 986 prtFlux ( 'ATM_to_OCE ', ATM_to_OCE , 'e', True ) 987 prtFlux ( 'OCE_from_ATM', OCE_from_ATM, 'e', True ) -
TOOLS/WATER_BUDGET/OCE_waterbudget.py
r6620 r6647 39 39 import nemo, lmdz 40 40 41 from WaterUtils import VarInt, Rho, Ra, Grav, ICE_rho_ice, ICE_rho_sno, OCE_rho_liq, ATM_rho, SRF_rho, RUN_rho, ICE_rho_pnd, YearLength 42 41 43 ## Creates parser for reading .ini input file 42 44 ## ------------------------------------------- … … 47 49 ## --------------------- 48 50 ATM=None ; ATM_HIS='latlon' ; SRF_HIS='latlon' ; RUN_HIS='latlon' ; ORCA=None ; NEMO=None ; OCE_relax=False 49 OCE_icb=False ; Coupled=False ; Routing=None 51 OCE_icb=False ; Coupled=False ; Routing=None ; TestInterp=None 50 52 TarRestartPeriod_beg=None ; TarRestartPeriod_end=None ; Comment=None ; Period=None ; Title=None 53 YearBegin=None ; YearEnd=None ; DateBegin=None ; DateEnd=None 51 54 52 55 ## … … 66 69 tar_restart_end_RUN=None ; tar_restart_end_OCE=None ; tar_restart_end_ICE=None 67 70 ContinueOnError=False ; ErrorCount=0 ; SortIco = False 71 72 ## 73 ## Precision of history file reading 74 ## --------------------------------- 75 # Default is float (full precision). Degrade the precision by using np.float32 76 # Restart file are always read at the full precision 77 readPrec=float 68 78 69 79 ## Read command line arguments … … 137 147 138 148 print ( f'\nConfig file readed : {IniFile} ' ) 139 149 150 ## 151 ## Reading prec 152 if wu.unDefined ( 'readPrec' ) : 153 readPrec = np.float64 154 else : 155 if readPrec in ["float", "float64", "r8", "double", "<class 'float'>" ] : readPrec = float 156 if readPrec in [ "float32", "r4", "single", "<class 'numpy.float32'>" ] : readPrec = np.float32 157 if readPrec in [ "float16", "r2", "half" , "<class 'numpy.float16'>" ] : readPrec = np.float16 158 140 159 ## Some physical constants 141 160 ## ======================= … … 155 174 if not 'Files' in config.keys () : config['Files'] = {} 156 175 157 config['Physics'] = { 'Ra': Ra, 'Grav':Grav, 'ICE_rho_ice':ICE_rho_ice, 'ICE_rho_sno':ICE_rho_sno,158 'OCE_rho_liq': OCE_rho_liq, 'ATM_rho':ATM_rho, 'SRF_rho':SRF_rho, 'RUN_rho':RUN_rho}159 160 config['Config'] = { 'ContinueOnError':ContinueOnError, 'SortIco':SortIco }176 config['Physics'] = { 'Ra':str(Ra), 'Grav':str(Grav), 'ICE_rho_ice':str(ICE_rho_ice), 'ICE_rho_sno':str(ICE_rho_sno), 177 'OCE_rho_liq':str(OCE_rho_liq), 'ATM_rho':str(ATM_rho), 'SRF_rho':str(SRF_rho), 'RUN_rho':str(RUN_rho)} 178 179 config['Config'] = { 'ContinueOnError':ContinueOnError, 'SortIco':SortIco, 'TestInterp':str(TestInterp), 'readPrec':str(readPrec) } 161 180 162 181 ## -------------------------- … … 178 197 config['Experiment']['DateBegin'] = DateBegin 179 198 else : 180 YearBegin, MonthBegin, DayBegin = wu. DateSplit( DateBegin )199 YearBegin, MonthBegin, DayBegin = wu.SplitDate ( DateBegin ) 181 200 DateBegin = wu.FormatToGregorian ( DateBegin) 182 config['Experiment']['YearBegin'] = YearBegin201 config['Experiment']['YearBegin'] = str(YearBegin) 183 202 184 203 if wu.unDefined ( 'DateEnd' ) : 185 204 DateEnd = f'{YearEnd}1231' 186 config['Experiment']['DateEnd'] = DateEnd205 config['Experiment']['DateEnd'] = str(DateEnd) 187 206 else : 188 YearEnd, MonthEnd, DayEnd = wu. DateSplit( DateEnd )207 YearEnd, MonthEnd, DayEnd = wu.SplitDate ( DateEnd ) 189 208 DateEnd = wu.FormatToGregorian ( DateEnd) 209 config['Experiment']['DateEnd'] = str(DateEnd) 190 210 191 211 if wu.unDefined ( 'PackFrequency' ) : … … 204 224 ## Output file with water budget diagnostics 205 225 ## ----------------------------------------- 206 if wu.unDefined ( 'FileOut' ) : FileOut = f'ATM_waterbudget_{JobName}_{DateBegin}_{DateEnd}.out' 207 config['Files']['FileOut'] = FileOut 226 if wu.unDefined ( 'FileOut' ) : 227 FileOut = f'OCE_waterbudget_{JobName}_{YearBegin}_{YearEnd}' 228 if readPrec == np.float32 : FileOut = f'{FileOut}_float32' 229 FileOut = f'{FileOut}.out' 230 231 config['Files']['FileOut'] = FileOut 208 232 209 233 f_out = open ( FileOut, mode = 'w' ) … … 211 235 ## Useful functions 212 236 ## ---------------- 213 def kg2Sv (val, rho=OCE_rho_liq) : 237 238 # Degrades precision 239 if readPrec == float : 240 def rprec (tab) : return tab 241 else : 242 def rprec (tab) : return tab.astype(readPrec).astype(float) 243 244 def kg2Sv (val, rho=ATM_rho) : 214 245 '''From kg to Sverdrup''' 215 246 return val/dtime_sec*1.0e-6/rho 216 247 217 def kg2myear (val, rho= OCE_rho_liq) :248 def kg2myear (val, rho=ATM_rho) : 218 249 '''From kg to m/year''' 219 250 return val/OCE_aire_tot/rho/NbYear 220 251 221 def var2prt (var, small=False, rho= OCE_rho_liq) :252 def var2prt (var, small=False, rho=ATM_rho) : 222 253 if small : return var , kg2Sv(var, rho=rho)*1000., kg2myear(var, rho=rho)*1000. 223 254 else : return var , kg2Sv(var, rho=rho) , kg2myear(var, rho=rho) 224 255 225 def prtFlux (Desc, var, Form='F', small=False, rho= OCE_rho_liq, width=15) :256 def prtFlux (Desc, var, Form='F', small=False, rho=ATM_rho, width=15) : 226 257 if small : 227 258 if Form in ['f', 'F'] : ff=" {:14.6e} kg | {:12.4f} mSv | {:12.4f} mm/year " … … 330 361 if NEMO == 3.6 :d_ICE_his = d_ICE_his.rename ( {'y_grid_T':'y', 'x_grid_T':'x'} ) 331 362 332 echo ( f ile_OCE_his)333 echo ( f ile_OCE_sca)334 echo ( f ile_ICE_his)363 echo ( f'{file_OCE_his = }' ) 364 echo ( f'{file_OCE_sca = }' ) 365 echo ( f'{file_ICE_his = }' ) 335 366 336 367 ## Compute run length … … 666 697 667 698 # Read variable and computes integral over space and time 668 OCE_empmr = d_OCE_his['wfo']; OCE_mas_empmr = OCE_flux_int ( OCE_empmr )669 OCE_wfob = d_OCE_his['wfob']; OCE_mas_wfob = OCE_flux_int ( OCE_wfob )670 OCE_emp_oce = d_OCE_his['emp_oce']; OCE_mas_emp_oce = OCE_flux_int ( OCE_emp_oce )671 OCE_emp_ice = d_OCE_his['emp_ice']; OCE_mas_emp_ice = OCE_flux_int ( OCE_emp_ice )672 OCE_iceshelf = d_OCE_his['iceshelf']; OCE_mas_iceshelf = OCE_flux_int ( OCE_iceshelf )673 OCE_calving = d_OCE_his['calving']; OCE_mas_calving = OCE_flux_int ( OCE_calving )674 OCE_iceberg = d_OCE_his['iceberg']; OCE_mas_iceberg = OCE_flux_int ( OCE_iceberg )675 OCE_friver = d_OCE_his['friver']; OCE_mas_friver = OCE_flux_int ( OCE_friver )676 OCE_runoffs = d_OCE_his['runoffs']; OCE_mas_runoffs = OCE_flux_int ( OCE_runoffs )699 OCE_empmr = rprec (d_OCE_his['wfo'] ) ; OCE_mas_empmr = OCE_flux_int ( OCE_empmr ) 700 OCE_wfob = rprec (d_OCE_his['wfob'] ) ; OCE_mas_wfob = OCE_flux_int ( OCE_wfob ) 701 OCE_emp_oce = rprec (d_OCE_his['emp_oce'] ) ; OCE_mas_emp_oce = OCE_flux_int ( OCE_emp_oce ) 702 OCE_emp_ice = rprec (d_OCE_his['emp_ice'] ) ; OCE_mas_emp_ice = OCE_flux_int ( OCE_emp_ice ) 703 OCE_iceshelf = rprec (d_OCE_his['iceshelf']) ; OCE_mas_iceshelf = OCE_flux_int ( OCE_iceshelf ) 704 OCE_calving = rprec (d_OCE_his['calving'] ) ; OCE_mas_calving = OCE_flux_int ( OCE_calving ) 705 OCE_iceberg = rprec (d_OCE_his['iceberg'] ) ; OCE_mas_iceberg = OCE_flux_int ( OCE_iceberg ) 706 OCE_friver = rprec (d_OCE_his['friver'] ) ; OCE_mas_friver = OCE_flux_int ( OCE_friver ) 707 OCE_runoffs = rprec (d_OCE_his['runoffs'] ) ; OCE_mas_runoffs = OCE_flux_int ( OCE_runoffs ) 677 708 if NEMO == 4.0 or NEMO == 4.2 : 678 OCE_wfxice = d_OCE_his['vfxice']; OCE_mas_wfxice = OCE_flux_int ( OCE_wfxice )679 OCE_wfxsnw = d_OCE_his['vfxsnw']; OCE_mas_wfxsnw = OCE_flux_int ( OCE_wfxsnw )680 OCE_wfxsub = d_OCE_his['vfxsub']; OCE_mas_wfxsub = OCE_flux_int ( OCE_wfxsub )709 OCE_wfxice = rprec (d_OCE_his['vfxice']) ; OCE_mas_wfxice = OCE_flux_int ( OCE_wfxice ) 710 OCE_wfxsnw = rprec (d_OCE_his['vfxsnw']) ; OCE_mas_wfxsnw = OCE_flux_int ( OCE_wfxsnw ) 711 OCE_wfxsub = rprec (d_OCE_his['vfxsub']) ; OCE_mas_wfxsub = OCE_flux_int ( OCE_wfxsub ) 681 712 if NEMO == 3.6 : 682 OCE_wfxice = d_OCE_his['vfxice']/86400.*ICE_rho_ice ; OCE_mas_wfxice = OCE_flux_int ( OCE_wfxice )683 OCE_wfxsnw = d_OCE_his['vfxsnw']/86400.*ICE_rho_sno ; OCE_mas_wfxsnw = OCE_flux_int ( OCE_wfxsnw )684 OCE_wfxsub = d_OCE_his['vfxsub']/86400.*ICE_rho_sno ; OCE_mas_wfxsub = OCE_flux_int ( OCE_wfxsub )713 OCE_wfxice = rprec (d_OCE_his['vfxice'])/86400.*ICE_rho_ice ; OCE_mas_wfxice = OCE_flux_int ( OCE_wfxice ) 714 OCE_wfxsnw = rprec (d_OCE_his['vfxsnw'])/86400.*ICE_rho_sno ; OCE_mas_wfxsnw = OCE_flux_int ( OCE_wfxsnw ) 715 OCE_wfxsub = rprec (d_OCE_his['vfxsub'])/86400.*ICE_rho_sno ; OCE_mas_wfxsub = OCE_flux_int ( OCE_wfxsub ) 685 716 # Additional checks 686 OCE_evap_oce = d_OCE_his['evap_ao_cea']; OCE_mas_evap_oce = OCE_flux_int ( OCE_evap_oce )687 ICE_evap_ice = d_OCE_his['subl_ai_cea']; ICE_mas_evap_ice = OCE_flux_int ( ICE_evap_ice )688 OCE_snow_oce = d_OCE_his['snow_ao_cea']; OCE_mas_snow_oce = OCE_flux_int ( OCE_snow_oce )689 OCE_snow_ice = d_OCE_his['snow_ai_cea']; OCE_mas_snow_ice = OCE_flux_int ( OCE_snow_ice )690 OCE_rain = d_OCE_his['rain']; OCE_mas_rain = OCE_flux_int ( OCE_rain )691 ICE_wfxsub_err = d_ICE_his['vfxsub_err']; ICE_mas_wfxsub_err = OCE_flux_int ( ICE_wfxsub_err )717 OCE_evap_oce = rprec (d_OCE_his['evap_ao_cea']) ; OCE_mas_evap_oce = OCE_flux_int ( OCE_evap_oce ) 718 ICE_evap_ice = rprec (d_OCE_his['subl_ai_cea']) ; ICE_mas_evap_ice = OCE_flux_int ( ICE_evap_ice ) 719 OCE_snow_oce = rprec (d_OCE_his['snow_ao_cea']) ; OCE_mas_snow_oce = OCE_flux_int ( OCE_snow_oce ) 720 OCE_snow_ice = rprec (d_OCE_his['snow_ai_cea']) ; OCE_mas_snow_ice = OCE_flux_int ( OCE_snow_ice ) 721 OCE_rain = rprec (d_OCE_his['rain'] ) ; OCE_mas_rain = OCE_flux_int ( OCE_rain ) 722 ICE_wfxsub_err = rprec (d_ICE_his['vfxsub_err'] ) ; ICE_mas_wfxsub_err = OCE_flux_int ( ICE_wfxsub_err ) 692 723 if NEMO == 4.0 or NEMO == 4.2 : 693 ICE_wfxpnd = d_ICE_his['vfxpnd']; ICE_mas_wfxpnd = OCE_flux_int ( ICE_wfxpnd )694 ICE_wfxsnw_sub = d_ICE_his['vfxsnw_sub']; ICE_mas_wfxsnw_sub = OCE_flux_int ( ICE_wfxsnw_sub )695 ICE_wfxsnw_pre = d_ICE_his['vfxsnw_pre']; ICE_mas_wfxsnw_pre = OCE_flux_int ( ICE_wfxsnw_pre )724 ICE_wfxpnd = rprec (d_ICE_his['vfxpnd'] ) ; ICE_mas_wfxpnd = OCE_flux_int ( ICE_wfxpnd ) 725 ICE_wfxsnw_sub = rprec (d_ICE_his['vfxsnw_sub']) ; ICE_mas_wfxsnw_sub = OCE_flux_int ( ICE_wfxsnw_sub ) 726 ICE_wfxsnw_pre = rprec (d_ICE_his['vfxsnw_pre']) ; ICE_mas_wfxsnw_pre = OCE_flux_int ( ICE_wfxsnw_pre ) 696 727 if NEMO == 3.6 : 697 728 ICE_wfxpnd = 0.0 ; ICE_mas_wfxpnd = 0.0 698 ICE_wfxsnw_sub = d_ICE_his['vfxsub']/86400.*ICE_rho_sno ; ICE_mas_wfxsnw_sub = OCE_flux_int ( ICE_wfxsnw_sub )699 ICE_wfxsnw_pre = d_ICE_his['vfxspr']/86400.*ICE_rho_sno ; ICE_mas_wfxsnw_pre = OCE_flux_int ( ICE_wfxsnw_pre )700 701 OCE_wfcorr = d_OCE_his['wfcorr']; OCE_mas_wfcorr = OCE_flux_int ( OCE_wfcorr )729 ICE_wfxsnw_sub = rprec (d_ICE_his['vfxsub'])/86400.*ICE_rho_sno ; ICE_mas_wfxsnw_sub = OCE_flux_int ( ICE_wfxsnw_sub ) 730 ICE_wfxsnw_pre = rprec (d_ICE_his['vfxspr'])/86400.*ICE_rho_sno ; ICE_mas_wfxsnw_pre = OCE_flux_int ( ICE_wfxsnw_pre ) 731 732 OCE_wfcorr = rprec (d_OCE_his['wfcorr']) ; OCE_mas_wfcorr = OCE_flux_int ( OCE_wfcorr ) 702 733 if OCE_relax : 703 734 # ssr and fwb are included in emp=>empmr but not in emp_oce (outputed by sea-ice) 704 OCE_vflx_fwb = d_OCE_his['vflx_fwb']; OCE_mas_vflx_fwb = OCE_flux_int ( OCE_vflx_fwb )705 OCE_vflx_ssr = d_OCE_his['vflx_ssr']; OCE_mas_vflx_ssr = OCE_flux_int ( OCE_vflx_ssr )735 OCE_vflx_fwb = rprec (d_OCE_his['vflx_fwb']) ; OCE_mas_vflx_fwb = OCE_flux_int ( OCE_vflx_fwb ) 736 OCE_vflx_ssr = rprec (d_OCE_his['vflx_ssr']) ; OCE_mas_vflx_ssr = OCE_flux_int ( OCE_vflx_ssr ) 706 737 else : 707 738 OCE_fwb = 0.0 ; OCE_mas_fwb = 0.0 708 739 OCE_ssr = 0.0 ; OCE_mas_ssr = 0.0 709 740 if OCE_icb : 710 OCE_berg_icb = d_OCE_his['berg_floating_melt']; OCE_mas_berg_icb = OCE_flux_int ( OCE_berg_icb )711 OCE_calving_icb = d_OCE_his['calving_icb']; OCE_mas_calv_icb = OCE_flux_int ( OCE_calving_icb )741 OCE_berg_icb = rprec (d_OCE_his['berg_floating_melt']) ; OCE_mas_berg_icb = OCE_flux_int ( OCE_berg_icb ) 742 OCE_calving_icb = rprec (d_OCE_his['calving_icb'] ) ; OCE_mas_calv_icb = OCE_flux_int ( OCE_calving_icb ) 712 743 else : 713 744 OCE_berg_icb = 0. ; OCE_mas_berg_icb = 0. … … 715 746 716 747 OCE_mas_emp = OCE_mas_emp_oce - OCE_mas_wfxice - OCE_mas_wfxsnw - ICE_mas_wfxpnd - ICE_mas_wfxsub_err 717 718 OCE_mas_all = OCE_mas_emp_oce +OCE_mas_emp_ice - OCE_mas_runoffs - OCE_mas_iceshelf 748 OCE_mas_all = OCE_mas_emp_oce + OCE_mas_emp_ice - OCE_mas_runoffs - OCE_mas_iceshelf 719 749 720 750 echo ('\n-- Fields:' ) … … 748 778 prtFlux (' CALV_ICB ', OCE_mas_calv_icb , 'e', True) 749 779 780 echo (' ') 781 if Coupled : 782 prtFlux ( 'Bilan ocean :', -OCE_mas_emp_oce - OCE_mas_emp_ice + OCE_mas_runoffs + OCE_mas_iceshelf, 'e', True ) 783 else : 784 prtFlux ( 'Bilan ocean :', -OCE_mas_emp_oce - OCE_mas_emp_ice + OCE_mas_runoffs + OCE_mas_iceberg + OCE_mas_calving + OCE_mas_iceshelf, 'e', True ) 785 786 750 787 echo ('\n===> Comparing ===>' ) 751 788 echo (' WFX OCE = -empmr + iceshelf = {:12.5e} (kg) '.format ( -OCE_mas_empmr + OCE_mas_iceshelf) ) … … 770 807 echo (' = (dSEA_mas_wat + emp_oce + emp_ice - runoffs - iceshelf)*/abs(dSEA_mas_wat) = {:12.1e} (-) '.format ( (dSEA_mas_wat + OCE_mas_emp_oce + OCE_mas_emp_ice - OCE_mas_runoffs - OCE_mas_iceshelf)/abs(dSEA_mas_wat) ) ) 771 808 772 prtFlux (' Leak OCE ', ( dOCE_mas_wat + OCE_mas_empmr - OCE_mas_iceshelf) , 'e' )773 prtFlux (' Leak ICE+SNW+PND ', ( dICE_mas_wat + OCE_mas_emp_ice + OCE_mas_wfxice + OCE_mas_wfxsnw + ICE_mas_wfxpnd + ICE_mas_wfxsub_err ) , 'e' )774 prtFlux (' Leak OCE+ICE+SNW+PND ', ( dSEA_mas_wat + OCE_mas_emp_oce +OCE_mas_emp_ice - OCE_mas_runoffs - OCE_mas_iceshelf ) , 'e' )809 prtFlux (' Leak OCE ', ( dOCE_mas_wat + OCE_mas_empmr - OCE_mas_iceshelf) , 'e', True ) 810 prtFlux (' Leak ICE+SNW+PND ', ( dICE_mas_wat + OCE_mas_emp_ice + OCE_mas_wfxice + OCE_mas_wfxsnw + ICE_mas_wfxpnd + ICE_mas_wfxsub_err ) , 'e', True ) 811 prtFlux (' Leak OCE+ICE+SNW+PND ', ( dSEA_mas_wat + OCE_mas_emp_oce +OCE_mas_emp_ice - OCE_mas_runoffs - OCE_mas_iceshelf ) , 'e', True ) 775 812 776 813 -
TOOLS/WATER_BUDGET/WaterUtils.py
r6620 r6647 70 70 def unDefined (char) : 71 71 '''True if a variable is not defined, or set to None''' 72 if char in locals () : 73 if locals()[char] == None : unDefined = True 72 if char in globals () : 73 if globals()[char] == None : 74 unDefined = True 74 75 else : unDefined = False 75 76 else : unDefined = True … … 79 80 '''True if a variable is defined and not equal to None''' 80 81 if char in globals () : 81 if globals()[char] == None : Defined = False 82 if globals()[char] == None : 83 Defined = False 82 84 else : Defined = True 83 85 else : Defined = False -
TOOLS/WATER_BUDGET/lmdz.py
r6519 r6647 28 28 __Date__ = "$Date$" 29 29 __Revision__ = "$Revision$" 30 __Id__ = "$Id: lmdz.py 6508 2023-06-13 10:58:38Z omamce$"30 __Id__ = "$Id: $" 31 31 __HeadURL = "$HeadURL$" 32 32 … … 36 36 except ImportError : pass 37 37 38 #try : import numba39 #except ImportError : pass38 try : import numba 39 except ImportError : pass 40 40 41 41 rpi = np.pi ; rad = np.deg2rad (1.0) ; dar = np.rad2deg (1.0) 42 42 43 43 44 def __m ath__ (tab) :44 def __mmath__ (tab) : 45 45 ''' 46 46 Determines the type of tab : i.e. numpy or xarray … … 71 71 72 72 ''' 73 math = __m ath__ (tab)73 math = __mmath__ (tab) 74 74 if tab.shape[-1] == 1 : extend = tab 75 75 … … 99 99 return extend 100 100 101 def interp1d (x, xp, yp, zdim='presnivs', verbose=False, method='linear') :101 def interp1d (x, xp, yp, zdim='presnivs', units=None, verbose=False, method='linear') : 102 102 ''' 103 103 One-dimensionnal interpolation of a multi-dimensionnal field … … 118 118 119 119 \!/ xp should be decreasing values along zdim axis \!/ 120 ''' 120 ''' 121 121 # Get the number of dimension with dim==zdim 122 122 axis = list(xp.dims).index(zdim) … … 128 128 # Define the result array 129 129 in_shape = np.array (xp.shape) 130 if verbose : print ( 'in_shape : ', in_shape)130 if verbose : print ( f'{in_shape=}' ) 131 131 ou_shape = np.array (in_shape) 132 if verbose : print ( 'ou_shape : ', ou_shape)132 if verbose : print ( f'{ou_shape=}' ) 133 133 ou_shape[axis] = nk_ou 134 134 135 135 in_dims = list (yp.dims) 136 if verbose : print ( 'in_dims : ', in_dims)136 if verbose : print ( f'{in_dims=}' ) 137 137 ou_dims = in_dims 138 if verbose : print ( 'ou_dims : ', ou_dims )138 139 139 pdim = x.dims[0] 140 140 ou_dims[axis] = pdim 141 141 142 142 new_coords = [] 143 for coord in yp.dims : 144 if coord == zdim : new_coords.append (x.coords[pdim].values) 145 else : new_coords.append (yp.coords[coord].values) 143 for i, dim in enumerate (yp.dims) : 144 if dim == zdim : 145 ou_dims[i] = x.dims[0] 146 if units != None : yp[dim].attrs['units'] = units 147 new_coords.append (x .values) 148 else : 149 new_coords.append (yp.coords[dim].values) 146 150 147 if verbose : print ( 'new_coords : ', new_coords ) 151 if verbose : 152 print ( f'{ou_dims =}' ) 153 print ( f'{new_coords=}' ) 148 154 149 155 ou_tab = xr.DataArray (np.empty (ou_shape), dims=ou_dims, coords=new_coords) … … 159 165 160 166 # Optimized (pre-compiled) interpolation loop 161 #@numba.jit (nopython=True)162 def __interp (nk_ou, x, xp, yp , result) :167 #@numba.jit (nopython=True) 168 def __interp (nk_ou, x, xp, yp) : 163 169 # Interpolate 164 for k in np.arange (nk_ou) : 165 # Find index of the just above level 166 idk1 = np.minimum ( (x[k]-xp), 0.).argmax (dim=zdim) 167 idk2 = idk1 - 1 168 idk2 = np.maximum (idk2, 0) 169 170 x1 = xp[{zdim:idk1}] 171 x2 = xp[{zdim:idk2}] 172 173 dx1 = x[k] - x1 174 dx2 = x2 - x[k] 175 dx = x2 - x1 176 dx1 = dx1/dx ; dx2 = dx2/dx 177 178 y1 = yp[{zdim:idk1}] 179 y2 = yp[{zdim:idk2}] 180 181 if 'linear' in method : 182 result = (dx1*y2 + dx2*y1) 183 if 'log' in method : 184 if yp_min > 0. : 185 result = np.power(y2, dx1) * np.power(y1, dx2) 186 if yp_max < 0. : 187 result = -np.power(-y2, dx1) * np.power(-y1, dx2) 188 if 'nearest' in method : 189 result = xr.where ( dx2>=dx1, y1, y2) 170 # Find index of the just above level 171 idk1 = np.minimum ( (x-xp), 0.).argmax (dim=zdim) 172 idk2 = idk1 - 1 173 idk2 = np.maximum (idk2, 0) 174 175 x1 = xp[{zdim:idk1}] 176 x2 = xp[{zdim:idk2}] 177 178 dx1 = x - x1 179 dx2 = x2 - x 180 dx = x2 - x1 181 dx1 = dx1/dx ; dx2 = dx2/dx 182 183 y1 = yp[{zdim:idk1}] 184 y2 = yp[{zdim:idk2}] 185 186 #print ( f'{k=} {idk1=} {idk2=} {x1=} {x2=} {dx=1} {dx2=} {y1=} {y2}' ) 187 188 if 'linear' in method : 189 result = (dx1*y2 + dx2*y1) 190 if 'log' in method : 191 if yp_min > 0. : 192 result = np.power(y2, dx1) * np.power(y1, dx2) 193 if yp_max < 0. : 194 result = -np.power(-y2, dx1) * np.power(-y1, dx2) 195 if 'nearest' in method : 196 result = xr.where ( dx2>=dx1, y1, y2) 190 197 191 return result 192 193 result = __interp (nk_ou, x, xp, yp, result) 194 198 return result 199 200 for k in np.arange (nk_ou) : 201 result = __interp (nk_ou, x[{pdim:k}], xp, yp) 202 195 203 # Put result in the final array 196 204 ou_tab [{pdim:k}] = result … … 198 206 return ou_tab.squeeze() 199 207 208 def fixed_lon (lon, center_lon=0.0) : 209 ''' 210 Returns corrected longitudes for nicer plots 211 212 lon : longitudes of the grid. At least 1D. 213 center_lon : center longitude. Default=0. 214 215 Designed by Phil Pelson. See https://gist.github.com/pelson/79cf31ef324774c97ae7 216 ''' 217 mmath = __mmath__ (lon) 218 219 fixed_lon = lon.copy () 220 221 fixed_lon = mmath.where (fixed_lon > center_lon+180., fixed_lon-360.0, fixed_lon) 222 fixed_lon = mmath.where (fixed_lon < center_lon-180., fixed_lon+360.0, fixed_lon) 223 224 start = np.argmax (np.abs (np.diff (fixed_lon, axis=-1)) > 180., axis=-1) 225 fixed_lon [start+1:] += 360. 226 227 return fixed_lon 228 200 229 def nord2sud (p2D) : 201 230 ''' … … 210 239 From 1D (restart type) to 2D 211 240 ''' 212 math = __m ath__ (p1D)241 math = __mmath__ (p1D) 213 242 214 243 # Get the dimensions … … 244 273 return p2D 245 274 246 def geo2point ( p2D, cumulPoles=False, dim1D=' cell', debug=False) :275 def geo2point ( p2D, cumulPoles=False, dim1D='points_physiques' ) : 247 276 ''' 248 277 From 2D (lat, lon) to 1D (points_phyiques) 249 278 ''' 250 math = __m ath__ (p2D)279 math = __mmath__ (p2D) 251 280 # 252 281 # Get the dimension … … 260 289 261 290 jpn = jpi*(jpj-2) + 2 262 263 if debug :264 print ( f'{jpi=} {jpj=} {jpn=} {jpt=}' )265 291 266 292 if jpt == -1 : … … 281 307 if math == xr : 282 308 p1D = xr.DataArray (p1D) 283 for attr in p2D.attrs : 309 for attr in p2D.attrs : 284 310 p1D.attrs[attr] = p2D.attrs[attr] 285 311 p1D = p1D.rename ( {p1D.dims[0]:p2D.dims[0], p1D.dims[-1]:dim1D} ) … … 291 317 return p1D 292 318 293 def geo3point ( p3D, cumulPoles=False, dim1D=' cell' ) :319 def geo3point ( p3D, cumulPoles=False, dim1D='points_physiques' ) : 294 320 ''' 295 321 From 3D (lev, lat, lon) to 2D (lev, points_phyiques) 296 322 ''' 297 math = __m ath__ (p3D)323 math = __mmath__ (p3D) 298 324 # 299 325 # Get the dimensions -
TOOLS/WATER_BUDGET/nemo.py
r6519 r6647 22 22 Periodicity and other stuff 23 23 24 - Lots of tests for xarray object 25 - Not much testerd for numpy objects 26 24 27 olivier.marti@lsce.ipsl.fr 25 '''26 28 27 29 ## SVN information … … 29 31 __Date__ = "$Date$" 30 32 __Revision__ = "$Revision$" 31 __Id__ = "$Id: nemo.py 6265 2022-11-02 12:45:56Z omamce$"33 __Id__ = "$Id: $" 32 34 __HeadURL = "$HeadURL$" 35 ''' 33 36 34 37 import numpy as np … … 36 39 except ImportError : pass 37 40 38 try : import f90nml 39 except : pass 40 41 try : from sklearn.impute import SimpleImputer 42 except : pass 43 44 try : import numba 45 except : pass 41 #try : import f90nml 42 #except : pass 43 44 #try : from sklearn.impute import SimpleImputer 45 #except : pass 46 46 47 47 rpi = np.pi ; rad = np.deg2rad (1.0) ; dar = np.rad2deg (1.0) … … 61 61 repsi = np.finfo (1.0).eps 62 62 63 xList = [ 'x', 'X', 'lon' , 'longitude' ] 64 yList = [ 'y', 'Y', 'lat' , 'latitude' ] 65 zList = [ 'z', 'Z', 'depth' , ] 66 tList = [ 't', 'T', 'time' , ] 63 ## Default names of dimensions 64 dim_names = {'x':'xx', 'y':'yy', 'z':'olevel', 't':None} 65 66 ## All possibles name of dimensions in Nemo files 67 xName = [ 'x', 'X', 'X1', 'xx', 'XX', 'x_grid_T', 'x_grid_U', 'x_grid_V', 'x_grid_F', 'x_grid_W', 'lon', 'nav_lon', 'longitude', 'X1', 'x_c', 'x_f', ] 68 yName = [ 'y', 'Y', 'Y1', 'yy', 'YY', 'y_grid_T', 'y_grid_U', 'y_grid_V', 'y_grid_F', 'y_grid_W', 'lat', 'nav_lat', 'latitude' , 'Y1', 'y_c', 'y_f', ] 69 zName = [ 'z', 'Z', 'Z1', 'zz', 'ZZ', 'depth', 'tdepth', 'udepth', 'vdepth', 'wdepth', 'fdepth', 'deptht', 'depthu', 'depthv', 'depthw', 'depthf', 'olevel', 'z_c', 'z_f', ] 70 tName = [ 't', 'T', 'tt', 'TT', 'time', 'time_counter', 'time_centered', ] 71 72 ## All possibles name of units of dimensions in Nemo files 73 xUnit = [ 'degrees_east', ] 74 yUnit = [ 'degrees_north', ] 75 zUnit = [ 'm', 'meter', ] 76 tUnit = [ 'second', 'minute', 'hour', 'day', 'month', 'year', ] 77 78 ## All possibles size of dimensions in Orca files 79 xLength = [ 180, 182, 360, 362 ] 80 yLength = [ 148, 149, 331, 332 ] 81 zLength = [31, 75] 67 82 68 83 ## =========================================================================== 69 84 def __mmath__ (tab, default=None) : 85 ''' 86 Determines the type of tab : xarray or numpy object ? 87 ''' 70 88 mmath = default 71 89 try : 72 90 if type (tab) == xr.core.dataarray.DataArray : mmath = xr 73 except : 74 pass 91 except : pass 75 92 76 93 try : 77 94 if type (tab) == np.ndarray : mmath = np 78 except : 79 pass 95 except : pass 80 96 81 97 return mmath 82 83 98 84 99 def __guessNperio__ (jpj, jpi, nperio=None, out='nperio') : … … 99 114 ''' 100 115 Tries to guess the value of nperio (periodicity parameter. See NEMO documentation for details) 101 116 102 117 Inputs 103 118 jpj : number of latitudes … … 105 120 nperio : periodicity parameter 106 121 ''' 122 print ( jpi, jpj) 107 123 if nperio == None : 108 124 ## Values for NEMO version < 4.2 109 if jpj == 149 and jpi == 182:125 if (jpj == 149 and jpi == 182) or (jpj == None and jpi == 182) or (jpj == 149 or jpi == None) : 110 126 config = 'ORCA2.3' 111 127 nperio = 4 # ORCA2. We choose legacy orca2. 112 128 Iperio = 1 ; Jperio = 0 ; NFold = 1 ; NFtype = 'T' 113 if jpj == 332 and jpi == 362: # eORCA1.129 if (jpj == 332 and jpi == 362) or (jpj == None and jpi == 362) or (jpj == 332 and jpi == None) : # eORCA1. 114 130 config = 'eORCA1.2' 115 131 nperio = 6 … … 125 141 126 142 ## Values for NEMO version >= 4.2. No more halo points 127 if jpj == 148 and jpi == 180:143 if (jpj == 148 and jpi == 180) or (jpj == None and jpi == 180) or (jpj == 148 and jpi == None) : 128 144 config = 'ORCA2.4' 129 145 nperio = 4.2 # ORCA2. We choose legacy orca2. 130 146 Iperio = 1 ; Jperio = 0 ; NFold = 1 ; NFtype = 'F' 131 if jpj == 331 and jpi == 360: # eORCA1.147 if (jpj == 331 and jpi == 360) or (jpj == None and jpi == 360) or (jpj == 331 and jpi == None) : # eORCA1. 132 148 config = 'eORCA1.4' 133 149 nperio = 6.2 … … 142 158 else : 143 159 if nperio in nperio_valid_range : 144 print ( 'nperio set as {:} (deduced from jpj={:d} jpi={:d})'.format (nperio, jpj, jpi))160 print ( f'nperio set as {nperio} (deduced from {jpj=} and {jpi=})' ) 145 161 else : 146 raise ValueError ( 'nperio set as {:} (deduced from jpi={:d}) : nemo.py is not ready for this value'.format (nperio, jpi))162 raise ValueError ( f'nperio set as {nperio} (deduced from {jpi=} and {jpj=}) : nemo.py is not ready for this value' ) 147 163 148 164 if out == 'nperio' : return nperio … … 162 178 Credits : who is the original author ? 163 179 ''' 180 164 181 gP = None 165 182 mmath = __mmath__ (ptab) … … 178 195 raise Exception ('in nemo module : cd_type not found, and cannot by guessed') 179 196 else : 180 print ( 'Grid set as', gP, 'deduced from dims ', ptab.dims)197 print ( f'Grid set as {gP} deduced from dims {ptab.dims}' ) 181 198 return gP 182 199 else : 183 200 raise Exception ('in nemo module : cd_type not found, input is not an xarray data') 184 201 202 def get_shape ( ptab ) : 203 ''' 204 Get shape of ptab : 205 shape main contain X, Y, Z or T 206 Y is missing for a latitudinal slice 207 X is missing for on longitudinal slice 208 etc ... 209 ''' 210 211 get_shape = '' 212 ix, ax = __findAxis__ (ptab, 'x') 213 jy, ay = __findAxis__ (ptab, 'y') 214 kz, az = __findAxis__ (ptab, 'z') 215 lt, at = __findAxis__ (ptab, 't') 216 if ax : get_shape = 'X' 217 if ay : get_shape = 'Y' + get_shape 218 if az : get_shape = 'Z' + get_shape 219 if at : get_shape = 'T' + get_shape 220 return get_shape 221 185 222 def lbc_diag (nperio) : 186 223 lperio = nperio ; aperio = False … … 190 227 lperio = 6 ; aperio = True 191 228 192 return lperio, aperio 229 return lperio, aperio 193 230 194 231 def __findAxis__ (tab, axis='z') : 195 232 ''' 196 Find number and name of the requested axis233 Find order and name of the requested axis 197 234 ''' 198 235 mmath = __mmath__ (tab) 199 236 ix = None ; ax = None 200 237 201 if axis in xList : 202 axList = [ 'x', 'X', 203 'lon', 'nav_lon', 'nav_lon_T', 'nav_lon_U', 'nav_lon_V', 'nav_lon_F', 'nav_lon_W', 204 'x_grid_T', 'x_grid_U', 'x_grid_V', 'x_grid_F', 'x_grid_W', 205 'glam', 'glamt', 'glamu', 'glamv', 'glamf', 'glamw' ] 206 unList = [ 'degrees_east' ] 207 if axis in yList : 208 axList = [ 'y', 'Y', 'lat', 209 'nav_lat', 'nav_lat_T', 'nav_lat_U', 'nav_lat_V', 'nav_lat_F', 'nav_lat_W', 210 'y_grid_T', 'y_grid_U', 'y_grid_V', 'y_grid_F', 'y_grid_W', 211 'gphi', 'gphi', 'gphiu', 'gphiv', 'gphif', 'gphiw'] 212 unList = [ 'degrees_north' ] 213 if axis in zList : 214 axList = [ 'z', 'Z', 215 'depth', 'deptht', 'depthu', 'depthv', 'depthf', 'depthw', 216 'olevel' ] 217 unList = [ 'm', 'meter' ] 218 if axis in tList : 219 axList = [ 't', 'T', 'time', 'time_counter' ] 220 unList = [ 'second', 'minute', 'hour', 'day', 'month' ] 238 if axis in xName : axName = xName ; unList = xUnit ; Length = xLength 239 if axis in yName : axName = yName ; unList = yUnit ; Length = yLength 240 if axis in zName : axName = zName ; unList = zUnit ; Length = zLength 241 if axis in tName : axName = tName ; unList = tUnit ; Length = None 221 242 222 243 if mmath == xr : 223 for Name in ax List:244 for Name in axName : 224 245 try : 225 246 ix = tab.dims.index (Name) … … 231 252 for name in unList : 232 253 if name in tab.coords[dim].attrs['units'] : 233 ix = i 234 ax = dim 254 ix = i ; ax = dim 235 255 else : 236 if axis in xList : ix=-1 237 if axis in yList : 238 if len(tab.shape) >= 2 : ix=-2 239 if axis in zList : 240 if len(tab.shape) >= 3 : ix=-3 241 if axis in tList : 242 if len(tab.shape) >=3 : ix=-3 243 if len(tab.shape) >=4 : ix=-4 256 #if axis in xName : ix=-1 257 #if axis in yName : 258 # if len(tab.shape) >= 2 : ix=-2 259 #if axis in zName : 260 # if len(tab.shape) >= 3 : ix=-3 261 #if axis in tName : 262 # if len(tab.shape) >=3 : ix=-3 263 # if len(tab.shape) >=4 : ix=-4 264 265 l_shape = tab.shape 266 for nn in np.arange ( len(l_shape)) : 267 if l_shape[nn] in Length : ix = nn 244 268 245 269 return ix, ax 246 270 247 #@numba.jit(forceobj=True) 271 def findAxis ( tab, axis= 'z' ) : 272 ix, xx = __findAxis__ (tab, axis) 273 return xx 274 248 275 def fixed_lon (lon, center_lon=0.0) : 249 276 ''' … … 277 304 return fixed_lon 278 305 279 #@numba.jit(forceobj=True) 306 def bounds_clolon ( bounds_lon, lon, rad=False, deg=True) : 307 '''Choose closest to lon0 longitude, adding or substacting 360° if needed''' 308 309 if rad : lon_range = 2.0*np.pi 310 if deg : lon_range = 360.0 311 bounds_clolon = bounds_lon.copy () 312 313 bounds_clolon = xr.where ( bounds_clolon < lon-lon_range/2., bounds_clolon+lon_range, bounds_clolon ) 314 bounds_clolon = xr.where ( bounds_clolon > lon+lon_range/2., bounds_clolon-lon_range, bounds_clolon ) 315 316 return bounds_clolon 317 318 def UnifyDims ( dd, udims=dim_names, verbose=False ) : 319 ''' 320 Rename dimensions to unify them between NEMO versions 321 ''' 322 323 if udims['x'] : 324 for xx in xName : 325 if xx in dd.dims and xx != udims['x'] : 326 if verbose : print ( f"{xx} renamed to {udims['x']}" ) 327 dd = dd.rename ( {xx:udims['x']}) 328 if udims['y'] : 329 for yy in yName : 330 if yy in dd.dims and yy != udims['y'] : 331 if verbose : print ( f"{yy} renamed to {udims['y']}" ) 332 dd = dd.rename ( {yy:udims['y']} ) 333 if udims['z'] : 334 for zz in zName : 335 if zz in dd.dims and zz != udims['z'] : 336 if verbose : print ( f"{zz} renamed to {udims['z']}" ) 337 dd = dd.rename ( {zz:udims['z']} ) 338 if udims['t'] : 339 for tt in tName : 340 if tt in dd.dims and tt != udims['t'] : 341 if verbose : print ( f"{tt} renamed to {udims['t']}" ) 342 dd = dd.rename ( {tt:udims['t']} ) 343 344 return dd 345 280 346 def fill_empty (ztab, sval=np.nan, transpose=False) : 281 347 ''' … … 283 349 284 350 Useful when NEMO has run with no wet points options : 285 some parts of the domain, with no ocean points, has no 286 lon/lat values 287 ''' 351 some parts of the domain, with no ocean points, have no 352 values 353 ''' 354 from sklearn.impute import SimpleImputer 288 355 mmath = __mmath__ (ztab) 289 356 … … 302 369 return ptab 303 370 304 #@numba.jit(forceobj=True)305 371 def fill_lonlat (lon, lat, sval=-1) : 306 372 ''' … … 308 374 309 375 Useful when NEMO has run with no wet points options : 310 some parts of the domain, with no ocean points, asno376 some parts of the domain, with no ocean points, have no 311 377 lon/lat values 312 378 ''' 379 from sklearn.impute import SimpleImputer 313 380 mmath = __mmath__ (lon) 314 381 … … 328 395 return plon, plat 329 396 330 #@numba.jit(forceobj=True) 397 def fill_bounds_lonlat (bounds_lon, bounds_lat, sval=-1) : 398 ''' 399 Fill longitude/latitude bounds values 400 401 Useful when NEMO has run with no wet points options : 402 some parts of the domain, with no ocean points, as no 403 lon/lat values 404 ''' 405 mmath = __mmath__ (bounds_lon) 406 407 p_bounds_lon = np.empty ( bounds_lon.shape ) 408 p_bounds_lat = np.empty ( bounds_lat.shape ) 409 410 imp = SimpleImputer (missing_values=sval, strategy='mean') 411 412 for n in np.arange (4) : 413 imp.fit (bounds_lon[:,:,n]) 414 p_bounds_lon[:,:,n] = imp.transform (bounds_lon[:,:,n]) 415 imp.fit (bounds_lat[:,:,n].T) 416 p_bounds_lat[:,:,n] = imp.transform (bounds_lat[:,:,n].T).T 417 418 if mmath == xr : 419 p_bounds_lon = xr.DataArray (bounds_lon, dims=bounds_lon.dims, coords=bounds_lon.coords) 420 p_bounds_lat = xr.DataArray (bounds_lat, dims=bounds_lat.dims, coords=bounds_lat.coords) 421 p_bounds_lon.attrs = bounds_lat.attrs ; p_bounds_lat.attrs = bounds_lat.attrs 422 423 return p_bounds_lon, p_bounds_lat 424 331 425 def jeq (lat) : 332 426 ''' … … 337 431 mmath = __mmath__ (lat) 338 432 ix, ax = __findAxis__ (lat, 'x') 339 iy, ay = __findAxis__ (lat, 'y')433 jy, ay = __findAxis__ (lat, 'y') 340 434 341 435 if mmath == xr : 342 jeq = int ( np.mean ( np.argmin (np.abs (np.float64 (lat)), axis= iy) ) )436 jeq = int ( np.mean ( np.argmin (np.abs (np.float64 (lat)), axis=jy) ) ) 343 437 else : 344 438 jeq = np.argmin (np.abs (np.float64 (lat[...,:, 0]))) 345 439 return jeq 346 440 347 #@numba.jit(forceobj=True)348 441 def lon1D (lon, lat=None) : 349 442 ''' … … 354 447 ''' 355 448 mmath = __mmath__ (lon) 356 if np.max (lat) != None : 449 jpj, jpi = lon.shape [-2:] 450 if np.max (lat) : 357 451 je = jeq (lat) 358 lon1D = lon.copy() [..., je, :] 452 #lon1D = lon.copy() [..., je, :] 453 lon0 = lon [..., je, 0].copy() 454 dlon = lon [..., je, 1].copy() - lon [..., je, 0].copy() 455 lon1D = np.linspace ( start=lon0, stop=lon0+360.+2*dlon, num=jpi ) 359 456 else : 360 jpj, jpi = lon.shape [-2:] 361 lon1D = lon.copy() [..., jpj//3, :] 362 363 start = np.argmax (np.abs (np.diff (lon1D, axis=-1)) > 180.0, axis=-1) 364 lon1D [..., start+1:] += 360 457 lon0 = lon [..., jpj//3, 0].copy() 458 dlon = lon [..., jpj//3, 1].copy() - lon [..., jpj//3, 0].copy() 459 lon1D = np.linspace ( start=lon0, stop=lon0+360.+2*dlon, num=jpi ) 460 461 #start = np.argmax (np.abs (np.diff (lon1D, axis=-1)) > 180.0, axis=-1) 462 #lon1D [..., start+1:] += 360 365 463 366 464 if mmath == xr : 465 lon1D = xr.DataArray( lon1D, dims=('lon',), coords=(lon1D,)) 367 466 lon1D.attrs = lon.attrs 368 lon1D = lon1D.assign_coords ( {'x':lon1D} ) 467 lon1D.attrs['units'] = 'degrees_east' 468 lon1D.attrs['standard_name'] = 'longitude' 469 lon1D.attrs['long_name :'] = 'Longitude' 369 470 370 471 return lon1D 371 472 372 #@numba.jit(forceobj=True)373 473 def latreg (lat, diff=0.1) : 374 474 ''' … … 381 481 if diff == None : 382 482 dy = np.float64 (np.mean (np.abs (lat - np.roll (lat,shift=1,axis=-2, roll_coords=False)))) 483 print ( f'{dy=}' ) 383 484 diff = dy/100. 384 485 385 486 je = jeq (lat) 386 487 jreg = np.where (lat[...,je:,:].max(axis=-1) - lat[...,je:,:].min(axis=-1)< diff)[-1][-1] + je … … 390 491 return jreg, latreg 391 492 392 #@numba.jit(forceobj=True)393 493 def lat1D (lat) : 394 494 ''' … … 403 503 je = jeq (lat) 404 504 lat_eq = np.float64 (lat[...,je,:].mean(axis=-1)) 405 505 406 506 jreg, lat_reg = latreg (lat) 407 507 lat_ave = np.mean (lat, axis=-1) 408 508 509 #print ( f'{dy=} {jpj=} {je=} {lat_eq=} {jreg=} ' ) 510 409 511 if (np.abs (lat_eq) < dy/100.) : # T, U or W grid 410 dys = (90.-lat_reg) / (jpj-jreg-1)*0.5 411 yrange = 90.-dys-lat_reg 512 if jpj-1 > jreg : dys = (90.-lat_reg) / (jpj-jreg-1)*0.5 513 else : dys = (90.-lat_reg) / 2.0 514 yrange = (90.-dys-lat_reg) 412 515 else : # V or F grid 413 yrange = 90. -lat_reg 414 415 lat1D = mmath.where (lat_ave<lat_reg, lat_ave, lat_reg + yrange * (np.arange(jpj)-jreg)/(jpj-jreg-1)) 416 516 yrange = 90.-lat_reg 517 518 if jpj-1 > jreg : 519 lat1D = mmath.where (lat_ave<lat_reg, lat_ave, lat_reg + yrange * (np.arange(jpj)-jreg)/(jpj-jreg-1) ) 520 else : 521 lat1D = lat_ave 522 lat1D[-1] = 90.0 523 417 524 if mmath == xr : 525 lat1D = xr.DataArray( lat1D.values, dims=('lat',), coords=(lat1D,)) 418 526 lat1D.attrs = lat.attrs 419 lat1D = lat1D.assign_coords ( {'y':lat1D} ) 420 527 lat1D.attrs ['units'] = 'degrees_north' 528 lat1D.attrs ['standard_name'] = 'latitude' 529 lat1D.attrs ['long_name :'] = 'Latitude' 530 421 531 return lat1D 422 532 423 #@numba.jit(forceobj=True)424 533 def latlon1D (lat, lon) : 425 534 ''' … … 430 539 return lat1D (lat), lon1D (lon, lat) 431 540 432 #@numba.jit(forceobj=True)433 541 def mask_lonlat (ptab, x0, x1, y0, y1, lon, lat, sval=np.nan) : 434 542 mmath = __mmath__ (ptab) … … 445 553 return tab 446 554 447 #@numba.jit(forceobj=True)448 555 def extend (tab, Lon=False, jplus=25, jpi=None, nperio=4) : 449 556 ''' 450 557 Returns extended field eastward to have better plots, and box average crossing the boundary 451 558 Works only for xarray and numpy data (?) 559 560 Useful for vertical sections in OCE and ATM. 452 561 453 562 tab : field to extend. … … 539 648 See NEMO documentation for further details 540 649 ''' 541 jpj, jpi = ptab.shape[-2:] 650 jpi = None ; jpj = None 651 ix, ax = __findAxis__ (ptab, 'x') 652 jy, ay = __findAxis__ (ptab, 'y') 653 if ax : jpi = ptab.shape[ix] 654 if ay : jpj = ptab.shape[jy] 655 542 656 if nperio == None : nperio = __guessNperio__ (jpj, jpi, nperio) 543 657 544 658 if nperio not in nperio_valid_range : 545 raise Exception ( 'nperio=', nperio, ' is not in the valid range', nperio_valid_range)659 raise Exception ( f'{nperio=} is not in the valid range {nperio_valid_range}' ) 546 660 547 661 return jpj, jpi, nperio 548 662 549 #@numba.jit(forceobj=True)550 663 def lbc (ptab, nperio=None, cd_type='T', psgn=1.0, nemo_4U_bug=False) : 551 664 ''' … … 559 672 ''' 560 673 jpj, jpi, nperio = lbc_init (ptab, nperio) 674 ix, ax = __findAxis__ (ptab, 'x') 675 jy, ay = __findAxis__ (ptab, 'y') 561 676 psgn = ptab.dtype.type (psgn) 562 677 mmath = __mmath__ (ptab) … … 565 680 else : ztab = ptab.copy () 566 681 567 # 568 #> East-West boundary conditions 569 # ------------------------------ 570 if nperio in [1, 4, 6] : 682 if ax : 683 # 684 #> East-West boundary conditions 685 # ------------------------------ 686 if nperio in [1, 4, 6] : 571 687 # ... cyclic 572 ztab [..., :, 0] = ztab [..., :, -2] 573 ztab [..., :, -1] = ztab [..., :, 1] 574 # 575 #> North-South boundary conditions 576 # -------------------------------- 577 if nperio in [3, 4] : # North fold T-point pivot 578 if cd_type in [ 'T', 'W' ] : # T-, W-point 579 ztab [..., -1, 1: ] = psgn * ztab [..., -3, -1:0:-1 ] 580 ztab [..., -1, 0 ] = psgn * ztab [..., -3, 2 ] 581 ztab [..., -2, jpi//2: ] = psgn * ztab [..., -2, jpi//2:0:-1 ] 688 ztab [..., 0] = ztab [..., -2] 689 ztab [..., -1] = ztab [..., 1] 690 691 if ay : 692 # 693 #> North-South boundary conditions 694 # -------------------------------- 695 if nperio in [3, 4] : # North fold T-point pivot 696 if cd_type in [ 'T', 'W' ] : # T-, W-point 697 ztab [..., -1, 1: ] = psgn * ztab [..., -3, -1:0:-1 ] 698 ztab [..., -1, 0 ] = psgn * ztab [..., -3, 2 ] 699 ztab [..., -2, jpi//2: ] = psgn * ztab [..., -2, jpi//2:0:-1 ] 700 701 if cd_type == 'U' : 702 ztab [..., -1, 0:-1 ] = psgn * ztab [..., -3, -1:0:-1 ] 703 ztab [..., -1, 0 ] = psgn * ztab [..., -3, 1 ] 704 ztab [..., -1, -1 ] = psgn * ztab [..., -3, -2 ] 705 706 if nemo_4U_bug : 707 ztab [..., -2, jpi//2+1:-1] = psgn * ztab [..., -2, jpi//2-2:0:-1] 708 ztab [..., -2, jpi//2-1 ] = psgn * ztab [..., -2, jpi//2 ] 709 else : 710 ztab [..., -2, jpi//2-1:-1] = psgn * ztab [..., -2, jpi//2:0:-1] 711 712 if cd_type == 'V' : 713 ztab [..., -2, 1: ] = psgn * ztab [..., -3, jpi-1:0:-1 ] 714 ztab [..., -1, 1: ] = psgn * ztab [..., -4, -1:0:-1 ] 715 ztab [..., -1, 0 ] = psgn * ztab [..., -4, 2 ] 716 717 if cd_type == 'F' : 718 ztab [..., -2, 0:-1 ] = psgn * ztab [..., -3, -1:0:-1 ] 719 ztab [..., -1, 0:-1 ] = psgn * ztab [..., -4, -1:0:-1 ] 720 ztab [..., -1, 0 ] = psgn * ztab [..., -4, 1 ] 721 ztab [..., -1, -1 ] = psgn * ztab [..., -4, -2 ] 582 722 583 if cd_type == 'U' : 584 ztab [..., -1, 0:-1 ] = psgn * ztab [..., -3, -1:0:-1 ] 585 ztab [..., -1, 0 ] = psgn * ztab [..., -3, 1 ] 586 ztab [..., -1, -1 ] = psgn * ztab [..., -3, -2 ] 723 if nperio in [4.2] : # North fold T-point pivot 724 if cd_type in [ 'T', 'W' ] : # T-, W-point 725 ztab [..., -1, jpi//2: ] = psgn * ztab [..., -1, jpi//2:0:-1 ] 726 727 if cd_type == 'U' : 728 ztab [..., -1, jpi//2-1:-1] = psgn * ztab [..., -1, jpi//2:0:-1] 729 730 if cd_type == 'V' : 731 ztab [..., -1, 1: ] = psgn * ztab [..., -2, jpi-1:0:-1 ] 732 733 if cd_type == 'F' : 734 ztab [..., -1, 0:-1 ] = psgn * ztab [..., -2, -1:0:-1 ] 587 735 588 if nemo_4U_bug : 589 ztab [..., -2, jpi//2+1:-1] = psgn * ztab [..., -2, jpi//2-2:0:-1] 590 ztab [..., -2, jpi//2-1 ] = psgn * ztab [..., -2, jpi//2 ] 591 else : 592 ztab [..., -2, jpi//2-1:-1] = psgn * ztab [..., -2, jpi//2:0:-1] 593 594 if cd_type == 'V' : 595 ztab [..., -2, 1: ] = psgn * ztab [..., -3, jpi-1:0:-1 ] 596 ztab [..., -1, 1: ] = psgn * ztab [..., -4, -1:0:-1 ] 597 ztab [..., -1, 0 ] = psgn * ztab [..., -4, 2 ] 598 599 if cd_type == 'F' : 600 ztab [..., -2, 0:-1 ] = psgn * ztab [..., -3, -1:0:-1 ] 601 ztab [..., -1, 0:-1 ] = psgn * ztab [..., -4, -1:0:-1 ] 602 ztab [..., -1, 0 ] = psgn * ztab [..., -4, 1 ] 603 ztab [..., -1, -1 ] = psgn * ztab [..., -4, -2 ] 604 605 if nperio in [4.2] : # North fold T-point pivot 606 if cd_type in [ 'T', 'W' ] : # T-, W-point 607 ztab [..., -1, jpi//2: ] = psgn * ztab [..., -1, jpi//2:0:-1 ] 608 609 if cd_type == 'U' : 610 ztab [..., -1, jpi//2-1:-1] = psgn * ztab [..., -1, jpi//2:0:-1] 611 612 if cd_type == 'V' : 613 ztab [..., -1, 1: ] = psgn * ztab [..., -2, jpi-1:0:-1 ] 614 615 if cd_type == 'F' : 616 ztab [..., -1, 0:-1 ] = psgn * ztab [..., -2, -1:0:-1 ] 617 618 if nperio in [5, 6] : # North fold F-point pivot 619 if cd_type in ['T', 'W'] : 620 ztab [..., -1, 0: ] = psgn * ztab [..., -2, -1::-1 ] 621 622 if cd_type == 'U' : 623 ztab [..., -1, 0:-1 ] = psgn * ztab [..., -2, -2::-1 ] 624 ztab [..., -1, -1 ] = psgn * ztab [..., -2, 0 ] # Bug ? 625 626 if cd_type == 'V' : 627 ztab [..., -1, 0: ] = psgn * ztab [..., -3, -1::-1 ] 628 ztab [..., -2, jpi//2: ] = psgn * ztab [..., -2, jpi//2-1::-1 ] 629 630 if cd_type == 'F' : 631 ztab [..., -1, 0:-1 ] = psgn * ztab [..., -3, -2::-1 ] 632 ztab [..., -1, -1 ] = psgn * ztab [..., -3, 0 ] 633 ztab [..., -2, jpi//2:-1] = psgn * ztab [..., -2, jpi//2-2::-1 ] 634 635 # 636 #> East-West boundary conditions 637 # ------------------------------ 638 if nperio in [1, 4, 6] : 639 # ... cyclic 640 ztab [..., :, 0] = ztab [..., :, -2] 641 ztab [..., :, -1] = ztab [..., :, 1] 736 if nperio in [5, 6] : # North fold F-point pivot 737 if cd_type in ['T', 'W'] : 738 ztab [..., -1, 0: ] = psgn * ztab [..., -2, -1::-1 ] 739 740 if cd_type == 'U' : 741 ztab [..., -1, 0:-1 ] = psgn * ztab [..., -2, -2::-1 ] 742 ztab [..., -1, -1 ] = psgn * ztab [..., -2, 0 ] # Bug ? 743 744 if cd_type == 'V' : 745 ztab [..., -1, 0: ] = psgn * ztab [..., -3, -1::-1 ] 746 ztab [..., -2, jpi//2: ] = psgn * ztab [..., -2, jpi//2-1::-1 ] 747 748 if cd_type == 'F' : 749 ztab [..., -1, 0:-1 ] = psgn * ztab [..., -3, -2::-1 ] 750 ztab [..., -1, -1 ] = psgn * ztab [..., -3, 0 ] 751 ztab [..., -2, jpi//2:-1] = psgn * ztab [..., -2, jpi//2-2::-1 ] 752 753 # 754 #> East-West boundary conditions 755 # ------------------------------ 756 if nperio in [1, 4, 6] : 757 # ... cyclic 758 ztab [..., 0] = ztab [..., -2] 759 ztab [..., -1] = ztab [..., 1] 642 760 643 761 if mmath == xr : 644 ztab = xr.DataArray ( ztab, dims=ptab.dims, coords=ptab.coords )762 ztab = xr.DataArray ( ztab, dims=ptab.dims, coords=ptab.coords ) 645 763 ztab.attrs = ptab.attrs 646 764 647 765 return ztab 648 766 649 #@numba.jit(forceobj=True)650 767 def lbc_mask (ptab, nperio=None, cd_type='T', sval=np.nan) : 651 768 # … … 659 776 ''' 660 777 jpj, jpi, nperio = lbc_init (ptab, nperio) 778 ix, ax = __findAxis__ (ptab, 'x') 779 jy, ay = __findAxis__ (ptab, 'y') 661 780 ztab = ptab.copy () 662 781 663 # 664 #> East-West boundary conditions 665 # ------------------------------ 666 if nperio in [1, 4, 6] : 782 if ax : 783 # 784 #> East-West boundary conditions 785 # ------------------------------ 786 if nperio in [1, 4, 6] : 667 787 # ... cyclic 668 ztab [..., :, 0] = sval 669 ztab [..., :, -1] = sval 670 671 # 672 #> South (in which nperio cases ?) 673 # -------------------------------- 674 if nperio in [1, 3, 4, 5, 6] : 675 ztab [..., 0, :] = sval 676 677 # 678 #> North-South boundary conditions 679 # -------------------------------- 680 if nperio in [3, 4] : # North fold T-point pivot 681 if cd_type in [ 'T', 'W' ] : # T-, W-point 682 ztab [..., -1, : ] = sval 683 ztab [..., -2, :jpi//2 ] = sval 788 ztab [..., 0] = sval 789 ztab [..., -1] = sval 790 791 if ay : 792 # 793 #> South (in which nperio cases ?) 794 # -------------------------------- 795 if nperio in [1, 3, 4, 5, 6] : 796 ztab [..., 0, :] = sval 797 798 # 799 #> North-South boundary conditions 800 # -------------------------------- 801 if nperio in [3, 4] : # North fold T-point pivot 802 if cd_type in [ 'T', 'W' ] : # T-, W-point 803 ztab [..., -1, : ] = sval 804 ztab [..., -2, :jpi//2 ] = sval 684 805 685 if cd_type == 'U' :686 ztab [..., -1, : ] = sval687 ztab [..., -2, jpi//2+1: ] = sval806 if cd_type == 'U' : 807 ztab [..., -1, : ] = sval 808 ztab [..., -2, jpi//2+1: ] = sval 688 809 689 if cd_type == 'V' :690 ztab [..., -2, : ] = sval691 ztab [..., -1, : ] = sval692 693 if cd_type == 'F' :694 ztab [..., -2, : ] = sval695 ztab [..., -1, : ] = sval696 697 if nperio in [4.2] : # North fold T-point pivot698 if cd_type in [ 'T', 'W' ] : # T-, W-point699 ztab [..., -1, jpi//2 : ] = sval700 701 if cd_type == 'U' :702 ztab [..., -1, jpi//2-1:-1] = sval703 704 if cd_type == 'V' :705 ztab [..., -1, 1: ] = sval706 707 if cd_type == 'F' :708 ztab [..., -1, 0:-1 ] = sval709 710 if nperio in [5, 6] : # North fold F-point pivot711 if cd_type in ['T', 'W'] :712 ztab [..., -1, 0: ] = sval713 714 if cd_type == 'U' :715 ztab [..., -1, 0:-1 ] = sval716 ztab [..., -1, -1 ] = sval717 718 if cd_type == 'V' :719 ztab [..., -1, 0: ] = sval720 ztab [..., -2, jpi//2: ] = sval721 722 if cd_type == 'F' :723 ztab [..., -1, 0:-1 ] = sval724 ztab [..., -1, -1 ] = sval725 ztab [..., -2, jpi//2+1:-1] = sval810 if cd_type == 'V' : 811 ztab [..., -2, : ] = sval 812 ztab [..., -1, : ] = sval 813 814 if cd_type == 'F' : 815 ztab [..., -2, : ] = sval 816 ztab [..., -1, : ] = sval 817 818 if nperio in [4.2] : # North fold T-point pivot 819 if cd_type in [ 'T', 'W' ] : # T-, W-point 820 ztab [..., -1, jpi//2 : ] = sval 821 822 if cd_type == 'U' : 823 ztab [..., -1, jpi//2-1:-1] = sval 824 825 if cd_type == 'V' : 826 ztab [..., -1, 1: ] = sval 827 828 if cd_type == 'F' : 829 ztab [..., -1, 0:-1 ] = sval 830 831 if nperio in [5, 6] : # North fold F-point pivot 832 if cd_type in ['T', 'W'] : 833 ztab [..., -1, 0: ] = sval 834 835 if cd_type == 'U' : 836 ztab [..., -1, 0:-1 ] = sval 837 ztab [..., -1, -1 ] = sval 838 839 if cd_type == 'V' : 840 ztab [..., -1, 0: ] = sval 841 ztab [..., -2, jpi//2: ] = sval 842 843 if cd_type == 'F' : 844 ztab [..., -1, 0:-1 ] = sval 845 ztab [..., -1, -1 ] = sval 846 ztab [..., -2, jpi//2+1:-1] = sval 726 847 727 848 return ztab 728 849 729 #@numba.jit(forceobj=True)730 850 def lbc_plot (ptab, nperio=None, cd_type='T', psgn=1.0, sval=np.nan) : 731 851 ''' … … 738 858 See NEMO documentation for further details 739 859 ''' 740 741 860 jpj, jpi, nperio = lbc_init (ptab, nperio) 861 ix, ax = __findAxis__ (ptab, 'x') 862 jy, ay = __findAxis__ (ptab, 'y') 742 863 psgn = ptab.dtype.type (psgn) 743 864 ztab = ptab.copy () 744 # 745 #> East-West boundary conditions 746 # ------------------------------ 747 if nperio in [1, 4, 6] : 748 # ... cyclic 749 ztab [..., :, 0] = ztab [..., :, -2] 750 ztab [..., :, -1] = ztab [..., :, 1] 751 752 #> Masks south 753 # ------------ 754 if nperio in [4, 6] : ztab [..., 0, : ] = sval 755 756 # 757 #> North-South boundary conditions 758 # -------------------------------- 759 if nperio in [3, 4] : # North fold T-point pivot 760 if cd_type in [ 'T', 'W' ] : # T-, W-point 761 ztab [..., -1, : ] = sval 762 #ztab [..., -2, jpi//2: ] = sval 763 ztab [..., -2, :jpi//2 ] = sval # Give better plots than above 764 if cd_type == 'U' : 765 ztab [..., -1, : ] = sval 766 767 if cd_type == 'V' : 768 ztab [..., -2, : ] = sval 769 ztab [..., -1, : ] = sval 770 771 if cd_type == 'F' : 772 ztab [..., -2, : ] = sval 773 ztab [..., -1, : ] = sval 774 775 if nperio in [4.2] : # North fold T-point pivot 776 if cd_type in [ 'T', 'W' ] : # T-, W-point 777 ztab [..., -1, jpi//2: ] = sval 778 779 if cd_type == 'U' : 780 ztab [..., -1, jpi//2-1:-1] = sval 781 782 if cd_type == 'V' : 783 ztab [..., -1, 1: ] = sval 784 785 if cd_type == 'F' : 786 ztab [..., -1, 0:-1 ] = sval 787 788 if nperio in [5, 6] : # North fold F-point pivot 789 if cd_type in ['T', 'W'] : 790 ztab [..., -1, : ] = sval 791 792 if cd_type == 'U' : 793 ztab [..., -1, : ] = sval 794 795 if cd_type == 'V' : 796 ztab [..., -1, : ] = sval 797 ztab [..., -2, jpi//2: ] = sval 798 799 if cd_type == 'F' : 800 ztab [..., -1, : ] = sval 801 ztab [..., -2, jpi//2+1:-1] = sval 865 866 if ax : 867 # 868 #> East-West boundary conditions 869 # ------------------------------ 870 if nperio in [1, 4, 6] : 871 # ... cyclic 872 ztab [..., :, 0] = ztab [..., :, -2] 873 ztab [..., :, -1] = ztab [..., :, 1] 874 875 if ay : 876 #> Masks south 877 # ------------ 878 if nperio in [4, 6] : ztab [..., 0, : ] = sval 879 880 # 881 #> North-South boundary conditions 882 # -------------------------------- 883 if nperio in [3, 4] : # North fold T-point pivot 884 if cd_type in [ 'T', 'W' ] : # T-, W-point 885 ztab [..., -1, : ] = sval 886 #ztab [..., -2, jpi//2: ] = sval 887 ztab [..., -2, :jpi//2 ] = sval # Give better plots than above 888 if cd_type == 'U' : 889 ztab [..., -1, : ] = sval 890 891 if cd_type == 'V' : 892 ztab [..., -2, : ] = sval 893 ztab [..., -1, : ] = sval 894 895 if cd_type == 'F' : 896 ztab [..., -2, : ] = sval 897 ztab [..., -1, : ] = sval 898 899 if nperio in [4.2] : # North fold T-point pivot 900 if cd_type in [ 'T', 'W' ] : # T-, W-point 901 ztab [..., -1, jpi//2: ] = sval 902 903 if cd_type == 'U' : 904 ztab [..., -1, jpi//2-1:-1] = sval 905 906 if cd_type == 'V' : 907 ztab [..., -1, 1: ] = sval 908 909 if cd_type == 'F' : 910 ztab [..., -1, 0:-1 ] = sval 911 912 if nperio in [5, 6] : # North fold F-point pivot 913 if cd_type in ['T', 'W'] : 914 ztab [..., -1, : ] = sval 915 916 if cd_type == 'U' : 917 ztab [..., -1, : ] = sval 918 919 if cd_type == 'V' : 920 ztab [..., -1, : ] = sval 921 ztab [..., -2, jpi//2: ] = sval 922 923 if cd_type == 'F' : 924 ztab [..., -1, : ] = sval 925 ztab [..., -2, jpi//2+1:-1] = sval 802 926 803 927 return ztab 804 928 805 #@numba.jit(forceobj=True)806 929 def lbc_add (ptab, nperio=None, cd_type=None, psgn=1, sval=None) : 807 930 ''' 808 Handle NEMO domain changes between NEMO 4.0 to NEMO 4.2931 Handles NEMO domain changes between NEMO 4.0 to NEMO 4.2 809 932 Peridodicity halo has been removed 810 933 This routine adds the halos if needed … … 818 941 mmath = __mmath__ (ptab) 819 942 jpj, jpi, nperio = lbc_init (ptab, nperio) 943 lshape = get_shape (ptab) 944 ix, ax = __findAxis__ (ptab, 'x') 945 jy, ay = __findAxis__ (ptab, 'y') 820 946 821 947 t_shape = np.array (ptab.shape) … … 823 949 if nperio == 4.2 or nperio == 6.2 : 824 950 825 ext_shape = t_shape 826 ext_shape[-1] = ext_shape[-1] + 2827 ext_shape[-2] = ext_shape[-2] + 1951 ext_shape = t_shape.copy() 952 if 'X' in lshape : ext_shape[ix] = ext_shape[ix] + 2 953 if 'Y' in lshape : ext_shape[jy] = ext_shape[jy] + 1 828 954 829 955 if mmath == xr : 830 ptab_ext = xr.DataArray (np.zeros (ext_shape), dims=ptab.dims) 831 ptab_ext.values[..., :-1, 1:-1] = ptab.values.copy () 956 ptab_ext = xr.DataArray (np.zeros (ext_shape), dims=ptab.dims) 957 if 'X' in lshape and 'Y' in lshape : 958 ptab_ext.values[..., :-1, 1:-1] = ptab.values.copy () 959 else : 960 if 'X' in lshape : ptab_ext.values[..., 1:-1] = ptab.values.copy () 961 if 'Y' in lshape : ptab_ext.values[..., :-1 ] = ptab.values.copy () 832 962 else : 833 963 ptab_ext = np.zeros (ext_shape) 834 ptab_ext[..., :-1, 1:-1] = ptab.copy () 835 836 #if sval != None : ptab_ext[..., 0, :] = sval 837 964 if 'X' in lshape and 'Y' in lshape : ptab_ext [..., :-1, 1:-1] = ptab.copy () 965 else : 966 if 'X' in lshape : ptab_ext [..., 1:-1] = ptab.copy () 967 if 'Y' in lshape : ptab_ext [..., :-1 ] = ptab.copy () 968 838 969 if nperio == 4.2 : ptab_ext = lbc (ptab_ext, nperio=4, cd_type=cd_type, psgn=psgn) 839 970 if nperio == 6.2 : ptab_ext = lbc (ptab_ext, nperio=6, cd_type=cd_type, psgn=psgn) 840 971 841 972 if mmath == xr : 842 973 ptab_ext.attrs = ptab.attrs 974 kz, az = __findAxis__ (ptab, 'z') 975 it, at = __findAxis__ (ptab, 't') 976 if az : ptab_ext = ptab_ext.assign_coords ( {az:ptab.coords[az]} ) 977 if at : ptab_ext = ptab_ext.assign_coords ( {at:ptab.coords[at]} ) 843 978 844 979 else : ptab_ext = lbc (ptab, nperio=nperio, cd_type=cd_type, psgn=psgn) … … 848 983 def lbc_del (ptab, nperio=None, cd_type='T', psgn=1) : 849 984 ''' 850 Handle NEMO domain changes between NEMO 4.0 to NEMO 4.2985 Handles NEMO domain changes between NEMO 4.0 to NEMO 4.2 851 986 Periodicity halo has been removed 852 987 This routine removes the halos if needed … … 858 993 See NEMO documentation for further details 859 994 ''' 860 861 995 jpj, jpi, nperio = lbc_init (ptab, nperio) 996 lshape = get_shape (ptab) 997 ix, ax = __findAxis__ (ptab, 'x') 998 jy, ay = __findAxis__ (ptab, 'y') 862 999 863 1000 if nperio == 4.2 or nperio == 6.2 : 864 return lbc (ptab[..., :-1, 1:-1], nperio=nperio, cd_type=cd_type, psgn=psgn) 1001 if ax or ay : 1002 if ax and ay : 1003 return lbc (ptab[..., :-1, 1:-1], nperio=nperio, cd_type=cd_type, psgn=psgn) 1004 else : 1005 if ax : 1006 return lbc (ptab[..., 1:-1], nperio=nperio, cd_type=cd_type, psgn=psgn) 1007 if ay : 1008 return lbc (ptab[..., -1], nperio=nperio, cd_type=cd_type, psgn=psgn) 1009 else : 1010 return ptab 865 1011 else : 866 1012 return ptab 867 1013 868 #@numba.jit(forceobj=True)869 1014 def lbc_index (jj, ii, jpj, jpi, nperio=None, cd_type='T') : 870 1015 ''' … … 951 1096 return jy, ix 952 1097 953 #def geo2en (pxx, pyy, pzz, glam, gphi) : 1098 def findJI (lat_data, lon_data, lat_grid, lon_grid, mask=1.0, verbose=False, out=None) : 1099 ''' 1100 Description: seeks J,I indices of the grid point which is the closest of a given point 1101 Usage: go FindJI <data latitude> <data longitude> <grid latitudes> <grid longitudes> [mask] 1102 <longitude fields> <latitude field> are 2D fields on J/I (Y/X) dimensions 1103 mask : if given, seek only non masked grid points (i.e with mask=1) 1104 1105 Example : findIJ (40, -20, nav_lat, nav_lon, mask=1.0) 1106 1107 Note : all longitudes and latitudes in degrees 1108 1109 Note : may work with 1D lon/lat (?) 1110 ''' 1111 # Get grid dimensions 1112 if len (lon_grid.shape) == 2 : (jpj, jpi) = lon_grid.shape 1113 else : jpj = len(lat_grid) ; jpi=len(lon_grid) 1114 1115 mmath = __mmath__ (lat_grid) 1116 1117 # Compute distance from the point to all grid points (in radian) 1118 arg = np.sin (rad*lat_data) * np.sin (rad*lat_grid) \ 1119 + np.cos (rad*lat_data) * np.cos (rad*lat_grid) * np.cos(rad*(lon_data-lon_grid)) 1120 distance = np.arccos (arg) + 4.0*rpi*(1.0-mask) # Send masked points to 'infinite' 1121 1122 # Truncates to alleviate some precision problem with some grids 1123 prec = int (1E7) 1124 distance = (distance*prec).astype(int) / prec 1125 1126 # Compute minimum of distance, and index of minimum 1127 # 1128 distance_min = distance.min () 1129 jimin = int (distance.argmin ()) 1130 1131 # Compute 2D indices 1132 jmin = jimin // jpi ; imin = jimin - jmin*jpi 1133 1134 # Result 1135 if verbose : 1136 # Compute distance achieved 1137 mindist = distance [jmin, imin] 1138 1139 # Compute azimuth 1140 dlon = lon_data-lon_grid[jmin,imin] 1141 arg = np.sin (rad*dlon) / (np.cos(rad*lat_data)*np.tan(rad*lat_grid[jmin,imin]) - np.sin(rad*lat_data)*np.cos(rad*dlon)) 1142 azimuth = dar*np.arctan (arg) 1143 print ( f'I={imin:d} J={jmin:d} - Data:{lat_data:5.1f}°N {lon_data:5.1f}°E - Grid:{lat_grid[jmin,imin]:4.1f}°N ' \ 1144 + f'{lon_grid[jmin,imin]:4.1f}°E - Dist: {ra*distance[jmin,imin]:6.1f}km {dar*distance[jmin,imin]:5.2f}° ' \ 1145 + f'- Azimuth: {rad*azimuth:3.2f}rad - {azimuth:5.1f}°' ) 1146 1147 if out=='dict' : return {'x':imin, 'y':jmin} 1148 elif out=='array' or out=='numpy' or out=='np': return np.array ( [jmin, imin] ) 1149 elif out=='xarray' or out=='xr' : return xr.DataArray ( [jmin, imin] ) 1150 elif out=='list' : return [jmin, imin] 1151 elif out=='tuple' : return jmin, imin 1152 else : return jmin, imin 1153 1154 def geo2en (pxx, pyy, pzz, glam, gphi) : 954 1155 ''' 955 1156 Change vector from geocentric to east/north … … 970 1171 return pte, ptn 971 1172 972 #def en2geo (pte, ptn, glam, gphi) :1173 def en2geo (pte, ptn, glam, gphi) : 973 1174 ''' 974 1175 Change vector from east/north to geocentric … … 990 1191 return pxx, pyy, pzz 991 1192 992 #def findJI (lat_data, lon_data, lat_grid, lon_grid, mask=1.0, verbose=False) : 993 ''' 994 Description: seeks J,I indices of the grid point which is the closest of a given point 995 Usage: go FindJI <data latitude> <data longitude> <grid latitudes> <grid longitudes> [mask] 996 <longitude fields> <latitude field> are 2D fields on J/I (Y/X) dimensions 997 mask : if given, seek only non masked grid points (i.e with mask=1) 998 999 Example : findIJ (40, -20, nav_lat, nav_lon, mask=1.0) 1000 1001 Note : all longitudes and latitudes in degrees 1002 1003 Note : may work with 1D lon/lat (?) 1004 ''' 1005 # Get grid dimensions 1006 if len (lon_grid.shape) == 2 : (jpj, jpi) = lon_grid.shape 1007 else : jpj = len(lat_grid) ; jpi=len(lon_grid) 1008 1009 mmath = __mmath__ (lat_grid) 1010 1011 # Compute distance from the point to all grid points (in radian) 1012 arg = np.sin (rad*lat_data) * np.sin (rad*lat_grid) \ 1013 + np.cos (rad*lat_data) * np.cos (rad*lat_grid) * np.cos(rad*(lon_data-lon_grid)) 1014 distance = np.arccos (arg) + 4.0*rpi*(1.0-mask) # Send masked points to 'infinite' 1015 1016 # Truncates to alleviate some precision problem with some grids 1017 prec = int (1E7) 1018 distance = (distance*prec).astype(int) / prec 1019 1020 # Compute minimum of distance, and index of minimum 1021 # 1022 distance_min = distance.min () 1023 jimin = int (distance.argmin ()) 1024 1025 # Compute 2D indices 1026 jmin = jimin // jpi ; imin = jimin - jmin*jpi 1027 1028 # Compute distance achieved 1029 mindist = distance[jmin, imin] 1030 1031 # Compute azimuth 1032 dlon = lon_data-lon_grid[jmin,imin] 1033 arg = np.sin (rad*dlon) / (np.cos(rad*lat_data)*np.tan(rad*lat_grid[jmin,imin]) - np.sin(rad*lat_data)*np.cos(rad*dlon)) 1034 azimuth = dar*np.arctan (arg) 1035 1036 # Result 1037 if verbose : 1038 print ('I={:d} J={:d} - Data:{:5.1f}°N {:5.1f}°E - Grid:{:4.1f}°N {:4.1f}°E - Dist: {:6.1f}km {:5.2f}° - Azimuth: {:3.2f}rad - {:5.1f}°' 1039 .format (imin, jmin, lat_data, lon_data, lat_grid[jmin,imin], lon_grid[jmin,imin], ra*distance[jmin,imin], dar*distance[jmin,imin], rad*azimuth, azimuth)) 1040 1041 return jmin, imin 1042 1043 #def clo_lon (lon, lon0) : 1193 1194 def clo_lon (lon, lon0=0., rad=False, deg=True) : 1044 1195 '''Choose closest to lon0 longitude, adding or substacting 360° if needed''' 1045 1196 mmath = __mmath__ (lon, np) 1046 1197 if rad : lon_range = 2.*np.pi 1198 if deg : lon_range = 360. 1047 1199 clo_lon = lon 1048 clo_lon = mmath.where (clo_lon > lon0 + 180., clo_lon-360., clo_lon)1049 clo_lon = mmath.where (clo_lon < lon0 - 180., clo_lon+360., clo_lon)1050 clo_lon = mmath.where (clo_lon > lon0 + 180., clo_lon-360., clo_lon)1051 clo_lon = mmath.where (clo_lon < lon0 - 180., clo_lon+360., clo_lon)1200 clo_lon = mmath.where (clo_lon > lon0 + lon_range*0.5, clo_lon-lon_range, clo_lon) 1201 clo_lon = mmath.where (clo_lon < lon0 - lon_range*0.5, clo_lon+lon_range, clo_lon) 1202 clo_lon = mmath.where (clo_lon > lon0 + lon_range*0.5, clo_lon-lon_range, clo_lon) 1203 clo_lon = mmath.where (clo_lon < lon0 - lon_range*0.5, clo_lon+lon_range, clo_lon) 1052 1204 if clo_lon.shape == () : clo_lon = clo_lon.item () 1205 if mmath == xr : 1206 try : 1207 for attr in lon.attrs : clo_lon.attrs[attr] = lon.attrs[attr] 1208 except : 1209 pass 1053 1210 return clo_lon 1054 1211 1055 #def angle_full (glamt, gphit, glamu, gphiu, glamv, gphiv, glamf, gphif, nperio=None) : 1212 1213 def index2depth (pk, gdept_0) : 1214 ''' 1215 From index (real, continuous), get depth 1216 ''' 1217 jpk = gdept_0.shape[0] 1218 kk = xr.DataArray(pk) 1219 k = np.maximum (0, np.minimum (jpk-1, kk )) 1220 k0 = np.floor (k).astype (int) 1221 k1 = np.maximum (0, np.minimum (jpk-1, k0+1)) 1222 zz = k - k0 1223 gz = (1.0-zz)*gdept_0[k0]+ zz*gdept_0[k1] 1224 return gz.values 1225 1226 def depth2index (pz, gdept_0) : 1227 ''' 1228 From depth, get index (real, continuous) 1229 ''' 1230 jpk = gdept_0.shape[0] 1231 if type (pz) == xr.core.dataarray.DataArray : 1232 zz = xr.DataArray (pz.values, dims=('zz',)) 1233 elif type (pz) == np.ndarray : 1234 zz = xr.DataArray (pz.ravel(), dims=('zz',)) 1235 else : 1236 zz = xr.DataArray (np.array([pz]).ravel(), dims=('zz',)) 1237 zz = np.minimum (gdept_0[-1], np.maximum (0, zz)) 1238 1239 idk1 = np.minimum ( (gdept_0-zz), 0.).argmax (axis=0).astype(int) 1240 idk1 = np.maximum (0, np.minimum (jpk-1, idk1 )) 1241 idk2 = np.maximum (0, np.minimum (jpk-1, idk1-1)) 1242 1243 ff = (zz - gdept_0[idk2])/(gdept_0[idk1]-gdept_0[idk2]) 1244 idk = ff*idk1 + (1.0-ff)*idk2 1245 idk = xr.where ( np.isnan(idk), idk1, idk) 1246 return idk.values 1247 1248 def index2depth_panels (pk, gdept_0, depth0, fact) : 1249 ''' 1250 From index (real, continuous), get depth, with bottom part compressed 1251 ''' 1252 jpk = gdept_0.shape[0] 1253 kk = xr.DataArray (pk) 1254 k = np.maximum (0, np.minimum (jpk-1, kk )) 1255 k0 = np.floor (k).astype (int) 1256 k1 = np.maximum (0, np.minimum (jpk-1, k0+1)) 1257 zz = k - k0 1258 gz = (1.0-zz)*gdept_0[k0]+ zz*gdept_0[k1] 1259 gz = xr.where ( gz<depth0, gz, depth0 + (gz-depth0)*fact) 1260 return gz.values 1261 1262 def depth2index_panels (pz, gdept_0, depth0, fact) : 1263 ''' 1264 From index (real, continuous), get depth, with bottom part compressed 1265 ''' 1266 jpk = gdept_0.shape[0] 1267 if type (pz) == xr.core.dataarray.DataArray : 1268 zz = xr.DataArray (pz.values , dims=('zz',)) 1269 elif type (pz) == np.ndarray : 1270 zz = xr.DataArray (pz.ravel(), dims=('zz',)) 1271 else : 1272 zz = xr.DataArray (np.array([pz]).ravel(), dims=('zz',)) 1273 zz = np.minimum (gdept_0[-1], np.maximum (0, zz)) 1274 gdept_comp = xr.where ( gdept_0>depth0, (gdept_0-depth0)*fact+depth0, gdept_0) 1275 zz_comp = xr.where ( zz >depth0, (zz -depth0)*fact+depth0, zz ) 1276 zz_comp = np.minimum (gdept_comp[-1], np.maximum (0, zz_comp)) 1277 1278 idk1 = np.minimum ( (gdept_0-zz_comp), 0.).argmax (axis=0).astype(int) 1279 idk1 = np.maximum (0, np.minimum (jpk-1, idk1 )) 1280 idk2 = np.maximum (0, np.minimum (jpk-1, idk1-1)) 1281 1282 ff = (zz_comp - gdept_0[idk2])/(gdept_0[idk1]-gdept_0[idk2]) 1283 idk = ff*idk1 + (1.0-ff)*idk2 1284 idk = xr.where ( np.isnan(idk), idk1, idk) 1285 return idk.values 1286 1287 def depth2comp (pz, depth0, fact ) : 1288 ''' 1289 Form depth, get compressed depth, with bottom part compressed 1290 ''' 1291 #print ('start depth2comp') 1292 if type (pz) == xr.core.dataarray.DataArray : 1293 zz = pz.values 1294 elif type(pz) == list : 1295 zz = np.array (pz) 1296 else : 1297 zz = pz 1298 gz = np.where ( zz>depth0, (zz-depth0)*fact+depth0, zz) 1299 #print ( f'depth2comp : {gz=}' ) 1300 if type (pz) in [int, float] : return gz.item() 1301 else : return gz 1302 #print ('end depth2comp') 1303 1304 def comp2depth (pz, depth0, fact ) : 1305 ''' 1306 Form compressed depth, get depth, with bottom part compressed 1307 ''' 1308 if type (pz) == xr.core.dataarray.DataArray : 1309 zz = pz.values 1310 elif type(pz) == list : 1311 zz = np.array (pz) 1312 else : 1313 zz = pz 1314 gz = np.where ( zz>depth0, (zz-depth0)/fact+depth0, zz) 1315 if type (pz) in [int, float] : return gz.item() 1316 else : return gz 1317 1318 def index2lon (pi, lon1D) : 1319 ''' 1320 From index (real, continuous), get longitude 1321 ''' 1322 jpi = lon1D.shape[0] 1323 ii = xr.DataArray (pi) 1324 i = np.maximum (0, np.minimum (jpi-1, ii )) 1325 i0 = np.floor (i).astype (int) 1326 i1 = np.maximum (0, np.minimum (jpi-1, i0+1)) 1327 xx = i - i0 1328 gx = (1.0-xx)*lon1D[i0]+ xx*lon1D[i1] 1329 return gx.values 1330 1331 def lon2index (px, lon1D) : 1332 ''' 1333 From longitude, get index (real, continuous) 1334 ''' 1335 jpi = lon1D.shape[0] 1336 if type (px) == xr.core.dataarray.DataArray : 1337 xx = xr.DataArray (px.values , dims=('xx',)) 1338 elif type (px) == np.ndarray : 1339 xx = xr.DataArray (px.ravel(), dims=('xx',)) 1340 else : 1341 xx = xr.DataArray (np.array([px]).ravel(), dims=('xx',)) 1342 xx = xr.where ( xx>lon1D.max(), xx-360.0, xx) 1343 xx = xr.where ( xx<lon1D.min(), xx+360.0, xx) 1344 xx = np.minimum (lon1D.max(), np.maximum(xx, lon1D.min() )) 1345 idi1 = np.minimum ( (lon1D-xx), 0.).argmax (axis=0).astype(int) 1346 idi1 = np.maximum (0, np.minimum (jpi-1, idi1 )) 1347 idi2 = np.maximum (0, np.minimum (jpi-1, idi1-1)) 1348 1349 ff = (xx - lon1D[idi2])/(lon1D[idi1]-lon1D[idi2]) 1350 idi = ff*idi1 + (1.0-ff)*idi2 1351 idi = xr.where ( np.isnan(idi), idi1, idi) 1352 return idi.values 1353 1354 def index2lat (pj, lat1D) : 1355 ''' 1356 From index (real, continuous), get latitude 1357 ''' 1358 jpj = lat1D.shape[0] 1359 jj = xr.DataArray (pj) 1360 j = np.maximum (0, np.minimum (jpj-1, jj )) 1361 j0 = np.floor (j).astype (int) 1362 j1 = np.maximum (0, np.minimum (jpj-1, j0+1)) 1363 yy = j - j0 1364 gy = (1.0-yy)*lat1D[j0]+ yy*lat1D[j1] 1365 return gy.values 1366 1367 def lat2index (py, lat1D) : 1368 ''' 1369 From latitude, get index (real, continuous) 1370 ''' 1371 jpj = lat1D.shape[0] 1372 if type (py) == xr.core.dataarray.DataArray : 1373 yy = xr.DataArray (py.values , dims=('yy',)) 1374 elif type (py) == np.ndarray : 1375 yy = xr.DataArray (py.ravel(), dims=('yy',)) 1376 else : 1377 yy = xr.DataArray (np.array([py]).ravel(), dims=('yy',)) 1378 yy = np.minimum (lat1D.max(), np.minimum(yy, lat1D.max() )) 1379 idj1 = np.minimum ( (lat1D-yy), 0.).argmax (axis=0).astype(int) 1380 idj1 = np.maximum (0, np.minimum (jpj-1, idj1 )) 1381 idj2 = np.maximum (0, np.minimum (jpj-1, idj1-1)) 1382 1383 ff = (yy - lat1D[idj2])/(lat1D[idj1]-lat1D[idj2]) 1384 idj = ff*idj1 + (1.0-ff)*idj2 1385 idj = xr.where ( np.isnan(idj), idj1, idj) 1386 return idj.values 1387 1388 def angle_full (glamt, gphit, glamu, gphiu, glamv, gphiv, glamf, gphif, nperio=None) : 1056 1389 '''Compute sinus and cosinus of model line direction with respect to east''' 1057 1390 mmath = __mmath__ (glamt) … … 1234 1567 v_n = + u_i * gsin + v_j * gcos 1235 1568 1236 u_e = lbc (u_e, nperio=nperio, cd_type=cd_type, psgn= 1237 v_n = lbc (v_n, nperio=nperio, cd_type=cd_type, psgn= 1569 u_e = lbc (u_e, nperio=nperio, cd_type=cd_type, psgn=1.0) 1570 v_n = lbc (v_n, nperio=nperio, cd_type=cd_type, psgn=1.0) 1238 1571 1239 1572 return u_e, v_n 1240 1573 1241 def rot_uv2en ( uo, vo, gsint, gcost, nperio, zdim= 'deptht') :1574 def rot_uv2en ( uo, vo, gsint, gcost, nperio, zdim=None ) : 1242 1575 ''' 1243 1576 ** Purpose : Rotate the Repere: Change vector componantes from … … 1247 1580 ''' 1248 1581 mmath = __mmath__ (uo) 1249 1582 1250 1583 ut = U2T (uo, nperio=nperio, psgn=-1.0, zdim=zdim) 1251 1584 vt = V2T (vo, nperio=nperio, psgn=-1.0, zdim=zdim) … … 1259 1592 return u_e, v_n 1260 1593 1261 def rot_uv2enF ( uo, vo, gsinf, gcosf, nperio, zdim= 'deptht') :1594 def rot_uv2enF ( uo, vo, gsinf, gcosf, nperio, zdim=None ) : 1262 1595 ''' 1263 1596 ** Purpose : Rotate the Repere: Change vector componantes from … … 1279 1612 return u_e, v_n 1280 1613 1281 #@numba.jit(forceobj=True) 1282 def U2T (utab, nperio=None, psgn=-1.0, zdim='deptht', action='ave') : 1614 def U2T (utab, nperio=None, psgn=-1.0, zdim=None, action='ave') : 1283 1615 '''Interpolate an array from U grid to T grid i-mean)''' 1284 1616 mmath = __mmath__ (utab) … … 1287 1619 utab_0 = lbc_add (utab_0, nperio=nperio, cd_type='U', psgn=psgn) 1288 1620 ix, ax = __findAxis__ (utab_0, 'x') 1289 iz, az = __findAxis__ (utab_0, 'z') 1290 if action == 'ave' : ttab = 0.5 * (utab_0 + np.roll (utab_0, axis=ix, shift=1)) 1291 if action == 'min' : ttab = np.minimum (utab_0 , np.roll (utab_0, axis=ix, shift=1)) 1292 if action == 'max' : ttab = np.maximum (utab_0 , np.roll (utab_0, axis=ix, shift=1)) 1293 if action == 'mult' : ttab = utab_0 * np.roll (utab_0, axis=ix, shift=1) 1294 ttab = lbc_del (ttab, nperio=nperio, cd_type='T', psgn=psgn) 1295 1621 kz, az = __findAxis__ (utab_0, 'z') 1622 1623 if ax : 1624 if action == 'ave' : ttab = 0.5 * (utab_0 + np.roll (utab_0, axis=ix, shift=1)) 1625 if action == 'min' : ttab = np.minimum (utab_0 , np.roll (utab_0, axis=ix, shift=1)) 1626 if action == 'max' : ttab = np.maximum (utab_0 , np.roll (utab_0, axis=ix, shift=1)) 1627 if action == 'mult': ttab = utab_0 * np.roll (utab_0, axis=ix, shift=1) 1628 ttab = lbc_del (ttab , nperio=nperio, cd_type='T', psgn=psgn) 1629 else : 1630 ttab = lbc_del (utab_0, nperio=nperio, cd_type='T', psgn=psgn) 1631 1296 1632 if mmath == xr : 1297 if ax != None:1633 if ax : 1298 1634 ttab = ttab.assign_coords({ax:np.arange (ttab.shape[ix])+1.}) 1299 if zdim != None and iz != None and az != 'olevel' :1300 ttab = ttab.rename( {az:zdim})1635 if zdim and az : 1636 if az != zdim : ttab = ttab.rename( {az:zdim}) 1301 1637 return ttab 1302 1638 1303 #@numba.jit(forceobj=True) 1304 def V2T (vtab, nperio=None, psgn=-1.0, zdim='deptht', action='ave') : 1639 def V2T (vtab, nperio=None, psgn=-1.0, zdim=None, action='ave') : 1305 1640 '''Interpolate an array from V grid to T grid (j-mean)''' 1306 1641 mmath = __mmath__ (vtab) … … 1308 1643 vtab_0 = mmath.where ( np.isnan(vtab), 0., vtab) 1309 1644 vtab_0 = lbc_add (vtab_0, nperio=nperio, cd_type='V', psgn=psgn) 1310 iy, ay = __findAxis__ (vtab_0, 'y') 1311 iz, az = __findAxis__ (vtab_0, 'z') 1312 if action == 'ave' : ttab = 0.5 * (vtab_0 + np.roll (vtab_0, axis=iy, shift=1)) 1313 if action == 'min' : ttab = np.minimum (vtab_0 , np.roll (vtab_0, axis=iy, shift=1)) 1314 if action == 'max' : ttab = np.maximum (vtab_0 , np.roll (vtab_0, axis=iy, shift=1)) 1315 if action == 'mult' : ttab = vtab_0 * np.roll (vtab_0, axis=iy, shift=1) 1316 ttab = lbc_del (ttab, nperio=nperio, cd_type='T', psgn=psgn) 1645 jy, ay = __findAxis__ (vtab_0, 'y') 1646 kz, az = __findAxis__ (vtab_0, 'z') 1647 if ay : 1648 if action == 'ave' : ttab = 0.5 * (vtab_0 + np.roll (vtab_0, axis=jy, shift=1)) 1649 if action == 'min' : ttab = np.minimum (vtab_0 , np.roll (vtab_0, axis=jy, shift=1)) 1650 if action == 'max' : ttab = np.maximum (vtab_0 , np.roll (vtab_0, axis=jy, shift=1)) 1651 if action == 'mult' : ttab = vtab_0 * np.roll (vtab_0, axis=jy, shift=1) 1652 ttab = lbc_del (ttab , nperio=nperio, cd_type='T', psgn=psgn) 1653 else : 1654 ttab = lbc_del (vtab_0, nperio=nperio, cd_type='T', psgn=psgn) 1655 1317 1656 if mmath == xr : 1318 if ay !=None :1319 ttab = ttab.assign_coords({ay:np.arange(ttab.shape[ iy])+1.})1320 if zdim != None and iz != None and az != 'olevel':1321 ttab = ttab.rename( {az:zdim})1657 if ay : 1658 ttab = ttab.assign_coords({ay:np.arange(ttab.shape[jy])+1.}) 1659 if zdim and az : 1660 if az != zdim : ttab = ttab.rename( {az:zdim}) 1322 1661 return ttab 1323 1662 1324 #@numba.jit(forceobj=True) 1325 def F2T (ftab, nperio=None, psgn=1.0, zdim='depthf', action='ave') : 1663 def F2T (ftab, nperio=None, psgn=1.0, zdim=None, action='ave') : 1326 1664 '''Interpolate an array from F grid to T grid (i- and j- means)''' 1327 1665 mmath = __mmath__ (ftab) 1328 1666 ftab_0 = mmath.where ( np.isnan(ftab), 0., ftab) 1329 1667 ftab_0 = lbc_add (ftab_0 , nperio=nperio, cd_type='F', psgn=psgn) 1330 ttab = V2T (F2V(ftab_0, nperio=nperio, psgn=psgn, zdim=zdim, action=action), nperio=nperio, psgn=psgn, zdim=zdim, action=action)1668 ttab = V2T (F2V (ftab_0, nperio=nperio, psgn=psgn, zdim=zdim, action=action), nperio=nperio, psgn=psgn, zdim=zdim, action=action) 1331 1669 return lbc_del (ttab, nperio=nperio, cd_type='T', psgn=psgn) 1332 1670 1333 #@numba.jit(forceobj=True) 1334 def T2U (ttab, nperio=None, psgn=1.0, zdim='depthu', action='ave') : 1671 def T2U (ttab, nperio=None, psgn=1.0, zdim=None, action='ave') : 1335 1672 '''Interpolate an array from T grid to U grid (i-mean)''' 1336 1673 mmath = __mmath__ (ttab) … … 1338 1675 ttab_0 = lbc_add (ttab_0 , nperio=nperio, cd_type='T', psgn=psgn) 1339 1676 ix, ax = __findAxis__ (ttab_0, 'x') 1340 iz, az = __findAxis__ (ttab_0, 'z') 1341 if action == 'ave' : utab = 0.5 * (ttab_0 + np.roll (ttab_0, axis=ix, shift=-1)) 1342 if action == 'min' : utab = np.minimum (ttab_0 , np.roll (ttab_0, axis=ix, shift=-1)) 1343 if action == 'max' : utab = np.maximum (ttab_0 , np.roll (ttab_0, axis=ix, shift=-1)) 1344 if action == 'mult' : utab = ttab_0 * np.roll (ttab_0, axis=ix, shift=-1) 1345 utab = lbc_del (utab, nperio=nperio, cd_type='U', psgn=psgn) 1346 1677 kz, az = __findAxis__ (ttab_0, 'z') 1678 if ix : 1679 if action == 'ave' : utab = 0.5 * (ttab_0 + np.roll (ttab_0, axis=ix, shift=-1)) 1680 if action == 'min' : utab = np.minimum (ttab_0 , np.roll (ttab_0, axis=ix, shift=-1)) 1681 if action == 'max' : utab = np.maximum (ttab_0 , np.roll (ttab_0, axis=ix, shift=-1)) 1682 if action == 'mult' : utab = ttab_0 * np.roll (ttab_0, axis=ix, shift=-1) 1683 utab = lbc_del (utab , nperio=nperio, cd_type='U', psgn=psgn) 1684 else : 1685 utab = lbc_del (ttab_0, nperio=nperio, cd_type='U', psgn=psgn) 1686 1347 1687 if mmath == xr : 1348 if ax != None:1688 if ax : 1349 1689 utab = ttab.assign_coords({ax:np.arange(utab.shape[ix])+1.}) 1350 if zdim != None and iz != None and az != 'olevel':1351 utab = utab.rename( {az:zdim})1690 if zdim and az : 1691 if az != zdim : utab = utab.rename( {az:zdim}) 1352 1692 return utab 1353 1693 1354 #@numba.jit(forceobj=True) 1355 def T2V (ttab, nperio=None, psgn=1.0, zdim='depthv', action='ave') : 1694 def T2V (ttab, nperio=None, psgn=1.0, zdim=None, action='ave') : 1356 1695 '''Interpolate an array from T grid to V grid (j-mean)''' 1357 1696 mmath = __mmath__ (ttab) 1358 1697 ttab_0 = mmath.where ( np.isnan(ttab), 0., ttab) 1359 1698 ttab_0 = lbc_add (ttab_0 , nperio=nperio, cd_type='T', psgn=psgn) 1360 iy, ay = __findAxis__ (ttab_0, 'y') 1361 iz, az = __findAxis__ (ttab_0, 'z') 1362 if action == 'ave' : vtab = 0.5 * (ttab_0 + np.roll (ttab_0, axis=iy, shift=-1)) 1363 if action == 'min' : vtab = np.minimum (ttab_0 , np.roll (ttab_0, axis=iy, shift=-1)) 1364 if action == 'max' : vtab = np.maximum (ttab_0 , np.roll (ttab_0, axis=iy, shift=-1)) 1365 if action == 'mult' : vtab = ttab_0 * np.roll (ttab_0, axis=iy, shift=-1) 1366 1367 vtab = lbc_del (vtab, nperio=nperio, cd_type='V', psgn=psgn) 1699 jy, ay = __findAxis__ (ttab_0, 'y') 1700 kz, az = __findAxis__ (ttab_0, 'z') 1701 if jy : 1702 if action == 'ave' : vtab = 0.5 * (ttab_0 + np.roll (ttab_0, axis=jy, shift=-1)) 1703 if action == 'min' : vtab = np.minimum (ttab_0 , np.roll (ttab_0, axis=jy, shift=-1)) 1704 if action == 'max' : vtab = np.maximum (ttab_0 , np.roll (ttab_0, axis=jy, shift=-1)) 1705 if action == 'mult' : vtab = ttab_0 * np.roll (ttab_0, axis=jy, shift=-1) 1706 vtab = lbc_del (vtab , nperio=nperio, cd_type='V', psgn=psgn) 1707 else : 1708 vtab = lbc_del (ttab_0, nperio=nperio, cd_type='V', psgn=psgn) 1709 1368 1710 if mmath == xr : 1369 if ay != None:1370 vtab = vtab.assign_coords({ay:np.arange(vtab.shape[ iy])+1.})1371 if zdim != None and iz != None and az != 'olevel':1372 vtab = vtab.rename( {az:zdim})1711 if ay : 1712 vtab = vtab.assign_coords({ay:np.arange(vtab.shape[jy])+1.}) 1713 if zdim and az : 1714 if az != zdim : vtab = vtab.rename( {az:zdim}) 1373 1715 return vtab 1374 1716 1375 #@numba.jit(forceobj=True) 1376 def V2F (vtab, nperio=None, psgn=-1.0, zdim='depthf', action='ave') : 1717 def V2F (vtab, nperio=None, psgn=-1.0, zdim=None, action='ave') : 1377 1718 '''Interpolate an array from V grid to F grid (i-mean)''' 1378 1719 mmath = __mmath__ (vtab) … … 1380 1721 vtab_0 = lbc_add (vtab_0 , nperio=nperio, cd_type='V', psgn=psgn) 1381 1722 ix, ax = __findAxis__ (vtab_0, 'x') 1382 iz, az = __findAxis__ (vtab_0, 'z') 1383 if action == 'ave' : 0.5 * (vtab_0 + np.roll (vtab_0, axis=ix, shift=-1)) 1384 if action == 'min' : np.minimum (vtab_0 , np.roll (vtab_0, axis=ix, shift=-1)) 1385 if action == 'max' : np.maximum (vtab_0 , np.roll (vtab_0, axis=ix, shift=-1)) 1386 if action == 'mult' : vtab_0 * np.roll (vtab_0, axis=ix, shift=-1) 1387 ftab = lbc_del (ftab, nperio=nperio, cd_type='F', psgn=psgn) 1388 1723 kz, az = __findAxis__ (vtab_0, 'z') 1724 if ix : 1725 if action == 'ave' : 0.5 * (vtab_0 + np.roll (vtab_0, axis=ix, shift=-1)) 1726 if action == 'min' : np.minimum (vtab_0 , np.roll (vtab_0, axis=ix, shift=-1)) 1727 if action == 'max' : np.maximum (vtab_0 , np.roll (vtab_0, axis=ix, shift=-1)) 1728 if action == 'mult' : vtab_0 * np.roll (vtab_0, axis=ix, shift=-1) 1729 ftab = lbc_del (ftab , nperio=nperio, cd_type='F', psgn=psgn) 1730 else : 1731 ftab = lbc_del (vtab_0, nperio=nperio, cd_type='F', psgn=psgn) 1732 1389 1733 if mmath == xr : 1390 if ax != None:1734 if ax : 1391 1735 ftab = ftab.assign_coords({ax:np.arange(ftab.shape[ix])+1.}) 1392 if zdim != None and iz != None and az != 'olevel':1393 ftab = ftab.rename( {az:zdim})1736 if zdim and az : 1737 if az != zdim : ftab = ftab.rename( {az:zdim}) 1394 1738 return lbc_del (ftab, nperio=nperio, cd_type='F', psgn=psgn) 1395 1739 1396 #@numba.jit(forceobj=True) 1397 def U2F (utab, nperio=None, psgn=-1.0, zdim='depthf', action='ave') : 1740 def U2F (utab, nperio=None, psgn=-1.0, zdim=None, action='ave') : 1398 1741 '''Interpolate an array from U grid to F grid i-mean)''' 1399 1742 mmath = __mmath__ (utab) 1400 1743 utab_0 = mmath.where ( np.isnan(utab), 0., utab) 1401 1744 utab_0 = lbc_add (utab_0 , nperio=nperio, cd_type='U', psgn=psgn) 1402 iy, ay = __findAxis__ (utab_0, 'y') 1403 iz, az = __findAxis__ (utab_0, 'z') 1404 if action == 'ave' : ftab = 0.5 * (utab_0 + np.roll (utab_0, axis=iy, shift=-1)) 1405 if action == 'min' : ftab = np.minimum (utab_0 , np.roll (utab_0, axis=iy, shift=-1)) 1406 if action == 'max' : ftab = np.maximum (utab_0 , np.roll (utab_0, axis=iy, shift=-1)) 1407 if action == 'mult' : ftab = utab_0 * np.roll (utab_0, axis=iy, shift=-1) 1408 ftab = lbc_del (ftab, nperio=nperio, cd_type='F', psgn=psgn) 1409 1745 jy, ay = __findAxis__ (utab_0, 'y') 1746 kz, az = __findAxis__ (utab_0, 'z') 1747 if jy : 1748 if action == 'ave' : ftab = 0.5 * (utab_0 + np.roll (utab_0, axis=jy, shift=-1)) 1749 if action == 'min' : ftab = np.minimum (utab_0 , np.roll (utab_0, axis=jy, shift=-1)) 1750 if action == 'max' : ftab = np.maximum (utab_0 , np.roll (utab_0, axis=jy, shift=-1)) 1751 if action == 'mult' : ftab = utab_0 * np.roll (utab_0, axis=jy, shift=-1) 1752 ftab = lbc_del (ftab , nperio=nperio, cd_type='F', psgn=psgn) 1753 else : 1754 ftab = lbc_del (utab_0, nperio=nperio, cd_type='F', psgn=psgn) 1755 1410 1756 if mmath == xr : 1411 if ay != None:1412 ftab = ftab.assign_coords({'y':np.arange(ftab.shape[ iy])+1.})1413 if zdim != None and iz != None and az != 'olevel':1414 ftab = ftab.rename( {az:zdim})1757 if ay : 1758 ftab = ftab.assign_coords({'y':np.arange(ftab.shape[jy])+1.}) 1759 if zdim and az : 1760 if az != zdim : ftab = ftab.rename( {az:zdim}) 1415 1761 return ftab 1416 1762 1417 #@numba.jit(forceobj=True) 1418 def F2T (ftab, nperio=None, psgn=1.0, zdim='deptht', action='ave') : 1763 def F2T (ftab, nperio=None, psgn=1.0, zdim=None, action='ave') : 1419 1764 '''Interpolate an array on F grid to T grid (i- and j- means)''' 1420 1765 mmath = __mmath__ (ftab) … … 1424 1769 return lbc_del (ttab, nperio=nperio, cd_type='T', psgn=psgn) 1425 1770 1426 #@numba.jit(forceobj=True) 1427 def T2F (ttab, nperio=None, psgn=1.0, zdim='deptht', action='mean') : 1771 def T2F (ttab, nperio=None, psgn=1.0, zdim=None, action='mean') : 1428 1772 '''Interpolate an array on T grid to F grid (i- and j- means)''' 1429 1773 mmath = __mmath__ (ttab) 1430 1774 ttab_0 = mmath.where ( np.isnan(ttab), 0., ttab) 1431 1775 ttab_0 = lbc_add (ttab_0 , nperio=nperio, cd_type='T', psgn=psgn) 1432 ftab = T2U (U2F(ttab, nperio=nperio, psgn=psgn, zdim=zdim, action=action), nperio=nperio, psgn=psgn, zdim=zdim, action=action)1776 ftab = T2U (U2F (ttab, nperio=nperio, psgn=psgn, zdim=zdim, action=action), nperio=nperio, psgn=psgn, zdim=zdim, action=action) 1433 1777 1434 1778 return lbc_del (ftab, nperio=nperio, cd_type='F', psgn=psgn) 1435 1779 1436 #@numba.jit(forceobj=True) 1437 def F2U (ftab, nperio=None, psgn=1.0, zdim='depthu', action='ave') : 1780 def F2U (ftab, nperio=None, psgn=1.0, zdim=None, action='ave') : 1438 1781 '''Interpolate an array on F grid to FUgrid (i-mean)''' 1439 1782 mmath = __mmath__ (ftab) 1440 1783 ftab_0 = mmath.where ( np.isnan(ftab), 0., ftab) 1441 1784 ftab_0 = lbc_add (ftab_0 , nperio=nperio, cd_type='F', psgn=psgn) 1442 iy, ay = __findAxis__ (ftab_0, 'y') 1443 iz, az = __findAxis__ (ftab_0, 'z') 1444 if action == 'ave' : utab = 0.5 * (ftab_0 + np.roll (ftab_0, axis=iy, shift=-1)) 1445 if action == 'min' : utab = np.minimum (ftab_0 , np.roll (ftab_0, axis=iy, shift=-1)) 1446 if action == 'max' : utab = np.maximum (ftab_0 , np.roll (ftab_0, axis=iy, shift=-1)) 1447 if action == 'mult' : utab = ftab_0 * np.roll (ftab_0, axis=iy, shift=-1) 1448 1449 utab = lbc_del (utab, nperio=nperio, cd_type='U', psgn=psgn) 1450 1785 jy, ay = __findAxis__ (ftab_0, 'y') 1786 kz, az = __findAxis__ (ftab_0, 'z') 1787 if jy : 1788 if action == 'ave' : utab = 0.5 * (ftab_0 + np.roll (ftab_0, axis=jy, shift=-1)) 1789 if action == 'min' : utab = np.minimum (ftab_0 , np.roll (ftab_0, axis=jy, shift=-1)) 1790 if action == 'max' : utab = np.maximum (ftab_0 , np.roll (ftab_0, axis=jy, shift=-1)) 1791 if action == 'mult' : utab = ftab_0 * np.roll (ftab_0, axis=jy, shift=-1) 1792 utab = lbc_del (utab , nperio=nperio, cd_type='U', psgn=psgn) 1793 else : 1794 utab = lbc_del (ftab_0, nperio=nperio, cd_type='U', psgn=psgn) 1795 1451 1796 if mmath == xr : 1452 utab = utab.assign_coords({ay:np.arange(ftab.shape[ iy])+1.})1453 if zdim != None and iz != None and az != 'olevel':1454 utab = utab.rename( {az:zdim})1797 utab = utab.assign_coords({ay:np.arange(ftab.shape[jy])+1.}) 1798 if zdim and zz : 1799 if az != zdim : utab = utab.rename( {az:zdim}) 1455 1800 return utab 1456 1801 1457 #@numba.jit(forceobj=True) 1458 def F2V (ftab, nperio=None, psgn=1.0, zdim='depthv', action='ave') : 1802 def F2V (ftab, nperio=None, psgn=1.0, zdim=None, action='ave') : 1459 1803 '''Interpolate an array from F grid to V grid (i-mean)''' 1460 1804 mmath = __mmath__ (ftab) … … 1462 1806 ftab_0 = lbc_add (ftab_0 , nperio=nperio, cd_type='F', psgn=psgn) 1463 1807 ix, ax = __findAxis__ (ftab_0, 'x') 1464 iz, az = __findAxis__ (ftab_0, 'z') 1465 if action == 'ave' : vtab = 0.5 * (ftab_0 + np.roll (ftab_0, axis=ix, shift=-1)) 1466 if action == 'min' : vtab = np.minimum (ftab_0 , np.roll (ftab_0, axis=ix, shift=-1)) 1467 if action == 'max' : vtab = np.maximum (ftab_0 , np.roll (ftab_0, axis=ix, shift=-1)) 1468 if action == 'mult' : vtab = ftab_0 * np.roll (ftab_0, axis=ix, shift=-1) 1469 1470 vtab = lbc_del (vtab, nperio=nperio, cd_type='V', psgn=psgn) 1808 kz, az = __findAxis__ (ftab_0, 'z') 1809 if ix : 1810 if action == 'ave' : vtab = 0.5 * (ftab_0 + np.roll (ftab_0, axis=ix, shift=-1)) 1811 if action == 'min' : vtab = np.minimum (ftab_0 , np.roll (ftab_0, axis=ix, shift=-1)) 1812 if action == 'max' : vtab = np.maximum (ftab_0 , np.roll (ftab_0, axis=ix, shift=-1)) 1813 if action == 'mult' : vtab = ftab_0 * np.roll (ftab_0, axis=ix, shift=-1) 1814 vtab = lbc_del (vtab , nperio=nperio, cd_type='V', psgn=psgn) 1815 else : 1816 vtab = lbc_del (ftab_0, nperio=nperio, cd_type='V', psgn=psgn) 1817 1471 1818 if mmath == xr : 1472 1819 vtab = vtab.assign_coords({ax:np.arange(ftab.shape[ix])+1.}) 1473 if zdim != None and iz != None and az != 'olevel':1474 vtab = vtab.rename( {az:zdim})1820 if zdim and az : 1821 if az != zdim : vtab = vtab.rename( {az:zdim}) 1475 1822 return vtab 1476 1823 1477 #@numba.jit(forceobj=True) 1478 def W2T (wtab, zcoord=None, zdim='deptht', sval=np.nan) : 1824 def W2T (wtab, zcoord=None, zdim=None, sval=np.nan) : 1479 1825 ''' 1480 1826 Interpolate an array on W grid to T grid (k-mean) … … 1484 1830 wtab_0 = mmath.where ( np.isnan(wtab), 0., wtab) 1485 1831 1486 iz, az = __findAxis__ (wtab_0, 'z') 1487 1488 ttab = 0.5 * ( wtab_0 + np.roll (wtab_0, axis=iz, shift=-1) ) 1489 1832 kz, az = __findAxis__ (wtab_0, 'z') 1833 1834 if kz : 1835 ttab = 0.5 * ( wtab_0 + np.roll (wtab_0, axis=kz, shift=-1) ) 1836 else : 1837 ttab = wtab_0 1838 1490 1839 if mmath == xr : 1491 ttab[{az: iz}] = sval1492 if zdim != None and iz != None and az != 'olevel':1493 ttab = ttab.rename ( {az:zdim} )1494 try : ttab = ttab.assign_coords ( {zdim:zcoord} )1495 except : pass1840 ttab[{az:kz}] = sval 1841 if zdim and az : 1842 if az != zdim : ttab = ttab.rename ( {az:zdim} ) 1843 if zcoord is not None : 1844 ttab = ttab.assign_coords ( {zdim:zcoord} ) 1496 1845 else : 1497 1846 ttab[..., -1, :, :] = sval … … 1499 1848 return ttab 1500 1849 1501 #@numba.jit(forceobj=True) 1502 def T2W (ttab, zcoord=None, zdim='depthw', sval=np.nan, extrap_surf=False) : 1850 def T2W (ttab, zcoord=None, zdim=None, sval=np.nan, extrap_surf=False) : 1503 1851 '''Interpolate an array from T grid to W grid (k-mean) 1504 1852 sval is the surface value … … 1507 1855 mmath = __mmath__ (ttab) 1508 1856 ttab_0 = mmath.where ( np.isnan(ttab), 0., ttab) 1509 iz, az = __findAxis__ (ttab_0, 'z')1510 wtab = 0.5 * ( ttab_0 + np.roll (ttab_0, axis= iz, shift=1) )1857 kz, az = __findAxis__ (ttab_0, 'z') 1858 wtab = 0.5 * ( ttab_0 + np.roll (ttab_0, axis=kz, shift=1) ) 1511 1859 1512 1860 if mmath == xr : … … 1518 1866 1519 1867 if mmath == xr : 1520 if zdim != None and iz != None and az != 'olevel' : 1521 wtab = wtab.rename ( {az:zdim}) 1522 if zcoord != None : wtab = wtab.assign_coords ( {zdim:zcoord}) 1523 else : ztab = wtab.assign_coords ( {zdim:np.arange(ttab.shape[iz])+1.} ) 1868 if zdim and az : 1869 if az != zdim : wtab = wtab.rename ( {az:zdim}) 1870 if zcoord is not None : 1871 wtab = wtab.assign_coords ( {zdim:zcoord}) 1872 else : 1873 ztab = wtab.assign_coords ( {zdim:np.arange(ttab.shape[kz])+1.} ) 1524 1874 return wtab 1525 1875 1526 #@numba.jit(forceobj=True)1527 1876 def fill (ptab, nperio, cd_type='T', npass=1, sval=0.) : 1528 1877 ''' … … 1584 1933 return ztab 1585 1934 1586 #@numba.jit(forceobj=True)1587 1935 def correct_uv (u, v, lat) : 1588 1936 ''' 1589 Correct a Cartopy bug in Orthographic projection1937 Correct a Cartopy bug in orthographic projection 1590 1938 1591 1939 See https://github.com/SciTools/cartopy/issues/1179 … … 1593 1941 The correction is needed with cartopy <= 0.20 1594 1942 It seems that version 0.21 will correct the bug (https://github.com/SciTools/cartopy/pull/1926) 1943 Later note : the bug is still present in Cartopy 0.22 1595 1944 1596 1945 Inputs : 1597 u, v : eastward/no thward components1946 u, v : eastward/northward components 1598 1947 lat : latitude of the point (degrees north) 1599 1948 … … 1608 1957 return uc, vc 1609 1958 1610 def msf (v_e1v_e3v, lat1d, depthw) : 1959 def norm_uv (u, v) : 1960 ''' 1961 Return norm of a 2 components vector 1962 ''' 1963 return np.sqrt (u*u + v*v) 1964 1965 def normalize_uv (u, v) : 1966 ''' 1967 Normalize 2 components vector 1968 ''' 1969 uv = norm_uv (u, v) 1970 return u/uv, v/uv 1971 1972 def msf (vv, e1v_e3v, lat1d, depthw) : 1611 1973 ''' 1612 1974 Computes the meridonal stream function 1613 1975 First input is meridional_velocity*e1v*e3v 1614 1976 ''' 1615 @numba.jit(forceobj=True) 1616 def iin (tab, dim) : 1617 ''' 1618 Integrate from the bottom 1619 ''' 1620 result = tab * 0.0 1621 nlen = len(tab.coords[dim]) 1622 for jn in np.arange (nlen-2, 0, -1) : 1623 result [{dim:jn}] = result [{dim:jn+1}] - tab [{dim:jn}] 1624 result = result.where (result !=0, np.nan) 1625 return result 1626 1627 zomsf = iin ((v_e1v_e3v).sum (dim='x', keep_attrs=True)*1E-6, dim='depthv') 1628 zomsf = zomsf.assign_coords ( {'depthv':depthw.values, 'y':lat1d}) 1629 zomsf = zomsf.rename ( {'depthv':'depthw', 'y':'lat'}) 1977 1978 v_e1v_e3v = vv * e1v_e3v 1979 v_e1v_e3v.attrs = vv.attrs 1980 1981 ix, ax = __findAxis__ (v_e1v_e3v, 'x') 1982 kz, az = __findAxis__ (v_e1v_e3v, 'z') 1983 if az == 'olevel' : new_az = 'olevel' 1984 else : new_az = 'depthw' 1985 1986 zomsf = -v_e1v_e3v.cumsum ( dim=az, keep_attrs=True).sum (dim=ax, keep_attrs=True)*1.E-6 1987 zomsf = zomsf - zomsf.isel ( { az:-1} ) 1988 1989 jy, ay = __findAxis__ (zomsf, 'y' ) 1990 zomsf = zomsf.assign_coords ( {az:depthw.values, ay:lat1d.values}) 1991 1992 zomsf = zomsf.rename ( {ay:'lat'}) 1993 if az != new_az : zomsf = zomsf.rename ( {az:new_az} ) 1994 zomsf.attrs['standard_name'] = 'Meridional stream function' 1630 1995 zomsf.attrs['long_name'] = 'Meridional stream function' 1631 1632 1996 zomsf.attrs['units'] = 'Sv' 1633 zomsf .depthw.attrs=depthw.attrs1997 zomsf[new_az].attrs = depthw.attrs 1634 1998 zomsf.lat.attrs=lat1d.attrs 1635 1999 1636 2000 return zomsf 1637 2001 1638 def bsf (u _e2u_e3u, mask, nperio=None, bsf0=None ) :2002 def bsf (uu, e2u_e3u, mask, nperio=None, bsf0=None ) : 1639 2003 ''' 1640 2004 Computes the barotropic stream function 1641 2005 First input is zonal_velocity*e2u*e3u 1642 bsf0 is the point with bsf=0 (ex: bsf0={'x':5, 'y':120} ) 1643 ''' 1644 @numba.jit(forceobj=True) 1645 def iin (tab, dim) : 1646 ''' 1647 Integrate from the south 1648 ''' 1649 result = tab * 0.0 1650 nlen = len(tab.coords[dim]) 1651 for jn in np.arange (3, nlen) : 1652 result [{dim:jn}] = result [{dim:jn-1}] + tab [{dim:jn}] 1653 return result 1654 1655 bsf = iin ((u_e2u_e3u).sum(dim='depthu', keep_attrs=True)*1E-6, dim='y') 1656 bsf.attrs = u_e2u_e3u.attrs 1657 if bsf0 != None : 2006 bsf0 is the point with bsf=0 2007 (ex: bsf0={'x':3, 'y':120} for orca2, 2008 bsf0={'x':5, 'y':300} for eeORCA1 2009 ''' 2010 u_e2u_e3u = uu * e2u_e3u 2011 u_e2u_e3u.attrs = uu.attrs 2012 2013 iy, ay = __findAxis__ (u_e2u_e3u, 'y') 2014 kz, az = __findAxis__ (u_e2u_e3u, 'z') 2015 2016 bsf = -u_e2u_e3u.cumsum ( dim=ay, keep_attrs=True ) 2017 bsf = bsf.sum (dim=az, keep_attrs=True)*1.E-6 2018 2019 if bsf0 : 1658 2020 bsf = bsf - bsf.isel (bsf0) 1659 2021 1660 2022 bsf = bsf.where (mask !=0, np.nan) 1661 bsf.attrs['long_name'] = 'Barotropic stream function' 1662 bsf.attrs['units'] = 'Sv' 2023 for attr in uu.attrs : 2024 bsf.attrs[attr] = uu.attrs[attr] 2025 bsf.attrs['standard_name'] = 'barotropic_stream_function' 2026 bsf.attrs['long_name'] = 'Barotropic stream function' 2027 bsf.attrs['units'] = 'Sv' 1663 2028 bsf = lbc (bsf, nperio=nperio, cd_type='F') 1664 2029 … … 1679 2044 1680 2045 ''' 1681 1682 if ref != None : 2046 2047 import f90nml 2048 if ref : 1683 2049 if isinstance (ref, str) : nml_ref = f90nml.read (ref) 1684 2050 if isinstance (ref, f90nml.namelist.Namelist) : nml_ref = ref 1685 2051 1686 if cfg != None:2052 if cfg : 1687 2053 if isinstance (cfg, str) : nml_cfg = f90nml.read (cfg) 1688 2054 if isinstance (cfg, f90nml.namelist.Namelist) : nml_cfg = cfg … … 1693 2059 list_nml = [] ; list_comment = [] 1694 2060 1695 if ref != None : 1696 list_nml.append (nml_ref) ; list_comment.append ('ref') 1697 if cfg != None : 1698 list_nml.append (nml_cfg) ; list_comment.append ('cfg') 2061 if ref : list_nml.append (nml_ref) ; list_comment.append ('ref') 2062 if cfg : list_nml.append (nml_cfg) ; list_comment.append ('cfg') 1699 2063 1700 2064 for nml, comment in zip (list_nml, list_comment) : … … 1719 2083 if out == 'xr' : return xr_namelist 1720 2084 1721 1722 2085 def fill_closed_seas (imask, nperio=None, cd_type='T') : 1723 2086 '''Fill closed seas with image processing library … … 1730 2093 1731 2094 return imask_filled 2095 2096 ''' 2097 Sea water state function parameters from NEMO code 2098 ''' 2099 rdeltaS = 32. ; r1_S0 = 0.875/35.16504 ; r1_T0 = 1./40. ; r1_Z0 = 1.e-4 2100 2101 EOS000 = 8.0189615746e+02 ; EOS100 = 8.6672408165e+02 ; EOS200 = -1.7864682637e+03 ; EOS300 = 2.0375295546e+03 ; EOS400 = -1.2849161071e+03 ; EOS500 = 4.3227585684e+02 ; EOS600 = -6.0579916612e+01 2102 EOS010 = 2.6010145068e+01 ; EOS110 = -6.5281885265e+01 ; EOS210 = 8.1770425108e+01 ; EOS310 = -5.6888046321e+01 ; EOS410 = 1.7681814114e+01 ; EOS510 = -1.9193502195 2103 EOS020 = -3.7074170417e+01 ; EOS120 = 6.1548258127e+01 ; EOS220 = -6.0362551501e+01 ; EOS320 = 2.9130021253e+01 ; EOS420 = -5.4723692739 ; EOS030 = 2.1661789529e+01 2104 EOS130 = -3.3449108469e+01 ; EOS230 = 1.9717078466e+01 ; EOS330 = -3.1742946532 2105 EOS040 = -8.3627885467 ; EOS140 = 1.1311538584e+01 ; EOS240 = -5.3563304045 2106 EOS050 = 5.4048723791e-01 ; EOS150 = 4.8169980163e-01 2107 EOS060 = -1.9083568888e-01 2108 EOS001 = 1.9681925209e+01 ; EOS101 = -4.2549998214e+01 ; EOS201 = 5.0774768218e+01 ; EOS301 = -3.0938076334e+01 ; EOS401 = 6.6051753097 ; EOS011 = -1.3336301113e+01 2109 EOS111 = -4.4870114575 ; EOS211 = 5.0042598061 ; EOS311 = -6.5399043664e-01 ; EOS021 = 6.7080479603 ; EOS121 = 3.5063081279 2110 EOS221 = -1.8795372996 ; EOS031 = -2.4649669534 ; EOS131 = -5.5077101279e-01 ; EOS041 = 5.5927935970e-01 2111 EOS002 = 2.0660924175 ; EOS102 = -4.9527603989 ; EOS202 = 2.5019633244 ; EOS012 = 2.0564311499 ; EOS112 = -2.1311365518e-01 ; EOS022 = -1.2419983026 2112 EOS003 = -2.3342758797e-02 ; EOS103 = -1.8507636718e-02 ; EOS013 = 3.7969820455e-01 2113 2114 def rhop ( ptemp, psal ) : 2115 ''' 2116 Potential density referenced to surface 2117 Computation from NEMO code 2118 ''' 2119 zt = ptemp * r1_T0 # Temperature (°C) 2120 zs = np.sqrt ( np.abs( psal + rdeltaS ) * r1_S0 ) # Square root of salinity (PSS) 2121 # 2122 prhop = (((((EOS060*zt \ 2123 + EOS150*zs + EOS050)*zt \ 2124 + (EOS240*zs + EOS140)*zs + EOS040)*zt \ 2125 + ((EOS330*zs + EOS230)*zs + EOS130)*zs + EOS030)*zt \ 2126 + (((EOS420*zs + EOS320)*zs + EOS220)*zs + EOS120)*zs + EOS020)*zt \ 2127 + ((((EOS510*zs + EOS410)*zs + EOS310)*zs + EOS210)*zs + EOS110)*zs + EOS010)*zt \ 2128 + (((((EOS600*zs+ EOS500)*zs + EOS400)*zs + EOS300)*zs + EOS200)*zs + EOS100)*zs + EOS000 2129 # 2130 return prhop 2131 2132 def rho ( pdep, ptemp, psal ) : 2133 ''' 2134 In situ density 2135 Computation from NEMO code 2136 ''' 2137 zh = pdep * r1_Z0 # Depth (m) 2138 zt = ptemp * r1_T0 # Temperature (°C) 2139 zs = np.sqrt ( np.abs( psal + rdeltaS ) * r1_S0 ) # Square root salinity (PSS) 2140 # 2141 zn3 = EOS013*zt + EOS103*zs+EOS003 2142 # 2143 zn2 = (EOS022*zt + EOS112*zs+EOS012)*zt + (EOS202*zs+EOS102)*zs+EOS002 2144 # 2145 zn1 = (((EOS041*zt \ 2146 + EOS131*zs + EOS031)*zt \ 2147 + (EOS221*zs + EOS121)*zs + EOS021)*zt \ 2148 + ((EOS311*zs + EOS211)*zs + EOS111)*zs + EOS011)*zt \ 2149 + (((EOS401*zs + EOS301)*zs + EOS201)*zs + EOS101)*zs + EOS001 2150 # 2151 zn0 = (((((EOS060*zt \ 2152 + EOS150*zs + EOS050)*zt \ 2153 + (EOS240*zs + EOS140)*zs + EOS040)*zt \ 2154 + ((EOS330*zs + EOS230)*zs + EOS130)*zs + EOS030)*zt \ 2155 + (((EOS420*zs + EOS320)*zs + EOS220)*zs + EOS120)*zs + EOS020)*zt \ 2156 + ((((EOS510*zs + EOS410)*zs + EOS310)*zs + EOS210)*zs + EOS110)*zs + EOS010)*zt \ 2157 + (((((EOS600*zs + EOS500)*zs + EOS400)*zs + EOS300)*zs + EOS200)*zs + EOS100)*zs + EOS000 2158 # 2159 prho = ( ( zn3 * zh + zn2 ) * zh + zn1 ) * zh + zn0 2160 # 2161 return prho 1732 2162 1733 2163 ## ===========================================================================
Note: See TracChangeset
for help on using the changeset viewer.