Esempio n. 1
0
def test_leapfrog_array_two_steps_filtered_williams(mock_prognostic_call):
    """Test that the Asselin filter is being correctly applied with a
    Williams factor of alpha=0.5"""
    mock_prognostic_call.return_value = ({
        'air_temperature':
        np.ones((3, 3)) * 0.
    }, {})
    state = {'air_temperature': np.ones((3, 3)) * 273.}
    timestep = timedelta(seconds=1.)
    time_stepper = Leapfrog([MockPrognostic()],
                            asselin_strength=0.5,
                            alpha=0.5)
    diagnostics, new_state = time_stepper.__call__(state, timestep)
    assert list(state.keys()) == ['air_temperature']
    assert (state['air_temperature'] == np.ones((3, 3)) * 273.).all()
    assert list(new_state.keys()) == ['air_temperature']
    assert (new_state['air_temperature'] == np.ones((3, 3)) * 273.).all()
    state = new_state
    mock_prognostic_call.return_value = ({
        'air_temperature':
        np.ones((3, 3)) * 2.
    }, {})
    diagnostics, new_state = time_stepper.__call__(state, timestep)
    # Asselin filter modifies the current state
    assert list(state.keys()) == ['air_temperature']
    assert (state['air_temperature'] == np.ones((3, 3)) * 273.5).all()
    assert list(new_state.keys()) == ['air_temperature']
    assert (new_state['air_temperature'] == np.ones((3, 3)) * 276.5).all()
Esempio n. 2
0
def test_leapfrog_array_two_steps_filtered(mock_prognostic_call):
    """Test that the Asselin filter is being correctly applied"""
    mock_prognostic_call.return_value = ({
        'air_temperature':
        np.ones((3, 3)) * 0.
    }, {})
    state = {'time': timedelta(0), 'air_temperature': np.ones((3, 3)) * 273.}
    timestep = timedelta(seconds=1.)
    time_stepper = Leapfrog(MockEmptyTendencyComponent(),
                            asselin_strength=0.5,
                            alpha=1.)
    diagnostics, new_state = time_stepper.__call__(state, timestep)
    assert same_list(state.keys(), ['time', 'air_temperature'])
    assert (state['air_temperature'] == np.ones((3, 3)) * 273.).all()
    assert same_list(new_state.keys(), ['time', 'air_temperature'])
    assert (new_state['air_temperature'] == np.ones((3, 3)) * 273.).all()
    state = new_state
    mock_prognostic_call.return_value = ({
        'air_temperature':
        np.ones((3, 3)) * 2.
    }, {})
    diagnostics, new_state = time_stepper.__call__(state, timestep)
    # Asselin filter modifies the current state
    assert same_list(state.keys(), ['time', 'air_temperature'])
    assert (state['air_temperature'] == np.ones((3, 3)) * 274.).all()
    assert same_list(new_state.keys(), ['time', 'air_temperature'])
    assert (new_state['air_temperature'] == np.ones((3, 3)) * 277.).all()
Esempio n. 3
0
def test_leapfrog_requires_same_timestep(mock_prognostic_call):
    """Test that the Asselin filter is being correctly applied"""
    mock_prognostic_call.return_value = ({'air_temperature': 0.}, {})
    state = {'air_temperature': 273.}
    time_stepper = Leapfrog([MockPrognostic()], asselin_strength=0.5)
    diagnostics, state = time_stepper.__call__(state, timedelta(seconds=1.))
    try:
        time_stepper.__call__(state, timedelta(seconds=2.))
    except ValueError:
        pass
    except Exception as err:
        raise err
    else:
        raise AssertionError('Leapfrog must require timestep to be constant')
Esempio n. 4
0
def test_leapfrog_float_two_steps_filtered(mock_prognostic_call):
    """Test that the Asselin filter is being correctly applied"""
    mock_prognostic_call.return_value = ({'air_temperature': 0.}, {})
    state = {'air_temperature': 273.}
    timestep = timedelta(seconds=1.)
    time_stepper = Leapfrog([MockPrognostic()], asselin_strength=0.5, alpha=1.)
    diagnostics, new_state = time_stepper.__call__(state, timestep)
    assert state == {'air_temperature': 273.}
    assert new_state == {'air_temperature': 273.}
    state = new_state
    mock_prognostic_call.return_value = ({'air_temperature': 2.}, {})
    diagnostics, new_state = time_stepper.__call__(state, timestep)
    # Asselin filter modifies the current state
    assert state == {'air_temperature': 274.}
    assert new_state == {'air_temperature': 277.}
Esempio n. 5
0
def main():
    # ============ Adjustable Variables ============
    # Integration Options
    dt = timedelta(minutes=15)  # timestep
    duration = '48_00:00'       # run duration ('<days>_<hours>:<mins>')t
    linearized = True
    ncout_freq = 6              # netcdf write frequency (hours)
    plot_freq = 6               # plot Monitor call frequency (hours)
    ntrunc = 42                 # triangular truncation for spharm (e.g., 21 --> T21)

    # Diffusion Options
    diff_on = True              # Use diffusion?
    k = 2.338e16                # Diffusion coefficient for del^4 hyperdiffusion

    # Forcing Options
    forcing_on = True           # Apply vort. tendency forcing?
    damp_ts = 14.7              # Damping timescale (in days)

    # I/O Options
    ncoutfile = os.path.join(os.path.dirname(__file__), 'sardeshmukh88.nc')
    append_nc = False           # Append to an existing netCDF file?
    # ==============================================

    start = time()

    # Get the initial state
    state = super_rotation(linearized=linearized, ntrunc=ntrunc)

    # Set up the Timestepper with the desired Prognostics
    if linearized:
        dynamics_prog = LinearizedDynamics(ntrunc=ntrunc)
        diffusion_prog = LinearizedDiffusion(k=k, ntrunc=ntrunc)
        damping_prog = LinearizedDamping(tau=damp_ts)
    else:
        dynamics_prog = NonlinearDynamics(ntrunc=ntrunc)
        diffusion_prog = NonlinearDiffusion(k=k, ntrunc=ntrunc)
        damping_prog = NonlinearDamping(tau=damp_ts)
    prognostics = [TendencyInDiagnosticsWrapper(dynamics_prog, 'dynamics')]
    if diff_on:
        prognostics.append(TendencyInDiagnosticsWrapper(diffusion_prog, 'diffusion'))
    if forcing_on:
        # Get our suptropical RWS forcing (from equatorial divergence)
        rws, rlat, rlon = rws_from_tropical_divergence(state)
        prognostics.append(TendencyInDiagnosticsWrapper(Forcing.from_numpy_array(rws, rlat, rlon, ntrunc=ntrunc,
                                                                                 linearized=linearized), 'forcing'))
        prognostics.append(TendencyInDiagnosticsWrapper(damping_prog, 'damping'))
    stepper = Leapfrog(prognostics)

    # Create Monitors for plotting & storing data
    plt_monitor = PlotFunctionMonitor(debug_plots.fourpanel)
    if os.path.isfile(ncoutfile) and not append_nc:
        os.remove(ncoutfile)

    aliases = get_component_aliases(*prognostics)
    nc_monitor = NetCDFMonitor(ncoutfile, write_on_store=True, aliases=aliases)

    # Figure out the end date of this run
    d, h, m = re.split('[_:]', duration)
    end_date = state['time'] + timedelta(days=int(d), hours=int(h), minutes=int(m))

    # Begin the integration loop
    idate = state['time']
    while state['time'] <= end_date:
        # Get the state at the next timestep using our Timestepper
        diagnostics, next_state = stepper(state, dt)

        # Add any calculated diagnostics to our current state
        state.update(diagnostics)

        # Write state to netCDF every <ncout_freq> hours
        fhour = (state['time'] - idate).days*24 + (state['time'] - idate).seconds/3600
        if fhour % ncout_freq == 0:
            print(state['time'])
            nc_monitor.store(state)

        # Make plot(s) every <plot_freq> hours
        if fhour % plot_freq == 0:
            plt_monitor.store(state)

        # Advance the state to the next timestep
        next_state['time'] = state['time'] + dt
        state = next_state

    print('TOTAL INTEGRATION TIME: {:.02f} min\n'.format((time()-start)/60.))
Esempio n. 6
0
    diffusion_prog = NonlinearDiffusion(k=k, ntrunc=ntrunc)
    damping_prog = NonlinearDamping(tau=damp_ts)
prognostics = [TendencyInDiagnosticsWrapper(dynamics_prog, 'dynamics')]

# Add diffusion
if diff_on:
    prognostics.append(
        TendencyInDiagnosticsWrapper(diffusion_prog, 'diffusion'))
# Add our forcing
if forcing_on:
    # Get our suptropical RWS forcing (from equatorial divergence)
    prognostics.append(TendencyInDiagnosticsWrapper(forcing_prog, 'forcing'))
    prognostics.append(TendencyInDiagnosticsWrapper(damping_prog, 'damping'))

# Create Timestepper
stepper = Leapfrog(prognostics)

# Create Monitors for plotting & storing data
plt_monitor = PlotFunctionMonitor(debug_plots.fourpanel)
if os.path.isfile(ncoutfile) and not append_nc:
    os.remove(ncoutfile)
aliases = get_component_aliases(*prognostics)
nc_monitor = NetCDFMonitor(ncoutfile, write_on_store=True, aliases=aliases)

# Figure out the end date of this run
d, h, m = re.split('[_:]', duration)
end_date = state['time'] + timedelta(days=int(d), hours=int(h), minutes=int(m))

# Begin the integration loop
idate = state['time']
while state['time'] <= end_date: