Example #1
0
    def __call__(self, state):
        """
        Calculate longwave optical depth from input state.

        Args:
            state (dict): A model state dictionary.

        Returns:
            tendencies (dict): A dictionary whose keys are strings indicating
                state quantities and values are the time derivative of those
                quantities in units/second at the time of the input state.
            diagnostics (dict): A dictionary whose keys are strings indicating
                state quantities and values are the value of those quantities
                at the time of the input state.
        """
        lat = get_numpy_array(state['latitude'].to_units('degrees_north'),
                              out_dims=('x', 'y', 'z'))

        sigma_interface = get_numpy_array(
            state['sigma_on_interface_levels'].to_units(''),
            out_dims=('x', 'y', 'z'))

        tau = DataArray(
            get_frierson_06_tau(lat, sigma_interface, self._tau0e, self._tau0p,
                                self._fl),
            dims=combine_dimensions(
                [state['latitude'], state['sigma_on_interface_levels']],
                out_dims=('x', 'y', 'z')),
            attrs={
                'units': ''
            }).squeeze()

        return {
            'longwave_optical_depth_on_interface_levels': tau,
        }
Example #2
0
    def _get_k_t(self, latitude, sigma):

        out_dims = combine_dimensions([latitude, sigma], out_dims=('x', 'y', 'z'))

        latitude = get_numpy_array(
            latitude.to_units('degrees_N'), out_dims=('x', 'y', 'z'))

        sigma = get_numpy_array(sigma, out_dims=('x', 'y', 'z'))

        return DataArray(
            self._k_a +
            (self._k_s - self._k_a) *
            np.maximum(0, (sigma - self._sigma_b)/(1 - self._sigma_b)) *
            np.cos(np.radians(latitude))**4,
            dims=out_dims,
            attrs={'units': 's^-1'})
Example #3
0
    def __call__(self, state):
        """
        Get heating tendencies and longwave fluxes.

        Args:

            state (dict): A model state dictionary.

        Returns:

            tendencies (dict), diagnostics (dict):

                * A dictionary whose keys are strings indicating
                  state quantities and values are the time derivative of those
                  quantities in units/second at the time of the input state.
                * A dictionary whose keys are strings indicating
                  state quantities and values are the value of those quantities
                  at the time of the input state.
        """
        tau = get_numpy_array(
            state['longwave_optical_depth_on_interface_levels'].to_units(''),
            out_dims=('x', 'y', 'z'))
        T = get_numpy_array(state['air_temperature'].to_units('degK'),
                            out_dims=('x', 'y', 'z'))
        p_interface = get_numpy_array(
            state['air_pressure_on_interface_levels'].to_units('Pa'),
            out_dims=('x', 'y', 'z'))
        Ts = get_numpy_array(state['surface_temperature'].to_units('degK'),
                             out_dims=('x', 'y'))

        (downward_flux, upward_flux, net_lw_flux, lw_temperature_tendency,
         tau) = get_longwave_fluxes(T, p_interface, Ts, tau,
                                    self._stefan_boltzmann, self._g, self._Cpd)

        tendencies = self.create_state_dict_for('_climt_tendencies', state)
        tendencies['air_temperature'].values = lw_temperature_tendency

        diagnostics = self.create_state_dict_for('_climt_diagnostics', state)

        diagnostics['downwelling_longwave_flux_in_air'].values = downward_flux
        diagnostics['upwelling_longwave_flux_in_air'].values = upward_flux
        diagnostics['longwave_heating_rate'].values = \
            tendencies['air_temperature'].to_units('degK/day')

        return tendencies, diagnostics
Example #4
0
    def _get_Teq(self, latitude, air_pressure):

        out_dims = combine_dimensions(
            [latitude, air_pressure], out_dims=('x', 'y', 'z'))

        latitude = get_numpy_array(
            latitude.to_units('degrees_N'), out_dims=['x', 'y', 'z'])

        air_pressure = get_numpy_array(
            air_pressure.to_units('Pa'), out_dims=['x', 'y', 'z'])

        return DataArray(np.maximum(
            200,
            (315 - self._delta_T_y*np.sin(np.radians(latitude))**2 -
             self._delta_theta_z*np.log(air_pressure/self._p0)*np.cos(np.radians(latitude))**2
             ) * (air_pressure/self._p0)**self._kappa),
            dims=out_dims,
            attrs={'units': 'degK'})
def test_restore_dimensions_starz_to_zyx_has_no_attrs():
    array = DataArray(
        np.random.randn(2, 3, 4),
        dims=['z', 'y', 'x'],
        attrs={'units': ''}
    )
    numpy_array = get_numpy_array(array, ['*', 'z'])
    restored_array = restore_dimensions(
        numpy_array, from_dims=['*', 'z'], result_like=array)
    assert len(restored_array.attrs) == 0
def test_get_numpy_array_complicated_asterisk():
    array = DataArray(
        np.random.randn(2, 3, 4, 5),
        dims=['x', 'h', 'y', 'q'],
        attrs={'units': ''}
    )
    numpy_array = get_numpy_array(array, ['*', 'x', 'y'])
    for i in range(2):
        for j in range(4):
            assert np.allclose(numpy_array[:, i, j], array.values[i, :, j, :].flatten())
def test_get_numpy_array_3d_no_change():
    array = DataArray(
        np.random.randn(2, 3, 4),
        dims=['x', 'y', 'z'],
        attrs={'units': ''},
    )
    numpy_array = get_numpy_array(array, ['x', 'y', 'z'])
    assert np.byte_bounds(numpy_array) == np.byte_bounds(array.values)
    assert np.all(numpy_array == array.values)
    assert numpy_array.base is array.values
def test_get_numpy_array_retrieves_explicit_dimensions():
    array = DataArray(
        np.random.randn(2, 3),
        dims=['alpha', 'zeta'],
        attrs={'units': ''},
    )
    numpy_array = get_numpy_array(array, ['zeta', 'alpha'])
    assert numpy_array.shape == (3, 2)
    assert np.all(np.transpose(numpy_array, (1, 0)) == array.values)
    assert np.byte_bounds(numpy_array) == np.byte_bounds(array.values)
    assert numpy_array.base is array.values
def test_restore_dimensions_starz_to_zalphabeta():
    array = DataArray(
        np.random.randn(2, 3, 4),
        dims=['z', 'alpha', 'beta'],
        attrs={'units': ''}
    )
    numpy_array = get_numpy_array(array, ['*', 'z'])
    restored_array = restore_dimensions(
        numpy_array, from_dims=['*', 'z'], result_like=array)
    assert np.all(restored_array.values == array.values)
    assert len(restored_array.attrs) == 0
def test_restore_dimensions_complicated_asterisk():
    array = DataArray(
        np.random.randn(2, 3, 4, 5),
        dims=['x', 'h', 'y', 'q'],
        attrs={'units': ''}
    )
    numpy_array = get_numpy_array(array, ['*', 'x', 'y'])
    restored_array = restore_dimensions(
        numpy_array, from_dims=['*', 'x', 'y'], result_like=array)
    assert np.all(restored_array.values == array.values)
    assert len(restored_array.attrs) == 0
def test_get_numpy_array_1d():
    array = DataArray(
        np.random.randn(2),
        dims=['y'],
        attrs={'units': ''},
    )
    numpy_array = get_numpy_array(array, ['y'])
    assert numpy_array.shape == (2,)
    assert np.all(numpy_array == array.values)
    assert np.byte_bounds(numpy_array) == np.byte_bounds(array.values)
    assert numpy_array.base is array.values
def test_get_numpy_array_asterisk_creates_new_dim():
    array = DataArray(
        np.random.randn(2),
        dims=['x'],
        attrs={'units': ''},
    )
    numpy_array = get_numpy_array(array, ['x', '*'])
    assert numpy_array.shape == (2, 1)
    assert np.all(numpy_array[:, 0] == array.values)
    assert np.byte_bounds(numpy_array) == np.byte_bounds(array.values)
    assert numpy_array.base is array.values
def test_get_numpy_array_invalid_dimension_collected_by_asterisk():
    array = DataArray(
        np.random.randn(2),
        dims=['sheep'],
        attrs={'units': ''},
    )
    numpy_array = get_numpy_array(array, ['*'])
    assert numpy_array.shape == (2,)
    assert np.all(numpy_array == array.values)
    assert np.byte_bounds(numpy_array) == np.byte_bounds(array.values)
    assert numpy_array.base is array.values
def test_get_numpy_array_creates_new_dim_in_front():
    array = DataArray(
        np.random.randn(2),
        dims=['x'],
        attrs={'units': ''},
    )
    numpy_array = get_numpy_array(array, ['y', 'x'])
    assert numpy_array.shape == (1, 2)
    assert np.all(numpy_array[0, :] == array.values)
    assert np.byte_bounds(numpy_array) == np.byte_bounds(array.values)
    assert numpy_array.base is array.values
def test_get_numpy_array_asterisk_flattens():
    array = DataArray(
        np.random.randn(2, 3),
        dims=['y', 'z'],
        attrs={'units': ''},
    )
    numpy_array = get_numpy_array(array, ['*'])
    assert numpy_array.shape == (6,)
    assert np.all(numpy_array.reshape((2, 3)) == array.values)
    assert np.byte_bounds(numpy_array) == np.byte_bounds(array.values)
    assert numpy_array.base is array.values
def test_get_numpy_array_2d_reverse():
    array = DataArray(
        np.random.randn(2, 3),
        dims=['y', 'z'],
        attrs={'units': ''},
    )
    numpy_array = get_numpy_array(array, ['z', 'y'])
    assert numpy_array.shape == (3, 2)
    assert np.all(np.transpose(numpy_array, (1, 0)) == array.values)
    assert np.byte_bounds(numpy_array) == np.byte_bounds(array.values)
    assert numpy_array.base is array.values
Example #17
0
def get_array_from_state(state,
                         quantity_name,
                         quantity_units,
                         quantity_dims):

    if quantity_name not in state:
        raise IndexError(
            'The input state does not contain {}'.format(quantity_name))

    return get_numpy_array(
        state[quantity_name].to_units(quantity_units), quantity_dims)
def test_restore_dimensions_starz_to_zyx_doesnt_copy():
    array = DataArray(
        np.random.randn(2, 3, 4),
        dims=['z', 'y', 'x'],
        attrs={'units': ''}
    )
    numpy_array = get_numpy_array(array, ['*', 'z'])
    restored_array = restore_dimensions(
        numpy_array, from_dims=['*', 'z'], result_like=array)
    assert np.byte_bounds(restored_array.values) == np.byte_bounds(
        array.values)
    assert restored_array.values.base is array.values
Example #19
0
    def _get_k_v(self, sigma):

        out_dims = combine_dimensions([sigma], out_dims=('x', 'y', 'z'))

        sigma = get_numpy_array(sigma.to_units(''), out_dims=('x', 'y', 'z'))

        return DataArray(
            self._k_f * np.maximum(
                0,
                (sigma - self._sigma_b)/(1 - self._sigma_b)),
            dims=out_dims,
            attrs={'units': 's^-1'})
def test_get_numpy_array_zyx_to_starz_doesnt_copy():
    array = DataArray(
        np.random.randn(2, 3, 4),
        dims=['z', 'y', 'x'],
        attrs={'units': ''}
    )
    original_array = array.values
    numpy_array = get_numpy_array(array, ['*', 'z'])
    for i in range(2):
        assert np.all(numpy_array[:, i] == array.values[i, :, :].flatten())
    assert original_array is array.values
    assert np.byte_bounds(numpy_array) == np.byte_bounds(array.values)
    assert numpy_array.base is array.values
def test_restore_dimensions_starz_to_zyx_with_attrs():
    array = DataArray(
        np.random.randn(2, 3, 4),
        dims=['z', 'y', 'x'],
        attrs={'units': ''}
    )
    numpy_array = get_numpy_array(array, ['*', 'z'])
    restored_array = restore_dimensions(
        numpy_array, from_dims=['*', 'z'], result_like=array, result_attrs={'units': 'K'})
    assert np.all(restored_array.values == array.values)
    assert len(restored_array.attrs) == 1
    assert 'units' in restored_array.attrs
    assert restored_array.attrs['units'] == 'K'
def test_get_numpy_array_no_dimensions_listed_raises_value_error():
    array = DataArray(
        np.random.randn(2),
        dims=['z'],
        attrs={'units': ''},
    )
    try:
        numpy_array = get_numpy_array(array, [])
    except ValueError:
        pass
    except Exception as err:
        raise err
    else:
        raise AssertionError('Expected ValueError but no error was raised')
def test_get_numpy_array_not_enough_out_dims():
    array = DataArray(
        np.random.randn(2, 3),
        dims=['x', 'y'],
        attrs={'units': ''},
    )
    try:
        numpy_array = get_numpy_array(array, ['x'])
    except ValueError:
        pass
    except Exception as err:
        raise err
    else:
        raise AssertionError('Expected ValueError but no error was raised')
def test_restore_dimensions_removes_dummy_axes():
    array = DataArray(
        np.random.randn(2),
        dims=['z'],
        attrs={'units': ''}
    )
    numpy_array = get_numpy_array(array, ['x', 'y', 'z'])
    restored_array = restore_dimensions(
        numpy_array, from_dims=['x', 'y', 'z'], result_like=array)
    assert np.all(restored_array.values == array.values)
    assert len(restored_array.attrs) == 0
    assert np.byte_bounds(restored_array.values) == np.byte_bounds(
        array.values)
    assert restored_array.values.base is array.values
Example #25
0
    def __call__(self, state, timestep):
        '''
        Calculate surface and boundary layer tendencies.

        Args:
            state (dict):
                The model state dictionary

            timestep (timedelta):
                The model timestep

        Returns:
            state (dict), diagnostics(dict) :

            * The updated model state.
            * diagnostics for Simple Physics
        '''

        if 'latitude' not in state.keys():
            raise IndexError(
                'Simple Physics: State must contain a quantity called latitude'
            )
        U = get_numpy_array(state['eastward_wind'].to_units('m/s'),
                            ['x', 'y', 'z'])
        V = get_numpy_array(state['northward_wind'].to_units('m/s'),
                            ['x', 'y', 'z'])
        P = get_numpy_array(state['air_pressure'].to_units('Pa'),
                            ['x', 'y', 'z'])
        Pint = get_numpy_array(
            state['air_pressure_on_interface_levels'].to_units('Pa'),
            ['x', 'y', 'z'])
        T = get_numpy_array(state['air_temperature'].to_units('degK'),
                            ['x', 'y', 'z'])
        q = get_numpy_array(state['specific_humidity'].to_units('g/g'),
                            ['x', 'y', 'z'])
        q_surface = get_numpy_array(
            state['surface_specific_humidity'].to_units('g/g'), ['x', 'y'])

        Ts = get_numpy_array(state['surface_temperature'].to_units('degK'),
                             ['x', 'y'])
        Ps = get_numpy_array(state['surface_air_pressure'].to_units('Pa'),
                             ['x', 'y'])
        lats = get_numpy_array(state['latitude'].to_units('degrees_north'),
                               ['x', 'y'])
        lats = np.asfortranarray(lats, dtype=np.double)

        if lats.shape[0] == 1:  # 1-d array only
            num_longitudes = Ts.shape[0]
            lat_list = [lats[0, :] for i in range(num_longitudes)]
            lats = np.asfortranarray(np.stack(lat_list, axis=0))

        dims_mid = combine_dimensions([
            state['surface_temperature'], state['air_temperature'],
            state['eastward_wind'], state['northward_wind']
        ], ['x', 'y', 'z'])

        (t_out, u_out, v_out, q_out, precip_out, sensible_heat_flux,
         latent_heat_flux) = phys.get_new_state(U, V, T, P, Pint, q, Ps, Ts,
                                                q_surface, lats,
                                                timestep.total_seconds())

        latent_heat_flux[latent_heat_flux < 0] = 0

        new_state = {
            'eastward_wind':
            DataArray(u_out, dims=dims_mid,
                      attrs=state['eastward_wind'].attrs),
            'northward_wind':
            DataArray(v_out,
                      dims=dims_mid,
                      attrs=state['northward_wind'].attrs),
            'air_temperature':
            DataArray(t_out,
                      dims=dims_mid,
                      attrs=state['air_temperature'].attrs),
            'specific_humidity':
            DataArray(q_out,
                      dims=dims_mid,
                      attrs=state['specific_humidity'].attrs),
        }

        diagnostics = self.create_state_dict_for('_climt_diagnostics', state)

        diagnostics['stratiform_precipitation_rate'].values[:] = precip_out
        diagnostics[
            'surface_upward_sensible_heat_flux'].values[:] = sensible_heat_flux
        diagnostics[
            'surface_upward_latent_heat_flux'].values[:] = latent_heat_flux

        return diagnostics, new_state
Example #26
0
    def __call__(self, state):
        """
        Get heating tendencies and longwave fluxes.

        Args:

            state (dict):
                The model state dictionary.

        Returns:

            tendencies (dict), diagnostics (dict):

                * The longwave heating tendency.
                * The upward/downward longwave fluxes for cloudy and clear
                  sky conditions.

        """

        raw_arrays = self.get_numpy_arrays_from_state('_climt_inputs', state)
        Q = get_numpy_array(state['specific_humidity'].to_units('g/g'),
                            ['x', 'y', 'z'])
        Q = mass_to_volume_mixing_ratio(Q, 18.02)

        mid_level_shape = raw_arrays['air_temperature'].shape

        if self._calc_Tint:
            Tint = get_interface_values(
                raw_arrays['air_temperature'],
                raw_arrays['surface_temperature'], raw_arrays['air_pressure'],
                raw_arrays['air_pressure_on_interface_levels'])
        else:
            Tint = raw_arrays['air_temperature_on_interface_levels']

        diag_dict = self.create_state_dict_for('_climt_diagnostics', state)

        diag_arrays = numpy_version_of(diag_dict)

        tend_dict = self.create_state_dict_for('_climt_tendencies', state)

        tend_arrays = numpy_version_of(tend_dict)

        # TODO add dflx_dt as well

        raw_f_arrays = {}
        diag_f_arrays = {}
        tend_f_arrays = {}
        for quantity in raw_arrays.keys():
            raw_f_arrays[quantity] = np.asfortranarray(
                raw_arrays[quantity].transpose())

        for quantity in diag_arrays.keys():
            diag_f_arrays[quantity] = np.asfortranarray(
                diag_arrays[quantity].transpose())

        for quantity in tend_arrays.keys():
            tend_f_arrays[quantity] = np.asfortranarray(
                tend_arrays[quantity].transpose())

        Tint_f = np.asfortranarray(Tint.transpose())
        Q_f = np.asfortranarray(Q.transpose())

        _rrtmg_lw.rrtm_calculate_longwave_fluxes(
            mid_level_shape[0], mid_level_shape[1], mid_level_shape[2],
            raw_f_arrays['air_pressure'],
            raw_f_arrays['air_pressure_on_interface_levels'],
            raw_f_arrays['air_temperature'], Tint_f,
            raw_f_arrays['surface_temperature'], Q_f,
            raw_f_arrays['mole_fraction_of_ozone_in_air'],
            raw_f_arrays['mole_fraction_of_carbon_dioxide_in_air'],
            raw_f_arrays['mole_fraction_of_methane_in_air'],
            raw_f_arrays['mole_fraction_of_nitrous_oxide_in_air'],
            raw_f_arrays['mole_fraction_of_oxygen_in_air'],
            raw_f_arrays['mole_fraction_of_cfc11_in_air'],
            raw_f_arrays['mole_fraction_of_cfc12_in_air'],
            raw_f_arrays['mole_fraction_of_cfc22_in_air'],
            raw_f_arrays['mole_fraction_of_carbon_tetrachloride_in_air'],
            raw_f_arrays['surface_longwave_emissivity'],
            raw_f_arrays['cloud_area_fraction_in_atmosphere_layer'],
            raw_f_arrays['longwave_optical_thickness_due_to_aerosol'],
            diag_f_arrays['upwelling_longwave_flux_in_air'],
            diag_f_arrays['downwelling_longwave_flux_in_air'],
            tend_f_arrays['air_temperature'],
            diag_f_arrays['upwelling_longwave_flux_in_air_assuming_clear_sky'],
            diag_f_arrays[
                'downwelling_longwave_flux_in_air_assuming_clear_sky'],
            diag_f_arrays['longwave_heating_rate_assuming_clear_sky'],
            raw_f_arrays['longwave_optical_thickness_due_to_cloud'],
            raw_f_arrays['mass_content_of_cloud_ice_in_atmosphere_layer'],
            raw_f_arrays[
                'mass_content_of_cloud_liquid_water_in_atmosphere_layer'],
            raw_f_arrays['cloud_ice_particle_size'],
            raw_f_arrays['cloud_water_droplet_radius'])

        for quantity in diag_dict.keys():
            diag_dict[quantity].values = diag_f_arrays[quantity].transpose()

        for quantity in tend_dict.keys():
            tend_dict[quantity].values = tend_f_arrays[quantity].transpose()

        diag_dict['longwave_heating_rate'].values = tend_dict[
            'air_temperature'].values

        return tend_dict, diag_dict
Example #27
0
    def __call__(self, state, timestep):
        """
        Gets diagnostics from the current model state and steps the state
        forward in time according to the timestep.

        Args:
            state (dict): A model state dictionary. Will be updated with any
                diagnostic quantities produced by this object for the time of
                the input state.

        Returns:
            next_state (dict): A dictionary whose keys are strings indicating
                state quantities and values are the value of those quantities
                at the timestep after input state.

        Raises:
            KeyError: If a required quantity is missing from the state.
            InvalidStateException: If state is not a valid input for the
                Implicit instance for other reasons.
        """
        T = get_numpy_array(state['air_temperature'].to_units('degK'),
                            out_dims=('x', 'y', 'z'))
        q = get_numpy_array(state['specific_humidity'].to_units('kg/kg'),
                            out_dims=('x', 'y', 'z'))
        p = get_numpy_array(state['air_pressure'].to_units('Pa'),
                            out_dims=('x', 'y', 'z'))
        p_interface = get_numpy_array(
            state['air_pressure_on_interface_levels'].to_units('Pa'),
            out_dims=('x', 'y', 'z'))

        q_sat = bolton_q_sat(T, p, self._Rd, self._Rh2O)
        saturated = q > q_sat
        dqsat_dT = bolton_dqsat_dT(T[saturated], self._Lv, self._Rh2O,
                                   q_sat[saturated])

        condensed_q = np.zeros_like(q)
        condensed_q[saturated] = (q[saturated] - q_sat[saturated]) / (
            1 + self._Lv / self._Cpd * dqsat_dT)
        new_q = q.copy()
        new_T = T.copy()
        new_q[saturated] -= condensed_q[saturated]
        new_T[saturated] += self._Lv / self._Cpd * condensed_q[saturated]
        mass = (p_interface[:, :, 1:] - p_interface[:, :, :-1]) / (self._g *
                                                                   self._rhow)
        precipitation = np.sum(condensed_q * mass, axis=2)

        dims_3d = combine_dimensions([
            state['air_temperature'], state['specific_humidity'],
            state['air_pressure']
        ],
                                     out_dims=('x', 'y', 'z'))
        dims_2d = dims_3d[:-1]
        diagnostics = {
            'column_integrated_precipitation_rate':
            DataArray(precipitation / timestep.total_seconds(),
                      dims=dims_2d,
                      attrs={
                          'units': 'kg/s'
                      }).squeeze()
        }
        new_state = {
            'air_temperature':
            DataArray(new_T,
                      dims=dims_3d,
                      attrs=state['air_temperature'].attrs).squeeze(),
            'specific_humidity':
            DataArray(new_q,
                      dims=dims_3d,
                      attrs=state['specific_humidity'].attrs).squeeze(),
        }
        return new_state, diagnostics
Example #28
0
    def __call__(self, state):
        """
        Get heating tendencies and shortwave fluxes.

        Args:

            state (dict):
                The model state dictionary.

        Returns:

            tendencies (dict), diagnostics (dict):

                * The shortwave heating tendency.
                * The upward/downward shortwave fluxes for cloudy and clear
                  sky conditions.

        """

        raw_arrays = self.get_numpy_arrays_from_state('_climt_inputs', state)

        Q = get_numpy_array(state['specific_humidity'].to_units('g/g'),
                            ['x', 'y', 'z'])
        Q = mass_to_volume_mixing_ratio(Q, 18.02)

        mid_level_shape = raw_arrays['air_temperature'].shape

        Tint = get_interface_values(
            raw_arrays['air_temperature'], raw_arrays['surface_temperature'],
            raw_arrays['air_pressure'],
            raw_arrays['air_pressure_on_interface_levels'])

        diag_dict = self.create_state_dict_for('_climt_diagnostics', state)

        diag_arrays = self.get_numpy_arrays_from_state('_climt_diagnostics',
                                                       diag_dict)

        tend_dict = self.create_state_dict_for('_climt_tendencies', state)

        tend_arrays = numpy_version_of(tend_dict)

        model_time = state['time']

        if self._ignore_day_of_year:
            day_of_year = 0
        else:
            day_of_year = model_time.timetuple().tm_yday

        cos_zenith_angle = np.asfortranarray(np.cos(
            raw_arrays['zenith_angle']))

        raw_f_arrays = {}
        diag_f_arrays = {}
        tend_f_arrays = {}
        for quantity in raw_arrays.keys():
            if quantity not in [
                    'flux_adjustment_for_earth_sun_distance',
                    'solar_cycle_fraction'
            ]:
                raw_f_arrays[quantity] = np.asfortranarray(
                    raw_arrays[quantity].transpose())
            else:
                raw_f_arrays[quantity] = raw_arrays[quantity]

        for quantity in diag_arrays.keys():
            diag_f_arrays[quantity] = np.asfortranarray(
                diag_arrays[quantity].transpose())

        for quantity in tend_arrays.keys():
            tend_f_arrays[quantity] = np.asfortranarray(
                tend_arrays[quantity].transpose())

        Tint_f = np.asfortranarray(Tint.transpose())
        Q_f = np.asfortranarray(Q.transpose())
        zenith_f = np.asfortranarray(cos_zenith_angle.transpose())

        _rrtmg_sw.rrtm_calculate_shortwave_fluxes(
            mid_level_shape[0], mid_level_shape[1], mid_level_shape[2],
            day_of_year, raw_f_arrays['solar_cycle_fraction'],
            raw_f_arrays['flux_adjustment_for_earth_sun_distance'],
            raw_f_arrays['air_pressure'],
            raw_f_arrays['air_pressure_on_interface_levels'],
            raw_f_arrays['air_temperature'], Tint_f,
            raw_f_arrays['surface_temperature'], Q_f,
            raw_f_arrays['mole_fraction_of_ozone_in_air'],
            raw_f_arrays['mole_fraction_of_carbon_dioxide_in_air'],
            raw_f_arrays['mole_fraction_of_methane_in_air'],
            raw_f_arrays['mole_fraction_of_nitrous_oxide_in_air'],
            raw_f_arrays['mole_fraction_of_oxygen_in_air'],
            raw_f_arrays['surface_albedo_for_direct_shortwave'],
            raw_f_arrays['surface_albedo_for_direct_near_infrared'],
            raw_f_arrays['surface_albedo_for_diffuse_shortwave'],
            raw_f_arrays['surface_albedo_for_diffuse_near_infrared'], zenith_f,
            raw_f_arrays['cloud_area_fraction_in_atmosphere_layer'],
            diag_f_arrays['upwelling_shortwave_flux_in_air'],
            diag_f_arrays['downwelling_shortwave_flux_in_air'],
            tend_f_arrays['air_temperature'], diag_f_arrays[
                'upwelling_shortwave_flux_in_air_assuming_clear_sky'],
            diag_f_arrays[
                'downwelling_shortwave_flux_in_air_assuming_clear_sky'],
            diag_f_arrays['shortwave_heating_rate_assuming_clear_sky'],
            raw_f_arrays['shortwave_optical_thickness_due_to_aerosol'],
            raw_f_arrays['single_scattering_albedo_due_to_aerosol'],
            raw_f_arrays['aerosol_asymmetry_parameter'],
            raw_f_arrays['aerosol_optical_depth_at_55_micron'],
            raw_f_arrays['shortwave_optical_thickness_due_to_cloud'],
            raw_f_arrays['single_scattering_albedo_due_to_cloud'],
            raw_f_arrays['cloud_asymmetry_parameter'],
            raw_f_arrays['cloud_forward_scattering_fraction'],
            raw_f_arrays['mass_content_of_cloud_ice_in_atmosphere_layer'],
            raw_f_arrays[
                'mass_content_of_cloud_liquid_water_in_atmosphere_layer'],
            raw_f_arrays['cloud_ice_particle_size'],
            raw_f_arrays['cloud_water_droplet_radius'])

        for quantity in diag_arrays.keys():
            diag_dict[quantity].values = diag_f_arrays[quantity].transpose()
        for quantity in tend_arrays.keys():
            tend_dict[quantity].values = tend_f_arrays[quantity].transpose()

        diag_dict['shortwave_heating_rate'].values[:] = tend_dict[
            'air_temperature'].values

        return tend_dict, diag_dict