def __init__(self, time_frame, start_location, start_velocity=(0, 0), **kwargs): """This class sets up and runs the components necessary to run an iceberg drift simulation. Args: time_frame (tuple of numpy.datetime64): start time, end time for the simulation. start_location (tuple of float): starting position (latitude, longitude) for the simulation. Kwargs: start_velocity (tuple of float): starting velocity (vx, vy) in m/s. time_step (numpy.timedelta64): Time step in seconds. drift_model (function): The drift model function. time_stepper (function): The numerical integrator function. ocean_model (str): Name of ocean model. Can be ECMWF or HYCOM. atmosphere_model (str): Name of the atmosphere model. Can be ECMWF or NARR. iceberg_size (str or tuple of float): size class for the iceberg or dims (waterline length, sail height). iceberg_shape (str): shape class for the iceberg. """ self.start_location = start_location self.time_frame = time_frame self.start_velocity = start_velocity self.time_step = kwargs.pop('time_step', np.timedelta64(300, 's')) self.drift_model = kwargs.pop('drift_model', drift.newtonian_drift_wrapper) self.time_stepper = kwargs.pop('time_stepper', timesteppers.euler) self.ocean_model = kwargs.pop('ocean_model', 'ECMWF') self.atmosphere_model = kwargs.pop('atmosphere_model', 'NARR') self.ocean = metocean.Ocean(self.time_frame, model=self.ocean_model) self.atmosphere = metocean.Atmosphere(self.time_frame, model=self.atmosphere_model) self.iceberg_size = kwargs.pop('iceberg_size', 'LG') self.iceberg_shape = kwargs.pop('iceberg_shape', 'TAB') self.iceberg = iceberg.quickstart(self.time_frame[0], self.start_location, velocity=self.start_velocity, size=self.iceberg_size, shape=self.iceberg_shape) self.results = {}
def reload_ocean(self): self.ocean = metocean.Ocean(self.time_frame, model=self.ocean_model)
def set_constant_current(self, constants): self.ocean = metocean.Ocean(self.time_frame, model=self.ocean_model, constants=constants)
def run_simulation(time_frame, start_location, start_velocity=(0, 0), **kwargs): time_step = kwargs.pop('time_step', np.timedelta64(300, 's')) time_stepper = kwargs.pop('time_stepper', timesteppers.euler) drift_model = kwargs.pop('drift_model', drift.newtonian_drift_wrapper) ocean_model = kwargs.pop('ocean_model', 'ECMWF') atmosphere_model = kwargs.pop('atmosphere_model', 'NARR') start_time, end_time = time_frame dt = time_step.item().total_seconds() nt = int( np.timedelta64(end_time - start_time, 's').item().total_seconds() / dt) size = kwargs.pop('iceberg_size', 'LG') shape = kwargs.pop('iceberg_shape', 'TAB') iceberg_ = kwargs.pop( 'iceberg', iceberg.quickstart(start_time, start_location, velocity=start_velocity, size=size, shape=shape)) current_constants = kwargs.pop('current_constants', None) wind_constants = kwargs.pop('wind_constants', None) ocean = kwargs.pop( 'ocean', metocean.Ocean(time_frame, model=ocean_model, constants=current_constants)) atmosphere = kwargs.pop( 'atmosphere', metocean.Atmosphere(time_frame, model=atmosphere_model, constants=wind_constants)) # Initialize arrays times = np.zeros(nt, dtype='datetime64[ns]') if drift_model is drift.newtonian_drift_wrapper: results = { 'latitude': np.zeros(nt), 'longitude': np.zeros(nt), 'iceberg_eastward_velocity': np.zeros(nt), 'iceberg_northward_velocity': np.zeros(nt) } kwargs = { 'form_drag_coefficient_in_air': kwargs.pop('Ca', iceberg_.FORM_DRAG_COEFFICIENT_IN_AIR), 'form_drag_coefficient_in_water': kwargs.pop('Cw', iceberg_.FORM_DRAG_COEFFICIENT_IN_WATER), 'skin_drag_coefficient_in_air': iceberg_.SKIN_DRAG_COEFFICIENT_IN_AIR, 'skin_drag_coefficient_in_water': iceberg_.SKIN_DRAG_COEFFICIENT_IN_WATER, 'sail_area': iceberg_.geometry.sail_area, 'keel_area': iceberg_.geometry.keel_area, 'top_area': iceberg_.geometry.waterline_length**2, 'bottom_area': iceberg_.geometry.bottom_area, 'mass': kwargs.pop('mass', iceberg_.geometry.mass), 'latitude': iceberg_.latitude, 'ekman': kwargs.pop('ekman', False), 'depth_vec': kwargs.pop('depth_vec', np.arange(0, -110, -10)), 'time_step': time_step, 'eastward_current': ocean.current.eastward_velocities, 'northward_current': ocean.current.northward_velocities, 'eastward_wind': atmosphere.wind.eastward_velocities, 'northward_wind': atmosphere.wind.northward_velocities, 'log': kwargs.pop('log', None), 'current_interpolator': ocean.current.interpolate, 'wind_interpolator': atmosphere.wind.interpolate } else: results = {'latitude': np.zeros(nt), 'longitude': np.zeros(nt)} kwargs = { 'form_drag_coefficient_in_air': kwargs.pop('Ca', iceberg_.FORM_DRAG_COEFFICIENT_IN_AIR), 'form_drag_coefficient_in_water': kwargs.pop('Cw', iceberg_.FORM_DRAG_COEFFICIENT_IN_WATER), 'waterline_length': iceberg_.geometry.waterline_length, 'time_step': time_step, 'eastward_current': ocean.current.eastward_velocities, 'northward_current': ocean.current.northward_velocities, 'eastward_wind': atmosphere.wind.eastward_velocities, 'northward_wind': atmosphere.wind.northward_velocities, 'current_interpolator': ocean.current.interpolate, 'wind_interpolator': atmosphere.wind.interpolate } for i in range(nt): times[i] = iceberg_.time results['latitude'][i] = iceberg_.latitude results['longitude'][i] = iceberg_.longitude if drift_model is drift.newtonian_drift_wrapper: results['iceberg_eastward_velocity'][ i] = iceberg_.eastward_velocity results['iceberg_northward_velocity'][ i] = iceberg_.northward_velocity if time_stepper in (timesteppers.ab2, timesteppers.ab3): if drift_model is drift.newtonian_drift_wrapper: dx, dy, dvx, dvy = time_stepper( drift_model, dt, times[:i + 1], results['longitude'][:i + 1], results['latitude'][:i + 1], results['iceberg_eastward_velocity'][:i + 1], results['iceberg_northward_velocity'][:i + 1], **kwargs) else: dx, dy = time_stepper(drift_model, dt, times[:i + 1], results['longitude'][:i + 1], results['latitude'][:i + 1], **kwargs) else: if drift_model is drift.newtonian_drift_wrapper: dx, dy, dvx, dvy = time_stepper(drift_model, dt, iceberg_.time, iceberg_.longitude, iceberg_.latitude, iceberg_.eastward_velocity, iceberg_.northward_velocity, **kwargs) else: dx, dy = time_stepper(drift_model, dt, iceberg_.time, iceberg_.longitude, iceberg_.latitude, **kwargs) if drift_model is drift.newtonian_drift_wrapper: iceberg_.eastward_velocity += dvx iceberg_.northward_velocity += dvy iceberg_.time += time_step iceberg_.latitude += tools.dy_to_dlat(dy) iceberg_.longitude += tools.dx_to_dlon(dx, iceberg_.latitude) xds = xr.Dataset() for key, value in results.items(): xarr = xr.DataArray(data=value, coords=[times], dims=['time']) xds[key] = xarr return xds
def run_simulation(time_frame, start_location, start_velocity=(0, 0), **kwargs): time_step = kwargs.pop('time_step', np.timedelta64(300, 's')) time_stepper = kwargs.pop('time_stepper', timesteppers.euler) drift_model = kwargs.pop('drift_model', drift.newtonian_drift_wrapper) ocean_model = kwargs.pop('ocean_model', 'ECMWF') atmosphere_model = kwargs.pop('atmosphere_model', 'NARR') perturb_current = kwargs.pop('perturb_current', False) perturb_wind = kwargs.pop('perturb_wind', False) smoothing_constant = kwargs.pop('smoothing_constant', 0.5) start_time, end_time = time_frame dt = time_step.item().total_seconds() nt = int( np.timedelta64(end_time - start_time, 's').item().total_seconds() / dt) waterline_length = kwargs.pop('waterline_length', None) sail_height = kwargs.pop('sail_height', None) if waterline_length is not None and sail_height is not None: size = waterline_length, sail_height else: size = kwargs.pop('iceberg_size', 'LG') shape = kwargs.pop('iceberg_shape', 'TAB') iceberg_ = kwargs.pop( 'iceberg', iceberg.quickstart(start_time, start_location, velocity=start_velocity, size=size, shape=shape)) current_constants = kwargs.pop('current_constants', None) wind_constants = kwargs.pop('wind_constants', None) ocean = kwargs.pop( 'ocean', metocean.Ocean(time_frame, model=ocean_model, constants=current_constants)) atmosphere = kwargs.pop( 'atmosphere', metocean.Atmosphere(time_frame, model=atmosphere_model, constants=wind_constants)) # Initialize arrays times = np.zeros(nt, dtype='datetime64[ns]') if drift_model is drift.newtonian_drift_wrapper: results = { 'latitude': np.zeros(nt), 'longitude': np.zeros(nt), 'iceberg_eastward_velocity': np.zeros(nt), 'iceberg_northward_velocity': np.zeros(nt) } kwargs = { 'form_drag_coefficient_in_air': kwargs.pop('Ca', iceberg_.FORM_DRAG_COEFFICIENT_IN_AIR), 'form_drag_coefficient_in_water': kwargs.pop('Cw', iceberg_.FORM_DRAG_COEFFICIENT_IN_WATER), 'skin_drag_coefficient_in_air': iceberg_.SKIN_DRAG_COEFFICIENT_IN_AIR, 'skin_drag_coefficient_in_water': iceberg_.SKIN_DRAG_COEFFICIENT_IN_WATER, 'sail_area': iceberg_.geometry.sail_area, 'keel_area': iceberg_.geometry.keel_area, 'top_area': iceberg_.geometry.waterline_length**2, 'bottom_area': iceberg_.geometry.bottom_area, 'mass': kwargs.pop('mass', iceberg_.geometry.mass), 'latitude': iceberg_.latitude, 'ekman': kwargs.pop('ekman', False), 'depth_vec': kwargs.pop('depth_vec', np.arange(0, -110, -10)), 'time_step': time_step, 'eastward_current': ocean.current.eastward_velocities, 'northward_current': ocean.current.northward_velocities, 'eastward_wind': atmosphere.wind.eastward_velocities, 'northward_wind': atmosphere.wind.northward_velocities, 'log': kwargs.pop('log', None), 'current_interpolator': ocean.current.interpolate, 'wind_interpolator': atmosphere.wind.interpolate, 'current_sample': np.array([0, 0]), 'wind_sample': np.array([0, 0]) } else: results = {'latitude': np.zeros(nt), 'longitude': np.zeros(nt)} kwargs = { 'form_drag_coefficient_in_air': kwargs.pop('Ca', iceberg_.FORM_DRAG_COEFFICIENT_IN_AIR), 'form_drag_coefficient_in_water': kwargs.pop('Cw', iceberg_.FORM_DRAG_COEFFICIENT_IN_WATER), 'waterline_length': iceberg_.geometry.waterline_length, 'time_step': time_step, 'eastward_current': ocean.current.eastward_velocities, 'northward_current': ocean.current.northward_velocities, 'eastward_wind': atmosphere.wind.eastward_velocities, 'northward_wind': atmosphere.wind.northward_velocities, 'current_interpolator': ocean.current.interpolate, 'wind_interpolator': atmosphere.wind.interpolate, 'current_sample': np.array([0, 0]), 'wind_sample': np.array([0, 0]) } current_correction_samples = read_csv( '/home/evankielley/current_correction_samples.csv') current_correction_samples = current_correction_samples.drop( columns='Unnamed: 0') wind_correction_samples = read_csv( '/home/evankielley/wind_correction_samples.csv') wind_correction_samples = wind_correction_samples.drop( columns='Unnamed: 0') for i in range(nt): times[i] = iceberg_.time results['latitude'][i] = iceberg_.latitude results['longitude'][i] = iceberg_.longitude if perturb_current: previous_current_sample = kwargs.get('current_sample') current_correction_sample = -1 * current_correction_samples.iloc[ np.random.randint(0, len(current_correction_samples))].values new_current_sample = previous_current_sample * ( 1 - smoothing_constant ) + current_correction_sample * smoothing_constant # new_current_sample = ocean.current.sample(previous_sample=previous_current_sample, alpha=smoothing_constant) kwargs['current_sample'] = new_current_sample if perturb_wind: previous_wind_sample = kwargs.get('wind_sample') wind_correction_sample = -1 * wind_correction_samples.iloc[ np.random.randint(0, len(wind_correction_samples))].values new_wind_sample = previous_wind_sample * ( 1 - smoothing_constant ) + wind_correction_sample * smoothing_constant # new_wind_sample = atmosphere.wind.sample(previous_sample=previous_wind_sample, alpha=smoothing_constant) kwargs['wind_sample'] = new_wind_sample if drift_model is drift.newtonian_drift_wrapper: results['iceberg_eastward_velocity'][ i] = iceberg_.eastward_velocity results['iceberg_northward_velocity'][ i] = iceberg_.northward_velocity if time_stepper in (timesteppers.ab2, timesteppers.ab3): if drift_model is drift.newtonian_drift_wrapper: dx, dy, dvx, dvy = time_stepper( drift_model, dt, times[:i + 1], results['longitude'][:i + 1], results['latitude'][:i + 1], results['iceberg_eastward_velocity'][:i + 1], results['iceberg_northward_velocity'][:i + 1], **kwargs) else: dx, dy = time_stepper(drift_model, dt, times[:i + 1], results['longitude'][:i + 1], results['latitude'][:i + 1], **kwargs) else: if drift_model is drift.newtonian_drift_wrapper: dx, dy, dvx, dvy = time_stepper(drift_model, dt, iceberg_.time, iceberg_.longitude, iceberg_.latitude, iceberg_.eastward_velocity, iceberg_.northward_velocity, **kwargs) else: dx, dy = time_stepper(drift_model, dt, iceberg_.time, iceberg_.longitude, iceberg_.latitude, **kwargs) if drift_model is drift.newtonian_drift_wrapper: iceberg_.eastward_velocity += dvx iceberg_.northward_velocity += dvy iceberg_.time += time_step iceberg_.latitude += tools.dy_to_dlat(dy) iceberg_.longitude += tools.dx_to_dlon(dx, iceberg_.latitude) xds = xr.Dataset() for key, value in results.items(): xarr = xr.DataArray(data=value, coords=[times], dims=['time']) xds[key] = xarr return xds