/[MITgcm]/MITgcm_contrib/gael/matlab_class/gcmfaces_smooth/diffsmooth2D_extrap_inv.m
ViewVC logotype

Contents of /MITgcm_contrib/gael/matlab_class/gcmfaces_smooth/diffsmooth2D_extrap_inv.m

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.9 - (show annotations) (download)
Sat Mar 21 11:18:38 2015 UTC (10 years, 4 months ago) by gforget
Branch: MAIN
CVS Tags: checkpoint65x, checkpoint65r, checkpoint65p, checkpoint65q, checkpoint65v, checkpoint65w, checkpoint65t, checkpoint65u, checkpoint66f, checkpoint66e, checkpoint66d, checkpoint66c, checkpoint66b, checkpoint66a, checkpoint66o, HEAD
Changes since 1.8: +5 -0 lines
- turn off singular matrix warnings.

1 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 %optional: doFormMatrix (1 by default)
8 % if set to 1 then compute the dFLDdt_op matrix
9 % if set to 0 then use precomputed one (global dFLDdt_op)
10 % doMSKOUT (1 by default)
11 % if set to 1 then first detect closed regions lacking
12 % data points to extrapolate from (e.g. abyssal canions)
13 % and restrict mskOut to MSKOUT accordingly
14 % if set to 0 then omit this step
15 %principle :
16 %in points where mskFreeze is 1 solve diffusion equation
17 %in points where mskFreeze is 0 solve the trivial FLD=fld
18
19 gcmfaces_global;
20
21 if nargin==3; doFormMatrix=varargin{1}; else; doFormMatrix=1; end;
22 if nargin==4; doMSKOUT=varargin{2}; else; doMSKOUT=1; end;
23
24 if doMSKOUT;
25 %problematic regions will show MSKOUT==0;
26 tmp1=1+0*fld; [MSKOUT]=diffsmooth2D_extrap_inv(tmp1,mskOut,doFormMatrix,0);
27 %if no problematic region then no need to recompute dFLDdt_op
28 if sum(MSKOUT==0)==0; doFormMatrix=0; end;
29 %finalize MSKOUT
30 MSKOUT(MSKOUT==0)=NaN;
31 MSKOUT(~isnan(MSKOUT))=1;
32 end;
33
34 dxC=mygrid.DXC; dyC=mygrid.DYC;
35 rA=mygrid.RAC;
36
37 dxCsm=dxC; dyCsm=dyC;
38 mskFreeze=fld; mskFreeze(find(~isnan(mskFreeze)))=0; mskFreeze(find(isnan(mskFreeze)))=1;
39
40 %check for domain edge points where no exchange is possible:
41 tmp1=mskOut; tmp1(:)=1; tmp2=exch_T_N(tmp1);
42 for iF=1:mskOut.nFaces;
43 tmp3=mskOut{iF}; tmp4=tmp2{iF};
44 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);
45 if ~isempty(find(isnan(tmp4)&~isnan(tmp3))); fprintf('warning: mask was modified\n'); end;
46 tmp3(isnan(tmp4))=NaN; mskOut{iF}=tmp3;
47 end;
48
49 %put 0 first guess if needed and switch land mask:
50 fld(find(isnan(fld)))=0; fld=fld.*mskOut;
51
52 %scale the diffusive operator:
53 tmp0=dxCsm./dxC; tmp0(isnan(mskOut))=NaN; tmp00=nanmax(tmp0);
54 tmp0=dyCsm./dyC; tmp0(isnan(mskOut))=NaN; tmp00=max([tmp00 nanmax(tmp0)]);
55 smooth2D_nbt=tmp00;
56 smooth2D_nbt=ceil(1.1*2*smooth2D_nbt^2);
57
58 smooth2D_dt=1;
59 smooth2D_T=smooth2D_nbt*smooth2D_dt;
60 smooth2D_Kux=dxCsm.*dxCsm/smooth2D_T/2;
61 smooth2D_Kvy=dyCsm.*dyCsm/smooth2D_T/2;
62
63 %form matrix problem:
64 tmp1=convert2array(mskOut);
65 kk=find(~isnan(tmp1));
66 KK=tmp1; KK(kk)=kk; KK=convert2array(KK);
67 nn=length(kk);
68 NN=tmp1; NN(kk)=[1:nn]; %NN=convert2array(NN);
69
70 global dFLDdt_op;
71 if doFormMatrix==1;
72
73 dFLDdt_op=sparse([],[],[],nn,nn,nn*5);
74
75 for iF=1:fld.nFaces; for ii=1:3; for jj=1:3;
76 FLDones=fld; FLDones(find(~isnan(fld)))=0;
77 FLDones{iF}(ii:3:end,jj:3:end)=1;
78 FLDones(find(isnan(fld)))=NaN;
79
80 FLDkkFROMtmp=fld; FLDkkFROMtmp(find(~isnan(fld)))=0;
81 FLDkkFROMtmp{iF}(ii:3:end,jj:3:end)=KK{iF}(ii:3:end,jj:3:end);
82 FLDkkFROMtmp(find(isnan(fld)))=0;
83
84 FLDkkFROM=exch_T_N(FLDkkFROMtmp);
85 FLDkkFROM(find(isnan(FLDkkFROM)))=0;
86 for iF2=1:fld.nFaces;
87 tmp1=FLDkkFROM{iF2}; tmp2=zeros(size(tmp1)-2);
88 for ii2=1:3; for jj2=1:3; tmp2=tmp2+tmp1(ii2:end-3+ii2,jj2:end-3+jj2); end; end;
89 FLDkkFROM{iF2}=tmp2;
90 end;
91 %clear FLDkkFROMtmp;
92
93 [dTdxAtU,dTdyAtV]=calc_T_grad(FLDones,0);
94 tmpU=dTdxAtU.*smooth2D_Kux;
95 tmpV=dTdyAtV.*smooth2D_Kvy;
96 [fldDIV]=calc_UV_conv(tmpU,tmpV);
97 dFLDdt=smooth2D_dt*fldDIV./rA;
98 dFLDdt=dFLDdt.*mskFreeze;
99
100 dFLDdt=convert2array(dFLDdt); FLDkkFROM=convert2array(FLDkkFROM); FLDkkTO=convert2array(KK);
101 tmp1=find(dFLDdt~=0&~isnan(dFLDdt));
102 dFLDdt=dFLDdt(tmp1); FLDkkFROM=FLDkkFROM(tmp1); FLDkkTO=FLDkkTO(tmp1);
103 dFLDdt_op=dFLDdt_op+sparse(NN(FLDkkTO),NN(FLDkkFROM),dFLDdt,nn,nn);
104
105 end; end; end;
106
107 end;%if doFormMatrix==1;
108
109 %figure; spy(dFLDdt_op);
110
111 FLD_vec=convert2array(fld);%right hand side of FLD=fld
112 mskFreeze_vec=convert2array(mskFreeze);
113 FLD_vec(find(mskFreeze_vec==1))=0;%right hand side of diffusion equation
114 FLD_vec=FLD_vec(kk);
115
116 INV_op=1-mskFreeze_vec(kk);
117 INV_op=sparse([1:nn],[1:nn],INV_op,nn,nn);%identity where mskFreeze is 0
118 INV_op=INV_op+dFLDdt_op;%add diffusion operator where mskFreeze is 1
119
120 warning('off','MATLAB:nearlySingularMatrix');
121 warning('off','MATLAB:singularMatrix');
122 INV_vec=INV_op\FLD_vec;%solve
123 warning('on','MATLAB:nearlySingularMatrix');
124 warning('on','MATLAB:singularMatrix');
125
126 INV_fld=convert2array(mskOut);
127 INV_fld(find(~isnan(INV_fld)))=INV_vec;
128 FLD=convert2array(INV_fld);%reformat
129
130 if doMSKOUT; FLD=FLD.*MSKOUT; end;%mask problematic regions
131
132

  ViewVC Help
Powered by ViewVC 1.1.22