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

Last change on this file since 2298 was 2298, checked in by Mathieu Morlighem, 15 years ago

removed mesh2grid

File size: 14.3 KB
Line 
1function bool=ismodelselfconsistent(md),
2%ISMODELSELFCONSISTENT - check that model forms a closed form solvable problem.
3%
4% Usage:
5% bool=ismodelselfconsistent(md),
6
7%tolerance we use in litmus tests for the consistency of the model
8tolerance=10^-12;
9if (nargin~=1 )
10 help ismodelselfconsistent
11 error('ismodelselfconsistent error message: wrong usage');
12end
13
14%initialize output
15bool=1;
16
17%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% COMMON CHECKS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
18
19%COUNTER
20if md.counter<3,
21 disp(['model ' md.name ' is not correctly configured. You forgot one step in the following sequence (mesh, geography, parameterize)!']);
22 bool=0;return;
23end
24
25%NAME
26if isempty(md.name),
27 disp(['model is not correctly configured: missing name!']);
28 bool=0;return;
29end
30
31%MESH
32if md.numberofelements<=0,
33 disp(['model ' md.name ' does not have any elements!']);
34 bool=0; return;
35end
36if md.numberofgrids<=0,
37 disp(['model ' md.name ' does not have any grids!']);
38 bool=0; return;
39end
40
41%ELEMENTSTYPE
42if size(md.elements_type,1)~=md.numberofelements | size(md.elements_type,2)~=2,
43 disp(['Types of elements have not been set properly, run setelementstype first'])
44 bool=0;return;
45end
46if any(ones(md.numberofelements,1)-((md.elements_type(:,1)==HutterFormulationEnum) + (md.elements_type(:,1)==MacAyealFormulationEnum) + (md.elements_type(:,1)==PattynFormulationEnum)))
47 disp(['Types of elements have not been set properly, run setelementstype first'])
48 bool=0;return;
49end
50if any(ones(md.numberofelements,1)-((md.elements_type(:,2)==StokesFormulationEnum) + (md.elements_type(:,2)==NoneFormulationEnum)))
51 disp(['Types of elements have not been set properly, run setelementstype first'])
52 bool=0;return;
53end
54if strcmpi(md.type,'2d'),
55 if (ismember(PattynFormulationEnum,md.elements_type(:,1)) | ismember(StokesFormulationEnum,md.elements_type(:,2))),
56 disp(['For a 2d model, only MacAyeal''s and Hutter''s elements are allowed']);
57 bool=0;return;
58 end
59end
60if (md.ismacayealpattyn==0 && md.ishutter==0 && md.isstokes==0),
61 disp(['no elements type set for this model. at least one of ismacayealpattyn, ishutter and isstokes need to be =1']);
62 bool=0;return;
63end
64if (md.analysis_type==DiagnosticAnalysisEnum & any(ismember(MacAyealFormulationEnum,md.elements_type(:,1)) & ismember(PattynFormulationEnum,md.elements_type(:,1))))
65 disp(['coupling MacAyeal/Pattyn not implemented yet']);
66 bool=0;return;
67end
68if (md.isstokes & md.analysis_type==TransientAnalysisEnum());
69 disp(['Stokes transient not implemented yet']);
70 bool=0;return;
71end
72
73%ICEFRONT
74if strcmpi(md.type,'2d'),
75 if size(md.pressureload,2)~=3 ,
76 disp(['pressureload in ' md.name ' shoud have three columns']);
77 bool=0;return;
78 end
79elseif strcmpi(md.type,'3d'),
80 if size(md.pressureload,2)~=5 ,
81 disp(['pressureload in ' md.name ' shoud have five columns']);
82 bool=0;return;
83 end
84end
85
86%NO NAN
87fields={'numberofelements','numberofgrids','x','y','z','drag','drag_type','p','q',...
88 'rho_ice','rho_water','B','elementoniceshelf','surface','thickness','bed','g','lowmem','sparsity','nsteps','maxiter',...
89 'tolx','np','eps_res','exclusive','n','gridonbed','gridonsurface','elementonbed','elementonsurface','deltaH','DeltaH','timeacc','timedec'};
90for i=1:length(fields),
91 if ~isempty(md.(fields{i})),
92 if any(isnan(md.(fields{i}))),
93 disp(['model ' md.name ' has an NaN value in field ' fields{i} '!']);
94 bool=0; return;
95 end
96 end
97end
98
99%FIELDS >= 0
100fields={'numberofelements','numberofgrids','elements','drag','drag_type','p','q',...
101 'rho_ice','rho_water','B','elementoniceshelf','thickness','g','eps_res','eps_rel','eps_abs','nsteps','maxiter','tolx','exclusive',...
102 'sparsity','lowmem','n','gridonbed','gridonsurface','elementonbed','elementonsurface','deltaH','DeltaH','timeacc','timedec'};
103for i=1:length(fields),
104 if ~isempty(md.(fields{i})),
105 if any(md.(fields{i})<0),
106 disp(['model ' md.name ' has a <0 value in field ' fields{i} '!']);
107 bool=0; return;
108 end
109 end
110end
111if any(md.p<=0),
112 disp(['model ' md.name ' has some p<0 friction coefficientsin sliding law']);
113 bool=0; return;
114end
115
116%FIELDS ~=0
117fields={'numberofelements','numberofgrids','elements','drag_type',...
118 'rho_ice','rho_water','B','thickness','g','eps_res','eps_rel','eps_abs','maxiter','tolx',...
119 'sparsity','deltaH','DeltaH','timeacc','timedec'};
120for i=1:length(fields),
121 if ~isempty(md.(fields{i})),
122 if any(md.(fields{i})==0),
123 disp(['model ' md.name ' has a =0 value in field ' fields{i} '!']);
124 bool=0; return;
125 end
126 end
127end
128
129%SIZE NUMBEROFELEMENTS
130fields={'elements','p','q','elementoniceshelf','n','elementonbed'};
131for i=1:size(fields,2),
132 if (size(md.(fields{i}),1)~=md.numberofelements),
133 disp(['model ' md.name ' field ' fields{i} ' should be of size ' num2str(md.numberofelements) '!']);
134 bool=0; return;
135 end
136end
137
138%SIZE NUMBEROFGRIDS
139fields={'x','y','z','B','drag','spcvelocity','melting','accumulation','surface','thickness','bed','gridonbed','gridonsurface'};
140for i=1:length(fields),
141 if length(md.(fields{i}))~=md.numberofgrids,
142 disp(['model ' md.name ' field ' fields{i} ' should be of size ' num2str(md.numberofgrids) '!']);
143 bool=0; return;
144 end
145end
146
147%THICKNESS = SURFACE - BED
148if any((md.thickness-md.surface+md.bed)>tolerance),
149 disp(['model ' md.name ' violates the equality thickness=surface-bed!']);
150 bool=0; return;
151end
152
153%RIFTS
154if md.numrifts,
155 if ~strcmpi(md.type,'2d'),
156 disp(['Models with rifts are only supported in 2d for now!']);
157 bool=0;return;
158 end
159end
160if ~isstruct(md.rifts),
161 if ~isnan(md.rifts),
162 if ~isempty(find(md.segmentmarkers>=2)),
163 %We have segments with rift markers, but no rift structure!
164 disp(['model ' md.name ' should be processed for rifts (run meshprocessrifts)!']);
165 bool=0; return;
166 end
167 end
168end
169
170%ARTIFICIAL DIFFUSIVITY
171if ~isscalar(md.artificial_diffusivity),
172 disp('artificial_diffusivity should be a scalar (1 or 0)');
173 bool=0;return;
174end
175
176%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% SOLUTION CHECKS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
177%QMU
178if md.qmu_analysis,
179 if md.qmu_params.evaluation_concurrency~=1,
180 disp(['concurrency should be set to 1 when running dakota in library mode']);
181 bool=0;return;
182 end
183 if ~isempty(md.part),
184 if numel(md.part)~=md.numberofgrids,
185 disp(['user supplied partition for qmu analysis should have size md.numberofgrids x 1 ']);
186 bool=0;return;
187 end
188 if find(md.part)>=md.numberofgrids,
189 disp(['user supplied partition should be indexed from 0 (c-convention)']);
190 bool=0;return;
191 end
192 if md.npart~=md.numberofgrids,
193 disp(['user supplied partition should have same size as md.npart']);
194 bool=0;return;
195 end
196
197 end
198 if md.eps_rel>10^-3,
199 disp(['for qmu analysis, eps_rel should be least than 10^-5, 10^-15 being a better value']);
200 bool=0;return;
201 end
202end
203
204%DIAGNOSTIC
205if md.analysis_type==DiagnosticAnalysisEnum,
206
207 %CHECK THAT WE ARE NOT FULLY CONSTRAINED
208 if strcmpi(md.type,'2d'),
209 if isempty(find(~md.spcvelocity(:,1:2))),
210 disp(['model ' md.name ' is totally constrained, no need to solve!']);
211 bool=0;return;
212 end
213 end
214
215 %HUTTER ON ICESHELF WARNING
216 if any(md.elements_type(:,1)==HutterFormulationEnum & md.elementoniceshelf),
217 disp(sprintf('\n !!! Warning: Hutter''s model is not consistent on ice shelves !!!\n'));
218 end
219
220 %SINGULAR
221 if ~any(sum(md.spcvelocity(:,1:2),2)==2),
222 disp(['model ' md.name ' is not well posed (singular). You need at least one grid with fixed velocity!'])
223 bool=0;return;
224 end
225
226 %DIRICHLET IF THICKNESS <= 0
227 if any(md.thickness<=0),
228 pos=find(md.thickness<=0);
229 if any(find(md.spcthickness(pos,1)==0)),
230 disp(['model ' md.name ' has some grids with 0 thickness']);
231 bool=0; return;
232 end
233 end
234end
235
236%PROGNOSTIC
237if md.analysis_type==PrognosticAnalysisEnum,
238
239 %VELOCITIES
240 if (size(md.vx,1)~=md.numberofgrids | size(md.vy,1)~=md.numberofgrids),
241 disp(['a 3d velocity is required. Run ''diagnostic'' solution first!'])
242 bool=0; return;
243 end
244end
245
246%STEADYSTATE
247if md.analysis_type==SteadystateAnalysisEnum,
248 %NDT
249 if md.dt~=0,
250 disp(['For a steadystate computation, dt must be zero.']);
251 bool=0;return;
252 end
253 %PRESSURE
254 if isnans(md.pressure),
255 disp(['For a steadystate computation, the model must have an initial pressure, even lithostatic will do.']);
256 bool=0;return;
257 end
258
259 %eps:
260 if isnan(md.eps_rel),
261 disp(['For a steadystate computation, eps_rel (relative convergence criterion) must be defined!']);
262 bool=0;return;
263 end
264
265 %dim:
266 if strcmpi(md.type,'2d'),
267 disp(['For a steadystate computation, model needs to be 3d']);
268 bool=0;return;
269 end
270end
271
272%THERMAL STEADY AND THERMAL TRANSIENT
273if md.analysis_type==ThermalAnalysisEnum,
274
275 %EXTRUSION
276 if strcmp(md.type,'2d'),
277 disp(['For a ' md.analysis_type ' computation, the model must be 3d, extrude it first!'])
278 bool=0;return;
279 end
280
281 %VELOCITIES AND PRESSURE
282 if (length(md.vx)~=md.numberofgrids | length(md.vy)~=md.numberofgrids | length(md.vz)~=md.numberofgrids),
283 disp(['a 3d velocity is required. Run ''diagnostic'' solution first!'])
284 bool=0;return;
285 end
286 if (length(md.pressure)~=md.numberofgrids),
287 disp(['pressure is required. Run ''diagnostic'' solution first!'])
288 bool=0;return;
289 end
290end
291
292%THERMAL TRANSIENT
293if md.analysis_type==ThermalAnalysisEnum & md.dt~=0
294
295 %DT and NDT
296 fields={'dt','ndt'};
297 for i=1:length(fields),
298 if any(md.(fields{i})<0),
299 disp(['model ' md.name ' has a <0 value in field ' fields{i} '!']);
300 bool=0; return;
301 end
302 end
303
304 %INITIAL TEMPERATURE, MELTING AND ACCUMULATION
305 if (length(md.temperature)~=md.numberofgrids),
306 disp(['An initial temperature is needed for a transient thermal computation'])
307 bool=0;return;
308 end
309 if (length(md.temperature)~=md.numberofgrids | length(md.accumulation)~=md.numberofgrids | length(md.melting)~=md.numberofgrids),
310 disp(['The initial temperature, melting or accumulation should be a list and not a structure'])
311 bool=0;return;
312 end
313end
314
315%PARAMETERS
316if md.analysis_type==ParametersAnalysisEnum,
317
318 %OUTPUT
319 if ~iscell(md.parameteroutput)
320 disp(['parameteroutput field must be a cell, example {''strainrate'',''stress'',''deviatoricstress'',''viscousheating''}']);
321 bool=0; return;
322 end
323 for i=1:length(md.parameteroutput)
324 if ~strcmpi(md.parameteroutput(i),'strainrate') & ~strcmpi(md.parameteroutput(i),'stress') & ~strcmpi(md.parameteroutput(i),'deviatoricstress') & ~strcmpi(md.parameteroutput(i),'viscousheating') ...
325 & ~strcmpi(md.parameteroutput(i),'pressure_elem') & ~strcmpi(md.parameteroutput(i),'stress_bed') & ~strcmpi(md.parameteroutput(i),'stress_surface')
326 disp(['one of the parameteroutput is not supported yet']);
327 bool=0; return;
328 end
329 end
330 %VELOCITY
331 if ~(size(md.vx,1)==md.numberofgrids & size(md.vy,1)==md.numberofgrids & (size(md.vz,1)==md.numberofgrids | strcmpi(md.type,'2d')))
332 disp(['velocities are required!']);
333 bool=0;return;
334 end
335
336 %HUTTER
337 if any(md.elements_type(:,1)==HutterFormulationEnum);
338 disp(['The model has Hutter''s elements. Impossible to compute parameters']);
339 bool=0;return;
340 end
341end
342
343%CONTROL
344if md.control_analysis,
345
346 %CONTROL TYPE
347 if ~ischar(md.control_type),
348 disp('control_type should be a string');
349 bool=0;return;
350 end
351
352 %LENGTH CONTROL FIELDS
353 if (length(md.maxiter)~=md.nsteps | length(md.optscal)~=md.nsteps | length(md.fit)~=md.nsteps | length(md.cm_jump)~=md.nsteps)
354 disp('maxiter, optscal, fit and cm_jump must have the length specified by nsteps')
355 bool=0;return;
356 end
357
358 %FIT
359 if sum((double(md.fit==1) + double(md.fit==0) + double(md.fit==2))==1)~=md.nsteps
360 disp('wrong fits: fit should be a vector of size nsteps holding 0, 1 and 2 only')
361 bool=0;return;
362 end
363
364 %OBSERVED VELOCITIES
365 fields={'vx_obs','vy_obs'};
366 for i=1:length(fields),
367 if any(length(md.(fields{i}))~=md.numberofgrids),
368 disp(['model ' md.name ' field ' fields{i} ' should be of size ' num2str(md.numberofgrids) '!']);
369 bool=0; return;
370 end
371 end
372
373 %SINGULAR
374 if ~any(sum(md.spcvelocity(:,1:3),2)==3),
375 disp(['model ' md.name ' is not well posed (singular). You need at least one grid with fixed velocity!'])
376 bool=0;return;
377 end
378
379 %DIRICHLET IF THICKNESS <= 0
380 if any(md.thickness<=0),
381 pos=find(md.thickness<=0);
382 if any(find(md.spcthickness(pos,1)==0)),
383 disp(['model ' md.name ' has some grids with 0 thickness']);
384 bool=0; return;
385 end
386 end
387end
388
389%QMU
390if strcmpi(md.analysis_type,'qmu'),
391 if ~strcmpi(md.cluster,'none'),
392 if md.waitonlock==0,
393 disp(['model is not correctly configured: waitonlock should be activated when running qmu in parallel mode!']);
394 bool=0;return;
395 end
396 end
397end
398
399%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% PACKAGE CHECKS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
400
401%NAN VALUES
402fields={'sparsity'};
403for i=1:length(fields),
404 if ~isempty(md.(fields{i})),
405 if any(isnan(md.(fields{i}))),
406 disp(['model ' md.name ' has an NaN value in field ' fields{i} '!']);
407 bool=0; return;
408 end
409 end
410end
411
412%FIELD > 0
413fields={'sparsity'};
414for i=1:length(fields),
415 if ~isempty(md.(fields{i})),
416 if any(md.(fields{i})<0),
417 disp(['model ' md.name ' has a <0 value in field ' fields{i} '!']);
418 bool=0; return;
419 end
420 end
421end
422
423%FIELD ~= 0
424fields={'sparsity'};
425for i=1:length(fields),
426 if ~isempty(md.(fields{i})),
427 if any(md.(fields{i})==0),
428 disp(['model ' md.name ' has a =0 value in field ' fields{i} '!']);
429 bool=0; return;
430 end
431 end
432end
433
434%SPARSITY BETWEEN 0 AND 1
435if ( (md.sparsity<=0) | (md.sparsity>1)),
436 disp(['model ' md.name ' sparsity should be inside the [0 1] range']);
437 bool=0; return;
438end
439
440%CONNECTIVITY
441if strcmpi(md.type,'2d'),
442 if md.connectivity<9,
443 disp('connectivity should be at least 9 for 2d models');
444 bool=0;return;
445 end
446end
447if strcmpi(md.type,'3d'),
448 if md.connectivity<24,
449 disp('connectivity should be at least 24 for 3d models');
450 bool=0;return;
451 end
452end
453
454%LOWMEM = 0 or 1
455if ((md.lowmem ~= 1) & (md.lowmem~=0)),
456 disp(['model ' md.name ' lowmem field should be 0 or 1']);
457 bool=0; return;
458end
459
460%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% PARALLEL CHECKS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
461
462if ~strcmpi(md.cluster,'none'),
463
464 %NAN VALUES
465 fields={'time','np'};
466 for i=1:length(fields),
467 if ~isempty(md.(fields{i})),
468 if any(isnan(md.(fields{i}))),
469 disp(['model ' md.name ' has an NaN value in field ' fields{i} '!']);
470 bool=0; return;
471 end
472 end
473 end
474
475 %FIELD > 0
476 fields={'time','np'};
477 for i=1:length(fields),
478 if ~isempty(md.(fields{i})),
479 if any(md.(fields{i})<0),
480 disp(['model ' md.name ' has a <0 value in field ' fields{i} '!']);
481 bool=0; return;
482 end
483 end
484 end
485
486 %FIELD ~= 0
487 fields={'time','np'};
488 for i=1:length(fields),
489 if ~isempty(md.(fields{i})),
490 if any(md.(fields{i})==0),
491 disp(['model ' md.name ' has a =0 value in field ' fields{i} '!']);
492 bool=0; return;
493 end
494 end
495 end
496
497end
Note: See TracBrowser for help on using the repository browser.