# Dynamic wakes 2¶

## Sequential wake propagation¶

For some applications it may be useful to run `foxes` in state-by-state mode, i.e., without the benefits of state-wise chunking. For example, when coupling it to another simulation tool that runs based on an overall outer loop over the individual states.

For such cases the `Sequential` algorithm has been added, which basically is an iterator over the states. Obviously this algorithm is much slower than the `Downwind` algorithm. On the plus side, for timeseries ambient states, it has the advantage that it can be combined with local propagation of wake parcels between two subsequent time stamps. This functionality is provided by the wake frame class `SeqDynamicWakes` and does not require spatial homogeneity.

``````In [1]:
``````
``````%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams["animation.html"] = "jshtml"

import foxes
import foxes.variables as FV
import foxes.constants as FC
``````

We create a case with a regular 3 x 3 wind farm layout:

``````In [2]:
``````
``````states = foxes.input.states.Timeseries(
data_source="timeseries_3000.csv.gz",
output_vars=[FV.WS, FV.WD, FV.TI, FV.RHO],
var2col={FV.WS: "WS", FV.WD: "WD", FV.TI: "TI", FV.RHO: "RHO"},
states_sel=range(230, 280),
)

farm = foxes.WindFarm()
farm,
xy_base=np.array([0.0, 0.0]),
step_vectors=np.array([[1000.0, 0], [0, 800.0]]),
steps=(3, 3),
turbine_models=["DTU10MW"],
verbosity=0
)

algo = foxes.algorithms.Sequential(
farm,
states,
rotor_model="centre",
wake_models=["Bastankhah025_linear_lim_k004"],
wake_frame="seq_dyn_wakes_1min",
chunks={FC.STATE: None, FC.POINT: 5000},
verbosity=1
)
``````

Notice that for the sake of drama, we artificially reset the time step to `1min` in the wake frame choice, more realistic would have been the choice `seq_dyn_wakes` which is based on the true time delta of the time series.

Our goal in this example is the creation of an animation that shows the dynamics of the flow in a horizontal plane at hub height. With the `Sequential` algorithm we can achieve this by treating the `algo` object as a Python iterator, for example within a `for`-loop.

Before doing so, we add a plugin that is evaluated whenever the iterator moves to the next state. In this case the plugin creates an image that is later on used for the animation:

``````In [3]:
``````
``````with foxes.utils.runners.DaskRunner() as runner:

# an image for an animation with every time step:
fig, ax = plt.subplots()
anigen = foxes.output.SeqFlowAnimationPlugin(
runner=runner,
orientation="xy",
var=FV.WS,
resolution=20,
levels=None,
quiver_pars=dict(scale=0.008, alpha=0.5),
quiver_n=111,
xmin=-5000,
ymin=-5000,
xmax=7000,
ymax=7000,
fig=fig,
ax=ax,
vmin=0,
vmax=10,
ret_im=True,
title=lambda si, s: f"t = {si:02d} min",
animated=True,
)
algo.plugins.append(anigen)

# Now run all states sequentially:
for r in algo:
print(algo.index)

print("\nFarm results:\n")
print(algo.farm_results)

# Create the animation:

anim = foxes.output.Animator(fig)
ani = anim.animate(interval=600)

lo = foxes.output.FarmLayoutOutput(farm)
lo.get_figure(
fig=fig,
ax=ax,
title="",
annotate=1,
anno_delx=-120,
anno_dely=-60,
alpha=0,
s=10,
)

plt.close()
print("done.")

print("Creating animation")
ani
``````
```
Initializing algorithm 'Sequential'
Initializing model 'Sequential'
Initializing model 'Timeseries'
States 'Timeseries': Reading static data 'timeseries_3000.csv.gz' from context 'states'
Path: /home/jonas/gits/wakes/foxes/foxes/data/states/timeseries_3000.csv.gz
Initializing model 'SeqState'
Initializing model 'centre'
Initializing model 'basic_ctrl_prer'
Initializing model 'DTU10MW'
Turbine type 'DTU10MW': Reading static data from context 'power_ct_curve'
Path: /home/jonas/gits/wakes/foxes/foxes/data/power_ct_curves/DTU-10MW-D178d3-H119.csv
Initializing model 'basic_ctrl_postr'
Initializing model 'basic_ctrl'
Initializing model 'seq_dyn_wakes_1min'
Initializing model 'WakeK'
Initializing model 'Bastankhah025_linear_lim_k004'
Initializing model 'axiwake6'

--------------------------------------------------
Running Sequential: calc_farm
--------------------------------------------------
n_states : 50
n_turbines: 9
--------------------------------------------------
states   : SeqState()
rotor    : CentreRotor()
controller: BasicFarmController()
wake frame: SeqDynamicWakes(dt_min=1.0)
--------------------------------------------------
wakes:
--------------------------------------------------
partial wakes:
0) Bastankhah025_linear_lim_k004: axiwake6, PartialAxiwake(n=6)
--------------------------------------------------
turbine models:
0) DTU10MW: PCtFile(D=178.3, H=119.0, P_nominal=10000.0, P_unit=kW, rho=1.225, var_ws_ct=REWS2, var_ws_P=REWS3)
--------------------------------------------------

Initializing model 'InitFarmData'
Initializing model 'SetAmbFarmResults'
Initializing model 'FarmWakesCalculation'
Initializing model 'ReorderFarmOutput'
Initializing model 'Sequential_calc'

--------------------------------------------------
Model oder
--------------------------------------------------
00) basic_ctrl
01) InitFarmData
02) centre
03) basic_ctrl
03.0) Post-rotor: DTU10MW
04) SetAmbFarmResults
05) FarmWakesCalculation
06) ReorderFarmOutput
--------------------------------------------------

Input data:

weight: ('state', 'turbine') float64, shape (50, 9)
Timeseries_data: ('state', 'Timeseries_vars') float64, shape (50, 4)
tmodel_sels: ('state', 'turbine', 'tmodels') bool, shape (50, 9, 1)

Output farm variables: AMB_CT, AMB_P, AMB_REWS, AMB_REWS2, AMB_REWS3, AMB_RHO, AMB_TI, AMB_WD, AMB_YAW, CT, D, H, P, REWS, REWS2, REWS3, RHO, TI, WD, X, Y, YAW, order, order_inv, order_ssel, weight

2018-10-10T05:00:00.000000000
2018-10-10T06:00:00.000000000
2018-10-10T07:00:00.000000000
2018-10-10T08:00:00.000000000
2018-10-10T09:00:00.000000000
2018-10-10T10:00:00.000000000
2018-10-10T11:00:00.000000000
2018-10-10T12:00:00.000000000
2018-10-10T13:00:00.000000000
2018-10-10T14:00:00.000000000
2018-10-10T15:00:00.000000000
2018-10-10T16:00:00.000000000
2018-10-10T17:00:00.000000000
2018-10-10T18:00:00.000000000
2018-10-10T19:00:00.000000000
2018-10-10T20:00:00.000000000
2018-10-10T21:00:00.000000000
2018-10-10T22:00:00.000000000
2018-10-10T23:00:00.000000000
2018-10-11T00:00:00.000000000
2018-10-11T01:00:00.000000000
2018-10-11T02:00:00.000000000
2018-10-11T03:00:00.000000000
2018-10-11T04:00:00.000000000
2018-10-11T05:00:00.000000000
2018-10-11T06:00:00.000000000
2018-10-11T07:00:00.000000000
2018-10-11T08:00:00.000000000
2018-10-11T09:00:00.000000000
2018-10-11T10:00:00.000000000
2018-10-11T11:00:00.000000000
2018-10-11T12:00:00.000000000
2018-10-11T13:00:00.000000000
2018-10-11T14:00:00.000000000
2018-10-11T15:00:00.000000000
2018-10-11T16:00:00.000000000
2018-10-11T17:00:00.000000000
2018-10-11T18:00:00.000000000
2018-10-11T19:00:00.000000000
2018-10-11T20:00:00.000000000
2018-10-11T21:00:00.000000000
2018-10-11T22:00:00.000000000
2018-10-11T23:00:00.000000000
2018-10-12T00:00:00.000000000
2018-10-12T01:00:00.000000000
2018-10-12T02:00:00.000000000
2018-10-12T03:00:00.000000000
2018-10-12T04:00:00.000000000
2018-10-12T05:00:00.000000000
2018-10-12T06:00:00.000000000

Farm results:

<xarray.Dataset> Size: 105kB
Dimensions:     (state: 50, turbine: 9, xyh: 3)
Coordinates:
* state       (state) datetime64[ns] 400B 2018-10-10T05:00:00 ... 2018-10-1...
* turbine     (turbine) int64 72B 0 1 2 3 4 5 6 7 8
Dimensions without coordinates: xyh
Data variables: (12/28)
AMB_CT      (state, turbine) float64 4kB 0.0 0.0 0.0 ... 0.814 0.814 0.814
AMB_P       (state, turbine) float64 4kB 0.0 0.0 0.0 ... 6.451e+03 6.451e+03
AMB_REWS    (state, turbine) float64 4kB 3.51 3.51 3.51 ... 9.59 9.59 9.59
AMB_REWS2   (state, turbine) float64 4kB 3.51 3.51 3.51 ... 9.59 9.59 9.59
AMB_REWS3   (state, turbine) float64 4kB 3.468 3.468 3.468 ... 9.577 9.577
AMB_RHO     (state, turbine) float64 4kB 1.27 1.27 1.27 ... 1.23 1.23 1.23
...          ...
order       (state, turbine) int64 4kB 8 7 6 5 4 3 2 1 0 ... 5 7 2 4 6 1 3 0
order_inv   (state, turbine) float64 4kB 8.0 7.0 6.0 5.0 ... 1.0 5.0 2.0 0.0
order_ssel  (state, turbine) float64 4kB 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0
weight      (state, turbine) float64 4kB 0.02 0.02 0.02 ... 0.02 0.02 0.02
txyh        (state, turbine, xyh) float64 11kB 0.0 0.0 ... 1.6e+03 119.0
tname       (turbine) <U2 72B 'T0' 'T1' 'T2' 'T3' 'T4' 'T5' 'T6' 'T7' 'T8'
Creating animation data
done.
Creating animation
```
``````Out[3]:
``````