def test_stokes():
    assert np.isclose(Stokes.water_phase_xfer_velocity(0.1, 400.0 / 1e6),
                      0.00872)
    assert np.isclose(Stokes.water_phase_xfer_velocity(0.2, 400.0 / 1e6),
                      0.01744)
    assert np.isclose(Stokes.water_phase_xfer_velocity(0.3, 400.0 / 1e6),
                      0.02616)
示例#2
0
def test_stokes():
    water_rho = 1000.0  # kg/m^3
    droplet_diameter = 0.0002  # 200 microns

    for oil_rho, expected in zip((900.0, 800.0, 700.0),
                                 (0.00217926, 0.00435852, 0.00653778)):
        delta_rho = water_rho - oil_rho
        assert np.isclose(
            Stokes.water_phase_xfer_velocity(delta_rho, droplet_diameter),
            expected)
示例#3
0
def test_stokes():
    water_rho = 1000.0  # kg/m^3
    droplet_diameter = 0.0002  # 200 microns

    for oil_rho, expected in zip((900.0, 800.0, 700.0),
                                 (0.00217926, 0.00435852, 0.00653778)):
        delta_rho = water_rho - oil_rho
        assert np.isclose(Stokes.water_phase_xfer_velocity(delta_rho,
                                                           droplet_diameter),
                          expected)
示例#4
0
def test_ding_farmer():
    wind_speed = 10.0  # m/s
    rdelta = 200.0  # oil/water density difference (kg / m^3)
    droplet_diameter = 0.0002  # 200 microns

    wave_height = PiersonMoskowitz.significant_wave_height(wind_speed)
    wave_period = PiersonMoskowitz.peak_wave_period(wind_speed)

    f_bw = DelvigneSweeney.breaking_waves_frac(wind_speed, wave_period)
    k_w = Stokes.water_phase_xfer_velocity(rdelta, droplet_diameter)

    assert np.isclose(DingFarmer.calm_between_wave_breaks(0.5, 10), 15.0)
    assert np.isclose(DingFarmer.calm_between_wave_breaks(f_bw, wave_period),
                      347.8125)
    assert np.isclose(DingFarmer.refloat_time(wave_height, k_w), 386.0328)

    assert np.isclose(
        DingFarmer.water_column_time_fraction(f_bw, wave_period, wave_height,
                                              k_w), 1.0)
def test_ding_farmer():
    wind_speed = 10.0  # m/s
    rdelta = 0.2  # oil/water density difference
    droplet_diameter = 0.0002  # 200 microns

    wave_height = PiersonMoskowitz.significant_wave_height(wind_speed)
    wave_period = PiersonMoskowitz.peak_wave_period(wind_speed)

    f_bw = DelvigneSweeney.breaking_waves_frac(wind_speed, wave_period)
    k_w = Stokes.water_phase_xfer_velocity(rdelta, droplet_diameter)

    assert np.isclose(DingFarmer.calm_between_wave_breaks(0.5, 10),
                      15.0)
    assert np.isclose(DingFarmer.calm_between_wave_breaks(f_bw, wave_period),
                      347.8125)
    assert np.isclose(DingFarmer.refloat_time(wave_height, k_w),
                      385.90177)

    assert np.isclose(DingFarmer.water_column_time_fraction(f_bw,
                                                            wave_period,
                                                            wave_height,
                                                            k_w),
                      1.1095)
示例#6
0
    def dissolve_oil(self, data, substance, **kwargs):
        '''
            Here is where we calculate the dissolved oil.
            We will outline the steps as we go along, but off the top of
            my head:
            - recalculate the partition coefficient (K_ow)
            - droplet distribution per LE should be calculated by the
              natural dispersion process and saved in the data arrays before
              the dissolution weathering process.
            - for each LE:
                (Note: right now the natural dispersion process only
                       calculates a single average droplet size. But we still
                       treat it as an iterable.)
                - for each droplet size category:
                    - calculate the water phase transfer velocity (k_w)
                    - calculate the mass xfer rate coefficient (beta)
                    - calculate the water column time fraction (f_wc)
                    - calculate the mass dissolved during refloat period
                - calculate the mass dissolved from the slick during the
                  calm period.
            - the mass dissolved in the water column and the slick is summed
              per mass fraction (should only be aromatic fractions)
            - the sum of dissolved masses are compared to the existing mass
              fractions and adjusted to make sure we don't dissolve more
              mass than exists in the mass fractions.
        '''
        model_time = kwargs.get('model_time')
        time_step = kwargs.get('time_step')

        fmasses = data['mass_components']
        droplet_avg_sizes = data['droplet_avg_size']
        areas = data['area']
        points = data['positions']

        # print 'droplet_avg_sizes = ', droplet_avg_sizes

        #arom_mask = substance._sara['type'] == 'Aromatics'
        sara = np.asarray(substance.sara_type)
        arom_mask = sara == 'Aromatics'

        mol_wt = substance.molecular_weight
        rho = substance.component_density

        assert mol_wt.shape == rho.shape

        # calculate the partition coefficient (K_ow) for all aromatics
        # for each LE.
        # K_ow for non-aromatics are masked to 0.0
        K_ow_comp = arom_mask * BanerjeeHuibers.partition_coeff(mol_wt, rho)
        data['partition_coeff'] = ((fmasses * K_ow_comp / mol_wt).sum(axis=1) /
                                   (fmasses / mol_wt).sum(axis=1))

        avg_rhos = self.oil_avg_density(fmasses, rho)
        # print ('oil density at temp = {}'
        #        .format(substance.get_density(self.waves.water
        #                                      .get('temperature'))))
        # print 'avg_rhos = ', avg_rhos
        water_rhos = np.zeros(avg_rhos.shape) + self.waves.water.get('density')

        k_w_i = Stokes.water_phase_xfer_velocity(water_rhos - avg_rhos,
                                                 droplet_avg_sizes)
        k_diffusion = 0.134  # Thorpe turbulent diffusion coefficient

        total_volumes = self.oil_total_volume(fmasses, rho)

        f_wc_i = self.water_column_time_fraction(points, model_time, k_w_i)
        T_wc_i = f_wc_i * time_step
        # print 'T_wc_i = ', T_wc_i

        T_calm_i = self.calm_between_wave_breaks(points, model_time, time_step,
                                                 T_wc_i)
        # print 'T_calm_i = ', T_calm_i

        assert np.alltrue(T_calm_i <= float(time_step))
        assert np.alltrue(T_wc_i <= float(time_step))
        assert np.alltrue(T_wc_i + T_calm_i <= float(time_step))

        oil_concentrations = self.oil_concentration(fmasses, rho)

        N_drop_i = self.droplet_subsurface_mass_xfer_rate(
            droplet_avg_sizes, k_w_i + k_diffusion, oil_concentrations,
            K_ow_comp, arom_mask, total_volumes)
        # with printoptions(precision=2):
        #     print 'N_drop_i = ', N_drop_i
        #
        # print 'T_wc_i = ', T_wc_i

        #
        # OK, here it is, the mass dissolved in the water column.
        #
        mass_dissolved_in_wc = (N_drop_i.T * T_wc_i).T

        # with printoptions(precision=2):
        #     print 'mass_dissolved_in_wc = ', mass_dissolved_in_wc

        N_s_i = self.slick_subsurface_mass_xfer_rate(points, model_time,
                                                     oil_concentrations,
                                                     K_ow_comp, areas,
                                                     arom_mask)
        # with printoptions(precision=2):
        #     print 'N_s_i = ', N_s_i

        #
        # OK, here it is, the mass dissolved in the slick.
        #
        mass_dissolved_in_slick = (N_s_i.T * T_calm_i).T

        # with printoptions(precision=2):
        #     print 'mass_dissolved_in_slick = ', mass_dissolved_in_slick

        mass_dissolved_in_wc = np.vstack(mass_dissolved_in_wc)
        mass_dissolved_in_slick = np.vstack(mass_dissolved_in_slick)
        total_mass_dissolved = mass_dissolved_in_wc + mass_dissolved_in_slick

        # adjust any masses that might go negative
        total_mass_dissolved += np.clip(fmasses - total_mass_dissolved,
                                        -np.inf, 0.0)

        return total_mass_dissolved
示例#7
0
    def dissolve_oil(self, data, substance, **kwargs):
        '''
            Here is where we calculate the dissolved oil.
            We will outline the steps as we go along, but off the top of
            my head:
            - recalculate the partition coefficient (K_ow)
            - droplet distribution per LE should be calculated by the
              natural dispersion process and saved in the data arrays before
              the dissolution weathering process.
            - for each LE:
                (Note: right now the natural dispersion process only
                       calculates a single average droplet size. But we still
                       treat it as an iterable.)
                - for each droplet size category:
                    - calculate the water phase transfer velocity (k_w)
                    - calculate the mass xfer rate coefficient (beta)
                    - calculate the water column time fraction (f_wc)
                    - calculate the mass dissolved during refloat period
                - calculate the mass dissolved from the slick during the
                  calm period.
            - the mass dissolved in the water column and the slick is summed
              per mass fraction (should only be aromatic fractions)
            - the sum of dissolved masses are compared to the existing mass
              fractions and adjusted to make sure we don't dissolve more
              mass than exists in the mass fractions.
        '''
        model_time = kwargs.get('model_time')
        time_step = kwargs.get('time_step')

        fmasses = data['mass_components']
        droplet_avg_sizes = data['droplet_avg_size']
        areas = data['area']
        points = data['positions']

        # print 'droplet_avg_sizes = ', droplet_avg_sizes

        arom_mask = substance._sara['type'] == 'Aromatics'

        mol_wt = substance.molecular_weight
        rho = substance.component_density

        assert mol_wt.shape == rho.shape

        # calculate the partition coefficient (K_ow) for all aromatics
        # for each LE.
        # K_ow for non-aromatics are masked to 0.0
        K_ow_comp = arom_mask * BanerjeeHuibers.partition_coeff(mol_wt, rho)
        data['partition_coeff'] = ((fmasses * K_ow_comp / mol_wt).sum(axis=1) /
                                   (fmasses / mol_wt).sum(axis=1))

        avg_rhos = self.oil_avg_density(fmasses, rho)
        # print ('oil density at temp = {}'
        #        .format(substance.get_density(self.waves.water
        #                                      .get('temperature'))))
        # print 'avg_rhos = ', avg_rhos
        water_rhos = np.zeros(avg_rhos.shape) + self.waves.water.get('density')

        k_w_i = Stokes.water_phase_xfer_velocity(water_rhos - avg_rhos,
                                                 droplet_avg_sizes)
        k_diffusion = 0.134  # Thorpe turbulent diffusion coefficient

        total_volumes = self.oil_total_volume(fmasses, rho)

        f_wc_i = self.water_column_time_fraction(points,model_time, k_w_i)
        T_wc_i = f_wc_i * time_step
        # print 'T_wc_i = ', T_wc_i

        T_calm_i = self.calm_between_wave_breaks(points,model_time, time_step, T_wc_i)
        # print 'T_calm_i = ', T_calm_i

        assert np.alltrue(T_calm_i <= float(time_step))
        assert np.alltrue(T_wc_i <= float(time_step))
        assert np.alltrue(T_wc_i + T_calm_i <= float(time_step))

        oil_concentrations = self.oil_concentration(fmasses, rho)

        N_drop_i = self.droplet_subsurface_mass_xfer_rate(droplet_avg_sizes,
                                                          k_w_i + k_diffusion,
                                                          oil_concentrations,
                                                          K_ow_comp,
                                                          arom_mask,
                                                          total_volumes
                                                          )
        # with printoptions(precision=2):
        #     print 'N_drop_i = ', N_drop_i
        #
        # print 'T_wc_i = ', T_wc_i

        #
        # OK, here it is, the mass dissolved in the water column.
        #
        mass_dissolved_in_wc = (N_drop_i.T * T_wc_i).T

        # with printoptions(precision=2):
        #     print 'mass_dissolved_in_wc = ', mass_dissolved_in_wc

        N_s_i = self.slick_subsurface_mass_xfer_rate(points,
                                                     model_time,
                                                     oil_concentrations,
                                                     K_ow_comp,
                                                     areas,
                                                     arom_mask)
        # with printoptions(precision=2):
        #     print 'N_s_i = ', N_s_i

        #
        # OK, here it is, the mass dissolved in the slick.
        #
        mass_dissolved_in_slick = (N_s_i.T * T_calm_i).T

        # with printoptions(precision=2):
        #     print 'mass_dissolved_in_slick = ', mass_dissolved_in_slick

        mass_dissolved_in_wc = np.vstack(mass_dissolved_in_wc)
        mass_dissolved_in_slick = np.vstack(mass_dissolved_in_slick)
        total_mass_dissolved = mass_dissolved_in_wc + mass_dissolved_in_slick

        # adjust any masses that might go negative
        total_mass_dissolved += np.clip(fmasses - total_mass_dissolved,
                                        - np.inf, 0.0)

        return total_mass_dissolved
示例#8
0
    def dissolve_oil(self, data, substance, **kwargs):
        '''
            Here is where we calculate the dissolved oil.
            We will outline the steps as we go along, but off the top of
            my head:
            - recalculate the partition coefficient (K_ow)
            - droplet distribution per LE should be calculated by the
              natural dispersion process and saved in the data arrays before
              the dissolution weathering process.
            - for each LE:
                (Note: right now the natural dispersion process only
                       calculates a single average droplet size. But we still
                       treat it as an iterable.)
                - for each droplet size category:
                    - calculate the water phase transfer velocity (k_w)
                    - calculate the mass xfer rate coefficient (beta)
                    - calculate the water column time fraction (f_wc)
                    - calculate the mass dissolved during refloat period
                - calculate the mass dissolved from the slick during the
                  calm period.
            - the mass dissolved in the water column and the slick is summed
              per mass fraction (should only be aromatic fractions)
            - the sum of dissolved masses are compared to the existing mass
              fractions and adjusted to make sure we don't dissolve more
              mass than exists in the mass fractions.
        '''
        model_time = kwargs.get('model_time')
        time_step = kwargs.get('time_step')

        fmasses = data['mass_components']
        droplet_avg_sizes = data['droplet_avg_size']
        areas = data['area']

        arom_mask = substance._sara['type'] == 'Aromatics'

        mol_wt = substance.molecular_weight
        rho = substance.component_density

        assert mol_wt.shape == rho.shape

        # calculate the partition coefficient (K_ow) for all aromatics
        # for each LE.
        # K_ow for non-aromatics are masked to 0.0
        K_ow_comp = arom_mask * LeeHuibers.partition_coeff(mol_wt, rho)
        data['partition_coeff'] = ((fmasses * K_ow_comp / mol_wt).sum(axis=1) /
                                   (fmasses / mol_wt).sum(axis=1))

        avg_rhos = self.oil_avg_density(fmasses, rho)
        water_rhos = np.zeros(avg_rhos.shape) + self.waves.water.get('density')

        k_w_i = Stokes.water_phase_xfer_velocity(water_rhos - avg_rhos,
                                                 droplet_avg_sizes)

        total_volumes = self.oil_total_volume(fmasses, rho)
        X_i, S_RA_volumes = self.state_variable(fmasses, rho, arom_mask)

        beta_i = self.beta_coeff(k_w_i, data['partition_coeff'], S_RA_volumes)

        dX_dt_i = beta_i * X_i / (X_i + 1.0) ** (1.0 / 3.0)

        f_wc_i = self.water_column_time_fraction(model_time, k_w_i)
        T_wc_i = f_wc_i * time_step

        T_calm_i = self.calm_between_wave_breaks(model_time, time_step, T_wc_i)

        assert np.alltrue(T_calm_i <= float(time_step))
        assert np.alltrue(T_wc_i <= float(time_step))
        assert np.alltrue(T_wc_i + T_calm_i <= float(time_step))

        aromatic_masses_i = fmasses * arom_mask
        aromatic_fractions_i = (aromatic_masses_i.T /
                                aromatic_masses_i.sum(axis=1)).T

        #
        # OK, here it is, the mass dissolved in the water column.
        #
        mass_dissolved_in_wc = np.nan_to_num((aromatic_fractions_i.T *
                                              dX_dt_i * T_wc_i).T)

        oil_concentrations = self.oil_concentration(fmasses, rho)

        N_s_i = self.slick_subsurface_mass_xfer_rate(model_time,
                                                     oil_concentrations,
                                                     K_ow_comp,
                                                     areas,
                                                     arom_mask)

        #
        # OK, here it is, the mass dissolved in the slick.
        #
        mass_dissolved_in_slick = (N_s_i.T * T_calm_i).T

        mass_dissolved_in_wc = np.vstack(mass_dissolved_in_wc)
        mass_dissolved_in_slick = np.vstack(mass_dissolved_in_slick)
        total_mass_dissolved = mass_dissolved_in_wc + mass_dissolved_in_slick

        # adjust any masses that might go negative
        total_mass_dissolved += np.clip(fmasses - total_mass_dissolved,
                                        -np.inf, 0.0)

        return total_mass_dissolved