1 |
dimitri |
1.1 |
clear all, close all |
2 |
|
|
|
3 |
|
|
% domain-specific preamble |
4 |
|
|
face=3; ix=326:365; jx=311:350; kx=1:50; % domain specification |
5 |
|
|
nme='beaufort'; % domain name |
6 |
|
|
obcs_src='cube78'; % source of open boundaries |
7 |
|
|
nt=179; % number of obcs time steps |
8 |
|
|
|
9 |
|
|
% directory names (may need to be created or modified) |
10 |
|
|
eval(['cd /skylla/' nme]); |
11 |
|
|
pout=['/skylla/' nme '/run_template/']; % output path name |
12 |
|
|
pin='/skylla/cube/run_template/'; % CS510 input files |
13 |
|
|
grid='/skylla/cube/grid/cube66/'; % location of CS510 grid files |
14 |
|
|
pnm=['/skylla/cube/' obcs_src '/']; % open boundary path name |
15 |
|
|
|
16 |
|
|
% miscellaneous input files |
17 |
|
|
bathy_file='GEBCO_510x6x510_ver06_dig.bin'; |
18 |
|
|
diffkr_file= ... |
19 |
dimitri |
1.2 |
'/skylla/data/atmos/blend_forcing/cube78_forcing/DIFFKR_2_20_1_lat6070_cube78'; |
20 |
dimitri |
1.1 |
|
21 |
|
|
% derived quantities |
22 |
|
|
nx=length(ix); ny=length(jx); nz=length(kx); |
23 |
|
|
dim=[num2str(nx) 'x' num2str(ny)]; |
24 |
|
|
|
25 |
|
|
% CS510 grid input files |
26 |
|
|
rc=-readbin([grid 'RC.data'],nz); % depths to center of cell |
27 |
|
|
rf=-readbin([grid 'RF.data'],nz+1); % depths to cell faces |
28 |
|
|
thk=diff(rf); % CS510 thicknesses |
29 |
|
|
xc=read_cs_ifjk([grid 'XC.data'],ix,face,jx); |
30 |
|
|
yc=read_cs_ifjk([grid 'YC.data'],ix,face,jx); |
31 |
|
|
|
32 |
|
|
% location of domain-specific grid files: these need to be |
33 |
|
|
% generated by running the model for at least one time step |
34 |
|
|
% prior to balancing BCs, the last item in this script. |
35 |
|
|
regional_grid=['/skylla/' nme '/grid/']; |
36 |
|
|
genBC={'N','W','S'}; % generate genBC boundary conditions |
37 |
|
|
balBC='W'; % balance balBC boundary condition |
38 |
|
|
|
39 |
|
|
|
40 |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
41 |
|
|
% create tile input |
42 |
|
|
fn=[pin 'tile00' int2str(face) '.mitgrid']; |
43 |
|
|
tile=readbin(fn,[511 511 16],1,'real*8'); |
44 |
|
|
writebin([pout 'LONC.bin'],tile(ix,jx, 1)); |
45 |
|
|
writebin([pout 'LATC.bin'],tile(ix,jx, 2)); |
46 |
|
|
writebin([pout 'DXF.bin' ],tile(ix,jx, 3)); |
47 |
|
|
writebin([pout 'DYF.bin' ],tile(ix,jx, 4)); |
48 |
|
|
writebin([pout 'RA.bin' ],tile(ix,jx, 5)); |
49 |
|
|
writebin([pout 'LONG.bin'],tile(ix,jx, 6)); |
50 |
|
|
writebin([pout 'LATG.bin'],tile(ix,jx, 7)); |
51 |
|
|
writebin([pout 'DXV.bin' ],tile(ix,jx, 8)); |
52 |
|
|
writebin([pout 'DYU.bin' ],tile(ix,jx, 9)); |
53 |
|
|
writebin([pout 'RAZ.bin' ],tile(ix,jx,10)); |
54 |
|
|
writebin([pout 'DXC.bin' ],tile(ix,jx,11)); |
55 |
|
|
writebin([pout 'DYC.bin' ],tile(ix,jx,12)); |
56 |
|
|
writebin([pout 'RAW.bin' ],tile(ix,jx,13)); |
57 |
|
|
writebin([pout 'RAS.bin' ],tile(ix,jx,14)); |
58 |
|
|
writebin([pout 'DXG.bin' ],tile(ix,jx,15)); |
59 |
|
|
writebin([pout 'DYG.bin' ],tile(ix,jx,16)); |
60 |
|
|
|
61 |
|
|
|
62 |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
63 |
|
|
% make bathymetry file |
64 |
|
|
topog=read_cs_ifjk([pin bathy_file],ix,face,jx); |
65 |
|
|
if strcmp(nme,'arctic') |
66 |
|
|
topog(368:420,1:43)=0; topog(375:417,1:63)=0; topog(376:396,1:80)=0; |
67 |
|
|
topog(377:386,1:92)=0; topog(355:420,220:384)=0; topog(408:420,213:384)=0; |
68 |
|
|
topog(413:420,207:384)=0; topog(417:420,202:384)=0; topog(94:103,379:384)=0; |
69 |
|
|
elseif strcmp(nme,'weddell') |
70 |
|
|
topog(37:41,1:7)=0; topog(48:54,1:12)=0; |
71 |
|
|
end |
72 |
|
|
writebin([pout 'BATHY_' obcs_src '_' dim '_' nme],topog); |
73 |
|
|
|
74 |
|
|
|
75 |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
76 |
|
|
% make DIFFKR file |
77 |
|
|
diffkr=read_cs_face(diffkr_file,face,kx); |
78 |
|
|
fout=[pout 'DIFFKR_' obcs_src '_' dim 'x' int2str(length(kx)) '_' nme]; |
79 |
|
|
writebin(fout,diffkr(ix,jx,:)); |
80 |
|
|
|
81 |
|
|
|
82 |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
83 |
|
|
% make pickup files |
84 |
|
|
% requires that pickup*.meta files be constructed mannually |
85 |
|
|
fn=[pin 'pickup.0000000216.' obcs_src]; |
86 |
|
|
for k=1:303, mydisp(k) |
87 |
|
|
tmp=read_cs_face(fn,face,k,'real*8'); |
88 |
dimitri |
1.2 |
writebin([pout 'pickup.0000000216.data'],tmp(ix,jx),1,'real*8',k-1); |
89 |
dimitri |
1.1 |
end |
90 |
|
|
fn=[pin 'pickup_seaice.0000000216.' obcs_src]; |
91 |
|
|
for k=1:22, mydisp(k) |
92 |
|
|
tmp=read_cs_face(fn,face,k,'real*8'); |
93 |
dimitri |
1.2 |
writebin([pout 'pickup_seaice.0000000216.data'],tmp(ix,jx),1,'real*8',k-1); |
94 |
dimitri |
1.1 |
end |
95 |
|
|
|
96 |
|
|
|
97 |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
98 |
|
|
% make start-up files |
99 |
|
|
for clm={'PHC','WGHC','WOA01','WOA05'} |
100 |
|
|
for fld={'SALT','THETA'} |
101 |
|
|
fin=[pin clm{1} '_' fld{1} '_JAN_510x6x510x50.bin']; |
102 |
|
|
fout=[pout clm{1} '_' fld{1} '_JAN_' dim 'x50_' nme]; |
103 |
|
|
tmp=read_cs_face(fin,face,kx); |
104 |
|
|
writebin(fout,tmp(ix,jx,:)); |
105 |
|
|
end |
106 |
|
|
end |
107 |
|
|
fn=[pin 'pickup_seaice.0000000216.' obcs_src]; |
108 |
|
|
id=[9 16 19 22]; fld={'HSNOW','HEFF','AREA','HSALT'} |
109 |
|
|
for i=1:length(id) |
110 |
|
|
tmp=read_cs_face(fn,face,id(i),'real*8'); tmp(find(tmp<0))=0; |
111 |
|
|
if id(i)==19, tmp(find(tmp>1))=1; end |
112 |
|
|
writebin([pout fld{i} '_' dim '_' nme '.' obcs_src],tmp(ix,jx)); |
113 |
|
|
end |
114 |
|
|
|
115 |
|
|
|
116 |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
117 |
|
|
% generate seaice boundary conditions |
118 |
|
|
for fld={'SIheff','SIarea','SIhsalt','SIhsnow','SIuice','SIvice'} |
119 |
|
|
switch fld{1} |
120 |
|
|
case 'SIheff', id = 'h' ; |
121 |
|
|
case 'SIarea', id = 'a' ; |
122 |
|
|
case 'SIhsalt', id = 'sl' ; |
123 |
|
|
case 'SIhsnow', id = 'sn' ; |
124 |
|
|
case 'SIuice', id = 'uice'; |
125 |
|
|
case 'SIvice', id = 'vice'; |
126 |
|
|
end |
127 |
|
|
fnm=dir([pnm fld{1} '/' fld{1} '.0*']); |
128 |
|
|
for i=1:length(fnm), mydisp(i) |
129 |
|
|
tmp=read_cs_face([pnm fld{1} '/' fnm(i).name],face); |
130 |
|
|
for g=1:length(genBC) |
131 |
|
|
switch genBC{g} |
132 |
|
|
case 'N', OB=tmp(ix,max(jx),:); |
133 |
|
|
case 'S' |
134 |
|
|
if strcmp(id,'vice') |
135 |
|
|
OB=tmp(ix,min(jx)+1,:); |
136 |
|
|
else |
137 |
|
|
OB=tmp(ix,min(jx),:); |
138 |
|
|
end |
139 |
|
|
case 'E', OB=tmp(max(ix),jx,:); |
140 |
|
|
case 'W' |
141 |
|
|
if strcmp(id,'uice') |
142 |
|
|
OB=tmp(min(ix)+1,jx,:); |
143 |
|
|
else |
144 |
|
|
OB=tmp(min(ix),jx,:); |
145 |
|
|
end |
146 |
|
|
end |
147 |
|
|
fout=[pout 'OB' genBC{g} id '_' nme '_' dim '.bin']; |
148 |
|
|
if i==1 |
149 |
|
|
% add 4 identical daily records so that it is possible, |
150 |
|
|
% if desired, to start from beginning of 1992 |
151 |
|
|
for r=1:4, writebin(fout,OB), end |
152 |
|
|
end |
153 |
|
|
writebin(fout,OB,1,'real*4',i+3) |
154 |
|
|
end |
155 |
|
|
end |
156 |
|
|
end |
157 |
|
|
|
158 |
|
|
|
159 |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
160 |
|
|
% generate U/V/T/S lateral boundary conditions |
161 |
|
|
for fld={'THETA','SALTanom','UVELMASS','VVELMASS'} |
162 |
|
|
fnm=dir([pnm fld{1} '/' fld{1} '.0*']); |
163 |
|
|
switch fld{1} |
164 |
|
|
case{'THETA','SALTanom'}, prec='real*8'; |
165 |
|
|
otherwise prec='real*4'; |
166 |
|
|
end |
167 |
|
|
for i=1:length(fnm), mydisp(i) |
168 |
|
|
tmp=read_cs_face([pnm fld{1} '/' fnm(i).name],face,kx,prec); |
169 |
|
|
if strcmp(fld{1},'SALTanom'), tmp=tmp+35; end |
170 |
|
|
for g=1:length(genBC) |
171 |
|
|
switch genBC{g} |
172 |
|
|
case 'N', OB=tmp(ix,max(jx),:); |
173 |
|
|
case 'S' |
174 |
|
|
if strcmp(fld{1},'VVELMASS') |
175 |
|
|
OB=tmp(ix,min(jx)+1,:); |
176 |
|
|
else |
177 |
|
|
OB=tmp(ix,min(jx),:); |
178 |
|
|
end |
179 |
|
|
case 'E', OB=tmp(max(ix),jx,:); |
180 |
|
|
case 'W' |
181 |
|
|
if strcmp(fld{1},'UVELMASS') |
182 |
|
|
OB=tmp(min(ix)+1,jx,:); |
183 |
|
|
else |
184 |
|
|
OB=tmp(min(ix),jx,:); |
185 |
|
|
end |
186 |
|
|
end |
187 |
|
|
fout=[pout 'OB' genBC{g} lower(fld{1}(1)) '_' nme '_' dim '.bin']; |
188 |
|
|
if i==1, writebin(fout,OB), end |
189 |
|
|
writebin(fout,OB,1,'real*4',i) |
190 |
|
|
end |
191 |
|
|
end |
192 |
|
|
end |
193 |
|
|
|
194 |
|
|
|
195 |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
196 |
|
|
% stabilize T/S |
197 |
|
|
tmp=read_cs_face([grid 'hFacC.data'],face,1:50); |
198 |
|
|
maskW=squeeze(tmp(ix(1),jx,:)); |
199 |
|
|
maskW(find(maskW))=1; maskW(find(~maskW))=nan; |
200 |
|
|
maskE=squeeze(tmp(max(ix),jx,:)); |
201 |
|
|
maskE(find(maskE))=1; maskE(find(~maskE))=nan; |
202 |
|
|
maskN=squeeze(tmp(ix,max(jx),:)); |
203 |
|
|
maskN(find(maskN))=1; maskN(find(~maskN))=nan; |
204 |
|
|
maskS=squeeze(tmp(ix,jx(1),:)); |
205 |
|
|
maskS(find(maskS))=1; maskS(find(~maskS))=nan; |
206 |
|
|
for t=1:nt, mydisp(t) |
207 |
|
|
for g=1:length(genBC) |
208 |
|
|
switch genBC{g} |
209 |
|
|
case 'N' |
210 |
|
|
T=readbin([pout 'OBNt_' nme '_' dim '.bin'],[nx nz],1,'real*4',t-1).*maskN; |
211 |
|
|
S=readbin([pout 'OBNs_' nme '_' dim '.bin'],[nx nz],1,'real*4',t-1).*maskN; |
212 |
|
|
case 'S' |
213 |
|
|
T=readbin([pout 'OBSt_' nme '_' dim '.bin'],[nx nz],1,'real*4',t-1).*maskS; |
214 |
|
|
S=readbin([pout 'OBSs_' nme '_' dim '.bin'],[nx nz],1,'real*4',t-1).*maskS; |
215 |
|
|
case 'E' |
216 |
|
|
T=readbin([pout 'OBEt_' nme '_' dim '.bin'],[ny nz],1,'real*4',t-1).*maskE; |
217 |
|
|
S=readbin([pout 'OBEs_' nme '_' dim '.bin'],[ny nz],1,'real*4',t-1).*maskE; |
218 |
|
|
case 'W' |
219 |
|
|
T=readbin([pout 'OBWt_' nme '_' dim '.bin'],[ny nz],1,'real*4',t-1).*maskW; |
220 |
|
|
S=readbin([pout 'OBWs_' nme '_' dim '.bin'],[ny nz],1,'real*4',t-1).*maskW; |
221 |
|
|
end |
222 |
|
|
R=rho(S,T,0); |
223 |
|
|
for j=1:ny |
224 |
|
|
idx=find(diff(R(j,:))<0); |
225 |
|
|
while ~isempty(idx) |
226 |
|
|
T(j,min(idx)+1)=T(j,min(idx)); |
227 |
|
|
S(j,min(idx)+1)=S(j,min(idx)); |
228 |
|
|
r=rho(S(j,:),T(j,:),0); idx=find(diff(r)<0); |
229 |
|
|
end |
230 |
|
|
end |
231 |
|
|
for k=1:nz |
232 |
|
|
if any(~isnan(T(:,k))) |
233 |
|
|
T(:,k)=xpolate(T(:,k)); S(:,k)=xpolate(S(:,k)); |
234 |
|
|
else |
235 |
|
|
T(:,k)=T(:,k-1); S(:,k)=S(:,k-1); |
236 |
|
|
end |
237 |
|
|
end |
238 |
|
|
writebin([pout 'OB' genBC{g} 's_' nme '_' dim '.stable'],S,1,'real*4',t-1); |
239 |
|
|
writebin([pout 'OB' genBC{g} 't_' nme '_' dim '.stable'],T,1,'real*4',t-1); |
240 |
|
|
end |
241 |
|
|
end |
242 |
|
|
|
243 |
|
|
|
244 |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
245 |
dimitri |
1.2 |
% balance BCs -- requires that model be integrated once so that |
246 |
dimitri |
1.1 |
% grid and mask files be available. |
247 |
|
|
DXG =readbin([regional_grid 'DXG.data' ],[nx ny] ); |
248 |
|
|
DYG =readbin([regional_grid 'DYG.data' ],[nx ny] ); |
249 |
|
|
HFACS=readbin([regional_grid 'hFacS.data'],[nx ny nz]); |
250 |
|
|
HFACW=readbin([regional_grid 'hFacW.data'],[nx ny nz]); |
251 |
|
|
OBWmask=squeeze(HFACW(2 ,: ,:)); OBWmask([1 ny],:)=0; |
252 |
|
|
OBEmask=squeeze(HFACW(nx,: ,:)); OBEmask([1 ny],:)=0; |
253 |
|
|
OBSmask=squeeze(HFACS(: ,2 ,:)); OBSmask([1 nx],:)=0; |
254 |
|
|
OBNmask=squeeze(HFACS(: ,ny,:)); OBNmask([1 nx],:)=0; |
255 |
|
|
for k=1:nz |
256 |
|
|
OBWmask(:,k)=thk(k)*OBWmask(:,k).*DYG(2 ,: )'; |
257 |
|
|
OBEmask(:,k)=thk(k)*OBEmask(:,k).*DYG(nx,: )'; |
258 |
|
|
OBSmask(:,k)=thk(k)*OBSmask(:,k).*DXG(: ,2 ) ; |
259 |
|
|
OBNmask(:,k)=thk(k)*OBNmask(:,k).*DXG(: ,ny) ; |
260 |
|
|
end |
261 |
|
|
OBW=zeros(nt,1); OBE=OBW; OBS=OBW; OBN=OBW; |
262 |
|
|
for t=1:nt, mydisp(t) |
263 |
|
|
for g=1:length(genBC) |
264 |
|
|
switch genBC{g} |
265 |
|
|
case 'E' |
266 |
|
|
tmp=readbin([pout 'OBEu_' nme '_' dim '.bin'],[ny nz],1,'real*4',t-1); |
267 |
|
|
OBE(t)=sum(sum(tmp.*OBEmask)); |
268 |
|
|
case 'W' |
269 |
|
|
tmp=readbin([pout 'OBWu_' nme '_' dim '.bin'],[ny nz],1,'real*4',t-1); |
270 |
|
|
OBW(t)=sum(sum(tmp.*OBWmask)); |
271 |
|
|
case 'N' |
272 |
|
|
tmp=readbin([pout 'OBNv_' nme '_' dim '.bin'],[nx nz],1,'real*4',t-1); |
273 |
|
|
OBN(t)=sum(sum(tmp.*OBNmask)); |
274 |
|
|
case 'S' |
275 |
|
|
tmp=readbin([pout 'OBSv_' nme '_' dim '.bin'],[nx nz],1,'real*4',t-1); |
276 |
|
|
OBS(t)=sum(sum(tmp.*OBSmask)); |
277 |
|
|
end |
278 |
|
|
end |
279 |
|
|
end |
280 |
|
|
for t=1:nt, mydisp(t) |
281 |
|
|
switch balBC |
282 |
|
|
case 'W' |
283 |
|
|
tmp=readbin([pout 'OBWu_' nme '_' dim '.bin'],[ny nz],1,'real*4',t-1); |
284 |
|
|
tmp(find(OBWmask))=tmp(find(OBWmask))+ ... |
285 |
|
|
mean(OBE(t)-OBS(t)+OBN(t)-OBW(t))/sum(sum(OBWmask)); |
286 |
|
|
writebin([pout 'OBWu_' nme '_' dim '.balance'],tmp,1,'real*4',t-1); |
287 |
|
|
case 'E' |
288 |
|
|
tmp=readbin([pout 'OBEu_' nme '_' dim '.bin'],[ny nz],1,'real*4',t-1); |
289 |
|
|
tmp(find(OBEmask))=tmp(find(OBEmask))+ ... |
290 |
|
|
mean(OBW(t)-OBN(t)+OBS(t)-OBE(t))/sum(sum(OBEmask)); |
291 |
|
|
writebin([pout 'OBEu_' nme '_' dim '.balance'],tmp,1,'real*4',t-1); |
292 |
|
|
case 'N' |
293 |
|
|
tmp=readbin([pout 'OBNv_' nme '_' dim '.bin'],[nx nz],1,'real*4',t-1); |
294 |
|
|
tmp(find(OBNmask))=tmp(find(OBNmask))+ ... |
295 |
|
|
mean(-OBE(t)+OBW(t)+OBS(t)-OBN(t))/sum(sum(OBNmask)); |
296 |
|
|
writebin([pout 'OBNv_' nme '_' dim '.balance'],tmp,1,'real*4',t-1); |
297 |
|
|
case 'S' |
298 |
|
|
tmp=readbin([pout 'OBSv_' nme '_' dim '.bin'],[nx nz],1,'real*4',t-1); |
299 |
|
|
tmp(find(OBSmask))=tmp(find(OBSmask))+ ... |
300 |
|
|
mean(OBE(t)-OBW(t)+OBN(t)-OBS(t))/sum(sum(OBSmask)); |
301 |
|
|
writebin([pout 'OBSv_' nme '_' dim '.balance'],tmp,1,'real*4',t-1); |
302 |
|
|
end |
303 |
|
|
end |
304 |
|
|
|
305 |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
306 |
|
|
|
307 |
|
|
cd /skylla/beaufort/run_template |
308 |
|
|
for t=1:nt, mydisp(t) |
309 |
|
|
tmp=readbin('OBNv_beaufort_40x40.bin',[nx nz],1,'real*4',t-1); |
310 |
|
|
OBN(t)=sum(sum(tmp.*OBNmask)); |
311 |
|
|
tmp=readbin('OBSv_beaufort_40x40.bin',[nx nz],1,'real*4',t-1); |
312 |
|
|
OBS(t)=sum(sum(tmp.*OBSmask)); |
313 |
|
|
tmp=readbin('OBWu_beaufort_40x40.bin',[ny nz],1,'real*4',t-1); |
314 |
|
|
OBW(t)=sum(sum(tmp.*OBWmask)); |
315 |
|
|
tmp=readbin('OBWu_beaufort_40x40.balance',[ny nz],1,'real*4',t-1); |
316 |
|
|
OBW2(t)=sum(sum(tmp.*OBWmask)); |
317 |
|
|
end |
318 |
|
|
t=(1:nt)'; |
319 |
|
|
clf, plot(t,cumsum(OBW2'-OBN+OBS),t,cumsum(OBW-OBN+OBS)), grid |
320 |
|
|
legend('cumsum(OBW-OBN2+OBS)','cumsum(OBW-OBN+OBS)') |