Example using lorenz-96 model in eWaterCycle

1         In:
# general python
import warnings
warnings.filterwarnings("ignore", category=UserWarning)
import numpy as np
import os
from pathlib import Path
import yaml
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime
import scipy
import xarray as xr
from tqdm import tqdm
import glob
from devtools import pprint
2         In:
# general eWC
import ewatercycle
import ewatercycle.forcing
import ewatercycle.models

Ensure correct package is installed:

pip install ewatercycle-lorenz
5         In:
from ewatercycle.models import Lorenz
6         In:
from ewatercycle.forcing import sources
7         In:
experiment_start_date = "1997-08-01T00:00:00Z"
experiment_end_date = "1997-08-20T00:00:00Z"
path = Path.cwd()
8         In:
forcing = sources.LorenzForcing(start_time = experiment_start_date,
                      end_time = experiment_end_date,
                      directory = path,
                      F=8,
                      dt=1e-3)
9         In:
model = Lorenz(forcing=forcing)
10         In:
J = 40
common_state = np.zeros(J)
common_state[19] = 0.01
11         In:
config, _ = model.setup(J=J,
                        start_state=list(common_state))
12         In:
model.initialize(config)
13         In:
n_timesteps = int((model.end_time - model.start_time) /  model.time_step)
pbar = tqdm(total=n_timesteps)

output = pd.DataFrame(columns = ['truth'])
while model.time < model.end_time:
    model.update()
    output.loc[model.time_as_datetime] = model.get_value("state")[5]

    pbar.update(1)
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████▉| 18990/19000 [01:40<00:00, 183.26it/s]
14         In:
pbar.close()
model.finalize()
15         In:
output.plot();
_images/example_model_run_lorenz_14_0.png
16         In:
N = 2 #numeber of ensemble members

#start with  an empty ensemble
ensemble = []

for n in range (N):
    #add an ensemble methods
    ensemble.append(Lorenz(forcing=forcing))
    config, _ = ensemble[n].setup(J=J, start_state=list(common_state))
    ensemble[n].initialize(config)

    ensemble_member_state = np.array(ensemble[n].get_value('state'))
    ensemble_member_state[5] = ensemble_member_state[5] + np.random.randn(1)[0]*0.01
    ensemble[n].set_value('state', ensemble_member_state)

    #also add a column to the output dataframe to store the output
    output['ensemble' + str(n)]= np.nan
17         In:
ref_model = ensemble[0]
          In:
#run the Ensemble. We will use the time of the first ensemble member to keep time, assuming that all
#models use the same time steps.
n_timesteps = int((ref_model.end_time - ref_model.start_time) /  ref_model.time_step)
# pbar = tqdm(total=n_timesteps) # some issue with double loops

while ensemble[0].time < ensemble[0].end_time:
    #loop through the ensemble members and store the state after each update
    for n in range (N):
        ensemble[n].update()
        output.at[ensemble[n].time_as_datetime,'ensemble' + str(n)] = ensemble[n].get_value('state')[5]
    # pbar.update(1) # visual
19         In:
output.loc[:,'ensemble0':].plot(color='k')
output.loc[:,'truth'].plot(color='r');
_images/example_model_run_lorenz_18_0.png
20         In:
for n in range (N):
     ensemble[n].finalize()