def get_SUMsalinity(year, month, product_n = 3): # 全球での塩分の総和を求める。 # 単位はkg。 rho0 = 1024.0 # 海水の密度はこれで統一。 _, title_name, _ = product_n_to_name(product_n) s = get_data(year, month, 's', 0, title_name) xgrid, ygrid, zgrid = product_grid_info('w', 'data', product_n) xn = xgrid.size yn = ygrid.size zn = zgrid.size ew_dist = zeros([yn, xn]) ns_dist = zeros([yn, xn]) S = zeros([yn, xn]) for i in range(0, xn): for j in range(0, yn): ew_dist[j, i] = dist_on_sphere([0, ygrid[j]], [1, ygrid[j]]) ns_dist[j, i] = dist_on_sphere([0, ygrid[j] - 0.5], [0, ygrid[j] + 0.5]) if isnan(s[j, i, 0]) == True: S[j, i] = 0.0 else: for k in range(0, zn): if k == 0: dH = zgrid[k] else: dH = zgrid[k] - zgrid[k - 1] if isnan(s[j, i, k]) == False: S[j, i] = S[j, i] + dH * ew_dist[j, i] * ns_dist[j, i] * rho0 * (s[j, i, k]/1000) else: break return sum(S)
def get_Gradient_of_variable_from_data(data, var, product_n = 3): xgrid, ygrid, zgrid = D.get_grid_value(var, product_n) xn = xgrid.size yn = ygrid.size zn = zgrid.size Data_ns = np.zeros((yn, xn, zn)) Data_ew = np.zeros((yn, xn, zn)) ns_dist = subroutine.dist_on_sphere([0.0, - 0.5], [0.0, 0.5]) for j in range(0, yn): if j == 0 or j == yn - 1: Data_ns[j, :, :] = np.nan Data_ew[j, :, :] = np.nan else: y0 = j - 1 y1 = j y2 = j + 1 lat1 = ygrid[y1] ew_dist = subroutine.dist_on_sphere([0.0, lat1], [1.0, lat1]) for i in range(0, xn): x1 = i lon1 = xgrid[x1] if i == 0: x0 = xn - 1 x2 = i + 1 elif i == xn - 1: x0 = i - 1 x2 = xn - 1 else: x0 = i - 1 x2 = i + 1 data01 = data[y1, x0, :] data10 = data[y0, x1, :] data11 = data[y1, x1, :] data21 = data[y1, x2, :] data12 = data[y2, x1, :] if np.isnan(data01[0]) == True and np.isnan(data21[0]) == False: Data_ew[j, i, :] = (data21 - data11) / ew_dist elif np.isnan(data21[0]) == True and np.isnan(data01[0]) == False: Data_ew[j, i, :] = (data11 - data01) / ew_dist else: Data_ew[j, i, :] = (data21 - data01) / (2.0 * ew_dist) if np.isnan(data10[0]) == True and np.isnan(data12[0]) == False: Data_ns[j, i, :] = (data12 - data11) / ns_dist elif np.isnan(data12[0]) == True and np.isnan(data10[0]) == False: Data_ns[j, i, :] = (data11 - data10) / ns_dist else: Data_ns[j, i, :] = (data12 - data10) / (2.0 * ns_dist) return Data_ew, Data_ns
def cal_GeostrophicCurrent_from_SSH(ssh, product_n = 3): ns_dist = subroutine.dist_on_sphere([0.0, - 0.5], [0.0, 0.5]) xgrid, ygrid, zgrid = D.get_grid_value('ht', product_n) yn = ygrid.size xn = xgrid.size Ug = np.zeros((yn, xn)) Vg = np.zeros((yn, xn)) xgrid_new = np.zeros(xn) ygrid_new = np.zeros(yn) for j in range(0, yn): if j == yn - 1: ygrid_new[j] = 0.5 * (ygrid[j] + ygrid[j] + 1) Ug[j, :] = np.nan Vg[j, :] = np.nan else: y0 = j y1 = j + 1 ygrid_new[j] = 0.5 * (ygrid[y0] + ygrid[y1]) if abs(ygrid_new[j]) <= 2.0: # 赤道付近においては地衡流は計算しない Ug[j, :] = np.nan Vg[j, :] = np.nan else: ew_dist = subroutine.dist_on_sphere([0.0, ygrid_new[j]], [1.0, ygrid_new[j]]) f = subroutine.f0(ygrid_new[j]) for i in range(0, xn): x0 = i if i == xn - 1: x1 = 0 lon = 0.5 * (xgrid[i] + xgrid[i] + 1.0) else: x1 = i + 1 lon = 0.5 * (xgrid[x0] + xgrid[x1]) if j == 1: xgrid_new[i] = lon ssh00 = ssh[y0, x0] ssh01 = ssh[y1, x0] ssh10 = ssh[y0, x1] ssh11 = ssh[y1, x1] a = Using_jit.average_of_2data(ssh01, ssh11) b = Using_jit.average_of_2data(ssh00, ssh10) c = Using_jit.average_of_2data(ssh10, ssh11) d = Using_jit.average_of_2data(ssh00, ssh01) Ug[j, i] = -g / f * (a - b) / ns_dist Vg[j, i] = g / f * (c - d) / ew_dist return Ug, Vg, xgrid_new, ygrid_new
def cal_curl(year, month, product_n = 3): taux = D.get_data(year, month, 'taux', 1, product_n) tauy = D.get_data(year, month, 'tauy', 1, product_n) xgrid, ygrid, zgrid = D.get_grid_value('taux', product_n) xn = xgrid.size yn = ygrid.size curl = np.zeros([yn, xn]) ns_dist = subroutine.dist_on_sphere([0.0, - 0.5], [0.0, 0.5]) for j in range(0, yn): if j == yn - 1: curl[j, :] = np.nan else: y0 = j y1 = j + 1 lat0 = ygrid[y0] lat1 = ygrid[y1] tmpdist = np.average(np.array([lat0, lat1])) ew_dist = subroutine.dist_on_sphere([0.0, tmpdist], [1.0, tmpdist]) for i in range(0, xn): x0 = i lon0 = xgrid[x0] if i == xn - 1: x1 = 0 lon1 = xgrid[x1] else: x1 = i + 1 lon1 = xgrid[x1] taux00 = taux[y0, x0] tauy00 = tauy[y0, x0] taux01 = taux[y1, x0] tauy01 = tauy[y1, x0] taux10 = taux[y0, x1] tauy10 = tauy[y0, x1] taux11 = taux[y1, x1] tauy11 = tauy[y1, x1] a = Using_jit.average_of_2data(tauy10, tauy11) b = Using_jit.average_of_2data(tauy00, tauy01) c = Using_jit.average_of_2data(taux01, taux11) d = Using_jit.average_of_2data(taux00, taux10) if np.isnan(a - b) == False and np.isnan(c - d) == False: curl[j, i] = (a - b) / ew_dist - (c - d) / ns_dist elif np.isnan(a - b) == False: curl[j, i] = (a - b) / ew_dist elif np.isnan(c - d) == False: curl[j, i] = - (c - d) / ns_dist else: curl[j, i] = np.nan return curl
def __init__(self, ID, AreaName, slat, nlat, wlon, elon): import subroutine self.ID = ID self.AreaName = AreaName self.slat = slat self.nlat = nlat self.wlon = wlon self.elon = elon self.xn = int(elon - wlon + 1) self.yn = int(nlat - slat + 1) self.EWdist = subroutine.dist_on_sphere([wlon, 0.5 * (slat + nlat)], [elon + 1, 0.5 * (slat + nlat)]) self.NSdist = subroutine.dist_on_sphere([0.0, slat], [0.0, nlat + 1]) self.Square = self.EWdist * self.NSdist # Areaの面積
def cal_Salt_Transport(s, u, Zonal_or_Meridional, product_n): # 東西輸送量も鉛直輸送量もどっちも求められます。 # Zonal : Zonal_or_Meridional = 0 # Meridional : Zonal_or_Meridional = 1 rho0 = 1024.0 # 面倒くさいので密度は一定値。 yn = s.shape[0] xn = s.shape[1] zn = s.shape[2] ns_dist = subroutine.dist_on_sphere([0.0, - 0.5], [0.0, 0.5]) xgrid, ygrid, zgrid = D.get_grid_value('s', product_n) Data = np.zeros((yn, xn, zn)) for j in range(0, yn): if j == 0: Data[j, :, :] = np.nan else: y0 = j - 1 y1 = j lat1 = ygrid[y1] if Zonal_or_Meridional == 0: L = ns_dist # 東西輸送量であれば、南北に積分 elif Zonal_or_Meridional == 1: L = subroutine.dist_on_sphere([0.0, lat1], [1.0, lat1]) # 南北輸送量であれば、東西に積分 else: raise ValueError('your Zonal_or_Meridional argument is not valid!') for i in range(0, xn): x1 = i if i == 0: x0 = xn - 1 else: x0 = i - 1 if np.isnan(s[y1, x1, 0]) == True: Data[y1, x1, :] = np.nan else: for k in range(0, zn): # U = np.array([u[y0, x0, k], u[y1, x0, k], u[y0, x1, k], u[y1, x1, k]]) # Data[y1, x1, k] = L * lz[k] * 1e-3 * rho0 * s[y1, x1, k] * \ # np.average(U[np.where(np.isnan(U) == False)]) Data[y1, x1, k] = L * lz[k] * 1e-3 * rho0 * s[y1, x1, k] * \ average_of_4data(u[y0, x0, k], u[y1, x0, k], u[y0, x1, k], u[y1, x1, k]) return Data
def cal_diffusion_of_variable(S, kappa, product_n): # kappaは水平拡散係数。 # 海洋ではkappa=500(m^2/s)程度としている文献多し。 Mt = 60 * 60 * 24 * 30 xgrid, ygrid, zgrid = subroutine.product_grid_info('s', 'data', product_n) yn = S.shape[0] xn = S.shape[1] zn = S.shape[2] ns_dist = subroutine.dist_on_sphere([0.0, - 0.5], [0.0, 0.5]) Diff = np.zeros((yn, xn, zn)) for j in range(yn): if j == 0 or j == yn - 1: Diff[j, :, :] = np.nan else: y0 = j - 1 y1 = j y2 = j + 1 lat1 = ygrid[y1] ew_dist = subroutine.dist_on_sphere([0.0, lat1], [1.0, lat1]) for i in range(xn): x1 = i if i == 0: x0 = xn - 1 else: x0 = i - 1 if i == xn - 1: x2 = 0 else: x2 = i + 1 S01 = S[y1, x0, :] S10 = S[y0, x1, :] S11 = S[y1, x1, :] S21 = S[y1, x2, :] S12 = S[y2, x1, :] Diff[j, i, :] = Mt * kappa * (S21 - 2.0 * S11 + S01) / (ew_dist)**2 + \ Mt * kappa * (S12 - 2.0 * S11 + S10) / (ns_dist)**2 return Diff
def cal_ew_ns_dist(year,month,product_n=3): _,title_name,_=product_n_to_name(product_n) xgrid,ygrid,zgrid=product_grid_info('u','data',product_n) u=get_data(year,month,'u',0,title_name) v=get_data(year,month,'v',0,title_name) xn=xgrid.size yn=ygrid.size zn=zgrid.size ew_dist=zeros([yn-1,xn]) ns_dist=zeros([yn-1,xn]) xgrid_for_manual_w=zeros(xn) ygrid_for_manual_w=zeros(yn-1) zgrid_for_manual_w=zeros(zn) for i in range(0,xn): x0=i lon0=xgrid[x0] if i==xn-1: x1=0 lon1=xgrid[x1] xgrid_for_manual_w[i]=average([lon0,lon1+360]) else: x1=i+1 lon1=xgrid[x1] xgrid_for_manual_w[i]=average([lon0,lon1]) for j in range(0,yn-1): y0=j y1=j+1 lat0=ygrid[y0] lat1=ygrid[y1] ygrid_for_manual_w[j]=average([lat0,lat1]) ew_dist[j,i]=dist_on_sphere([lon0,ygrid_for_manual_w[j]],[lon1,ygrid_for_manual_w[j]]) ns_dist[j,i]=dist_on_sphere([xgrid_for_manual_w[i],lat0],[xgrid_for_manual_w[i],lat1]) return ew_dist,ns_dist
def get_water_mass(product_n = 3): _, title_name, _ = product_n_to_name(product_n) s = get_data(2001, 1, 's', 0, title_name) xgrid, ygrid, zgrid = product_grid_info('w', 'data', product_n) xn = xgrid.size yn = ygrid.size zn = zgrid.size ew_dist = zeros([yn, xn]) ns_dist = zeros([yn, xn]) Mass = zeros([yn, xn]) for i in range(0, xn): for j in range(0, yn): ew_dist[j, i] = dist_on_sphere([0, ygrid[j]], [1, ygrid[j]]) ns_dist[j, i] = dist_on_sphere([0, ygrid[j] - 0.5], [0, ygrid[j] + 0.5]) if isnan(s[j, i, 0]) == True: Mass[j, i] = 0.0 else: L = max(where(isnan(s[j, i, :]) == False)[0]) Mass[j, i] = zgrid[L] * ew_dist[j, i] * ns_dist[j, i] return sum(Mass)
def get_SUMsff(year, month, product_n = 3): # 全球での淡水フラックスの総和を求める # 単位はm^3/month。 _, title_name, _ = product_n_to_name(product_n) sff = get_data(year, month, 'sff', 1, title_name) xgrid, ygrid, _ = product_grid_info('t', 'data', product_n) xn = xgrid.size yn = ygrid.size ew_dist = zeros([yn, xn]) ns_dist = zeros([yn, xn]) SFF = zeros([yn, xn]) for i in range(0, xn): for j in range(0, yn): ew_dist[j, i] = dist_on_sphere([0, ygrid[j]], [1, ygrid[j]]) ns_dist[j, i] = dist_on_sphere([0, ygrid[j] - 0.5], [0, ygrid[j] + 0.5]) if isnan(sff[j, i]) == True: SFF[j, i] = 0.0 else: SFF[j, i] = sff[j, i] * ew_dist[j, i] * ns_dist[j, i] return sum(SFF)
def cal_Hor_and_Ver_Flux(s, u, v, w): product_n = 3 Mt = 60 * 60 * 24 * 30 xgrid, ygrid, zgrid = product_grid_info('t', 'data', product_n) xn = xgrid.size yn = ygrid.size zn = zgrid.size s[where(abs(s) == inf)] = nan u[where(abs(u) == inf)] = nan v[where(abs(v) == inf)] = nan w[where(abs(w) == inf)] = nan ZonalFlux = zeros((yn, xn, zn), dtype = float64) MeridFlux = zeros((yn, xn, zn), dtype = float64) VertcFlux = zeros((yn, xn, zn), dtype = float64) ns_dist = dist_on_sphere([0.0, - 0.5], [0.0, 0.5]) for j in range(0, yn): if j % 10 == 0: print 'j= %3i' % j if j == 0 or j == yn - 1: ZonalFlux[j, :, :] = nan MeridFlux[j, :, :] = nan VertcFlux[j, :, :] = nan else: y0 = j - 1 y1 = j y2 = j + 1 lat1 = ygrid[y1] ew_dist = dist_on_sphere([0.0, lat1], [1.0, lat1]) for i in range(0, xn): x1 = i lon1 = xgrid[x1] if i == 0: x0 = xn - 1 x2 = i + 1 elif i == xn - 1: x0 = i - 1 x2 = xn - 1 else: x0 = i - 1 x2 = i + 1 u00 = u[y0, x0, :] v00 = v[y0, x0, :] s00 = s[y0, x0, :] s01 = s[y1, x0, :] s10 = s[y0, x1, :] s11 = s[y1, x1, :] ZonalFlux[j, i, :] = cal_a_Flux(u00, s00, s01, s10, s11, ew_dist) MeridFlux[j, i, :] = cal_a_Flux(v00, s00, s10, s01, s11, ns_dist) for k in range(0, zn): # VertcFlux if k != zn - 1: dz = zgrid[k + 1] - zgrid[k] VertcFlux[:, :, k] = w[:, :, k] * (s[:, :, k + 1] - s[:, :, k])/dz * Mt else: VertcFlux[:, :, k] = nan # VertcFlux VertcFlux = convert.convert_Sgrid_value_to_UVgrid_value_3D(VertcFlux) return ZonalFlux, MeridFlux, VertcFlux
def cal_manual_w(year,month,product_n=3, GM = 'N'): _,title_name,_=product_n_to_name(product_n) if GM == 'N': u=get_data(year,month,'u',0,title_name) v=get_data(year,month,'v',0,title_name) elif GM == 'Y': u = get_data(year, month, 'ustar', 0, title_name) v = get_data(year, month, 'vstar', 0, title_name) else: raise Exception('your GM argument is not valid!') xgrid,ygrid,zgrid=product_grid_info('u','data',product_n) xn=xgrid.size yn=ygrid.size zn=zgrid.size manual_w=zeros([yn,xn,zn]) xgrid_for_manual_w=zeros(xn) ygrid_for_manual_w=zeros(yn) zgrid_for_manual_w=zeros(zn) dH=zeros(zn) for k in range(0,zn): if k==0: zgrid_for_manual_w[k]=2*zgrid[k] dH[k]=zgrid_for_manual_w[k] else: zgrid_for_manual_w[k]=2*zgrid[k]-zgrid_for_manual_w[k-1] dH[k]=zgrid_for_manual_w[k]-zgrid_for_manual_w[k-1] for i in range(0,xn): x0=i lon0=xgrid[x0] if i==xn-1: x1=0 lon1=xgrid[x1] xgrid_for_manual_w[i]=average([lon0,lon1+360]) else: x1=i+1 lon1=xgrid[x1] xgrid_for_manual_w[i]=average([lon0,lon1]) for j in range(0,yn): if j == yn - 1: manual_w[j,i,:]=nan ygrid_for_manual_w[j]=average([ygrid[yn - 1],ygrid[yn - 1] + 1]) else: y0=j y1=j + 1 lat0=ygrid[y0] lat1=ygrid[y1] ygrid_for_manual_w[j]=average([lat0,lat1]) ew_dist=dist_on_sphere([lon0,ygrid_for_manual_w[j]],[lon1,ygrid_for_manual_w[j]]) ns_dist=dist_on_sphere([xgrid_for_manual_w[i],lat0],[xgrid_for_manual_w[i],lat1]) for k in range(0,zn): if k==0: manual_w0=0.0 else: manual_w0=manual_w[j,i,k-1] u00=u[y0,x0,k] v00=v[y0,x0,k] u01=u[y1,x0,k] v01=v[y1,x0,k] u10=u[y0,x1,k] v10=v[y0,x1,k] u11=u[y1,x1,k] v11=v[y1,x1,k] if any(isnan(u00, u01, u10, u11)) == False: manual_w[j,i,k]=dH[k]*(((v01+v11)/2.0-(v00+v10)/2.0)/ns_dist +((u10+u11)/2.0-(u00+u01)/2.0)/ew_dist)+manual_w0 else: manual_w[j,i,k]=nan return manual_w,xgrid_for_manual_w,ygrid_for_manual_w,zgrid_for_manual_w
def cal_GM_diffusion(S, ustar, vstar): # GM velocityを用いてGM拡散項を計算 # 増田さんいわく、この項を入れなくても収支は閉じるということだが、 # GM項がどれくらいの大きさなのかを見ておくのは悪くないと思ったので計算してみる。 product_n = 3 Mt = 60 * 60 * 24 * 30 xgrid, ygrid, zgrid = product_grid_info("t", "data", product_n) xn = xgrid.size yn = ygrid.size zn = zgrid.size ZonalFlux = zeros((yn, xn, zn)) MeridFlux = zeros((yn, xn, zn)) ns_dist = dist_on_sphere([0.0, -0.5], [0.0, 0.5]) for j in range(0, yn): if j % 10 == 0: print "j= %3i" % j if j == 0 or j == yn - 1: ZonalFlux[j, :, :] = nan MeridFlux[j, :, :] = nan else: y0 = j - 1 y1 = j y2 = j + 1 lat1 = ygrid[y1] ew_dist = dist_on_sphere([0.0, lat1], [1.0, lat1]) for i in range(0, xn): x1 = i lon1 = xgrid[x1] if i == 0: x0 = xn - 1 x2 = i + 1 elif i == xn - 1: x0 = i - 1 x2 = xn - 1 else: x0 = i - 1 x2 = i + 1 if isnan(S[j, i, 0]) == True: ZonalFlux[j, i, :] = nan MeridFlux[j, i, :] = nan else: for k in range(0, zn): S00 = S[y0, x0, k] S01 = S[y1, x0, k] S10 = S[y0, x1, k] S11 = S[y1, x1, k] ustar01 = ustar[y1, x0, k] ustar11 = ustar[y1, x1, k] ustar21 = ustar[y1, x2, k] vstar10 = vstar[y0, x1, k] vstar11 = vstar[y1, x1, k] vstar12 = vstar[y2, x1, k] if isnan(S11) == True: ZonalFlux[j, i, k:] = nan MeridFlux[j, i, k:] = nan break else: ZonalFlux[j, i, k] = cal_a_GM_Flux(S00, S01, S10, S11, ustar01, ustar11, ustar21, ew_dist) MeridFlux[j, i, k] = cal_a_GM_Flux(S00, S10, S01, S11, vstar10, vstar11, vstar12, ns_dist) return ZonalFlux, MeridFlux
def cal_Hor_and_Ver_Flux(s, u, v, w, ID): Method_doc = Budget_at_Global_Ocean.Method[ID].Method_doc Hadv_func = getattr(Using_jit, 'cal_a_HFlux' + Method_doc) Vadv_func = getattr(Using_jit, 'cal_a_VFlux' + Method_doc) product_n = 3 xgrid, ygrid, zgrid = subroutine.product_grid_info('t', 'data', product_n) xn = xgrid.size yn = ygrid.size zn = zgrid.size s[np.where(abs(s) == np.inf)] = np.nan u[np.where(abs(u) == np.inf)] = np.nan v[np.where(abs(v) == np.inf)] = np.nan w[np.where(abs(w) == np.inf)] = np.nan ZonalFlux = np.zeros((yn, xn, zn)) MeridFlux = np.zeros((yn, xn, zn)) VertcFlux = np.zeros((yn, xn, zn)) ns_dist = subroutine.dist_on_sphere([0.0, - 0.5], [0.0, 0.5]) for j in range(0, yn): if j == 0 or j == yn - 1: ZonalFlux[j, :, :] = np.nan MeridFlux[j, :, :] = np.nan VertcFlux[j, :, :] = np.nan else: y0 = j - 1 y1 = j y2 = j + 1 lat1 = ygrid[y1] ew_dist = subroutine.dist_on_sphere([0.0, lat1], [1.0, lat1]) for i in range(0, xn): x1 = i lon1 = xgrid[x1] if i == 0: x0 = xn - 1 x2 = i + 1 elif i == xn - 1: x0 = i - 1 x2 = xn - 1 else: x0 = i - 1 x2 = i + 1 u00 = u[y0, x0, :] u01 = u[y1, x0, :] u10 = u[y0, x1, :] u11 = u[y1, x1, :] v00 = v[y0, x0, :] v01 = v[y1, x0, :] v10 = v[y0, x1, :] v11 = v[y1, x1, :] s01 = s[y1, x0, :] s10 = s[y0, x1, :] s11 = s[y1, x1, :] s21 = s[y1, x2, :] s12 = s[y2, x1, :] ZonalFlux[j, i, :] = Hadv_func(u00, u01, u10, u11, s01, s11, s21, ew_dist) MeridFlux[j, i, :] = Hadv_func(v00, v10, v01, v11, s10, s11, s12, ns_dist) VertcFlux[j, i, :] = Vadv_func(w[j, i, :], s[j, i, :]) Flux = np.array([ZonalFlux, MeridFlux, VertcFlux]) return Flux