/[MITgcm]/MITgcm_contrib/gael/matlab_class/gcmfaces_calc/gcmfaces_timestep.m
ViewVC logotype

Annotation of /MITgcm_contrib/gael/matlab_class/gcmfaces_calc/gcmfaces_timestep.m

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


Revision 1.2 - (hide annotations) (download)
Wed Aug 1 01:47:44 2012 UTC (12 years, 11 months ago) by gforget
Branch: MAIN
Changes since 1.1: +18 -1 lines
- added myOp.doStep : field of 0 (tracer stays unchanged)
  and 1 (tracer evolves). See diffsmooth2D_extrap_fwd.m

1 gforget 1.1 function [FLD]=gcmfaces_timestep(myOp,fld,fldRelax);
2     %object: time step a 2D tracer diffusion/relaxation (could later be
3     % extended with 3D case, advection and surface forcing)
4     %inputs: myOp specifies the equation with the following fields
5     % dt time step
6     % nbt number of time steps
7     % eps termination criterium
8     % Kux, Kvy diffusion coefficients (along grid axes; m2/s)
9     % tau relaxation time scale
10     % Kuy, Kvx diffusion coefficients (only for rotated diff)
11 gforget 1.2 % doStep is a field of 0 (tracer stays unchanged)
12     % and 1 (tracer evolves).
13 gforget 1.1 % fld is the initial tracer field
14     % fldRelax is the field to relax to (if tau<Inf)
15     %output: FLD is the final tracer field
16     %
17     %note : case of 3D tracer is not coded yet
18     %note : advection (m/s) and forcing (tracer/area/s) are not coded yet
19    
20    
21     gcmfaces_global;
22    
23 gforget 1.2 if isempty(who('fldRelax')); fldRelax=[]; end;
24 gforget 1.1 if isempty(who('fldForcing')); fldForcing=[]; end;
25    
26     %rotated diffusion:
27     if isfield(myOp,'Kuy')&isfield(myOp,'Kvx');
28     if ~isempty(myOp.Kuy)&~isempty(myOp.Kvx);
29     doExtraDiag=1;
30     if myenv.verbose;
31     gcmfaces_msg(['* extra-diagonal diffusion included.']);
32     end;
33     else;
34     doExtraDiag=0;
35     end;
36     else;
37     doExtraDiag=0;
38     end;
39    
40     %relaxation term:
41     if isfield(myOp,'tau');
42     doRelax=1;
43     if isempty(fldRelax);
44     error('relaxation field must be specified');
45     end;
46     if ~isa(myOp.tau,'double')&~isa(myOp.tau,'gcmfaces');
47     error('mispecified relaxation time scale (must be doule or gcmfaces)');
48     end;
49    
50     if myenv.verbose;
51     gcmfaces_msg(['* relaxation term included.']);
52     end;
53     test1=1*(myOp.tau<myOp.dt);
54     if isa(myOp.tau,'gcmfaces'); test1=convert2vector(test1); end;
55     test1=~isempty(find(test1==1));
56     if test1;
57     error('tau cannot exceed 1');
58     end;
59     else;
60     doRelax=0;
61     end;
62    
63 gforget 1.2 %mask of frozen/evolving points:
64     if isfield(myOp,'doStep');
65     doStep=myOp.doStep;
66     test1=sum(doStep~=1&doStep~=0);
67     if test1;
68     error('myOp.doStep must be a field of 0/1');
69     end;
70     else;
71     doStep=mygrid.XC; doStep(:)=1;
72     end;
73    
74 gforget 1.1 %forcing term:
75     if ~isempty(fldForcing);
76     doForcing=1;
77     if myenv.verbose;
78     gcmfaces_msg(['* forcing term included.']);
79     end;
80     else;
81     doForcing=0;
82     end;
83    
84     %
85     if isfield(myOp,'eps');
86     nbt=Inf;
87     eps=myOp.eps;
88     if myenv.verbose;
89     gcmfaces_msg(['* specified termination : ' num2str(eps) ' .']);
90     end;
91     else;
92     nbt=myOp.nbt;
93     eps=0;
94     if myenv.verbose;
95     gcmfaces_msg(['* specified number of time steps : ' num2str(nbt) ' .']);
96     end;
97     end;
98    
99     %initialization
100     FLD=fld; it=0; doStop=0; nrm=[]; nrmRef=Inf;
101    
102     %time-stepping loop:
103     while ~doStop;
104    
105     it=it+1;
106    
107     [dTdxAtU,dTdyAtV]=calc_T_grad(FLD,0);
108     tmpU=dTdxAtU.*myOp.Kux;
109     tmpV=dTdyAtV.*myOp.Kvy;
110    
111     if doExtraDiag;
112     dTdyAtU=dTdxAtU; dTdxAtV=dTdyAtV;
113     [dTdxAtU,dTdyAtV]=exch_UV_N(dTdxAtU,dTdyAtV);
114     for iF=1:FLD.nFaces;
115     msk=dTdxAtU{iF}(2:end-1,2:end-1); msk(~isnan(msk))=1;
116     tmp1=dTdyAtV{iF}; tmp1(isnan(tmp1))=0;
117     dTdyAtU{iF}=0.25*msk.*(tmp1(1:end-2,2:end-1)+tmp1(1:end-2,3:end)+...
118     tmp1(2:end-1,2:end-1)+tmp1(2:end-1,3:end));
119    
120     msk=dTdyAtV{iF}(2:end-1,2:end-1); msk(~isnan(msk))=1;
121     tmp1=dTdxAtU{iF}; tmp1(isnan(tmp1))=0;
122     dTdxAtV{iF}=0.25*msk.*(tmp1(2:end-1,1:end-2)+tmp1(3:end,1:end-2)+...
123     tmp1(2:end-1,2:end-1)+tmp1(3:end,2:end-1));
124     end;
125     dTdxAtU=cut_T_N(dTdxAtU);
126     dTdyAtV=cut_T_N(dTdyAtV);
127    
128     tmpU=tmpU+dTdyAtU.*myOp.Kuy;
129     tmpV=tmpV+dTdxAtV.*myOp.Kvx;
130     end;
131    
132     [fldDIV]=calc_UV_div(tmpU,tmpV,{'dh'});
133     dFLDdt=-myOp.dt*fldDIV./mygrid.RAC;
134    
135     if doRelax;
136     dFLDdt=dFLDdt+myOp.dt*(fldRelax-FLD)./myOp.tau;
137     end;
138    
139 gforget 1.2 %mask of frozen/evolving points:
140     dFLDdt=dFLDdt.*doStep;
141    
142     %now step forward
143 gforget 1.1 FLD=FLD+dFLDdt;
144    
145     %test for termination criteria
146     nrm=[nrm;sqrt(nanmean(dFLDdt.^2))];
147     if it==1; nrmRef=nrm(it); end;
148     doStop=((nrm(it)<nrmRef*eps)|(it==nbt));
149    
150     %monitor convergence
151     if mod(it,50)==0|it==1|doStop;
152     tmp1=sprintf('it=%04i 100*nrm/nrmRef=%4.4g.',it,100*nrm(it)/nrmRef);
153     if myenv.verbose;
154     gcmfaces_msg(['* convergence monitor : ' tmp1]);
155     end;
156     end;
157    
158     if 0;%monitor convergence
159     if mod(it,1000)==0|doStop;
160     figure; plot(log10(nrm)); ylabel('log10(increment)');
161     eval(['FLD_' num2str(it) '=FLD;']);
162     end;
163     end;
164    
165     if 0;%test of positivity
166     test1=convert2vector(FLD<0); test1=~isempty(find(test1(:)==1));
167     if test1;
168     fprintf(['it=' num2str(it) ' min(FLD)=' num2str(min(FLD)) '\n']);
169     end;
170     end;
171    
172     end;
173    

  ViewVC Help
Powered by ViewVC 1.1.22