1- include (" GModel.jl" ) # Contains Lorenz 96 source code
2-
31# Import modules
42using Distributions # probability distributions and associated functions
53using LinearAlgebra
@@ -16,134 +14,7 @@ using CalibrateEmulateSample.EnsembleKalmanProcesses.Localizers
1614
1715const EKP = EnsembleKalmanProcesses
1816
19- # G(θ) = H(Ψ(θ,x₀,t₀,t₁))
20- # y = G(θ) + η
21-
22- # This will change for different Lorenz simulators
23- struct LorenzConfig{FT <: Real }
24- " Length of a fixed integration timestep"
25- dt:: FT
26- " Total duration of integration (T = N*dt)"
27- T:: FT
28- end
29-
30- # This will change for each ensemble member
31- struct EnsembleMemberConfig{VV <: AbstractVector }
32- " state-dependent-forcing"
33- F:: VV
34- end
35-
36- # This will change for different "Observations" of Lorenz
37- struct ObservationConfig{FT1 <: Real , FT2 <: Real }
38- " initial time to gather statistics (T_start = N_start*dt)"
39- T_start:: FT1
40- " end time to gather statistics (T_end = N_end*dt)"
41- T_end:: FT2
42- end
43- # ########################################################################
44- # ########################### Model Functions ############################
45- # ########################################################################
46-
47- # Forward pass of forward model
48- # Inputs:
49- # - params: structure with F (state-dependent-forcing vector)
50- # - x0: initial condition vector
51- # - config: config of forward run
52- # - observation_config: config for observations
53-
54- function lorenz_forward (
55- params:: EnsembleMemberConfig ,
56- x0:: VV ,
57- config:: LorenzConfig ,
58- observation_config:: ObservationConfig ,
59- ) where {VV <: AbstractVector }
60- # run the Lorenz simulation
61- xn = lorenz_solve (params, x0, config)
62- # Get statistics
63- gt = stats (xn, config, observation_config)
64- return gt
65- end
66-
67- # Calculates statistics for forward model output
68- # Inputs:
69- # - xn: timeseries of states for length of simulation through Lorenz96
70- # - config: config of forward run
71- # - observation_config: config for observations
72- function stats (xn:: VorM , config:: LorenzConfig , observation_config:: ObservationConfig ) where {VorM <: AbstractVecOrMat }
73- T_start = observation_config. T_start
74- T_end = observation_config. T_end
75- dt = config. dt
76- N_start = Int (ceil (T_start / dt))
77- N_end = Int (ceil (T_end / dt))
78- xn_stat = xn[:, N_start: N_end]
79- N_state = size (xn_stat, 1 )
80- gt = zeros (2 * N_state)
81- gt[1 : N_state] = mean (xn_stat, dims = 2 )
82- gt[(N_state + 1 ): (2 * N_state)] = std (xn_stat, dims = 2 )
83- return gt
84- end
85-
86- # Forward pass of the Lorenz 96 model
87- # Inputs:
88- # - params: structure with F (state-dependent-forcing vector)
89- # - x0: initial condition vector
90- # - config: structure including dt (timestep Float64(1)) and T (total time Float64(1))
91- function lorenz_solve (params:: EnsembleMemberConfig , x0:: VorM , config:: LorenzConfig ) where {VorM <: AbstractVecOrMat }
92- # Initialize
93- nstep = Int (ceil (config. T / config. dt))
94- state_dim = size (x0, 1 )
95- xn = zeros (state_dim, nstep + 1 )
96- xn[:, 1 ] = x0
97-
98- # March forward in time
99- for j in 1 : nstep
100- xn[:, j + 1 ] = RK4 (params, xn[:, j], config)
101- end
102-
103- return xn
104- end
105-
106- # Lorenz 96 system
107- # f = dx/dt
108- # Inputs:
109- # - params: structure with F (state-dependent-forcing vector)
110- # - x: current state
111- function f (params:: EnsembleMemberConfig , x:: VV ) where {VV <: AbstractVector }
112- F = params. F
113- N = length (x)
114- f = zeros (N)
115- # Loop over N positions
116- for i in 3 : (N - 1 )
117- f[i] = - x[i - 2 ] * x[i - 1 ] + x[i - 1 ] * x[i + 1 ] - x[i] + F[i]
118- end
119- # Periodic boundary conditions
120- f[1 ] = - x[N - 1 ] * x[N] + x[N] * x[2 ] - x[1 ] + F[1 ]
121- f[2 ] = - x[N] * x[1 ] + x[1 ] * x[3 ] - x[2 ] + F[2 ]
122- f[N] = - x[N - 2 ] * x[N - 1 ] + x[N - 1 ] * x[1 ] - x[N] + F[N]
123- # Output
124- return f
125- end
126-
127- # RK4 solve
128- # Inputs:
129- # - params: structure with F (state-dependent-forcing vector)
130- # - xold: current state
131- # - config: structure including dt (timestep Float64(1)) and T (total time Float64(1))
132- function RK4 (params:: EnsembleMemberConfig , xold:: VorM , config:: LorenzConfig ) where {VorM <: AbstractVecOrMat }
133- N = length (xold)
134- dt = config. dt
135-
136- # Predictor steps (note no time-dependence is needed here)
137- k1 = f (params, xold)
138- k2 = f (params, xold + k1 * dt / 2.0 )
139- k3 = f (params, xold + k2 * dt / 2.0 )
140- k4 = f (params, xold + k3 * dt)
141- # Step
142- xnew = xold + (dt / 6.0 ) * (k1 + 2.0 * k2 + 2.0 * k3 + k4)
143- # Output
144- return xnew
145- end
146-
17+ include (" ./lorenz_spatial_dep.jl" )
14718
14819# #######################################################################
14920# ########################### Problem setup #############################
0 commit comments