diff --git a/pyschism/forcing/tides/hamtide.py b/pyschism/forcing/tides/hamtide.py index 020366b4..38eab8ea 100644 --- a/pyschism/forcing/tides/hamtide.py +++ b/pyschism/forcing/tides/hamtide.py @@ -95,12 +95,22 @@ def _get_interpolation(self, phys_var, ncvar, constituent, vertices): yi = yi.flatten() zi = self._get_resource( phys_var, constituent)[ncvar][yidx, xidx].flatten() - return griddata( - (xi[~zi.mask], yi[~zi.mask]), - zi[~zi.mask], - (xq, yq), - method='nearest' + values = griddata( + (xi[~zi.mask], yi[~zi.mask]), + zi[~zi.mask], + (xq, yq), + method='linear', + fill_value=np.nan + ) + nan_idxs = np.where(np.isnan(values)) + values[nan_idxs] = griddata( + (xi[~zi.mask], yi[~zi.mask]), + zi[~zi.mask], + (xq[nan_idxs], yq[nan_idxs]), + method='nearest', ) + return values + @property def resource(self): diff --git a/pyschism/forcing/tides/tpxo.py b/pyschism/forcing/tides/tpxo.py index e9d06970..0583d226 100644 --- a/pyschism/forcing/tides/tpxo.py +++ b/pyschism/forcing/tides/tpxo.py @@ -49,11 +49,11 @@ def get_velocity(self, constituent, vertices): logger.info('Querying TPXO for velocity constituent ' f'{constituent}.') uamp = self._get_interpolation( - 'velocity', 'ua', constituent, vertices) + 'velocity', 'ua', constituent, vertices) / 100. uphase = self._get_interpolation( 'velocity', 'up', constituent, vertices) vamp = self._get_interpolation( - 'velocity', 'va', constituent, vertices) + 'velocity', 'va', constituent, vertices) / 100. vphase = self._get_interpolation( 'velocity', 'vp', constituent, vertices) return uamp, uphase, vamp, vphase @@ -132,9 +132,18 @@ def _get_interpolation(self, phys_var, ncvar, constituent, vertices): ) # "method" can be 'spline' or any string accepted by griddata()'s method kwarg. - return griddata( + values = griddata( (x[_idx], y[_idx]), array[_idx], (_x, _y), - method='nearest' + method='linear', + fill_value=np.nan, ) + nan_idxs = np.where(np.isnan(values)) + values[nan_idxs] = griddata( + (x[_idx], y[_idx]), + array[_idx], + (_x[nan_idxs], _y[nan_idxs]), + method='nearest', + ) + return values diff --git a/pyschism/mesh/base.py b/pyschism/mesh/base.py index 00fccba7..6b50b40e 100644 --- a/pyschism/mesh/base.py +++ b/pyschism/mesh/base.py @@ -43,6 +43,7 @@ def __init__(self, nodes: Dict[Hashable, List[List]], crs=None): triangles or quads. """ + for coords, _ in nodes.values(): if len(coords) != 2: raise ValueError( @@ -53,7 +54,7 @@ def __init__(self, nodes: Dict[Hashable, List[List]], crs=None): self._coords = np.array( [coords for coords, _ in nodes.values()]) self._crs = CRS.from_user_input(crs) if crs is not None else crs - self.values = np.array( + self._values = np.array( [value for _, value in nodes.values()]) def transform_to(self, dst_crs): @@ -103,6 +104,10 @@ def index(self): def crs(self): return self._crs + @property + def values(self): + return self._values + @property def coords(self): return self._coords @@ -410,6 +415,7 @@ def __init__(self, nodes, elements=None, description=None, crs=None): self.nodes = Nodes(nodes, crs) self.elements = Elements(self.nodes, elements) self.description = '' if description is None else str(description) + self.hull = Hull(self) def __str__(self): return grd.to_string(**self.to_dict()) @@ -594,12 +600,6 @@ def x(self): def y(self): return self.nodes.coord[:, 1] - @property - def hull(self): - if not hasattr(self, '_hull'): - self._hull = Hull(self) - return self._hull - @property def triangles(self): return self.elements.triangles diff --git a/pyschism/mesh/fgrid.py b/pyschism/mesh/fgrid.py index 97a6b69a..c6e684ae 100644 --- a/pyschism/mesh/fgrid.py +++ b/pyschism/mesh/fgrid.py @@ -48,13 +48,16 @@ def nchi(self): def fname(self): return self._fname.value - @staticmethod - def open(file: Union[str, os.PathLike], + @classmethod + def open(cls, file: Union[str, os.PathLike], crs: Union[str, CRS] = None): filename = pathlib.Path(file).name - return FrictionDispatch[ - FrictionFilename(filename).name].value( - **grd.read(pathlib.Path(file), boundaries=False, crs=crs)) + if cls.__name__ == "Fgrid": + return FrictionDispatch[ + FrictionFilename(filename).name].value( + **grd.read(pathlib.Path(file), boundaries=False, crs=crs)) + else: + return super().open(file, crs) @classmethod def constant(cls, hgrid, value): @@ -66,7 +69,8 @@ def constant(cls, hgrid, value): def add_region( self, region: Union[Polygon, MultiPolygon], - value: float = 0.02): + value + ): # Assuming input polygons are in EPSG:4326 if isinstance(region, Polygon): region = [region] @@ -89,11 +93,6 @@ def __init__(self, *argv, **kwargs): self.hmin_man = 1. super().__init__(NchiType.MANNINGS_N, *argv, **kwargs) - @classmethod - def open(cls, file: Union[str, os.PathLike], - crs: Union[str, CRS] = None): - return super(Fgrid, cls).open(file, crs) - @classmethod def linear_with_depth( cls, @@ -131,11 +130,6 @@ class RoughnessLength(Fgrid): def __init__(self, *argv, **kwargs): super().__init__(NchiType.ROUGHNESS_LENGTH, *argv, **kwargs) - @classmethod - def open(cls, file: Union[str, os.PathLike], - crs: Union[str, CRS] = None): - return super(Fgrid, cls).open(file, crs) - class DragCoefficient(Fgrid): @@ -144,11 +138,6 @@ def __init__(self, *argv, **kwargs): self.dzb_decay = 0. super().__init__(NchiType.DRAG_COEFFICIENT, *argv, **kwargs) - @classmethod - def open(cls, file: Union[str, os.PathLike], - crs: Union[str, CRS] = None): - return super(Fgrid, cls).open(file, crs) - class FrictionDispatch(Enum): MANNINGS_N = ManningsN