require 'getopts' require 'numru/gphys' def cal_global_mean(gp) lat = gp.coord('lat') phi = lat*2*PI/360.0 grid = Grid.new(gp.axis('lat')) cos_lat = GPhys.new(grid, cos(phi)) gp_global_mean = ( gp.average('lon').average('level') * cos_lat ).average('lat') return gp_global_mean end ################################################################################ include NumRu include Misc::EMath unless getopts("v:", "hgt:", "temp:", "shum:", "mask:", "output:epflx.nc") print "#{$0}:illegal options.\n" exit 1 end Cp = UNumeric.new(1004.0, 'J.K-1.kg-1') G = UNumeric.new(9.81, "m.s-2") nc_vwnd, var_vwnd = ($OPT_v).split(/\s*@\s*/) nc_hgt, var_hgt = ($OPT_hgt).split(/\s*@\s*/) nc_temp, var_temp = ($OPT_temp).split(/\s*@\s*/) nc_mask, var_mask = ($OPT_mask).split(/\s*@\s*/) gp_v = GPhys::IO.open( nc_vwnd, var_vwnd ) gp_hgt = GPhys::IO.open( nc_hgt, var_hgt ) gp_t = GPhys::IO.open( nc_temp, var_temp ) gp_mask = GPhys::IO.open( nc_mask, var_mask ) ofile = NetCDF.create($OPT_output) nt = gp_v.shape[-1] i = 0 GPhys::IO.each_along_dims_write([gp_v, gp_hgt, gp_t, gp_mask], ofile, -1){ |v, hgt, temp, mask| i += 1 print "processing #{i} / #{nt} ..\n" if (i % (nt/20+1))==1 v = v + mask hgt = hgt + mask temp = temp + mask temp_bar = temp.mean('lon') temp_dash = temp - temp_bar hgt_bar = hgt.mean('lon') hgt_dash = hgt - hgt_bar v_bar = v.mean('lon') v_dash = v - v_bar temp_gl = cal_global_mean(temp) hgt_gl = cal_global_mean(hgt) vt = v * ( temp - temp_gl ) * Cp vh = v * ( hgt - hgt_gl ) * G dsefl = ( vt + vh ).mean('lon') dsefl_bar = ( ( temp_bar - temp_gl ) * Cp + ( hgt_bar - hgt_gl ) * G ) * v_bar dsefl_dash = ( ( ( temp_dash - temp_gl ) * Cp + ( hgt_dash - hgt_gl ) * G ) * v_dash ).mean('lon') dsefl.data.rename!("dsefl") dsefl.data.set_att('long_name', 'dry staitic energy transport (total)') dsefl.data.set_att('units', 'W') dsefl_bar.data.rename!("dsefl_bar") dsefl_bar.data.set_att('long_name', 'dry staitic energy transport (bar)') dsefl_bar.data.set_att('units', 'W') dsefl_dash.data.rename!("dsefl_dash") dsefl_dash.data.set_att('long_name', 'dry staitic energy transport (dash)') dsefl_dash.data.set_att('units', 'W') [ dsefl, dsefl_bar, dsefl_dash ].each{|gp| # This part will not gp.data.att_names.each{|nm| # be needed in future. gp.data.del_att(nm) if /^valid_/ =~ nm # (Even now, it is not gp.data.del_att(nm) if /^title/ =~ nm # needed if the valid } # range is wide enough) } [ dsefl, dsefl_bar, dsefl_dash ] } ofile.close