def const_spec(k, K, u_10, fetch, azimuth, div, wind_dir): nk = k.shape[0] T = const_Trans(k, K, u_10, fetch, azimuth, div) ind = np.where(np.degrees(azimuth) == wind_dir)[0] B_old = kudryavtsev05(k.reshape(nk, 1), u_10, fetch, azimuth)[:, ind][:, 0] B_new = B_old * (1 + np.abs(T)) return B_old, B_new
def Wavebreaking_modulation(kr, K, theta, azimuth, u_10, fetch, wind_dir, tsc, polarization): """ :param kp: :param kr: :param theta: :param azi: :param u_10: :param fetch: :return: """ if polarization == 'VH': print('no modulation cross-pol') return nphi = theta.shape[0] ind = np.where(np.degrees(azimuth) == wind_dir)[0] # divergence of the sea surface current divergence = np.gradient(tsc[:, :, 0], 1e3, axis=1) + np.gradient( tsc[:, :, 1], 1e3, axis=0) # NRCS of plumes wb0 = np.exp(-np.tan(theta)**2 / const.Swb) / ( np.cos(theta)**4 * const.Swb ) + const.yitawb / const.Swb # Kudryavstev 2003a equation (60) knb = min(const.br * kr, const.kwb) # tilting transfer function dtheta = theta[1] - theta[0] Mwb = np.gradient(wb0, dtheta) / wb0 # distribution function # in radians azimuth of breaking surface area: -pi/2,pi/2 # phi1 = np.linspace(-np.pi/2, np.pi/2, nphi) phi1 = np.linspace(-np.pi, np.pi, nphi) nk = 1024 q = np.zeros([tsc.shape[0], tsc.shape[1]]) WB = np.zeros([tsc.shape[0], tsc.shape[1]]) for ii in np.arange(tsc.shape[0]): for jj in np.arange(tsc.shape[1]): KK = np.linspace(10 * spec_peak(u_10[ii, jj], fetch), knb, nk) T = Trans_func(KK, K[ii, jj], u_10[ii, jj], fetch, azimuth, divergence[ii, jj]) Bkdir = kudryavtsev05(KK.reshape(nk, 1), u_10[ii, jj], fetch, phi1) * (1 + abs(T.reshape(nk, 1))) n, alpha = param(KK, u_10[ii, jj], fetch) lamda = (Bkdir / alpha.reshape(nk, 1))**(n.reshape(nk, 1) + 1) / ( 2 * KK.reshape(nk, 1) ) # distribution of breaking front lengths lamda_k = np.trapz(lamda, phi1, axis=1) lamda = np.trapz(lamda, KK, axis=0) lamda_k = np.trapz(lamda_k, KK) q[ii, jj] = const.cq * lamda_k Awb = np.trapz(np.cos(phi1 - azimuth[ind]) * lamda, phi1) / lamda_k WB[ii, jj] = wb0[jj] * (1 + Mwb[jj] * const.theta_wb * Awb) return WB, q
def B_int(k, u_10, fetch, azi): if azi.max() > np.pi: azimuth = np.linspace(0, 2 * np.pi, 361) # 1024 elif azi.min() < -np.pi: azimuth = np.linspace(-2 * np.pi, 0, 361) else: azimuth = np.linspace(-np.pi, np.pi, 361) # 1024 B = kudryavtsev05(k, u_10, fetch, azimuth) f = interp2d(azimuth, k[:, 0], B, kind='linear') return f(azi, k[:, 0])
def GoM_spec(k, K, u_10, fetch, azimuth, div, wind_dir): nk = k.shape[2] T = GoM_Trans(k, K, u_10, fetch, azimuth, div) ind = np.where(np.degrees(azimuth) == wind_dir)[0] B_old = np.zeros([div.shape[0], div.shape[1], nk]) for ii in np.arange(k.shape[0]): for jj in np.arange(k.shape[1]): B_old[ii, jj, :] = kudryavtsev05(k[ii, jj, :].reshape(nk, 1), u_10[ii, jj], fetch, azimuth)[:, ind][:, 0] B_new = B_old * (1 + np.abs(T)) return B_old, B_new
def wn_exp(k, u_10, fetch, azimuth): # mk # wave number exponent of the omnidirirectional spectrum of the wave action nk = k.shape[0] omega = np.sqrt( const.g * k + const.gamma * k**3 / const.rho_water) # intrinstic frequency from dispersion relation # Omni directional spectrum model name Sk = kudryavtsev05(k.reshape(nk, 1), u_10, fetch, azimuth) * k.reshape( nk, 1)**4 # equation 45 Sk = np.trapz(Sk, azimuth, axis=1) N = omega.reshape(nk, 1) * Sk.reshape(nk, 1) / k.reshape(nk, 1)**2 mk = k.reshape(nk, 1) * np.gradient(np.log(N[:, 0]), k[1, 0] - k[0, 0]).reshape(nk, 1) return mk
def eq_wb_mo(kr, K, theta_eq, eq_azi, u_10, fetch, div): """ :param kp: :param kr: :param theta: :param azi: :param u_10: :param fetch: :return: """ # NRCS of plumes wb0 = np.exp(-np.tan(theta_eq)**2 / const.Swb) / ( np.cos(theta_eq)**4 * const.Swb ) + const.yitawb / const.Swb # Kudryavstev 2003a equation (60) knb = min(const.br * kr, const.kwb) # tilting transfer function dtheta = theta_eq[1] - theta_eq[0] Mwb = np.gradient(wb0, dtheta) / wb0 # distribution function phi1 = np.linspace(-np.pi, np.pi, 37) nk = 1024 q = np.zeros([div.shape[0], div.shape[1]]) WB = np.zeros([div.shape[0], div.shape[1]]) for ii in np.arange(div.shape[0]): for jj in np.arange(div.shape[1]): KK = np.linspace(10 * spec_peak(u_10[ii, jj], fetch), knb, nk) T = Trans_func(KK, K[ii, jj], u_10[ii, jj], fetch, phi1, div[ii, jj]) Bkdir = kudryavtsev05(KK.reshape(nk, 1), u_10[ii, jj], fetch, phi1) * (1 + abs(T.reshape(nk, 1))) n, alpha = param(KK, u_10[ii, jj], fetch) lamda = (Bkdir / alpha.reshape(nk, 1))**(n.reshape(nk, 1) + 1) / ( 2 * KK.reshape(nk, 1) ) # distribution of breaking front lengths lamda_k = np.trapz(lamda, phi1, axis=1) lamda = np.trapz(lamda, KK, axis=0) lamda_k = np.trapz(lamda_k, KK) q[ii, jj] = const.cq * lamda_k Awb = np.trapz(np.cos(phi1 - eq_azi[jj]) * lamda, phi1) / lamda_k WB[ii, jj] = wb0[jj] * (1 + Mwb[jj] * const.theta_wb * Awb) return WB, q
def CPBr_new(kr, K, theta, azimuth, u_10, ind, fetch, divergence): # [Kudryavtsev, 2019] equation A1c nphi = theta.shape[0] eps_sin = np.sqrt(const.epsilon_sw - np.sin(theta)**2) Gvv = np.cos(theta)**2 * (const.epsilon_sw - 1) * ( const.epsilon_sw * (1 + np.sin(theta)**2) - np.sin(theta)**2) / (const.epsilon_sw * np.cos(theta) + eps_sin)**2 Ghh = np.cos(theta)**2 * (const.epsilon_sw - 1) / (np.cos(theta) + eps_sin)**2 G = np.abs(Gvv - Ghh)**2 kbr = 2 * kr * np.sin(theta) sn2 = MSS(kbr, u_10, fetch) Bkdir = np.zeros([u_10.shape[0], u_10.shape[1]]) for ii in np.arange(u_10.shape[0]): for jj in np.arange(u_10.shape[1]): T = Trans_func(kbr, K[ii, jj], u_10[ii, jj], fetch, azimuth, divergence[ii, jj]).reshape(nphi, 1) Bkdir[ii, jj] = (kudryavtsev05(kbr.reshape(nphi, 1), u_10[ii, jj], fetch, azimuth) * (1 + abs(T)))[jj, ind] Brcp = np.pi * G * sn2 * Bkdir / (np.tan(theta)**4 * np.sin(theta)**2) return Brcp
def const_brmo(k, K, kr, theta, azimuth, u_10, fetch, wind_dir, ind_pi, div, polarization): """ :param k: :param kr: :param theta: :param azimuth: :param u_10: :param fetch: :return: """ nk = k.shape[0] # wind direction index ind = np.where(np.degrees(azimuth) == wind_dir)[0] # # Sea surface slope in the direction of incidence angle ni2 = const_ni2_func(kr, k, K, u_10, fetch, azimuth, div, wind_dir) nn = 89 * 2 * np.pi / 180 ni = (np.arange(nk) * nn / nk).reshape(1, nk) - nn / 2 ni = ni.reshape(nk, 1) ni = np.tan(ni) Br = np.zeros([div.shape[0], div.shape[1]]) for ii in np.arange(ni2.shape[0]): for jj in np.arange(ni2.shape[1]): P = np.exp(-0.5 * (ni - np.mean(ni))**2 / ni2[ii, jj]) / np.sqrt( 2 * np.pi * ni2[ii, jj]) # the range of the sea surface slope angle_index = np.logical_and( -3 * 180 * np.arctan(np.sqrt(ni2[ii, jj])) / np.pi < np.arctan(ni) * 180 / np.pi, np.arctan(ni) * 180 / np.pi < 3 * 180 * np.arctan(np.sqrt(ni2[ii, jj])) / np.pi) P = P[angle_index] nini = ni[angle_index] nnk = nini.shape[0] nini = nini.reshape(nnk, 1) # local incidence angle theta_l = np.abs(theta[jj] - np.arctan(nini).reshape(nnk, 1)) kbr = 2 * kr * np.sin(theta_l) # geometric scattering coefficients [Plant 1997] equation 5,6 eps_sin = np.sqrt(const.epsilon_sw - np.sin(theta_l)**2) kkbr = np.sort(kbr[:, 0]) T = Trans_func(kkbr, K[ii, jj], u_10, fetch, azimuth, div[ii, jj])[np.argsort(kbr[:, 0])].reshape(nnk, 1) spec_Skk = kudryavtsev05(kkbr.reshape(nnk, 1), u_10, fetch, azimuth)[np.argsort(kbr[:, 0]), :] * ( 1 + abs(T)) / kbr.reshape(nnk, 1)**4 Skb_r = (spec_Skk[:, ind] + spec_Skk[:, ind_pi]) / 2 if polarization == 'VV': G = np.cos(theta_l)**2 * (const.epsilon_sw - 1) * ( const.epsilon_sw * (1 + np.sin(theta_l)**2) - np.sin(theta_l)**2) / ( const.epsilon_sw * np.cos(theta_l) + eps_sin)**2 G = np.abs(G)**2 else: G = np.cos(theta_l)**2 * (const.epsilon_sw - 1) / (np.cos(theta_l) + eps_sin)**2 G = np.abs(G)**2 # pure Bragg scattering NRCS br0 = 16 * np.pi * kr**4 * G * Skb_r # Bragg scattering composite model BR = br0 * P.reshape(nnk, 1) # integral over kbr >= kd a = np.tan(theta[jj] - const.d / 2) b = np.tan(theta[jj] + const.d / 2) Br[ii, jj] = np.trapz(BR[nini <= a], nini[nini <= a]) + np.trapz( BR[nini >= b], nini[nini >= b]) return Br
def eq_br_cali(k, kr, theta_eq, bist_ang_az, eq_azi, u_10, fetch, polarization): """ all the angles are in radians :param k: :param kr: :param theta: :param azimuth: :param u_10: :param fetch: :param spec_name: :return: """ nk = k.shape[0] kd = const.d * kr # Spectral model # # Sea surface slope in the direction of incidence angle phi_inc = np.linspace( -np.pi, np.pi, 37 * 2) # in radians wave direction relative to the incidence plane Skdir_ni = kudryavtsev05(k.reshape(nk, 1), u_10, fetch, phi_inc) / k.reshape(nk, 1)**4 ni = np.trapz(k.reshape(nk, 1)**3 * np.cos(phi_inc)**2 * Skdir_ni, phi_inc, axis=1) ni2 = np.trapz(ni[k >= kd], k[k >= kd]) nn = 89 * 2 * np.pi / 180 ni = (np.arange(nk) * nn / nk).reshape(1, nk) - nn / 2 ni = ni.reshape(nk, 1) ni = np.tan(ni) P = np.exp(-0.5 * (ni - np.mean(ni))**2 / ni2) / np.sqrt(2 * np.pi * ni2) # the range of the sea surface slope angle_index = np.logical_and( -3 * 180 * np.arctan(np.sqrt(ni2)) / np.pi < np.arctan(ni) * 180 / np.pi, np.arctan(ni) * 180 / np.pi < 3 * 180 * np.arctan(np.sqrt(ni2)) / np.pi) P = P[angle_index] ni = ni[angle_index] nnk = ni.shape[0] ni = ni.reshape(nnk, 1) # local incidence angle theta_l = np.abs(theta_eq - np.arctan(ni).reshape(nnk, 1)) # geometric scattering coefficients [Plant 1997] equation 5,6 eps_sin = np.sqrt(const.epsilon_sw - np.sin(theta_l)**2) if polarization == 'VV': G = np.cos(theta_l)**2 * (const.epsilon_sw - 1) * ( const.epsilon_sw * (1 + np.sin(theta_l)**2) - np.sin(theta_l)**2) / ( const.epsilon_sw * np.cos(theta_l) + eps_sin)**2 G = np.abs(G)**2 else: G = np.cos(theta_l)**2 * (const.epsilon_sw - 1) / (np.cos(theta_l) + eps_sin)**2 G = np.abs(G)**2 # compute the wave number for bistatic geometry kbr = 2 * kr * np.sin(theta_l) * np.cos(bist_ang_az / 2) # sort eq_azi kkbr = np.sort(kbr[:, 0]) spec_Skk1 = B_int_bf(kkbr.reshape(nnk, 1), u_10, fetch, eq_azi)[np.argsort(kbr[:, 0]), :] / kbr.reshape( nnk, 1)**4 spec_Skk2 = B_int_bf( kkbr.reshape(nnk, 1), u_10, fetch, np.pi + eq_azi)[np.argsort(kbr[:, 0]), :] / kbr.reshape(nnk, 1)**4 Skb_r = (spec_Skk1 + spec_Skk2) / 2 # pure Bragg scattering NRCS br0 = 16 * np.pi * kr**4 * G * Skb_r # Bragg scattering composite model BR = br0 * P.reshape(nnk, 1) # integral over kbr >= kd a = np.tan(theta_eq - const.d / (2 * np.cos(bist_ang_az / 2))) b = np.tan(theta_eq + const.d / (2 * np.cos(bist_ang_az / 2))) Br = np.trapz(BR[ni <= a], ni[ni <= a]) + np.trapz(BR[ni >= b], ni[ni >= b]) return Br