1 |
function [H2,Hx2,Hy2]=xyrecur_fv(He,Hx,Hy,niter) |
2 |
% |
3 |
% Returns the gridded data on a grid of half the size |
4 |
% with the data "averaged" to the cell-centers using |
5 |
% a "Finite Volume" algorithm (see Adcroft, JPO 2000). |
6 |
% |
7 |
% e.g. |
8 |
% [H2,Hx2,Hy2]=xyrecur_fv(He,Hx,Hy,3); |
9 |
|
10 |
debuglevels=0; |
11 |
|
12 |
%H2=He; |
13 |
%Hx2=Hx; |
14 |
%Hy2=Hy; |
15 |
|
16 |
% Check that Hx and Hy don't violate basic rules |
17 |
check_HxHy(He,Hx,Hy) |
18 |
|
19 |
% Recursively iterate |
20 |
for nit=1:niter, |
21 |
|
22 |
clear H2 Hx2 Hy2 |
23 |
[nx,ny,nt]=size(He); |
24 |
disp(sprintf(' Recursion level %i (%i,%i) -> (%i,%i) ... ',nit,nx,ny,nx/2,ny/2)); |
25 |
|
26 |
%ii=1:2:nx-1; |
27 |
%jj=1:2:ny-1; |
28 |
%ip=2:2:nx; |
29 |
%im=[nx 2:2:nx-2]; |
30 |
%jp=2:2:ny; |
31 |
%jm=[2 2:2:ny-2]; |
32 |
%I=1:nx/2; IM=I([end 1:end-1]); |
33 |
%J=1:ny/2; JM=J([end 1:end-1]); |
34 |
|
35 |
for J=1:ny/2; jj=1+2*(J-1); |
36 |
jp=mymod(jj+1,ny);jm=mymod(jj-1,ny);JM=mymod(J-1,ny/2); |
37 |
for I=1:nx/2; ii=1+2*(I-1); |
38 |
ip=mymod(ii+1,nx);im=mymod(ii-1,nx);IM=mymod(I-1,nx/2); |
39 |
|
40 |
% Four-point average in X-Y |
41 |
%new? H2=(He(ii,jj,:)+He(ii+1,jj,:)+He(ii,jj+1,:)+He(ii+1,jj+1,:))/4; |
42 |
H2(I,J,:)=(He(ii,jj,:)+He(ip,jj,:)+He(ii,jp,:)+He(ip,jp,:))/4; |
43 |
|
44 |
% Two-point average in X |
45 |
%new? Hx2=(Hx(ii,jj,:)+Hx(ii,jj+1,:))/2; |
46 |
Hx2(I,J,:)=(Hx(ii,jj,:)+Hx(ii,jp,:))/2; |
47 |
|
48 |
% Two-point average in Y |
49 |
%new? Hy2=(Hy(ii,jj,:)+Hy(ii+1,jj,:))/2; |
50 |
Hy2(I,J,:)=(Hy(ii,jj,:)+Hy(ip,jj,:))/2; |
51 |
|
52 |
end;end; |
53 |
for J=1:ny/2; jj=1+2*(J-1); |
54 |
jp=mymod(jj+1,ny),jm=mymod(jj-1,ny),JM=mymod(J-1,ny/2), |
55 |
for I=1:nx/2; ii=1+2*(I-1); |
56 |
ip=mymod(ii+1,nx),im=mymod(ii-1,nx),IM=mymod(I-1,nx/2), |
57 |
|
58 |
% Blocking from either side? |
59 |
Hx2e=(Hx(ip,jj,:)+Hx(ip,jp,:))/2; |
60 |
Hx2w=(Hx(im,jj,:)+Hx(im,jp,:))/2; |
61 |
Hx2(I,J,:)=max( max( Hx2(I,J,:), Hx2e ) , Hx2w); |
62 |
|
63 |
% Blocking from either side? |
64 |
Hy2n=(Hy(ii,jp,:)+Hy(ip,jp,:))/2; |
65 |
Hy2s=(Hy(ii,jm,:)+Hy(ip,jm,:))/2; |
66 |
Hy2(I,J,:)=max( max( Hy2(I,J,:), Hy2n ) , Hy2s); |
67 |
|
68 |
% Make Hx2,Hy2 consistent with coarse H2 |
69 |
%Hx2=max( max(Hx2, H2), H2([end 1:end-1],:,:)); |
70 |
%Hy2=max( max(Hy2, H2), H2(:,[end 1:end-1],:)); |
71 |
|
72 |
% Fill-up cell-centers where all sides are higher |
73 |
%H2sides=min( Hx2, Hx2([2:end 1],:,:) ); |
74 |
%H2sides=min( H2sides, Hy2 ); |
75 |
%H2sides=min( H2sides, Hy2(:,[2:end end],:) ); |
76 |
%H2=max( H2, H2sides ); |
77 |
|
78 |
% Fill up if barriers intersects coarse cell |
79 |
%%Hx2mid=(Hx(ip,jj,:)+Hx(ip,jp,:))/2; |
80 |
%%Hy2mid=(Hy(ii,jp,:)+Hy(ip,jp,:))/2; |
81 |
%Hx2mid=min(Hx(ip,jj,:),Hx(ip,jp,:)); |
82 |
%Hy2mid=min(Hy(ii,jp,:),Hy(ip,jp,:)); |
83 |
%H2mid=max(max(H2, Hy2mid),Hx2mid); |
84 |
%ll=find(H2mid>H2sides); |
85 |
%H2(ll)=H2mid(ll); |
86 |
|
87 |
% Make Hx2,Hy2 consistent with coarse H2 |
88 |
%Hx2=max( max(Hx2, H2), H2([end 1:end-1],:,:)); |
89 |
%Hy2=max( max(Hy2, H2), H2(:,[end 1:end-1],:)); |
90 |
Hx2(I,J,:)=max( max(Hx2(I,J,:), H2(I,J,:)), H2(IM,J,:)); |
91 |
Hy2(I,J,:)=max( max(Hy2(I,J,:), H2(I,J,:)), H2(I,JM,:)); |
92 |
|
93 |
end;end; |
94 |
|
95 |
% Check that Hx2 and Hy2 don't violate basic rules |
96 |
check_HxHy(H2,Hx2,Hy2) |
97 |
|
98 |
% Re-cycle data for another iteration |
99 |
He=H2; |
100 |
Hx=Hx2; |
101 |
Hy=Hy2; |
102 |
|
103 |
if debuglevels |
104 |
eval(sprintf('save LEVEL%2.2i He Hx Hy',nit)); |
105 |
end |
106 |
|
107 |
end |
108 |
|
109 |
% Fill-up cell-centers where all sides are higher |
110 |
H2sides=min( Hx2, Hx2([2:end 1],:,:) ); |
111 |
H2sides=min( H2sides, Hy2 ); |
112 |
H2sides=min( H2sides, Hy2(:,[2:end end],:) ); |
113 |
H2=max( H2, H2sides ); |
114 |
|
115 |
|
116 |
|
117 |
function []=QQQQQcheck_HxHy(H2,Hx2,Hy2) |
118 |
% Check that Hx2 and Hy2 don't violate basic rules |
119 |
% This should *not* ever happen |
120 |
return; % spead up process |
121 |
[Hxcc,Hycc]=gen_hxhy(H2,x2,y2); |
122 |
ic=find(Hx2<Hxcc-0.001); |
123 |
if prod(size(ic)) ~= 0 |
124 |
[Hx2(ic)/1e3 Hxcc(ic)/1e3 Hx2(ic)-Hxcc(ic)] |
125 |
error('The X cross-sectional area turned out inconsistently') |
126 |
end |
127 |
jc=find(Hy2<Hycc-0.001); |
128 |
if prod(size(jc)) ~= 0 |
129 |
[Hy2(jc)/1e3 Hycc(jc)/1e3 Hy2(jc)-Hycc(jc)] |
130 |
error('The Y cross-sectional area turned out inconsistently') |
131 |
end |
132 |
|
133 |
|
134 |
function [n] = mymod(n,N) |
135 |
n=mod(n+N-1,N)+1; |