コード例 #1
0
ファイル: estuary.py プロジェクト: darothen/blb_estuary
    def run_model(self, dt=1., t_end=1000., t_spinup=48.):
        """ Run the current model with a simple Euler marching algorithm

        Parameters
        ----------
        dt : float
            Timestep, in hours
        t_end : float
            Cut-off time in hours to end integration/marching
        t_spinup : float
            Time in hours after which productivity will be scaled by
            daily averages of nutrient availability

        Returns
        -------
        result : DataFrame
            A DataFrame with the columns V, S, N, O corresponding to the
            components of the model state vector, indexed along time in hours.
            S, N, O are in kg/m3 and mmol/m3, and V is % of initial volume

        """

        # Initialize output as an array
        out_y = vstack([self.y0, ])
        ts = [0., ]

        # Main integration loop
        i, t = 1, 0.
        while t < t_end:
            # Pop last state off of stack
            y = out_y[-1].T

            # If we're past spin-up, then average the N concentration over
            # the last 24 hours to scale productivity
            if t > t_spinup:
                n_24hrs = int(ceil(24./dt))
                P_scale = \
                    mean(out_y[-n_24hrs:, 2]/out_y[-n_24hrs:, 0])/self.N_ocean
            else:
                P_scale = 1.

            # Euler step
            t += dt
            new_y = y + dt*self.estuary_ode(y, t, P_scale)

            # Correct non-physical V, S, N, or O (where they're < 0)
            new_y[new_y < 0] = 0.

            # Save output onto stack
            out_y = vstack([out_y, new_y])
            ts.append(t)

            i += 1

        # Shape output into DataFrame
        out = out_y[:]
        ts = array(ts)
        result = DataFrame(data=out, columns=['V', 'S', 'N', 'O'],
                           dtype=float,
                           index=Index(ts, name='time'))

        # Convert to molar concentrations
        result.S /= result.V
        result.N /= result.V
        result.O /= result.V

        # Add tidal height (meters) to output
        result['Z'] = result.V/self.estuary_area

        # Convert volume to percentage relative to initial
        result.V = 100*(result.V - self.V)/self.V

        return result