def pe(avgfile, grdfile, gridid=None, maskfile='/media/Armadillo/bkp/lado/MSc/work/ROMS/plot_outputs3/msk_shelf.npy', normalize=False, verbose=True): """ USAGE ----- t, pe = pe(avgfile, grdfile, gridid=None, maskfile='/media/Armadillo/bkp/lado/MSc/work/ROMS/plot_outputs3/msk_shelf.npy', normalize=False, verbose=True): Calculates Potential Energy (PE) change integrated within a control volume for each time record of a ROMS *.avg or *.his file. The change is computed relative to the initial conditions, i.e., rhop(x,y,z,t=ti) = rho(x,y,z,t=ti) - rho(x,y,z,t=t0). [-g*(rhop^2)] PE = Integrated in a control volume V [-----------] # [J] [ 2*drhodz ] If 'normalize' is set to 'True', then PE/V (mean PE density [J/m3]) is returned instead. Reference: ---------- Cushman-Roisin (1994): Introduction to Geophysical Fluid Dynamics, page 213, Combination of Equations 15-29 and 15-30. """ print("Loading outputs and grid.") ## Get outputs. avg = Dataset(avgfile) ## Load domain mask. if maskfile: mask = np.load(maskfile) if type(mask[0,0])==np.bool_: pass else: mask=mask==1. ## Getting mask indices. ilon,ilat = np.where(mask) ## Get grid, time-dependent free-surface and topography. zeta = avg.variables['zeta'] grd = pyroms.grid.get_ROMS_grid(gridid, zeta=zeta, hist_file=avgfile, grid_file=grdfile) ## Get time. t = avg.variables['ocean_time'][:] t = t - t[0] nt = t.size ## Get grid coordinates at RHO-points. lonr, latr = avg.variables['lon_rho'][:], avg.variables['lat_rho'][:] ## Get grid spacings at RHO-points. ## Find cell widths. dx = grd.hgrid.dx # Cell width in the XI-direction. dy = grd.hgrid.dy # Cell width in the ETA-direction. if maskfile: dA = dx[mask]*dy[mask] else: dA = dx*dy ## Get temp, salt. temp = avg.variables['temp'] salt = avg.variables['salt'] ## Find cell heights (at ti=0). zw = grd.vgrid.z_w[0,:] # Cell depths (at ti=0). if maskfile: dz = zw[1:,ilat,ilon] - zw[:-1,ilat,ilon] # Cell height. else: dz = zw[1:,:] - zw[:-1,:] dz = 0.5*(dz[1:,:] + dz[:-1,:]) # Cell heights at W-points. ## Get pres, g and pden (at ti=0). p0 = -zw # Approximation, for computational efficiency. p0 = 0.5*(p0[1:,:]+p0[:-1,:]) if maskfile: rho0 = pden(salt[0,:,ilat,ilon],temp[0,:,ilat,ilon],p0[:,ilat,ilon],pr=0.) else: rho0 = pden(salt[0,:],temp[0,:],p0,pr=0.) if maskfile: g = grav(latr[mask]) else: g = grav(latr) drho0 = rho0[1:,:] - rho0[:-1,:] rho0z = drho0/dz # Background potential density vertical gradient. PE = np.array([]) for ti in range(nt): tp = ti + 1 print("Processing time record %s of %s"%(tp,nt)) if maskfile: rhoi = pden(salt[ti,:,ilat,ilon],temp[ti,:,ilat,ilon],p0[:,ilat,ilon],pr=0.) else: rhoi = pden(salt[ti,:],temp[ti,:],p0,pr=0.) rhop = rhoi - rho0 # Density anomaly, i.e., rho(x,y,z,t=ti) - rho(x,y,z,t=0) rhop = 0.5*(rhop[1:,:] + rhop[:-1,:]) ## Find cell heights. zw = grd.vgrid.z_w[ti,:] # Cell depths (at ti=0). if maskfile: dz = zw[1:,ilat,ilon] - zw[:-1,ilat,ilon] # Cell height. else: dz = zw[1:,:] - zw[:-1,:] ## Find cell volumes. print(dx.shape,dy.shape,dz.shape) dV = dA*dz # [m3] dV = 0.5*(dV[1:,:]+dV[:-1,:]) ## Gravitational Available Potential Energy density (energy/volume). print(g.shape) print(rhop.shape) print(rho0z.shape) pe = -g*(rhop**2)/(2*rho0z) # [J/m3] ## Do volume integral to calculate Gravitational Available Potential Energy of the control volume. Pe = np.sum(pe*dV) # [J] if normalize: V = dV.sum() Pe = Pe/V print("") print("Total volume of the control volume is %e m3."%V) print("Normalizing PE by this volume, i.e., mean PE density [J/m3].") print("") if verbose: if normalize: print("PE = %e J/m3"%Pe) else: print("PE = %e J"%Pe) PE = np.append(PE, Pe) return t, PE
def pe(avgfile, grdfile, gridid=None, maskfile='/media/Armadillo/bkp/lado/MSc/work/ROMS/plot_outputs3/msk_shelf.npy', normalize=False, verbose=True): """ USAGE ----- t, pe = pe(avgfile, grdfile, gridid=None, maskfile='/media/Armadillo/bkp/lado/MSc/work/ROMS/plot_outputs3/msk_shelf.npy', normalize=False, verbose=True): Calculates Potential Energy (PE) change integrated within a control volume for each time record of a ROMS *.avg or *.his file. The change is computed relative to the initial conditions, i.e., rhop(x,y,z,t=ti) = rho(x,y,z,t=ti) - rho(x,y,z,t=t0). [-g*(rhop^2)] PE = Integrated in a control volume V [-----------] # [J] [ 2*drhodz ] If 'normalize' is set to 'True', then PE/V (mean PE density [J/m3]) is returned instead. Reference: ---------- Cushman-Roisin (1994): Introduction to Geophysical Fluid Dynamics, page 213, Combination of Equations 15-29 and 15-30. """ print("Loading outputs and grid.") ## Get outputs. avg = Dataset(avgfile) ## Load domain mask. if maskfile: mask = np.load(maskfile) if type(mask[0, 0]) == np.bool_: pass else: mask = mask == 1. ## Getting mask indices. ilon, ilat = np.where(mask) ## Get grid, time-dependent free-surface and topography. zeta = avg.variables['zeta'] grd = pyroms.grid.get_ROMS_grid(gridid, zeta=zeta, hist_file=avgfile, grid_file=grdfile) ## Get time. t = avg.variables['ocean_time'][:] t = t - t[0] nt = t.size ## Get grid coordinates at RHO-points. lonr, latr = avg.variables['lon_rho'][:], avg.variables['lat_rho'][:] ## Get grid spacings at RHO-points. ## Find cell widths. dx = grd.hgrid.dx # Cell width in the XI-direction. dy = grd.hgrid.dy # Cell width in the ETA-direction. if maskfile: dA = dx[mask] * dy[mask] else: dA = dx * dy ## Get temp, salt. temp = avg.variables['temp'] salt = avg.variables['salt'] ## Find cell heights (at ti=0). zw = grd.vgrid.z_w[0, :] # Cell depths (at ti=0). if maskfile: dz = zw[1:, ilat, ilon] - zw[:-1, ilat, ilon] # Cell height. else: dz = zw[1:, :] - zw[:-1, :] dz = 0.5 * (dz[1:, :] + dz[:-1, :]) # Cell heights at W-points. ## Get pres, g and pden (at ti=0). p0 = -zw # Approximation, for computational efficiency. p0 = 0.5 * (p0[1:, :] + p0[:-1, :]) if maskfile: rho0 = pden(salt[0, :, ilat, ilon], temp[0, :, ilat, ilon], p0[:, ilat, ilon], pr=0.) else: rho0 = pden(salt[0, :], temp[0, :], p0, pr=0.) if maskfile: g = grav(latr[mask]) else: g = grav(latr) drho0 = rho0[1:, :] - rho0[:-1, :] rho0z = drho0 / dz # Background potential density vertical gradient. PE = np.array([]) for ti in range(nt): tp = ti + 1 print("Processing time record %s of %s" % (tp, nt)) if maskfile: rhoi = pden(salt[ti, :, ilat, ilon], temp[ti, :, ilat, ilon], p0[:, ilat, ilon], pr=0.) else: rhoi = pden(salt[ti, :], temp[ti, :], p0, pr=0.) rhop = rhoi - rho0 # Density anomaly, i.e., rho(x,y,z,t=ti) - rho(x,y,z,t=0) rhop = 0.5 * (rhop[1:, :] + rhop[:-1, :]) ## Find cell heights. zw = grd.vgrid.z_w[ti, :] # Cell depths (at ti=0). if maskfile: dz = zw[1:, ilat, ilon] - zw[:-1, ilat, ilon] # Cell height. else: dz = zw[1:, :] - zw[:-1, :] ## Find cell volumes. print(dx.shape, dy.shape, dz.shape) dV = dA * dz # [m3] dV = 0.5 * (dV[1:, :] + dV[:-1, :]) ## Gravitational Available Potential Energy density (energy/volume). print(g.shape) print(rhop.shape) print(rho0z.shape) pe = -g * (rhop**2) / (2 * rho0z) # [J/m3] ## Do volume integral to calculate Gravitational Available Potential Energy of the control volume. Pe = np.sum(pe * dV) # [J] if normalize: V = dV.sum() Pe = Pe / V print("") print("Total volume of the control volume is %e m3." % V) print( "Normalizing PE by this volume, i.e., mean PE density [J/m3].") print("") if verbose: if normalize: print("PE = %e J/m3" % Pe) else: print("PE = %e J" % Pe) PE = np.append(PE, Pe) return t, PE
def energy_diagnostics(avgfile, grdfile, rho0=1025., gridid=None, maskfile='msk_shelf.npy', normalize=True, verbose=True): """ USAGE ----- t, HKE, TPE = energy_diagnostics(avgfile, grdfile, rho0=1025., gridid=None, maskfile='msk_shelf.npy', normalize=True, verbose=True) Calculates volume-integrated Horizontal Kinetic Energy (HKE) and Total Potential Energy (TPE) within a control volume for each time record of a ROMS *.avg or *.his file. """ avg = Dataset(avgfile) print("Loading outputs and grid.") ## Load domain mask. if maskfile: mask = np.load(maskfile) if type(mask[0,0])==np.bool_: pass else: mask=mask==1. ## Getting mask indices. ilon,ilat = np.where(mask) ## Getting velocity field. try: U = avg.variables['u'] V = avg.variables['v'] uvrho3 = False except KeyError: U = avg.variables['u_eastward'] V = avg.variables['v_northward'] uvrho3 = True ## Get temp, salt. temp = avg.variables['temp'] salt = avg.variables['salt'] ## Get grid, time-dependent free-surface and topography. zeta = avg.variables['zeta'] grd = pyroms.grid.get_ROMS_grid(gridid, zeta=zeta, hist_file=avgfile, grid_file=grdfile) ## Find cell widths at RHO-points. dx = grd.hgrid.dx # Cell width in the XI-direction. dy = grd.hgrid.dy # Cell width in the ETA-direction. if maskfile: dA = dx[mask]*dy[mask] else: dA = dx*dy ## Get pres, g and pden (at ti=0). p0 = -grd.vgrid.z_r[0,:] # Approximation, for computational efficiency. if maskfile: g = grav(avg.variables['lat_rho'][:][mask]) else: g = grav(avg.variables['lat_rho'][:]) ## Get time. t = avg.variables['ocean_time'][:] t = t - t[0] nt = t.size KE = np.array([]) PE = np.array([]) for ti in range(nt): tp = ti + 1 print("") print("Processing time record %s of %s"%(tp,nt)) print("Calculating density.") if maskfile: rho = pden(salt[ti,:,ilat,ilon],temp[ti,:,ilat,ilon],p0[:,ilat,ilon],pr=0.) else: rho = pden(salt[ti,:],temp[ti,:],p0,pr=0.) print("Loading velocities.") uu = U[ti,:] vv = V[ti,:] if not uvrho3: # Calculate u and v at PSI-points. u = 0.5*(uu[:,1:,:] + uu[:,:-1,:]) v = 0.5*(vv[:,:,1:] + vv[:,:,:-1]) # Calculate rho at PSI-points. rhop = 0.5*(rho[:,1:,:] + rho[:,:-1,:]) rhop = 0.5*(rhop[:,:,1:] + rhop[:,:,:-1]) if maskfile: u = u[:,ilat+1,ilon+1] v = v[:,ilat+1,ilon+1] rhop = rhop[:,ilat+1,ilon+1] else: pass else: # U and V both at RHO-points, no reshaping necessary. if maskfile: u = uu[:,ilat,ilon] v = vv[:,ilat,ilon] else: u = uu v = vv ## Find cell depths, invert z-axis direction (downward). if maskfile: z = -grd.vgrid.z_r[ti,:,ilat,ilon] else: z = -grd.vgrid.z_r[ti,:] ## Find cell heights. zw = grd.vgrid.z_w[ti,:] if maskfile: dz = zw[1:,ilat,ilon] - zw[:-1,ilat,ilon] # Cell height. else: dz = zw[1:,:] - zw[:-1,:] ## Find cell volumes. dV = dA*dz # [m3] print("Squaring velocities.") u2v2 = u*u + v*v ## Total Potential Energy (TPE) density relative to z=0 (energy/volume). pe = rho*g*z # [J/m3] ## Horizontal Kinetic Energy (HKE) density (energy/volume). if not uvrho3: ke = 0.5*rhop*u2v2 # [J/m3] else: ke = 0.5*rho*u2v2 # [J/m3] ## Do volume integral to calculate TPE/HKE of the control volume. Pe = np.sum(pe*dV) # [J] Ke = np.sum(ke*dV) # [J] if normalize: Vol = dV.sum() Pe = Pe/Vol Ke = Ke/Vol if verbose and tp==1: print("") print("Total volume of the control volume is %e m3."%Vol) print("Normalizing TPE/HKE by this volume, i.e., mean TPE/HKE density [J/m3].") print("") if verbose: print("") if normalize: print("TPE/vol = %e J/m3"%Pe) print("HKE/vol = %e J/m3"%Ke) else: print("TPE = %e J"%Pe) print("HKE = %e J"%Ke) PE = np.append(PE, Pe) KE = np.append(KE, Ke) return t, KE, PE
def energy_diagnostics(avgfile, grdfile, rho0=1025., gridid=None, maskfile='msk_shelf.npy', normalize=True, verbose=True): """ USAGE ----- t, HKE, TPE = energy_diagnostics(avgfile, grdfile, rho0=1025., gridid=None, maskfile='msk_shelf.npy', normalize=True, verbose=True) Calculates volume-integrated Horizontal Kinetic Energy (HKE) and Total Potential Energy (TPE) within a control volume for each time record of a ROMS *.avg or *.his file. """ avg = Dataset(avgfile) print("Loading outputs and grid.") ## Load domain mask. if maskfile: mask = np.load(maskfile) if type(mask[0, 0]) == np.bool_: pass else: mask = mask == 1. ## Getting mask indices. ilon, ilat = np.where(mask) ## Getting velocity field. try: U = avg.variables['u'] V = avg.variables['v'] uvrho3 = False except KeyError: U = avg.variables['u_eastward'] V = avg.variables['v_northward'] uvrho3 = True ## Get temp, salt. temp = avg.variables['temp'] salt = avg.variables['salt'] ## Get grid, time-dependent free-surface and topography. zeta = avg.variables['zeta'] grd = pyroms.grid.get_ROMS_grid(gridid, zeta=zeta, hist_file=avgfile, grid_file=grdfile) ## Find cell widths at RHO-points. dx = grd.hgrid.dx # Cell width in the XI-direction. dy = grd.hgrid.dy # Cell width in the ETA-direction. if maskfile: dA = dx[mask] * dy[mask] else: dA = dx * dy ## Get pres, g and pden (at ti=0). p0 = -grd.vgrid.z_r[0, :] # Approximation, for computational efficiency. if maskfile: g = grav(avg.variables['lat_rho'][:][mask]) else: g = grav(avg.variables['lat_rho'][:]) ## Get time. t = avg.variables['ocean_time'][:] t = t - t[0] nt = t.size KE = np.array([]) PE = np.array([]) for ti in range(nt): tp = ti + 1 print("") print("Processing time record %s of %s" % (tp, nt)) print("Calculating density.") if maskfile: rho = pden(salt[ti, :, ilat, ilon], temp[ti, :, ilat, ilon], p0[:, ilat, ilon], pr=0.) else: rho = pden(salt[ti, :], temp[ti, :], p0, pr=0.) print("Loading velocities.") uu = U[ti, :] vv = V[ti, :] if not uvrho3: # Calculate u and v at PSI-points. u = 0.5 * (uu[:, 1:, :] + uu[:, :-1, :]) v = 0.5 * (vv[:, :, 1:] + vv[:, :, :-1]) # Calculate rho at PSI-points. rhop = 0.5 * (rho[:, 1:, :] + rho[:, :-1, :]) rhop = 0.5 * (rhop[:, :, 1:] + rhop[:, :, :-1]) if maskfile: u = u[:, ilat + 1, ilon + 1] v = v[:, ilat + 1, ilon + 1] rhop = rhop[:, ilat + 1, ilon + 1] else: pass else: # U and V both at RHO-points, no reshaping necessary. if maskfile: u = uu[:, ilat, ilon] v = vv[:, ilat, ilon] else: u = uu v = vv ## Find cell depths, invert z-axis direction (downward). if maskfile: z = -grd.vgrid.z_r[ti, :, ilat, ilon] else: z = -grd.vgrid.z_r[ti, :] ## Find cell heights. zw = grd.vgrid.z_w[ti, :] if maskfile: dz = zw[1:, ilat, ilon] - zw[:-1, ilat, ilon] # Cell height. else: dz = zw[1:, :] - zw[:-1, :] ## Find cell volumes. dV = dA * dz # [m3] print("Squaring velocities.") u2v2 = u * u + v * v ## Total Potential Energy (TPE) density relative to z=0 (energy/volume). pe = rho * g * z # [J/m3] ## Horizontal Kinetic Energy (HKE) density (energy/volume). if not uvrho3: ke = 0.5 * rhop * u2v2 # [J/m3] else: ke = 0.5 * rho * u2v2 # [J/m3] ## Do volume integral to calculate TPE/HKE of the control volume. Pe = np.sum(pe * dV) # [J] Ke = np.sum(ke * dV) # [J] if normalize: Vol = dV.sum() Pe = Pe / Vol Ke = Ke / Vol if verbose and tp == 1: print("") print("Total volume of the control volume is %e m3." % Vol) print( "Normalizing TPE/HKE by this volume, i.e., mean TPE/HKE density [J/m3]." ) print("") if verbose: print("") if normalize: print("TPE/vol = %e J/m3" % Pe) print("HKE/vol = %e J/m3" % Ke) else: print("TPE = %e J" % Pe) print("HKE = %e J" % Ke) PE = np.append(PE, Pe) KE = np.append(KE, Ke) return t, KE, PE