@@ -2031,3 +2031,107 @@ def actualize_grid_info(
20312031 )
20322032
20332033 return ds_GFD_calc_info
2034+
2035+ def GS_windsetup_reconstruction_nc (
2036+ greensurge_dataset ,
2037+ ds_gfd_metadata : xr .Dataset ,
2038+ wind_direction_input : xr .Dataset ,
2039+ velocity_thresholds : np .ndarray = np .array ([0 , 100 , 100 ]),
2040+ drag_coefficients : np .ndarray = np .array ([0.00063 , 0.00723 , 0.00723 ]),
2041+ ) -> xr .Dataset :
2042+ """
2043+ Reconstructs the GreenSurge wind setup using the provided wind direction input and metadata.
2044+
2045+ Parameters
2046+ ----------
2047+ greensurge_dataset : xr.Dataset
2048+ xarray Dataset containing the GreenSurge mesh and forcing data.
2049+ ds_gfd_metadata: xr.Dataset
2050+ xarray Dataset containing metadata for the GFD mesh.
2051+ wind_direction_input: xr.Dataset
2052+ xarray Dataset containing wind direction and speed data.
2053+ velocity_thresholds : np.ndarray
2054+ Array of velocity thresholds for drag coefficient calculation.
2055+ drag_coefficients : np.ndarray
2056+ Array of drag coefficients corresponding to the velocity thresholds.
2057+
2058+ Returns
2059+ -------
2060+ xr.Dataset
2061+ xarray Dataset containing the reconstructed wind setup.
2062+ """
2063+
2064+ velocity_thresholds = np .asarray (velocity_thresholds )
2065+ drag_coefficients = np .asarray (drag_coefficients )
2066+
2067+ direction_bins = ds_gfd_metadata .wind_directions .values
2068+ forcing_cell_indices = ds_gfd_metadata .element_forcing_index .values
2069+ wind_speed_reference = ds_gfd_metadata .wind_speed .values .item ()
2070+ base_drag_coeff = GS_LinearWindDragCoef (
2071+ wind_speed_reference , drag_coefficients , velocity_thresholds
2072+ )
2073+ time_step_hours = ds_gfd_metadata .time_step_hours .values
2074+
2075+ time_start = wind_direction_input .time .values .min ()
2076+ time_end = wind_direction_input .time .values .max ()
2077+ duration_in_steps = (
2078+ int ((ds_gfd_metadata .simulation_duration_hours .values ) / time_step_hours ) + 1
2079+ )
2080+ output_time_vector = np .arange (
2081+ time_start , time_end , np .timedelta64 (int (60 * time_step_hours .item ()), "m" )
2082+ )
2083+ num_output_times = len (output_time_vector )
2084+
2085+ direction_data = wind_direction_input .Dir .values
2086+ wind_speed_data = wind_direction_input .W .values
2087+
2088+ ds_ex = xr .open_dataset (f"{ greensurge_dataset } /GF_T_0_D_0/dflowfmoutput/GreenSurge_GFDcase_map.nc" )
2089+
2090+ n_faces = ds_ex ["mesh2d_s1" ].shape
2091+
2092+ wind_setup_output = np .zeros ((num_output_times , n_faces [1 ]))
2093+ water_level_accumulator = np .zeros (n_faces )
2094+
2095+ for time_index in tqdm (range (num_output_times ), desc = "Processing time steps" ):
2096+ water_level_accumulator [:] = 0
2097+ for cell_index in forcing_cell_indices .astype (int ):
2098+ current_dir = direction_data [cell_index , time_index ] % 360
2099+ adjusted_bins = np .where (direction_bins == 0 , 360 , direction_bins )
2100+ closest_direction_index = np .abs (adjusted_bins - current_dir ).argmin ()
2101+
2102+ water_level_case = xr .open_dataset (
2103+ f"{ greensurge_dataset } /GF_T_{ cell_index } _D_{ closest_direction_index } /dflowfmoutput/GreenSurge_GFDcase_map.nc"
2104+ )["mesh2d_s1" ].values
2105+ water_level_case = np .nan_to_num (water_level_case , nan = 0 )
2106+
2107+ wind_speed_value = wind_speed_data [cell_index , time_index ]
2108+ drag_coeff_value = GS_LinearWindDragCoef (
2109+ wind_speed_value , drag_coefficients , velocity_thresholds
2110+ )
2111+
2112+ scaling_factor = (wind_speed_value ** 2 / wind_speed_reference ** 2 ) * (
2113+ drag_coeff_value / base_drag_coeff
2114+ )
2115+ water_level_accumulator += water_level_case * scaling_factor
2116+
2117+ step_window = min (duration_in_steps , num_output_times - time_index )
2118+ if (num_output_times - time_index ) > step_window :
2119+ wind_setup_output [time_index : time_index + step_window ] += (
2120+ water_level_accumulator
2121+ )
2122+ else :
2123+ shift_counter = step_window - (num_output_times - time_index )
2124+ wind_setup_output [
2125+ time_index : time_index + step_window - shift_counter
2126+ ] += water_level_accumulator [: step_window - shift_counter ]
2127+
2128+ ds_wind_setup = xr .Dataset (
2129+ {"WL" : (["time" , "nface" ], wind_setup_output )},
2130+ coords = {
2131+ "time" : output_time_vector ,
2132+ "nface" : np .arange (wind_setup_output .shape [1 ]),
2133+ },
2134+ )
2135+ ds_wind_setup .attrs ["description" ] = "Wind setup from GreenSurge methodology"
2136+
2137+ return ds_wind_setup
0 commit comments