Skip to content

Commit 41b094d

Browse files
authored
Merge pull request #2 from UMD-AOSC/day2-dev
Day2 dev
2 parents 2b4ac3e + a034d15 commit 41b094d

24 files changed

Lines changed: 239 additions & 339 deletions

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,15 @@
22

33
This is a 'hands-on' tutorial for the RIKEN International School on Data Assimilation (RISDA2018).
44
http://www.data-assimilation.riken.jp/risda2018/
5+
6+
This software package is based on routines developed for the publication:
7+
8+
Mathematical foundations of hybrid data assimilation from a synchronization perspective
9+
Penny, S.G., Chaos 27, 126801 (2017); https://doi.org/10.1063/1.5001819
10+
11+
http://aip.scitation.org/doi/full/10.1063/1.5001819
12+
13+
Instructions:
14+
This package uses the anaconda python distribution and for plotting uses plotly.
15+
16+
10.7 KB
Binary file not shown.
7.71 KB
Binary file not shown.
3.56 KB
Binary file not shown.
4.33 KB
Binary file not shown.

analysis_init.py

Lines changed: 51 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,21 @@
33
from class_state_vector import state_vector
44
from class_obs_data import obs_data
55
from class_da_system import da_system
6+
from sys import argv
7+
8+
#-----------------------------------------------------------------------
9+
# Usage:
10+
# python analysis_init.py {method}
11+
#
12+
# where {method} is any one of:
13+
# skip
14+
# nudging
15+
# OI
16+
# 3DVar
17+
# ETKF
18+
# PF
19+
# Hybrid
20+
#-----------------------------------------------------------------------
621

722
#-----------------------------------------------------------------------
823
# Read the L63 nature run
@@ -23,12 +38,15 @@
2338
#-----------------------------------------------------------------------
2439
# Try reducing the observed dimensions
2540
#-----------------------------------------------------------------------
26-
#obs.reduceDim([0]) # x only
27-
#obs.reduceDim([1]) # y only
28-
#obs.reduceDim([2]) # z only
29-
#obs.reduceDim([0,1]) # x and y only
30-
#obs.reduceDim([1,2]) # y and z only
31-
#obs.reduceDim([0,2]) # z and x only
41+
yp = [0,1,2]
42+
#yp = [0] # x only
43+
#yp = [1] # y only
44+
#yp = [2] # z only
45+
#yp = [0,1] # x and y only
46+
#yp = [1,2] # y and z only
47+
#yp = [0,2] # z and x only
48+
if len(yp) < xdim:
49+
obs.reduceDim(yp)
3250

3351
y_obs = obs.getVal()
3452
y_pts = obs.getPos()
@@ -52,6 +70,13 @@
5270
das.t = sv.getTimes()
5371
das.t0 = das.t[0]
5472

73+
#-----------------------------------------------------------------------
74+
# Initialize the ensemble
75+
#-----------------------------------------------------------------------
76+
das.edim = 3 #np.int(1*xdim)
77+
das.ens_bias_init = 0
78+
das.ens_sigma_init = 0.1
79+
5580
#-----------------------------------------------------------------------
5681
# Initialize the error covariances B and R, and the linearized
5782
# observation operator H
@@ -60,7 +85,7 @@
6085
I = np.identity(xdim)
6186

6287
# Set background error covariance
63-
sigma_b = 0.9
88+
sigma_b = 1.0
6489
B = I * sigma_b**2
6590

6691
# Set observation error covariance
@@ -70,16 +95,26 @@
7095
# Set the linear observation operator matrix as the identity by default
7196
H = I
7297

73-
print('B = ')
74-
print(B)
75-
print('R = ')
76-
print(R)
77-
print('H = ')
78-
print(H)
98+
# Set constant matrix for nudging
99+
const = 0.5
100+
C = I * const
79101

80102
das.setB(B)
81103
das.setR(R)
82104
das.setH(H)
105+
das.setC(C)
106+
107+
# Update the matrices to fit the reduced observation dimension
108+
if len(yp) < xdim:
109+
das.reduceYdim(yp)
110+
111+
print('B = ')
112+
print(das.getB())
113+
print('R = ')
114+
print(das.getR())
115+
print('H = ')
116+
print(das.getH())
117+
83118

84119
#-----------------------------------------------------------------------
85120
# Initialize the timesteps
@@ -104,10 +139,12 @@
104139
# Choose DA method:
105140
#-----------------------------------------------------------------------
106141

142+
method = argv[1]
143+
107144
#-----------
108145
# Test basic functionality
109146
#-----------
110-
method='skip'
147+
#method='skip'
111148

112149
#-----------
113150
# 3D methods

class_da_system.py

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ def __init__(self,x0=[],yo=[],t0=0,dt=0,alpha=0.5,state_vector=[],obs_data=[],ac
2929
self.SqrtB = []
3030
self.state_vector = state_vector
3131
self.obs_data = obs_data
32+
self.method = ''
33+
self.KH = []
34+
self.khidx = []
35+
self.edim = 0
36+
self.das_bias_init = 0
37+
self.das_sigma_init = 1
3238

3339
def __str__(self):
3440
print('xdim = ', self.xdim)
@@ -51,6 +57,8 @@ def __str__(self):
5157
print(self.state_vector)
5258
print('obs_data = ')
5359
print(obs_data)
60+
print('method = ')
61+
print(self.method)
5462
return 'type::da_system'
5563

5664
def setMethod(self,method):
@@ -80,6 +88,12 @@ def update(self,B=[0],R=[0],H=[0],t=[0],x0=[0]):
8088
self.t = t
8189
self.x0 = x0
8290

91+
def getC(self):
92+
return self.C
93+
94+
def setC(self,C):
95+
self.C = np.matrix(C)
96+
8397
def getB(self):
8498
return self.B
8599

@@ -119,12 +133,22 @@ def setH(self,H):
119133
# if (nc != self.xdim):
120134
# error('H must be ydim x xdim, but instead H is %d x %d'%(nr,nc))
121135

136+
def getKH(self):
137+
return self.KH, self.khidx
138+
139+
def setKH(self,KH,khidx):
140+
self.KH = KH
141+
self.khidx = khidx
142+
122143
def reduceYdim(self,yp):
123144
# print('reduceYdim:')
124145
# print('yp = ', yp)
125146
self.ydim = len(yp)
126147
self.setH(self.H[yp,:])
127-
self.setR(self.R[yp,yp])
148+
R = self.R
149+
R = R[yp,:]
150+
R = R[:,yp]
151+
self.setR(R)
128152

129153
def compute_analysis(self,xb,yo,params=[0]):
130154
# (params needed for 4D-Var)
@@ -190,16 +214,30 @@ def nudging(self,xb,yo):
190214
#---------------------------------------------------------------------------------------------------
191215
# Use observations at predefined points to drive the model system to the observed nature system
192216

217+
verbose = False
218+
193219
xb = np.matrix(xb).flatten().T
194220
yo = np.matrix(yo).flatten().T
221+
Hl = np.matrix(self.H)
222+
Ht = np.matrix(self.Ht)
195223

196-
const = np.diagonal(self.B)
224+
C = self.C
225+
xa = xb + C*(yo - Hl*xb)
197226

198-
xa = xb + const*(yo - xb)
227+
if verbose:
228+
print('xb = ')
229+
print(xb)
230+
print('C = ')
231+
print(C)
232+
print('yo = ')
233+
print(yo)
234+
print('Hl = ')
235+
print(Hl)
236+
print('xa = ')
237+
print(xa)
238+
print('Ht = ')
239+
print(Ht)
199240

200-
C = np.diag(const)
201-
Hl = self.H
202-
Ht = self.Ht
203241
KH = Ht*C*Hl
204242

205243
return xa.A1,KH
@@ -255,10 +293,10 @@ def _3DVar(self,xb,yo):
255293

256294
# 'preconditioning with B'
257295
I = np.identity(xdim)
258-
BHt = B*Ht
259-
BHtRinv = BHt*Rinv
260-
A = I + BHtRinv*Hl
261-
b1 = xb + BHtRinv*yo
296+
BHt = np.dot(B,Ht)
297+
BHtRinv = np.dot(BHt,Rinv)
298+
A = I + np.dot(BHtRinv,Hl)
299+
b1 = xb + np.dot(BHtRinv,yo)
262300

263301
# Use minimization algorithm to minimize cost function:
264302
xa,ierr = sp.sparse.linalg.cg(A,b1,x0=xb,tol=1e-05,maxiter=1000)

class_state_vector.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ def setTrajectory(self,states):
5151
x_avg = np.zeros(self.xdim)
5252
x_std = np.zeros(self.xdim)
5353
for i in range(self.xdim):
54-
x_avg[i] = np.mean(states[:,i])
55-
x_std[i] = np.std(states[:,i])
54+
x_avg[i] = np.nanmean(states[:,i])
55+
x_std[i] = np.nanstd(states[:,i])
5656
self.clim_mean = x_avg
5757
self.clim_std = x_std
5858

clean.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
rm *_*.pkl
2+
rm *.html

generate_analysis_3dDet.py

Lines changed: 8 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -57,33 +57,17 @@
5757
#-----------------------------------------------------------------------
5858
# Choose DA method:
5959
#-----------------------------------------------------------------------
60-
61-
method = das.getMethod() # (use default)
62-
63-
#-----------
64-
# Test basic functionality
65-
#-----------
66-
#method='skip'
67-
68-
#-----------
69-
# 3D methods
70-
#-----------
71-
# Nudging
72-
#method='nudging'
73-
# OI
74-
#method='OI'
75-
# 3D-Var
76-
#method='3DVar'
77-
78-
#das.setMethod(method)
60+
method = das.getMethod()
7961

8062
#-----------------------------------------------------------------------
8163
# Conduct data assimilation process
8264
#-----------------------------------------------------------------------
8365
#
84-
xa = sv.x0
66+
xa = das.x0
8567
xa_history = np.zeros_like(x_nature)
68+
xa_history[:] = np.nan
8669
KH_history = []
70+
KH_idx = []
8771
for i in range(0,maxit-acyc_step,acyc_step):
8872

8973
#----------------------------------------------
@@ -104,9 +88,6 @@
10488
yo = y_obs[i+acyc_step,:]
10589
yp = y_pts[i+acyc_step,:]
10690

107-
# if (len(yp) < xdim):
108-
# das.reduceYdim(yp)
109-
11091
#----------------------------------------------
11192
# Compute analysis
11293
#----------------------------------------------
@@ -116,22 +97,18 @@
11697
# print('KH = ')
11798
# print(KH)
11899

119-
# Archive the analysis
120-
xa_history[i+acyc_step,:] = xa
121100
# Fill in the missing timesteps with the forecast from the previous analysis IC's
122101
xa_history[i:i+acyc_step,:] = xf_4d[0:acyc_step,:]
102+
# Archive the analysis
103+
xa_history[i+acyc_step,:] = xa
123104

124105
# print('xa_history[i:i+acyc_step+1,:] = ', xa_history[i:i+acyc_step+1,:])
125106

126107
# Archive the KH matrix
127108
KH_history.append(deepcopy(KH))
109+
KH_idx.append(i)
128110

129-
#--------------------------------------------------------------------------------
130-
# Fill in unobserved dimensions (for plotting)
131-
#--------------------------------------------------------------------------------
132-
#fillValue=0.0
133-
#obs.fillDim(fillValue)
134-
#das.setObsData(obs)
111+
das.setKH(KH_history,KH_idx)
135112

136113
sv.setTrajectory(xa_history)
137114
sv.setName(name)

0 commit comments

Comments
 (0)