## Wave transmission through a Breakwater # Author: AJMR # December 14, 2021 # %% Setup Project from mikeio import Dfs0, Dfs1 from mikeio.eum import ItemInfo, EUMUnit, EUMType import pandas as pd import pathlib as pl import numpy as np import geopandas as gp import math import matplotlib.pyplot as plt import contextily as ctx # %% Read Model Log pth = pl.Path("//srv-mad3.baird.com/", "Projects", "13632.101 South Shore Breakwater", "06_Models", "13632.101.W.AJMR.Rev0_ModelLog.xlsx") runLog = pd.read_excel(pth.as_posix(), "ModelLog") # %% Read in Point Sh breakwaterPTS = gp.read_file("//srv-mad3.baird.com/Projects/" "13632.101 South Shore Breakwater/08_CADD/Outgoing/" "20211211_Toe Extents (to Alexander)/" "20211211_Toe_Extents_NAD83_WISStatePlaneSZn_USFt_Lines_OffshoreClipSimple_10m_vertexUTM.shp") # %% Read in Breakwater crest breakCrest = pd.read_csv( '//srv-mad3.baird.com/Projects/13632.101 South Shore Breakwater/08_CADD/Outgoing/20211214_Crest Points (to Alexander)/20211214_Crest_Points_m.csv', header=None, names=['x', 'y', 'z']) breakCrest_gdf = gp.GeoDataFrame(breakCrest, crs='EPSG:32154', geometry=gp.points_from_xy(breakCrest.x, breakCrest.y)) breakCrest_gdf.to_crs('EPSG:32616', inplace=True) breakwaterPTS_Crest = breakwaterPTS.sjoin_nearest(breakCrest_gdf) breakwaterPTS_Crest.rename(columns={'x': 'breakCrest_x', 'y': 'breakCrest_y', 'z': 'Crest'}, inplace=True) # %% Modify Breakwater Crest to new elevation # From email breakSegments = np.zeros((4, 3)) breakSegments[0, :] = [2534702.7417, 372246.1099, 0] # 6+85 breakSegments[1, :] = [2535059.6902, 371628.1622, 180] # 14+00 breakSegments[2, :] = [2535910.4820, 370655.9834, 181.1] # 27+00 breakSegments[3, :] = [2536821.5682, 369722.4850, 180.5] # 40+05 breakSegments_gdf = gp.GeoDataFrame(breakSegments, geometry=gp.points_from_xy(breakSegments[:, 0], breakSegments[:, 1]), crs='EPSG:8796') breakSegments_gdf.to_crs('EPSG:32616', inplace=True) for idx in range(0, breakwaterPTS_Crest.shape[0]): # Check where point is (based on x coordinate) and assign new crest elevation if breakSegments_gdf.geometry.x[0] <= breakwaterPTS_Crest.geometry.x[idx] <= breakSegments_gdf.geometry.x[1]: breakwaterPTS_Crest.loc[idx, 'Crest'] = breakSegments[1, 2] elif breakSegments_gdf.geometry.x[1] <= breakwaterPTS_Crest.geometry.x[idx] <= breakSegments_gdf.geometry.x[2]: breakwaterPTS_Crest.loc[idx, 'Crest'] = breakSegments[2, 2] elif breakSegments_gdf.geometry.x[2] <= breakwaterPTS_Crest.geometry.x[idx] <= breakSegments_gdf.geometry.x[3]: breakwaterPTS_Crest.loc[idx, 'Crest'] = breakSegments[3, 2] # %% Read Model Results modelPlot = range(31, 32) for m in modelPlot: dfsIN = Dfs0(pl.Path(runLog['Run Location'][m], str(runLog['Number'][m]) + '_' + runLog['Run Name'][m] + '.sw - Result Files', 'BreakPts.dfs0').as_posix()) dfsIN_read = dfsIN.read() MIKEds = dfsIN_read.to_dataframe() # %% Merge with dataframe breakwaterPTS_times = None for t in range(0, MIKEds.shape[0]): breakwaterPTS_merge = None breakwaterPTS_merge = breakwaterPTS_Crest for i in range(0, MIKEds.shape[1]): paramName = MIKEds.columns.values[i][MIKEds.columns.values[i].find('"', 5, -1) + 3:] if paramName not in breakwaterPTS_merge.columns: breakwaterPTS_merge[paramName] = np.full([breakwaterPTS_merge.shape[0], 1], np.nan) # MIKEds_dict[paramName] = [] # MIKEid_dict[paramName] = [] tmpFID = int(MIKEds.columns.values[i][1:MIKEds.columns.values[i].find('"', 1)]) tmpIND = int(MIKEds.columns.values[i][5:MIKEds.columns.values[i].find('"', 5)]) breakwaterPTS_merge.loc[((breakwaterPTS_merge.FID == tmpFID) & (breakwaterPTS_merge.vertex_ind == tmpIND)), paramName] = MIKEds.iloc[t, i] breakwaterPTS_merge['Time'] = MIKEds.index[t] breakwaterPTS_times = pd.concat([breakwaterPTS_times, breakwaterPTS_merge], ignore_index=True) breakwaterPTS_times.rename(columns={'index_right': 'index_right_old'}, inplace=True) # %% Conversion breakwaterPTS_times['transmitted'] = np.full([breakwaterPTS_times.shape[0], 1], np.nan) gamma = 1.2 transmit_paramA = 0.81 * gamma transmit_paramB = 0.45 * gamma - 0.3 * gamma * \ (breakwaterPTS_times['Crest'] - breakwaterPTS_times['Surface elevation']) / \ breakwaterPTS_times['Sign. Wave Height'] # Identify different overtopping regimes breakMask_A = (breakwaterPTS_times['Crest'] - breakwaterPTS_times['Surface elevation']) / \ breakwaterPTS_times['Sign. Wave Height'] >= 1.2 breakMask_B = (((breakwaterPTS_times['Crest'] - breakwaterPTS_times['Surface elevation']) / breakwaterPTS_times['Sign. Wave Height'] < 1.2) & (transmit_paramA < transmit_paramB)) breakMask_C = (((breakwaterPTS_times['Crest'] - breakwaterPTS_times['Surface elevation']) / breakwaterPTS_times['Sign. Wave Height'] < 1.2) & (transmit_paramA > transmit_paramB)) # Updated approach breakwaterPTS_times.loc[breakMask_A, 'transmitted'] = breakwaterPTS_times['Sign. Wave Height'][breakMask_A] * 0.09 * gamma breakwaterPTS_times.loc[breakMask_B, 'transmitted'] = breakwaterPTS_times['Sign. Wave Height'][breakMask_B] *\ transmit_paramA breakwaterPTS_times.loc[breakMask_C, 'transmitted'] = breakwaterPTS_times['Sign. Wave Height'][breakMask_C] * \ transmit_paramB[breakMask_C] # %% Merge with breakwater transformed waves breakwaterPTS_end = breakwaterPTS_times['Time'] == breakwaterPTS_times['Time'].max() # %% Read Inner Boundary Points North # innerBoundNorth = pd.read_csv( # '//srv-mad3.baird.com/Projects/13632.101 South Shore Breakwater/06_Models/02_Mike21SW/InnerBound_North.txt', # delimiter='\s+', header=None, names=['x', 'y']) innerBoundNorth = pd.read_csv( '//srv-mad3.baird.com/Projects/13632.101 South Shore Breakwater/06_Models/02_Mike21SW/InnerBound_Mesh2_North.txt', delimiter='\s+', header=None, names=['node', 'val', 'x', 'y']) innerBoundNorth.sort_values(by=['x'], inplace=True) innerBoundNorth_gdf = gp.GeoDataFrame(innerBoundNorth, crs='EPSG:32616', geometry=gp.points_from_xy(innerBoundNorth.x, innerBoundNorth.y)) innerBoundNorth_gdf = innerBoundNorth_gdf.sjoin_nearest(breakwaterPTS_times.loc[breakwaterPTS_end, :]) # %% Read Inner Boundary Points Mid # innerBoundMid = pd.read_csv( # '//srv-mad3.baird.com/Projects/13632.101 South Shore Breakwater/06_Models/02_Mike21SW/InnerBound_Mid.txt', # delimiter='\s+', header=None, names=['x', 'y']) innerBoundMid = pd.read_csv( '//srv-mad3.baird.com/Projects/13632.101 South Shore Breakwater/06_Models/02_Mike21SW/InnerBound_Mesh2_Mid.txt', delimiter='\s+', header=None, names=['node', 'val', 'x', 'y']) innerBoundMid.sort_values(by=['x'], inplace=True) innerBoundMid_gdf = gp.GeoDataFrame(innerBoundMid, crs='EPSG:32616', geometry=gp.points_from_xy(innerBoundMid.x, innerBoundMid.y)) innerBoundMid_gdf = innerBoundMid_gdf.sjoin_nearest(breakwaterPTS_times.loc[breakwaterPTS_end, :]) # %% Read Inner Boundary Points South innerBoundSouth = pd.read_csv( '//srv-mad3.baird.com/Projects/13632.101 South Shore Breakwater/06_Models/02_Mike21SW/InnerBound_South.txt', delimiter='\s+', header=None, names=['x', 'y']) innerBoundSouth.sort_values(by=['x'], inplace=True) innerBoundSouth_gdf = gp.GeoDataFrame(innerBoundSouth, crs='EPSG:32616', geometry=gp.points_from_xy(innerBoundSouth.x, innerBoundSouth.y)) innerBoundSouth_gdf = innerBoundSouth_gdf.sjoin_nearest(breakwaterPTS_times.loc[breakwaterPTS_end, :]) # %% Save as DFS1 boundDataNorth = pd.DataFrame( innerBoundNorth_gdf.loc[:, ['Time', 'transmitted', 'Peak Wave Period', 'Mean Wave Direction']]) boundDataNorth.set_index('Time', inplace=True) boundDataNorth.rename(columns={'transmitted': 'Significant wave height', 'Peak Wave Period': 'Peak wave period', 'Mean Wave Direction': 'Mean wave direction'}, inplace=True) dfsfilename = '//oak-spillway.baird.com/F/13632.101 South Shore Breakwater/SetupFiles/InnerBounds/' + \ runLog['Run Name'][m] + 'ProdInnerNorth1.dfs1' items = [ItemInfo("Significant wave height", EUMType.Significant_wave_height, EUMUnit.meter), ItemInfo("Peak wave period", EUMType.Wave_period, EUMUnit.second), ItemInfo("Mean wave direction", EUMType.Mean_Wave_Direction, EUMUnit.degree), ItemInfo("Directional Standard Deviation, n", EUMType.Directional_Standard_Deviation, EUMUnit.degree)] dfs = Dfs1() dfs.write(filename=dfsfilename, data=[np.array((boundDataNorth['Significant wave height'], boundDataNorth['Significant wave height'])), np.array((boundDataNorth['Peak wave period'], boundDataNorth['Peak wave period'])), np.array((boundDataNorth['Mean wave direction'], boundDataNorth['Mean wave direction'])), np.ones((2, boundDataNorth.shape[0])) * 23.28], start_time=breakwaterPTS_times['Time'].min(), dt=86400, datetimes=None, items=items, title=None) # %% Save as DFS1- Mid boundDataMid = pd.DataFrame( innerBoundMid_gdf.loc[:, ['Time', 'transmitted', 'Peak Wave Period', 'Mean Wave Direction']]) boundDataMid.set_index('Time', inplace=True) boundDataMid.rename(columns={'transmitted': 'Significant wave height', 'Peak Wave Period': 'Peak wave period', 'Mean Wave Direction': 'Mean wave direction'}, inplace=True) dfsfilename = '//oak-spillway.baird.com/F/13632.101 South Shore Breakwater/SetupFiles/InnerBounds/' + \ runLog['Run Name'][m] + 'ProdInnerMid.dfs1' items = [ItemInfo("Significant wave height", EUMType.Significant_wave_height, EUMUnit.meter), ItemInfo("Peak wave period", EUMType.Wave_period, EUMUnit.second), ItemInfo("Mean wave direction", EUMType.Mean_Wave_Direction, EUMUnit.degree), ItemInfo("Directional Standard Deviation, n", EUMType.Directional_Standard_Deviation, EUMUnit.degree)] dfs = Dfs1() dfs.write(filename=dfsfilename, data=[np.array((boundDataMid['Significant wave height'], boundDataMid['Significant wave height'])), np.array((boundDataMid['Peak wave period'], boundDataMid['Peak wave period'])), np.array((boundDataMid['Mean wave direction'], boundDataMid['Mean wave direction'])), np.ones((2, boundDataMid.shape[0])) * 23.28], start_time=breakwaterPTS_times['Time'].min(), dt=86400, items=items) # %% Save as DFS1- South boundDataSouth = pd.DataFrame( innerBoundSouth_gdf.loc[:, ['Time', 'transmitted', 'Peak Wave Period', 'Mean Wave Direction']]) boundDataSouth.set_index('Time', inplace=True) boundDataSouth.rename(columns={'transmitted': 'Significant wave height', 'Peak Wave Period': 'Peak wave period', 'Mean Wave Direction': 'Mean wave direction'}, inplace=True) dfsfilename = '//oak-spillway.baird.com/F/13632.101 South Shore Breakwater/SetupFiles/InnerBounds/' + \ runLog['Run Name'][m] + 'ProdInnerSouth.dfs1' items = [ItemInfo("Significant wave height", EUMType.Significant_wave_height, EUMUnit.meter), ItemInfo("Peak wave period", EUMType.Wave_period, EUMUnit.second), ItemInfo("Mean wave direction", EUMType.Mean_Wave_Direction, EUMUnit.degree), ItemInfo("Directional Standard Deviation, n", EUMType.Directional_Standard_Deviation, EUMUnit.degree)] dfs = Dfs1() dfs.write(filename=dfsfilename, data=[np.array((boundDataSouth['Significant wave height'], boundDataSouth['Significant wave height'])), np.array((boundDataSouth['Peak wave period'], boundDataSouth['Peak wave period'])), np.array((boundDataSouth['Mean wave direction'], boundDataSouth['Mean wave direction'])), np.ones((2, boundDataSouth.shape[0])) * 23.28], start_time=breakwaterPTS_times['Time'].min(), dt=86400, items=items) # %% Test Plot mapbox = 'https://api.mapbox.com/styles/v1/alexander0042/ckemxgtk51fgp19nybfmdcb1e/tiles/256/{z}/{x}/{y}@2x?access_token=pk.eyJ1IjoiYWxleGFuZGVyMDA0MiIsImEiOiJjazVmdG4zbncwMHY4M2VrcThwZGUzZDFhIn0.w6oDHoo1eCeRlSBpwzwVtw' fig, axes = plt.subplots(nrows=1, ncols=1, figsize=(9, 9), constrained_layout=True) breakwaterPTS_merge.plot(ax=axes, column='Sign. Wave Height', cmap='viridis') # breakwaterPTS_merge.plot(ax=axes, column='Crest', cmap='viridis', legend=True) innerBound_gdf.plot(ax=axes, column='transmitted', cmap='viridis') ctx.add_basemap(axes, source=mapbox, crs='EPSG:32616') plt.show()