예제 #1
0
    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 = {}
예제 #2
0
 def reload_ocean(self):
     self.ocean = metocean.Ocean(self.time_frame, model=self.ocean_model)
예제 #3
0
 def set_constant_current(self, constants):
     self.ocean = metocean.Ocean(self.time_frame,
                                 model=self.ocean_model,
                                 constants=constants)
예제 #4
0
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
예제 #5
0
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