source: issm/trunk/src/m/classes/public/ismodelselfconsistent.m@ 45

Last change on this file since 45 was 45, checked in by Mathieu Morlighem, 16 years ago

removed accelerated element

File size: 12.5 KB
RevLine 
[1]1function bool=ismodelselfconsistent(md,solutiontype,package),
2%ISMODELSELFCONSISTENT - check that model forms a closed form solvable problem.
3%
4% Usage:
5% bool=ismodelselfconsistent(md,solutiontype,package),
6
7%tolerance we use in litmus tests for the consistency of the model
8tolerance=10^-12;
9if (nargin~=3 )
[27]10 help ismodelselfconsistent
11 error('ismodelselfconsistent error message: wrong usage');
[1]12end
13
[27]14%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% COMMON CHECKS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15
16%COUNTER
17if md.counter<3,
18 disp(['model ' md.name ' is not correctly configured. You forgot one step in the following sequence (mesh, geography, parameterize)!']);
19 bool=0;return;
[1]20end
21
[27]22%NAME
[1]23if isempty(md.name),
24 disp(['model is not correctly configured: missing name!']);
25 bool=0;return;
26end
27
[27]28%MESH
[1]29if md.numberofelements<=0,
30 disp(['model ' md.name ' does not have any elements!']);
31 bool=0; return;
32end
33if md.numberofgrids<=0,
34 disp(['model ' md.name ' does not have any grids!']);
35 bool=0; return;
36end
37
[27]38%ELEMENTSTYPE
[1]39if size(md.elements_type,1)~=md.numberofelements | size(md.elements_type,2)~=2,
40 disp(['Types of elements have not been set properly, run setelementstype first'])
41 bool=0;return;
42end
43if any(ones(md.numberofelements,1)-((md.elements_type(:,1)==hutterenum) + (md.elements_type(:,1)==macayealenum) + (md.elements_type(:,1)==pattynenum)))
44 disp(['Types of elements have not been set properly, run setelementstype first'])
45 bool=0;return;
46end
47if any(ones(md.numberofelements,1)-((md.elements_type(:,2)==stokesenum) + (md.elements_type(:,2)==noneenum)))
48 disp(['Types of elements have not been set properly, run setelementstype first'])
49 bool=0;return;
50end
51if strcmpi(md.type,'2d'),
52 if (ismember(pattynenum,md.elements_type(:,1)) | ismember(stokesenum,md.elements_type(:,2))),
53 disp(['For a 2d model, only MacAyeal''s and Hutter''s elements are allowed']);
54 bool=0;return;
55 end
56end
[27]57
58%NO NAN
59fields={'numberofelements','numberofgrids','x','y','z','segmentonneumann_diag','drag','drag_type','p','q','gridondirichlet_diag',...
60 'rho_ice','rho_water','B','elementoniceshelf','surface','thickness','bed','g','lowmem','sparsity','nsteps','maxiter',...
61 'tolx','np','eps_rel','exclusive','n','gridonbed','gridonsurface','elementonbed','elementonsurface','deltaH','DeltaH','timeacc','timedec'};
62for i=1:length(fields),
63 if ~isempty(eval(['md.' char(fields(i))])),
64 if find(isnan(eval(['md.' char(fields(i))]))),
65 disp(['model ' md.name ' has an NaN value in field ' char(fields(i)) '!']);
66 bool=0; return;
67 end
[1]68 end
69end
70
[27]71%FIELDS > 0
72fields={'numberofelements','numberofgrids','elements','segmentonneumann_diag','drag','drag_type','p','q','gridondirichlet_diag',...
73 'rho_ice','rho_water','B','elementoniceshelf','thickness','g','eps_rel','eps_abs','nsteps','maxiter','tolx','exclusive',...
74 'sparsity','lowmem','n','gridonbed','gridonsurface','elementonbed','elementonsurface','deltaH','DeltaH','timeacc','timedec'};
75for i=1:length(fields),
76 if ~isempty(eval(['md.' char(fields(i))])),
77 if find((eval(['md.' char(fields(i))]))<0),
78 disp(['model ' md.name ' has a <0 value in field ' char(fields(i)) '!']);
79 bool=0; return;
[1]80 end
81 end
82end
[27]83if any(md.p<=0),
84 disp(['model ' md.name ' has some p<0 friction coefficientsin sliding law']);
85 bool=0; return;
86end
[1]87
[27]88%FIELDS ~=0
89fields={'numberofelements','numberofgrids','elements','segmentonneumann_diag','drag_type',...
90 'rho_ice','rho_water','B','thickness','g','eps_rel','eps_abs','maxiter','tolx',...
91 'sparsity','deltaH','DeltaH','timeacc','timedec'};
92for i=1:length(fields),
93 if ~isempty(eval(['md.' char(fields(i))])),
94 if find((eval(['md.' char(fields(i))]))==0),
95 disp(['model ' md.name ' has a =0 value in field ' char(fields(i)) '!']);
96 bool=0; return;
97 end
[1]98 end
99end
100
[27]101%SIZE NUMBEROFELEMENTS
102fields={'elements','p','q','elementoniceshelf','n','elementonbed'};
103for i=1:size(fields,2),
104 if (size(eval(['md.' char(fields(i))]),1)~=md.numberofelements),
105 disp(['model ' md.name ' field ' char(fields(i)) ' should be of size ' num2str(md.numberofelements) '!']);
106 bool=0; return;
107 end
108end
109
110%SIZE NUMBEROFGRIDS
111fields={'x','y','z','B','drag','gridondirichlet_diag','melting','accumulation','surface','thickness','bed','gridonbed','gridonsurface'};
112for i=1:length(fields),
113 if find(length(eval(['md.' char(fields(i))]))~=md.numberofgrids),
114 disp(['model ' md.name ' field ' char(fields(i)) ' should be of size ' num2str(md.numberofgrids) '!']);
115 bool=0; return;
116 end
117end
118
119%THICKNESS = SURFACE - BED
120if find((md.thickness-md.surface+md.bed)>tolerance),
121 disp(['model ' md.name ' violates the equality thickness=surface-bed!']);
122 bool=0; return;
123end
124
125%RIFTS
126if md.numrifts,
127 if ~strcmpi(md.type,'2d'),
128 disp(['Models with rifts are only supported in 2d for now!']);
[1]129 bool=0;return;
130 end
131end
[27]132if ~isstruct(md.rifts),
133 if ~isempty(find(md.segmentmarkers>=2)),
134 %We have segments with rift markers, but no rift structure!
135 disp(['model ' md.name ' should be processed for rifts (run meshprocessrifts)!']);
136 bool=0; return;
137 end
138end
[1]139
[27]140%ARTIFICIAL DIFFUSIVITY
[1]141if ~isscalar(md.artificial_diffusivity),
142 disp('artificial_diffusivity should be a scalar (1 or 0)');
143 bool=0;return;
144end
145
[27]146%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% SOLUTION CHECKS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
147
148%DIAGNOSTIC
149if strcmpi(solutiontype,'diagnostic')
150
151 %HUTTER ON ICESHELF WARNING
152 if any(md.elements_type(:,1)==hutterenum & md.elementoniceshelf),
153 disp(sprintf('\n !!! Warning: Hutter''s model is not consistent on ice shelves !!!\n'));
154 end
155
156 %SINGULAR
157 if ~any(md.gridondirichlet_diag),
158 disp(['model ' md.name ' is not well posed (singular). You need at least one grid with fixed velocity!'])
[1]159 bool=0;return;
160 end
161
[27]162 %DIRICHLET VALUES
163 if isempty(md.gridondirichlet_diag) | isempty(md.dirichletvalues_diag),
164 disp(['model ' md.name ' is not well posed. Missing dirichlet values for diagnostic run']);
[1]165 bool=0;return;
166 end
[27]167
168 %DIRICHLET IF THICKNESS <= 0
169 if ~isempty(find(md.thickness<=0)),
170 pos=find(md.thickness<=0);
171 if ~isempty(find(md.gridondirichlet_diag(pos)==0)),
172 disp(['model ' md.name ' has some grids with 0 thickness']);
173 bool=0; return;
174 end
175 end
[1]176end
177
[27]178%PROGNOSTIC
179if strcmp(solutiontype,'prognostic'),
180 %old testing
181 % if isempty(find(md.gridondirichlet_diag)),
182 % disp(['model ' md.name ' diagnostic is not well posed (singular). You need at least one grid with fixed velocity!'])
183 % bool=0;return;
184 % end
185 % if isempty(find(md.gridondirichlet_prog)),
186 % disp(['model ' md.name ' prognostic is not well posed (singular). You need at least one grid with fixed thickness!'])
187 % bool=0;return;
188 % end
[1]189
[27]190 %VELOCITIES
191 if (size(md.vx,1)~=md.numberofgrids | size(md.vy,1)~=md.numberofgrids),
[1]192 disp(['a 3d velocity is required. Run ''diagnostic'' solution first!'])
[27]193 bool=0; return;
[1]194 end
195end
196
[27]197%THERMAL TRANSIENT
198if strcmp(solutiontype,'thermaltransient')
199
200 %INITIAL TEMPERATURE, MELTING AND ACCUMULATION
201 if isempty(md.temperature),
202 disp(['An initial temperature is needed for a transient thermal computation'])
[1]203 bool=0;return;
204 end
[27]205 if isstruct(md.temperature) | isstruct(md.melting) | isstruct(md.accumulation),
206 disp(['The initial temperature, melting or accumulation should be a list and not a structure'])
[1]207 bool=0;return;
208 end
209end
210
[27]211%THERMAL STEADY AND THERMAL TRANSIENT
212if strcmpi(solutiontype,'thermalsteady') | strcmp(solutiontype,'thermaltransient'),
213
214 %EXTRUSION
215 if strcmp(md.type,'2d'),
216 disp(['For a ' solutiontype ' computation, the model must be 3d, extrude it first!'])
[1]217 bool=0;return;
218 end
[27]219
220 %VELOCITIES AND PRESSURE
221 if (isempty(md.vx) | isnan(md.vx) | isempty(md.vy) | isnan(md.vy) | isempty(md.vz) | isnan(md.vz)),
222 disp(['a 3d velocity is required. Run ''diagnostic'' solution first!'])
[1]223 bool=0;return;
224 end
[27]225 if (isempty(md.pressure) | isnan(md.pressure)),
226 disp(['pressure is required. Run ''diagnostic'' solution first!'])
227 bool=0;return;
228 end
[1]229end
230
[27]231%THERMAL TRANSIENT AND TRANSIENT
232if strcmp(solutiontype,'thermaltransient') | strcmp(solutiontype,'transient'),
233
234 %DT and NDT
235 fields={'dt','ndt'};
236 for i=1:length(fields),
237 if find((eval(['md.' char(fields(i))]))<0),
238 disp(['model ' md.name ' has a <0 value in field ' char(fields(i)) '!']);
239 bool=0; return;
240 end
241 end
242
243 %INITIAL TEMPERATURE
[1]244 if isstruct(md.temperature),
245 disp(['The initial temperature should be empty or a list but not a structure'])
246 bool=0;return;
247 end
248end
249
[27]250%PARAMETERS
[1]251if strcmp(solutiontype,'parameters')
[27]252
253 %OUTPUT
254 if ~iscell(md.parameteroutput)
255 disp(['parameteroutput field must be a cell, example {''strainrate'',''stress'',''deviatoricstress'',''viscousheating''}']);
256 bool=0; return;
257 end
258 for i=1:length(md.parameteroutput)
259 if ~strcmpi(md.parameteroutput(i),'strainrate') & ~strcmpi(md.parameteroutput(i),'stress') & ~strcmpi(md.parameteroutput(i),'deviatoricstress') & ~strcmpi(md.parameteroutput(i),'viscousheating') ...
260 & ~strcmpi(md.parameteroutput(i),'pressure_elem') & ~strcmpi(md.parameteroutput(i),'stress_bed') & ~strcmpi(md.parameteroutput(i),'stress_surface')
261 disp(['one of the parameteroutput is not supported yet']);
262 bool=0; return;
263 end
264 end
265 %VELOCITY
[1]266 if ~(size(md.vx,1)==md.numberofgrids & size(md.vy,1)==md.numberofgrids & (size(md.vz,1)==md.numberofgrids | strcmpi(md.type,'2d')))
267 disp(['velocities are required!']);
268 bool=0;return;
269 end
[27]270
271 %HUTTER
[1]272 if any(md.elements_type(:,1)==hutterenum);
273 disp(['The model has Hutter''s elements. Impossible to compute parameters']);
274 bool=0;return;
275 end
276end
277
[27]278%CONTROL
279if strcmpi(solutiontype,'control'),
[1]280
[27]281 %CONTROL TYPE
[45]282 if ~ischar(md.control_type),
283 disp('control_type should be a string');
[1]284 bool=0;return;
285 end
286
[27]287 %LENGTH CONTROL FIELDS
[1]288 if (length(md.maxiter)~=md.nsteps | length(md.optscal)~=md.nsteps | length(md.fit)~=md.nsteps)
289 disp('maxiter, optscal and fit must have the length specified by nsteps')
290 bool=0;return;
291 end
[27]292
293 %FIT
[1]294 if sum((double(md.fit==1) + double(md.fit==0) + double(md.fit==2))==1)~=md.nsteps
295 disp('wrong fits: fit should be a vector of size nsteps holding 0, 1 and 2 only')
296 bool=0;return;
297 end
298
[27]299 %OBSERVED VELOCITIES
300 fields={'vx_obs','vy_obs'};
301 for i=1:length(fields),
302 if find(length(eval(['md.' char(fields(i))]))~=md.numberofgrids),
303 disp(['model ' md.name ' field ' char(fields(i)) ' should be of size ' num2str(md.numberofgrids) '!']);
[1]304 bool=0; return;
305 end
306 end
307end
308
[27]309%QMU
310if strcmpi(solutiontype,'qmu'),
311 if ~strcmpi(md.cluster,'none'),
312 if md.waitonlock==0,
313 disp(['model is not correctly configured: waitonlock should be activated when running qmu in parallel mode!']);
314 bool=0;return;
[1]315 end
316 end
317end
318
[27]319%MESH
320if strcmpi(solutiontype,'mesh'),
321 %this solution is a little special. It should come right after the md=model; operation. So a lot less checks!
[1]322
[27]323 bool=1;
324 return;
[1]325end
326
[27]327%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% PACKAGE CHECKS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[1]328
[27]329%CIELO
330if strcmpi(package,'cielo'),
[1]331
[27]332 %NAN VALUES
333 fields={'time','sparsity'};
334 for i=1:length(fields),
335 if ~isempty(eval(['md.' char(fields(i))])),
336 if find(isnan(eval(['md.' char(fields(i))]))),
337 disp(['model ' md.name ' has an NaN value in field ' char(fields(i)) '!']);
338 bool=0; return;
339 end
340 end
341 end
[1]342
[27]343 %FIELD > 0
344 fields={'time','sparsity'};
345 for i=1:length(fields),
346 if ~isempty(eval(['md.' char(fields(i))])),
347 if find((eval(['md.' char(fields(i))]))<0),
348 disp(['model ' md.name ' has a <0 value in field ' char(fields(i)) '!']);
349 bool=0; return;
350 end
351 end
352 end
[1]353
[27]354 %FIELD ~= 0
355 fields={'time','sparsity'};
356 for i=1:length(fields),
357 if ~isempty(eval(['md.' char(fields(i))])),
358 if find((eval(['md.' char(fields(i))]))==0),
359 disp(['model ' md.name ' has a =0 value in field ' char(fields(i)) '!']);
360 bool=0; return;
361 end
362 end
[1]363 end
364
[27]365 %SPARSITY BETWEEN 0 AND 1
366 if ( (md.sparsity<=0) | (md.sparsity>1)),
[39]367 disp(['model ' md.name ' sparsity should be inside the [0 1] range']);
[1]368 bool=0; return;
369 end
370
[27]371 %RIFTS
372 if md.numrifts,
373 if ~strcmpi(md.cluster,'none')
374 if isempty(findstr('aijmumps',md.solverstring)),
375 disp(['For a 2d model with rifts, running on a cluster, you should use a direct solver like MUMPS!']);
376 bool=0;return;
377 end
378 end
379 end
[1]380
[27]381 %CONNECTIVITY
382 if strcmpi(md.type,'2d'),
383 if md.connectivity<9,
384 disp('connectivity should be at least 9 for 2d models');
385 bool=0;return;
386 end
387 end
388 if strcmpi(md.type,'3d'),
389 if md.connectivity<24,
390 disp('connectivity should be at least 24 for 3d models');
391 bool=0;return;
392 end
393 end
[1]394
[27]395 %NP
[39]396 if ~strcmpi(md.cluster,'none'),
397 if md.np==0,
398 disp(['model ' md.name ' has a =0 value in field np !']);
399 elseif md.np<0,
400 disp(['model ' md.name ' has a negative value in field np !']);
401 end
[1]402 end
403
[27]404 %LOWMEM = 0 or 1
405 if ((md.lowmem ~= 1) & (md.lowmem~=0)),
406 disp(['model ' md.name ' lowmem field should be 0 or 1']);
[1]407 bool=0; return;
408 end
409end
410
411%No problems, just return 1;
412bool=1;
413return;
Note: See TracBrowser for help on using the repository browser.