/[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.1 - (hide annotations) (download)
Wed Aug 1 00:25:15 2012 UTC (12 years, 11 months ago) by gforget
Branch: MAIN
- time step a 2D tracer diffusion/relaxation equation.

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

  ViewVC Help
Powered by ViewVC 1.1.22