1 |
gforget |
1.5 |
function [FLD]=diffsmooth2D_extrap_inv(fld,mskOut,varargin); |
2 |
|
|
%object: extrapolate an incomplete field to create a full field, by |
3 |
|
|
% solving for a diffusion equation equilibrium state. |
4 |
|
|
%inputs: fld incomplete field of interest (masked with NaN) |
5 |
|
|
% mskOut land mask (1s and NaNs) for the full field (output) |
6 |
|
|
%output: FLD full field |
7 |
gforget |
1.1 |
|
8 |
|
|
global mygrid; |
9 |
|
|
|
10 |
|
|
dxC=mygrid.DXC; dyC=mygrid.DYC; |
11 |
|
|
dxG=mygrid.DXG; dyG=mygrid.DYG; |
12 |
|
|
rA=mygrid.RAC; |
13 |
|
|
|
14 |
|
|
dxCsm=dxC; dyCsm=dyC; |
15 |
|
|
mskFreeze=fld; mskFreeze(find(~isnan(mskFreeze)))=0; mskFreeze(find(isnan(mskFreeze)))=1; |
16 |
|
|
|
17 |
|
|
%check for domain edge points where no exchange is possible: |
18 |
|
|
tmp1=mskOut; tmp1(:)=1; tmp2=exch_T_N(tmp1); |
19 |
|
|
for iF=1:mskOut.nFaces; |
20 |
|
|
tmp3=mskOut{iF}; tmp4=tmp2{iF}; |
21 |
|
|
tmp4=tmp4(2:end-1,1:end-2)+tmp4(2:end-1,3:end)+tmp4(1:end-2,2:end-1)+tmp4(3:end,2:end-1); |
22 |
|
|
if ~isempty(find(isnan(tmp4)&~isnan(tmp3))); fprintf('warning: mask was modified\n'); end; |
23 |
|
|
tmp3(isnan(tmp4))=NaN; mskOut{iF}=tmp3; |
24 |
|
|
end; |
25 |
|
|
|
26 |
|
|
%put 0 first guess if needed and switch land mask: |
27 |
|
|
fld(find(isnan(fld)))=0; fld=fld.*mskOut; |
28 |
|
|
|
29 |
|
|
%scale the diffusive operator: |
30 |
|
|
tmp0=dxCsm./dxC; tmp0(isnan(mskOut))=NaN; tmp00=nanmax(tmp0); |
31 |
|
|
tmp0=dyCsm./dyC; tmp0(isnan(mskOut))=NaN; tmp00=max([tmp00 nanmax(tmp0)]); |
32 |
|
|
smooth2D_nbt=tmp00; |
33 |
|
|
smooth2D_nbt=ceil(1.1*2*smooth2D_nbt^2); |
34 |
|
|
|
35 |
|
|
smooth2D_dt=1; |
36 |
|
|
smooth2D_T=smooth2D_nbt*smooth2D_dt; |
37 |
|
|
smooth2D_Kux=dxCsm.*dxCsm/smooth2D_T/2; |
38 |
|
|
smooth2D_Kvy=dyCsm.*dyCsm/smooth2D_T/2; |
39 |
|
|
|
40 |
|
|
%form matrix problem: |
41 |
|
|
tmp1=convert2array(mskOut); |
42 |
|
|
kk=find(~isnan(tmp1)); |
43 |
gforget |
1.4 |
KK=tmp1; KK(kk)=kk; KK=convert2array(KK); |
44 |
gforget |
1.1 |
nn=length(kk); |
45 |
gforget |
1.4 |
NN=tmp1; NN(kk)=[1:nn]; %NN=convert2array(NN); |
46 |
gforget |
1.1 |
|
47 |
gforget |
1.2 |
if nargin==3; doFormMatrix=varargin{1}; else; doFormMatrix=1; end; |
48 |
|
|
|
49 |
|
|
global dFLDdt_op; |
50 |
|
|
if doFormMatrix==1; |
51 |
|
|
|
52 |
gforget |
1.1 |
dFLDdt_op=sparse([],[],[],nn,nn,nn*5); |
53 |
|
|
|
54 |
|
|
for iF=1:fld.nFaces; for ii=1:3; for jj=1:3; |
55 |
|
|
FLDones=fld; FLDones(find(~isnan(fld)))=0; |
56 |
|
|
FLDones{iF}(ii:3:end,jj:3:end)=1; |
57 |
|
|
FLDones(find(isnan(fld)))=NaN; |
58 |
|
|
|
59 |
|
|
FLDkkFROMtmp=fld; FLDkkFROMtmp(find(~isnan(fld)))=0; |
60 |
|
|
FLDkkFROMtmp{iF}(ii:3:end,jj:3:end)=KK{iF}(ii:3:end,jj:3:end); |
61 |
|
|
FLDkkFROMtmp(find(isnan(fld)))=0; |
62 |
|
|
|
63 |
|
|
FLDkkFROM=exch_T_N(FLDkkFROMtmp); |
64 |
gforget |
1.3 |
FLDkkFROM(find(isnan(FLDkkFROM)))=0; |
65 |
gforget |
1.1 |
for iF2=1:fld.nFaces; |
66 |
|
|
tmp1=FLDkkFROM{iF2}; tmp2=zeros(size(tmp1)-2); |
67 |
|
|
for ii2=1:3; for jj2=1:3; tmp2=tmp2+tmp1(ii2:end-3+ii2,jj2:end-3+jj2); end; end; |
68 |
|
|
FLDkkFROM{iF2}=tmp2; |
69 |
|
|
end; |
70 |
|
|
%clear FLDkkFROMtmp; |
71 |
|
|
|
72 |
|
|
[dTdxAtU,dTdyAtV]=calc_T_grad(FLDones,0); |
73 |
|
|
tmpU=dTdxAtU.*smooth2D_Kux; |
74 |
|
|
tmpV=dTdyAtV.*smooth2D_Kvy; |
75 |
|
|
[fldDIV]=calc_UV_div(tmpU,tmpV); |
76 |
|
|
dFLDdt=smooth2D_dt*fldDIV./rA; |
77 |
|
|
dFLDdt=dFLDdt.*mskFreeze; |
78 |
|
|
|
79 |
|
|
dFLDdt=convert2array(dFLDdt); FLDkkFROM=convert2array(FLDkkFROM); FLDkkTO=convert2array(KK); |
80 |
|
|
tmp1=find(dFLDdt~=0&~isnan(dFLDdt)); |
81 |
|
|
dFLDdt=dFLDdt(tmp1); FLDkkFROM=FLDkkFROM(tmp1); FLDkkTO=FLDkkTO(tmp1); |
82 |
|
|
dFLDdt_op=dFLDdt_op+sparse(NN(FLDkkTO),NN(FLDkkFROM),dFLDdt,nn,nn); |
83 |
|
|
|
84 |
|
|
end; end; end; |
85 |
|
|
|
86 |
gforget |
1.2 |
end;%if doFormMatrix==1; |
87 |
|
|
|
88 |
gforget |
1.1 |
%figure; spy(dFLDdt_op); |
89 |
|
|
|
90 |
|
|
FLD_vec=convert2array(fld); |
91 |
|
|
mskFreeze_vec=convert2array(mskFreeze); |
92 |
|
|
FLD_vec(find(mskFreeze_vec==1))=0; |
93 |
|
|
FLD_vec=FLD_vec(kk); |
94 |
|
|
|
95 |
|
|
INV_op=1-mskFreeze_vec(kk); |
96 |
|
|
INV_op=sparse([1:nn],[1:nn],INV_op,nn,nn); |
97 |
|
|
INV_op=INV_op+dFLDdt_op; |
98 |
|
|
INV_vec=INV_op\FLD_vec; |
99 |
|
|
INV_fld=convert2array(mskOut); |
100 |
|
|
INV_fld(find(~isnan(INV_fld)))=INV_vec; |
101 |
|
|
|
102 |
gforget |
1.4 |
FLD=convert2array(INV_fld); |
103 |
gforget |
1.1 |
|
104 |
|
|
return; |
105 |
|
|
|
106 |
|
|
%time step using matrix: |
107 |
|
|
FLD_vec=convert2array(fld); |
108 |
|
|
FLD_vec=FLD_vec(find(~isnan(FLD_vec))); |
109 |
|
|
dFLDdt_vec=dFLDdt_op*FLD_vec; |
110 |
|
|
dFLDdt_fld=convert2array(FLD); |
111 |
|
|
dFLDdt_fld(find(~isnan(dFLDdt_fld)))=dFLDdt_vec; |
112 |
|
|
dFLDdt_fld(find(isnan(dFLDdt_fld)))=0; |
113 |
|
|
|
114 |
|
|
%time-stepping loop: |
115 |
|
|
FLD=fld; |
116 |
|
|
|
117 |
|
|
test1=0; it=0; |
118 |
|
|
while ~test1; |
119 |
|
|
|
120 |
|
|
it=it+1; |
121 |
|
|
|
122 |
|
|
[dTdxAtU,dTdyAtV]=calc_T_grad(FLD,0); |
123 |
|
|
tmpU=dTdxAtU.*smooth2D_Kux; |
124 |
|
|
tmpV=dTdyAtV.*smooth2D_Kvy; |
125 |
|
|
[fldDIV]=calc_UV_div(tmpU,tmpV); |
126 |
|
|
dFLDdt=smooth2D_dt*fldDIV./rA; |
127 |
|
|
dFLDdt=dFLDdt.*mskFreeze; |
128 |
|
|
FLD=FLD-dFLDdt; |
129 |
|
|
|
130 |
|
|
tmp1=max(abs(dFLDdt)); |
131 |
|
|
if mod(it,10)==0; fprintf([num2str(it) ' del=' num2str(tmp1) ' eps=' num2str(eps) ' \n']); end; |
132 |
|
|
test1=tmp1<eps; |
133 |
|
|
|
134 |
|
|
FLDstore{it}=dFLDdt; |
135 |
|
|
end; |
136 |
|
|
|
137 |
|
|
if 1; |
138 |
|
|
jj=1; FLDstore2=zeros([size(FLD{jj}) length(FLDstore)]); |
139 |
|
|
for ii=1:length(FLDstore); FLDstore2(:,:,ii)=FLDstore{ii}{jj}; end; |
140 |
|
|
tmp1=abs(FLDstore2(:,:,end)); [ii,jj]=find(tmp1==max(tmp1(:))); |
141 |
|
|
figure; plot(cumsum(squeeze(FLDstore2(ii,jj,:)))); |
142 |
|
|
end; |
143 |
|
|
|
144 |
|
|
|
145 |
|
|
|