From 14ffd7d324496a66cc3d88dfd8b2b1b5ff765ba6 Mon Sep 17 00:00:00 2001 From: thopri <thopri@noc.ac.uk> Date: Thu, 2 Apr 2020 14:52:59 +0100 Subject: [PATCH] updated fes tide code --- inputs/namelist_remote.bdy | 9 ++-- pynemo/profile.py | 10 ++-- pynemo/tide/fes_extract_HC.py | 98 +++++++++++++++++++++++------------ pynemo/tide/nemo_bdy_tide3.py | 52 +++++++++++++------ 4 files changed, 113 insertions(+), 56 deletions(-) diff --git a/inputs/namelist_remote.bdy b/inputs/namelist_remote.bdy index 9eeb1b6..97a61de 100644 --- a/inputs/namelist_remote.bdy +++ b/inputs/namelist_remote.bdy @@ -83,9 +83,12 @@ nn_month_end = 11 ! month end (default = 12 is years>1) sn_dst_calendar = 'gregorian' ! output calendar format nn_base_year = 1960 ! base year for time counter - sn_tide_grid = './src_data/tide/grid_tpxo7.2.nc' - sn_tide_h = './src_data/tide/h_tpxo7.2.nc' - sn_tide_u = './src_data/tide/u_tpxo7.2.nc' + ! TPXO file locations + sn_tide_grid = '/Users/thopri/Projects/PyNEMO/DATA/TPXO/grid_tpxo7.2.nc' + sn_tide_h = '/Users/thopri/Projects/PyNEMO/DATA/TPXO/h_tpxo7.2.nc' + sn_tide_u = './Users/thopri/Projects/PyNEMO/DATA/TPXO/u_tpxo7.2.nc' + ! location of FES data + sn_tide_fes = '/Users/thopri/Projects/PyNEMO/DATA/FES/' !------------------------------------------------------------------------------ ! Additional parameters diff --git a/pynemo/profile.py b/pynemo/profile.py index a172225..83061b0 100644 --- a/pynemo/profile.py +++ b/pynemo/profile.py @@ -438,13 +438,15 @@ def process_bdy(setup_filepath=0, mask_gui=False): if settings['tide']: if settings['tide_model']=='tpxo': - cons = tide.nemo_bdy_tpx7p2_rot( + cons = tide.nemo_bdy_tide_rot( Setup, DstCoord, bdy_ind['t'], bdy_ind['u'], bdy_ind['v'], - settings['clname']) + settings['clname'], settings['tide_model']) elif settings['tide_model']=='fes': - logger.error('Tidal model: %s, not yet implimented', + cons = tide.nemo_bdy_tide_rot( + Setup, DstCoord, bdy_ind['t'], bdy_ind['u'], bdy_ind['v'], + settings['clname'],settings['tide_model']) + logger.warning('Tidal model: %s, not yet properly implimented', settings['tide_model']) - return else: logger.error('Tidal model: %s, not recognised', settings['tide_model']) diff --git a/pynemo/tide/fes_extract_HC.py b/pynemo/tide/fes_extract_HC.py index 7403781..747e043 100644 --- a/pynemo/tide/fes_extract_HC.py +++ b/pynemo/tide/fes_extract_HC.py @@ -12,8 +12,8 @@ from netCDF4 import Dataset from scipy import interpolate import numpy as np -class FESExtract(object): - """ This is TPXO model extract_hc.c implementation in python""" +class FesExtract(object): + """ This is FES model extract_hc.c implementation in python adapted from tpxo_extract_HC.py""" def __init__(self, settings, lat, lon, grid_type): """initialises the Extract of tide information from the netcdf Tidal files""" @@ -21,37 +21,69 @@ class FESExtract(object): tide_model = 'fes' if tide_model == 'fes': # Define stuff to generalise Tide model - hRe_name = 'hRe' - hIm_name = 'hIm' - lon_z_name = 'lon_z' - lat_z_name = 'lat_z' - URe_name = 'URe' - UIm_name = 'UIm' - lon_u_name = 'lon_u' - lat_u_name = 'lat_u' - VRe_name = 'VRe' - VIm_name = 'VIm' - lon_v_name = 'lon_v' - lat_v_name = 'lat_v' - mz_name = 'mz' - mu_name = 'mu' - mv_name = 'mv' - self.grid = Dataset(settings['tide_grid'])#../data/tide/grid_tpxo7.2.nc') - #read the height_dataset file - self.height_dataset = Dataset(settings['tide_h'])#../data/tide/h_tpxo7.2.nc') - #read the velocity_dataset file - self.velocity_dataset = Dataset(settings['tide_u'])#../data/tide/u_tpxo7.2.nc') - - height_z = self.grid.variables['hz'] - mask_z = self.grid.variables['mz'] - lon_z = self.height_dataset.variables[lon_z_name][:, 0] - lat_z = self.height_dataset.variables[lat_z_name][0, :] - lon_resolution = lon_z[1] - lon_z[0] - data_in_km = 0 # added to maintain the reference to matlab tmd code - # Pull out the constituents that are avaibable - self.cons = [] - for ncon in range(self.height_dataset.variables['con'].shape[0]): - self.cons.append(self.height_dataset.variables['con'][ncon, :].tostring().strip()) + + hRe_name = 'hRe' + hIm_name = 'hIm' + lon_z_name = 'lon' + lat_z_name = 'lat' + URe_name = 'URe' + UIm_name = 'UIm' + lon_u_name = 'lon' + lat_u_name = 'lat' + VRe_name = 'VRe' + VIm_name = 'VIm' + lon_v_name = 'lon' + lat_v_name = 'lat' + mz_name = 'mz' + mu_name = 'mu' + mv_name = 'mv' + + #constituents = ['2N2', 'EPS2', 'J1', 'K1', 'K2', 'L2', 'LA2', 'M2', 'M3', 'M4', 'M6', 'M8', 'MF', 'MKS2', + #'MM', 'MN4', 'MS4', 'MSF', 'MSQM', 'MTM', 'MU2', 'N2', 'N4', 'NU2', 'O1', 'P1', 'Q1', 'R2', + #'S1', 'S2', 'S4', 'SA', 'SSA', 'T2'] + constituents = ['M2','S2'] + + # extract lon and lat z data + lon_z = Dataset[settings['tide_fes']+constituents[0]+'_Z.nc'].variables['lon'] + lat_z = Dataset[settings['tide_fes']+constituents[0]+'_Z.nc'].variabels['lat'] + lon_resolution = lon_z[1] - lon_z[0] + data_in_km = 0 # added to maintain the reference to matlab tmd code + self.cons = constituents + + #read and convert the height_dataset file to complex + for ncon in constituents: + amp = Dataset(settings['tide_fes']+constituents[ncon]+'_Z.nc').variables['amplitude'][:] + phase = Dataset(settings['tide_fes']+constituents[ncon]+'_Z.nc').variables['phase'][:] + hRe = amp*np.sin(phase) + hIm = amp*np.cos(phase) + self.height_dataset = {'hRe':hRe,'hIm':hIm} + + #read and convert the velocity_dataset files to complex + for ncon in constituents: + amp = Dataset(settings['tide_fes']+constituents[ncon]+'_U.nc').variables['Ua'][:] + phase = Dataset(settings['tide_fes']+constituents[ncon]+'_U.nc').variables['Ug'][:] + URe = amp*np.sin(phase) + UIm = amp*np.cos(phase) + self.Uvelocity_dataset = {'URe':URe,'UIm':UIm} + + for ncon in constituents: + amp = Dataset(settings['tide_fes']+constituents[ncon]+'_V.nc').variables['Va'][:] + phase = Dataset(settings['tide_fes']+constituents[ncon]+'_V.nc').variables['Vg'][:] + VRe = amp*np.sin(phase) + VIm = amp*np.cos(phase) + self.Vvelocity_dataset = {'VRe':VRe,'VIm':VIm} + + # extract example amplitude grid and change NaNs to 0 (for land) and other values to 1 (for water) + mask_z = Dataset(settings['tide_fes']+constituents[ncon]+'_Z.nc').variables['amplitude'][:] + where_are_NaNs = np.isnan(mask_z) + where_no_NaNs = np.invert(np.isnan(mask_z)) + mask_z[where_no_NaNs] = 1 + mask_z[where_are_NaNs] = 0 + + # need to sort for FES + self.grid = Dataset(settings['tide_grid'])#../data/tide/grid_tpxo7.2.nc') + height_z = self.grid.variables['hz'] + else: print('Don''t know that tide model') diff --git a/pynemo/tide/nemo_bdy_tide3.py b/pynemo/tide/nemo_bdy_tide3.py index 7c9a148..4aa9222 100644 --- a/pynemo/tide/nemo_bdy_tide3.py +++ b/pynemo/tide/nemo_bdy_tide3.py @@ -8,6 +8,7 @@ Module to extract constituents for the input grid mapped onto output grid # pylint: disable=no-name-in-module import copy from . import tpxo_extract_HC +from . import fes_extract_HC import numpy as np from netCDF4 import Dataset from pynemo import nemo_bdy_grid_angle @@ -16,8 +17,8 @@ from pynemo.reader.factory import GetFile import logging -def nemo_bdy_tpx7p2_rot(setup, DstCoord, Grid_T, Grid_U, Grid_V, comp): - """ TPXO Global Tidal model interpolation including rotation grid""" +def nemo_bdy_tide_rot(setup, DstCoord, Grid_T, Grid_U, Grid_V, comp,tide_model): + """ Global Tidal model interpolation including rotation grid""" key_transport = 0 # compute the velocities from transport numharm = len(comp) logger = logging.getLogger(__name__) @@ -52,16 +53,25 @@ def nemo_bdy_tpx7p2_rot(setup, DstCoord, Grid_T, Grid_U, Grid_V, comp): #convert the U-longitudes into the TMD conventions (0/360E) dst_lon[dst_lon < 0.0] = dst_lon[dst_lon < 0.0]+360.0 + if tide_model == 'tpxo': + tpxo_ux = tpxo_extract_HC.TpxoExtract(setup.settings, dst_lat, dst_lon, Grid_U.grid_type) + tpxo_vx = tpxo_extract_HC.TpxoExtract(setup.settings, dst_lat, dst_lon, Grid_V.grid_type) - tpxo_ux = tpxo_extract_HC.TpxoExtract(setup.settings, dst_lat, dst_lon, Grid_U.grid_type) - tpxo_vx = tpxo_extract_HC.TpxoExtract(setup.settings, dst_lat, dst_lon, Grid_V.grid_type) + ampuX = tpxo_ux.amp + phauX = tpxo_ux.gph + ampvX = tpxo_vx.amp + phavX = tpxo_vx.gph - ampuX = tpxo_ux.amp - phauX = tpxo_ux.gph - ampvX = tpxo_vx.amp - phavX = tpxo_vx.gph + if tide_model == 'fes': + fes_uy = fes_extract_HC.FesExtract(setup.settings, dst_lat, dst_lon, Grid_U.grid_type) + fes_vy = fes_extract_HC.FesExtract(setup.settings, dst_lat, dst_lon, Grid_V.grid_type) - #check if ux data are missing + ampuY = fes_uy.amp + phauY = fes_uy.gph + ampvY = fes_vy.amp + phavY = fes_vy.gph + + #check if ux data are missing ind = np.where((np.isnan(ampuX)) | (np.isnan(phauX))) if ind[0].size > 0: logger.warning('Missing zonal velocity along the x open boundary') @@ -83,13 +93,23 @@ def nemo_bdy_tpx7p2_rot(setup, DstCoord, Grid_T, Grid_U, Grid_V, comp): #convert the U-longitudes into the TMD conventions (0/360E) dst_lon[dst_lon < 0.0] = dst_lon[dst_lon < 0.0]+360.0 - tpxo_uy = tpxo_extract_HC.TpxoExtract(setup.settings, dst_lat, dst_lon, Grid_U.grid_type) - tpxo_vy = tpxo_extract_HC.TpxoExtract(setup.settings, dst_lat, dst_lon, Grid_V.grid_type) - - ampuY = tpxo_uy.amp - phauY = tpxo_uy.gph - ampvY = tpxo_vy.amp - phavY = tpxo_vy.gph + if tide_model == 'tpxo': + tpxo_uy = tpxo_extract_HC.TpxoExtract(setup.settings, dst_lat, dst_lon, Grid_U.grid_type) + tpxo_vy = tpxo_extract_HC.TpxoExtract(setup.settings, dst_lat, dst_lon, Grid_V.grid_type) + + ampuY = tpxo_uy.amp + phauY = tpxo_uy.gph + ampvY = tpxo_vy.amp + phavY = tpxo_vy.gph + + if tide_model == 'fes': + fes_uy = fes_extract_HC.FesExtract(setup.settings, dst_lat, dst_lon, Grid_U.grid_type) + fes_vy = fes_extract_HC.FesExtract(setup.settings, dst_lat, dst_lon, Grid_V.grid_type) + + ampuY = fes_uy.amp + phauY = fes_uy.gph + ampvY = fes_vy.amp + phavY = fes_vy.gph #check if ux data are missing ind = np.where((np.isnan(ampuY)) | (np.isnan(phauY))) -- GitLab