Beispiel #1
0
def iterate_runs(V, initial_aerosols, T, P, dt=0.01, dt_iters=2, max_steps=500):
    """
    Iterate through several different strategies for integrating the parcel model.
    """
    aerosols = initial_aerosols
    if V <= 0:
        return 0., 0., 0.

    ## Check that there are actually aerosols to deal with
    aerosol_N = [a.distribution.N for a in initial_aerosols]
    if len(aerosol_N) == 1:
        if aerosol_N[0] < 0.01: return (-9999., -9999., -9999.)
    else:
        new_aerosols = []
        for i in xrange(len(aerosol_N)):
            if aerosol_N[i] > 0.01: 
                new_aerosols.append(initial_aerosols[i])
        aerosols = new_aerosols[:]

    S_max_arg, _ = arg2000(V, T, P, aerosols)
    S_max_fn, _ = fn2005(V, T, P, aerosols)

    dt_orig = dt*1.
    finished = False
    S_max = None

    ## Strategy 1: Try CVODE with modest tolerances.
    print " Trying CVODE with default tolerance"
    S_max = run_model(V, aerosols, T, P, dt, max_steps=2000, solver='cvode')

    ## Strategy 2: Iterate over some increasingly relaxed tolerances for LSODA.
    if not S_max:
        while dt > dt_orig/(2**dt_iters):
            print " Trying LSODA, dt = %1.3e, max_steps = %d" % (dt, max_steps)
            S_max = run_model(V, aerosols, T, P, dt, max_steps, solver='lsoda')
            if not S_max:
                dt = dt/2.
                print "    Retrying..."
            else:
                finished = True
                break

    ## Strategy 3: Last ditch numerical integration with LSODE. This will likely take a
    ##             a very long time.
    if not finished and not S_max:
        print " Trying LSODE"
        S_max = run_model(V, aerosols, T, P, dt_orig, max_steps=1000, solver='lsode')

    ## Strategy 4: If all else fails return -9999.
    if not S_max:
        S_max = -9999.
        print " failed", V, dt

    return S_max, S_max_arg, S_max_fn
Beispiel #2
0
from lognorm import Lognorm
from parcel import AerosolSpecies
from pce_params import pce_deg1, pce_deg2, pce_deg3, pce_deg4
from activation import arg2000, fn2005

P0 = 80000. # Pressure, Pa
T0 = 283.15 # Temperature, K
S0 = -0.00 # Supersaturation. 1-RH from wv term
V = 0.7076312079 # m/s

aerosol1 = AerosolSpecies('(NH4)2SO4', Lognorm(mu=0.02494149518, sigma=1.301854178, N=2299.298741 ),
                          bins=200, kappa=0.4983795899)

pce1_Smax, pce1_ratio = pce_deg1(V, T0, P0, aerosol1)
pce2_Smax, pce2_ratio = pce_deg2(V, T0, P0, aerosol1)
pce3_Smax, pce3_ratio = pce_deg3(V, T0, P0, aerosol1)
pce4_Smax, pce4_ratio = pce_deg4(V, T0, P0, aerosol1)

ghan_Smax, ghan_ratio = arg2000(V, T0, P0, [aerosol1, ])

nenes_Smax, nenes_ratio = fn2005(V, T0, P0, [aerosol1, ])
Beispiel #3
0
def iterate_runs(V, initial_aerosols, T, P, S0=-0.0, dt=0.01, dt_iters=2, 
                 t_end=500., max_steps=500, output='smax',
                 fail_easy=True):
    """ Iterate through several different strategies for integrating the parcel model.

    As long as `fail_easy` is set to `False`, the strategies this method implements are:

    1. **CVODE** with a 10 second time limit and 2000 step limit.
    2. **LSODA** with up to `dt_iters` iterations, where the timestep `dt` is
       halved each time.
    3. **LSODE** with coarse tolerance and the original timestep.

    If these strategies all fail, the model will print a statement indicating such
    and return either -9999 if `output` was 'smax', or an empty array or DataFrame
    accordingly.

    Parameters
    ----------
    V, T, P : float
        Updraft speed and parcel initial temperature and pressure.
    S0 : float, optional, default 0.0
        Initial supersaturation, as a percent. Defaults to 100% relative humidity.
    initial_aerosols : array_like of :class:`AerosolSpecies`
        Set of aerosol populations contained in the parcel.
    dt : float
        Solver timestep, in seconds.
    dt_iters : int, optional, default 2
        Number of times to halve `dt` when attempting **LSODA** solver.
    max_steps : int, optional, default 1000
        Maximum number of steps per solver iteration. Defaults to 1000; setting 
        excessively high could produce extremely long computation times.
    t_end : float, optional, default 500.0
        Model time in seconds after which the integration will stop.
    solver : string, optional, default 'lsoda'
        Alias of which solver to use; see :class:`Integrator` for all options.
    output : string, optional, default 'smax'
        Alias indicating which output format to use; see :class:`ParcelModel` for
        all options.
    fail_easy : boolean, optional, default `True`
        If `True`, then stop after the first strategy (**CVODE**)

    Returns
    -------
    Smax : (user-defined)
        Output from parcel model simulation based on user-specified `output` argument. See
        :class:`ParcelModel` for details.

    """
    aerosols = initial_aerosols
    if V <= 0:
        return 0., 0., 0.

    ## Check that there are actually aerosols to deal with
    aerosol_N = [a.distribution.N for a in initial_aerosols]
    if len(aerosol_N) == 1:
        if aerosol_N[0] < 0.01: return (-9999., -9999., -9999.)
    else:
        new_aerosols = []
        for i in xrange(len(aerosol_N)):
            if aerosol_N[i] > 0.01: 
                new_aerosols.append(initial_aerosols[i])
        aerosols = new_aerosols[:]

    S_max_arg, _, _ = arg2000(V, T, P, aerosols)
    S_max_fn, _, _ = mbn2014(V, T, P, aerosols)

    dt_orig = dt*1.
    finished = False
    S_max = None

    ## Strategy 1: Try CVODE with modest tolerances.
    print " Trying CVODE with default tolerance"
    S_max = run_model(V, aerosols, T, P, dt, S0=S0, max_steps=2000, solver='cvode',
                      t_end=t_end, output=output, 
                      solver_args={'iter': 'Newton', 'time_limit': 10.0, 
                                   'linear_solver': "DENSE"})

    ## Strategy 2: Iterate over some increasingly relaxed tolerances for LSODA.
    if not S_max and not fail_easy:
        while dt > dt_orig/(2**dt_iters):
            print " Trying LSODA, dt = %1.3e, max_steps = %d" % (dt, max_steps)
            S_max = run_model(V, aerosols, T, P, dt, S0, max_steps, solver='lsoda',
                              t_end=t_end)
            if not S_max:
                dt /= 2.
                print "    Retrying..."
            else:
                finished = True
                break

    ## Strategy 3: Last ditch numerical integration with LSODE. This will likely take a
    ##             a very long time.
    if not finished and not S_max and not fail_easy:
        print " Trying LSODE"
        S_max = run_model(V, aerosols, T, P, dt_orig, max_steps=1000, solver='lsode',
                          t_end=t_end, S0=S0)

    ## Strategy 4: If all else fails return -9999.
    if not S_max:
        if output == "smax":
            S_max = -9999.
        elif output == "arrays":
            S_max = empty([0]), empty([0])
        elif output == "dataframes":
            S_max = DataFrame(data={"S": [nan]}), DataFrame(data={"aerosol1": [nan]})
        else:
            S_max = nan
        print " failed", V, dt

    return S_max, S_max_arg, S_max_fn