def __init__(self, grid, X, Y): self.grid = grid # Vertices, in subgrid coordinates self.X = X - grid.i0 self.Y = Y - grid.j0 # Nodes self.Xm = 0.5*(self.X[:-1] + self.X[1:]) self.Ym = 0.5*(self.Y[:-1] + self.Y[1:]) # Section size self.nseg = len(self.Xm) # Number of segments = Number of nodes self.N = len(self.grid.Cs_r) # Compatible with both SGrid and grdClass try: self.h = sample2D(self.grid.h, self.Xm, self.Ym, mask=self.grid.mask_rho, undef_value=0.0) except AttributeError: self.h = sample2D(self.grid.depth, self.Xm, self.Ym) pm = sample2D(self.grid.pm, self.Xm, self.Ym) pn = sample2D(self.grid.pn, self.Xm, self.Ym) # Unit normal vector (nx, ny) # Sjekk om dette er korrekt hvis pm og pn er ulike dX = (X[1:]-X[:-1]) / pm dY = (Y[1:]-Y[:-1]) / pn # Length of segments # Kan kanskje forbedres med sfærisk avstand self.dS = np.sqrt(dX*dX+dY*dY) # Cumulative distance (at vertices)s self.S = np.concatenate(([0], np.add.accumulate(self.dS))) nx, ny = dY, -dX norm = np.sqrt(nx*nx + ny*ny) self.nx, self.ny = nx/norm, ny/norm # Vertical structure self.z_r = sdepth(self.h, self.grid.hc, self.grid.Cs_r, stagger='rho', Vtransform=self.grid.Vtransform) self.z_w = sdepth(self.h, self.grid.hc, self.grid.Cs_w, stagger='w', Vtransform=self.grid.Vtransform) self.dZ = self.z_w[1:,:]-self.z_w[:-1,:] self.Area = self.dZ * self.dS
def __init__(self, grid, X, Y): self.grid = grid # Vertices, in subgrid coordinates self.X = X self.Y = Y # Section size self.L = len(self.X) # Number of nodes self.N = len(self.grid.Cs_r) # Topography self.h = sample2D(self.grid.h, self.X, self.Y, mask=self.grid.mask_rho, undef_value=1.0) # Metric pm = sample2D(self.grid.pm, self.X, self.Y) pn = sample2D(self.grid.pn, self.X, self.Y) dX = 2 * (X[1:]-X[:-1]) / (pm[:-1] + pm[1:]) # unit = meter dY = 2 * (Y[1:]-Y[:-1]) / (pn[:-1] + pn[1:]) # Assume spacing is close enough to approximate distance self.dS = np.sqrt(dX*dX+dY*dY) # Cumulative distance self.S = np.concatenate(([0], np.add.accumulate(self.dS))) # Weights for trapez integration (linear interpolation) self.W = 0.5*np.concatenate(([self.dS[0]], self.dS[:-1] + self.dS[1:], [self.dS[-1]])) #nx, ny = dY, -dX #norm = np.sqrt(nx*nx + ny*ny) #self.nx, self.ny = nx/norm, ny/norm # Vertical structure self.z_r = sdepth(self.h, self.grid.hc, self.grid.Cs_r, stagger='rho', Vtransform=self.grid.Vtransform) self.z_w = sdepth(self.h, self.grid.hc, self.grid.Cs_w, stagger='w', Vtransform=self.grid.Vtransform) self.dZ = self.z_w[1:, :]-self.z_w[:-1, :] self.Area = self.dZ * self.W
def z_w(self): if self.vertical: return sdepth(self.h, self.hc, self.Cs_w, stagger='w', Vtransform=self.Vtransform)
def z_r(self): if self.vertical: return sdepth(self.h, self.hc, self.Cs_r, stagger='rho', Vtransform=self.Vtransform)
def __init__(self, ncid, subgrid=None, Vinfo=None): # ---------------------------------- # Handle the vertical discretization # ---------------------------------- if Vinfo: self.N = Vinfo['N'] self.hc = Vinfo['hc'] # Trengs ikke utenfor her if Vinfo.has_key('Vstretching'): self.Vstretching = Vinfo['Vstretching'] else: self.Vstretching = 1 if Vinfo.has_key('Vtransform'): # Denne trenger self self.Vtransform = Vinfo['Vtransform'] else: self.Vtransform = 1 self.Cs_r = s_stretch(self.N, Vinfo['theta_s'], Vinfo['theta_b'], stagger='rho', Vstretching=self.Vstretching) self.Cs_w = s_stretch(self.N, Vinfo['theta_s'], Vinfo['theta_b'], stagger='w', Vstretching=self.Vstretching) else: # Read vertical info from the file self.hc = ncid.variables['hc'].getValue() self.Cs_r = ncid.variables['Cs_r'][:] self.Cs_w = ncid.variables['Cs_w'][:] # Vertical grid size self.N = len(self.Cs_r) # Vertical transform self.Vtransform = 1 # Default try: # Look for standard_name attribute of variable s_rho v = ncid.variables['s_rho'] if v.standard_name[-1] == '2': self.Vtransform = 2 # No variable s_rho or no standard_name attribute except (KeyError, RuntimeError): pass # keep default Vtransform = 1 # --------------------- # Subgrid specification # --------------------- Mp, Lp = ncid.variables['h'].shape if subgrid: i0 = subgrid[0] i1 = subgrid[1] j0 = subgrid[2] j1 = subgrid[3] if i0 < 0: i0 += Lp if i1 < 0: i1 += Lp if j0 < 0: j0 += Mp if j1 < 0: j1 += Mp # should have test 0 <= i0 < i1 = Lp # should have test 0 <= j0 < j1 = Mp #self.Lp = self.i1 - self.i0 #elf.Mp = self.j1 - self.j0 self.i0, self.i1 = i0, i1 self.j0, self.j1 = j0, j1 else: self.i0, self.i1 = 0, Lp self.j0, self.j1 = 0, Mp # Shape self.shape = (self.j1-self.j0, self.i1-self.i0) # Slices self.I = slice(self.i0, self.i1) self.J = slice(self.j0, self.j1) # U and V-points i0_u = max(0, self.i0-1) i1_u = min(self.i1, Lp-1) j0_v = max(0, self.j0-1) j1_v = min(self.j1, Mp-1) self.i0_u = i0_u self.j0_v = j0_v self.Iu = slice(i0_u, i1_u) self.Ju = self.J self.Iv = self.I self.Jv = slice(j0_v, j1_v) # --------------- # Coordinates # --------------- # Limits self.xmin = float(self.i0) self.xmax = float(self.i1 - 1) self.ymin = float(self.j0) self.ymax = float(self.j1 - 1) # Grid cell centers self.X = np.arange(self.i0, self.i1) self.Y = np.arange(self.j0, self.j1) # U points #self.Xu = np.arange(self.i0_u, self.i1_u) #self.Yu = self.Y # V points #self.Xv = self.X #self.Yv = np.arange(self.j0_v, self.j1_v) # Grid cell boundaries = psi-points self.Xb = np.arange(self.i0-0.5, self.i1) self.Yb = np.arange(self.j0-0.5, self.j1) # Read variables from the NetCDF file self.h = ncid.variables['h'][self.J, self.I] # mask_rho should not be masked self.mask_rho = np.array(ncid.variables['mask_rho'][self.J, self.I]) try: self.pm = ncid.variables['pm'][self.J, self.I] self.pn = ncid.variables['pn'][self.J, self.I] except KeyError: pass try: self.lon_rho = ncid.variables['lon_rho'][self.J, self.I] self.lat_rho = ncid.variables['lat_rho'][self.J, self.I] except KeyError: pass try: self.angle = ncid.variables['angle'][self.J, self.I] self.f = ncid.variables['f'][self.J, self.I] except KeyError: pass # --------------------- # 3D depth structure # --------------------- self.z_r = sdepth(self.h, self.hc, self.Cs_r, stagger='rho', Vtransform=self.Vtransform) self.z_w = sdepth(self.h, self.hc, self.Cs_w, stagger='w', Vtransform=self.Vtransform)