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

Last change on this file since 2208 was 2208, checked in by Eric.Larour, 16 years ago

neumann boundary conditions gone, corrected displaybc.
added check for diagnostic horiz, when all grids are spc'd.

File size: 14.5 KB
RevLine 
[2164]1function bool=ismodelselfconsistent(md),
[1]2%ISMODELSELFCONSISTENT - check that model forms a closed form solvable problem.
3%
4% Usage:
[2164]5% bool=ismodelselfconsistent(md),
[1]6
7%tolerance we use in litmus tests for the consistency of the model
8tolerance=10^-12;
[2164]9if (nargin~=1 )
[27]10 help ismodelselfconsistent
11 error('ismodelselfconsistent error message: wrong usage');
[1]12end
13
[1670]14%initialize output
15bool=1;
16
[27]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;
[1]23end
24
[27]25%NAME
[1]26if isempty(md.name),
27 disp(['model is not correctly configured: missing name!']);
28 bool=0;return;
29end
30
[27]31%MESH
[1]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
[27]41%ELEMENTSTYPE
[1]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
[1651]46if any(ones(md.numberofelements,1)-((md.elements_type(:,1)==HutterFormulationEnum) + (md.elements_type(:,1)==MacAyealFormulationEnum) + (md.elements_type(:,1)==PattynFormulationEnum)))
[1]47 disp(['Types of elements have not been set properly, run setelementstype first'])
48 bool=0;return;
49end
[1651]50if any(ones(md.numberofelements,1)-((md.elements_type(:,2)==StokesFormulationEnum) + (md.elements_type(:,2)==NoneFormulationEnum)))
[1]51 disp(['Types of elements have not been set properly, run setelementstype first'])
52 bool=0;return;
53end
54if strcmpi(md.type,'2d'),
[1651]55 if (ismember(PattynFormulationEnum,md.elements_type(:,1)) | ismember(StokesFormulationEnum,md.elements_type(:,2))),
[1]56 disp(['For a 2d model, only MacAyeal''s and Hutter''s elements are allowed']);
57 bool=0;return;
58 end
59end
[358]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
[2164]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
[358]72
[1796]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
[358]85
[27]86%NO NAN
[1755]87fields={'numberofelements','numberofgrids','x','y','z','drag','drag_type','p','q',...
[27]88 'rho_ice','rho_water','B','elementoniceshelf','surface','thickness','bed','g','lowmem','sparsity','nsteps','maxiter',...
[1666]89 'tolx','np','eps_res','exclusive','n','gridonbed','gridonsurface','elementonbed','elementonsurface','deltaH','DeltaH','timeacc','timedec'};
[27]90for i=1:length(fields),
[806]91 if ~isempty(md.(fields{i})),
92 if any(isnan(md.(fields{i}))),
[681]93 disp(['model ' md.name ' has an NaN value in field ' fields{i} '!']);
[27]94 bool=0; return;
95 end
[1]96 end
97end
98
[1666]99%FIELDS >= 0
[1755]100fields={'numberofelements','numberofgrids','elements','drag','drag_type','p','q',...
[1666]101 'rho_ice','rho_water','B','elementoniceshelf','thickness','g','eps_res','eps_rel','eps_abs','nsteps','maxiter','tolx','exclusive',...
[27]102 'sparsity','lowmem','n','gridonbed','gridonsurface','elementonbed','elementonsurface','deltaH','DeltaH','timeacc','timedec'};
103for i=1:length(fields),
[806]104 if ~isempty(md.(fields{i})),
105 if any(md.(fields{i})<0),
[681]106 disp(['model ' md.name ' has a <0 value in field ' fields{i} '!']);
[27]107 bool=0; return;
[1]108 end
109 end
110end
[27]111if any(md.p<=0),
112 disp(['model ' md.name ' has some p<0 friction coefficientsin sliding law']);
113 bool=0; return;
114end
[1]115
[27]116%FIELDS ~=0
[1755]117fields={'numberofelements','numberofgrids','elements','drag_type',...
[1666]118 'rho_ice','rho_water','B','thickness','g','eps_res','eps_rel','eps_abs','maxiter','tolx',...
[27]119 'sparsity','deltaH','DeltaH','timeacc','timedec'};
120for i=1:length(fields),
[806]121 if ~isempty(md.(fields{i})),
122 if any(md.(fields{i})==0),
[681]123 disp(['model ' md.name ' has a =0 value in field ' fields{i} '!']);
[27]124 bool=0; return;
125 end
[1]126 end
127end
128
[27]129%SIZE NUMBEROFELEMENTS
130fields={'elements','p','q','elementoniceshelf','n','elementonbed'};
131for i=1:size(fields,2),
[806]132 if (size(md.(fields{i}),1)~=md.numberofelements),
[681]133 disp(['model ' md.name ' field ' fields{i} ' should be of size ' num2str(md.numberofelements) '!']);
[27]134 bool=0; return;
135 end
136end
137
138%SIZE NUMBEROFGRIDS
[1757]139fields={'x','y','z','B','drag','spcvelocity','melting','accumulation','surface','thickness','bed','gridonbed','gridonsurface'};
[27]140for i=1:length(fields),
[806]141 if length(md.(fields{i}))~=md.numberofgrids,
[681]142 disp(['model ' md.name ' field ' fields{i} ' should be of size ' num2str(md.numberofgrids) '!']);
[27]143 bool=0; return;
144 end
145end
146
147%THICKNESS = SURFACE - BED
[681]148if any((md.thickness-md.surface+md.bed)>tolerance),
[27]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!']);
[1]157 bool=0;return;
158 end
159end
[27]160if ~isstruct(md.rifts),
[1222]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
[27]167 end
168end
[1]169
[27]170%ARTIFICIAL DIFFUSIVITY
[1]171if ~isscalar(md.artificial_diffusivity),
172 disp('artificial_diffusivity should be a scalar (1 or 0)');
173 bool=0;return;
174end
175
[27]176%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% SOLUTION CHECKS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[804]177%QMU
[966]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
[1111]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
[2052]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
[804]202end
[27]203
204%DIAGNOSTIC
[1781]205if md.analysis_type==DiagnosticAnalysisEnum,
[27]206
[2208]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
[27]215 %HUTTER ON ICESHELF WARNING
[1651]216 if any(md.elements_type(:,1)==HutterFormulationEnum & md.elementoniceshelf),
[27]217 disp(sprintf('\n !!! Warning: Hutter''s model is not consistent on ice shelves !!!\n'));
218 end
219
220 %SINGULAR
[1755]221 if ~any(sum(md.spcvelocity(:,1:3),2)==3),
[27]222 disp(['model ' md.name ' is not well posed (singular). You need at least one grid with fixed velocity!'])
[1]223 bool=0;return;
224 end
225
[27]226 %DIRICHLET IF THICKNESS <= 0
[681]227 if any(md.thickness<=0),
[27]228 pos=find(md.thickness<=0);
[1755]229 if any(find(md.spcthickness(pos,1)==0)),
[27]230 disp(['model ' md.name ' has some grids with 0 thickness']);
231 bool=0; return;
232 end
233 end
[1]234end
235
[27]236%PROGNOSTIC
[1781]237if md.analysis_type==PrognosticAnalysisEnum,
[1]238
[27]239 %VELOCITIES
240 if (size(md.vx,1)~=md.numberofgrids | size(md.vy,1)~=md.numberofgrids),
[1]241 disp(['a 3d velocity is required. Run ''diagnostic'' solution first!'])
[27]242 bool=0; return;
[1]243 end
244end
245
[1867]246%STEADYSTATE
247if md.analysis_type==SteadystateAnalysisEnum,
[1901]248 %NDT
249 if md.dt~=0,
[1917]250 disp(['For a steadystate computation, dt must be zero.']);
[1901]251 bool=0;return;
252 end
[1787]253 %PRESSURE
254 if isnans(md.pressure),
[1862]255 disp(['For a steadystate computation, the model must have an initial pressure, even lithostatic will do.']);
[1787]256 bool=0;return;
257 end
258
259 %eps:
260 if isnan(md.eps_rel),
[1862]261 disp(['For a steadystate computation, eps_rel (relative convergence criterion) must be defined!']);
[1787]262 bool=0;return;
263 end
264
265 %dim:
266 if strcmpi(md.type,'2d'),
[1862]267 disp(['For a steadystate computation, model needs to be 3d']);
[1787]268 bool=0;return;
269 end
270end
271
[27]272%THERMAL STEADY AND THERMAL TRANSIENT
[1781]273if md.analysis_type==ThermalAnalysisEnum,
[27]274
275 %EXTRUSION
276 if strcmp(md.type,'2d'),
[465]277 disp(['For a ' md.analysis_type ' computation, the model must be 3d, extrude it first!'])
[1]278 bool=0;return;
279 end
[27]280
281 %VELOCITIES AND PRESSURE
[1311]282 if (length(md.vx)~=md.numberofgrids | length(md.vy)~=md.numberofgrids | length(md.vz)~=md.numberofgrids),
[27]283 disp(['a 3d velocity is required. Run ''diagnostic'' solution first!'])
[1]284 bool=0;return;
285 end
[1311]286 if (length(md.pressure)~=md.numberofgrids),
[27]287 disp(['pressure is required. Run ''diagnostic'' solution first!'])
288 bool=0;return;
289 end
[1]290end
291
[1311]292%THERMAL TRANSIENT
[1901]293if md.analysis_type==ThermalAnalysisEnum & md.dt~=0
[27]294
295 %DT and NDT
296 fields={'dt','ndt'};
297 for i=1:length(fields),
[806]298 if any(md.(fields{i})<0),
[681]299 disp(['model ' md.name ' has a <0 value in field ' fields{i} '!']);
[27]300 bool=0; return;
301 end
302 end
303
[1311]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'])
[1]307 bool=0;return;
308 end
[1311]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
[1]313end
314
[27]315%PARAMETERS
[1781]316if md.analysis_type==ParametersAnalysisEnum,
[27]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
[1]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
[27]335
336 %HUTTER
[1651]337 if any(md.elements_type(:,1)==HutterFormulationEnum);
[1]338 disp(['The model has Hutter''s elements. Impossible to compute parameters']);
339 bool=0;return;
340 end
341end
342
[27]343%CONTROL
[1907]344if md.control_analysis,
[1]345
[27]346 %CONTROL TYPE
[45]347 if ~ischar(md.control_type),
348 disp('control_type should be a string');
[1]349 bool=0;return;
350 end
351
[27]352 %LENGTH CONTROL FIELDS
[1]353 if (length(md.maxiter)~=md.nsteps | length(md.optscal)~=md.nsteps | length(md.fit)~=md.nsteps)
354 disp('maxiter, optscal and fit must have the length specified by nsteps')
355 bool=0;return;
356 end
[27]357
358 %FIT
[1]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
[27]364 %OBSERVED VELOCITIES
365 fields={'vx_obs','vy_obs'};
366 for i=1:length(fields),
[806]367 if any(length(md.(fields{i}))~=md.numberofgrids),
[681]368 disp(['model ' md.name ' field ' fields{i} ' should be of size ' num2str(md.numberofgrids) '!']);
[1]369 bool=0; return;
370 end
371 end
[1361]372
373 %SINGULAR
[1755]374 if ~any(sum(md.spcvelocity(:,1:3),2)==3),
[1361]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);
[1755]382 if any(find(md.spcthickness(pos,1)==0)),
[1361]383 disp(['model ' md.name ' has some grids with 0 thickness']);
384 bool=0; return;
385 end
386 end
[1]387end
388
[27]389%QMU
[465]390if strcmpi(md.analysis_type,'qmu'),
[27]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;
[1]395 end
396 end
397end
398
[132]399%MESH2GRID
[1781]400if md.analysis_type==Mesh2gridAnalysisEnum,
[132]401 if ~strcmpi(md.cluster,'none'),
402 disp(['model is not correctly configured: mesh2grid not supported in parallel yet!']);
403 bool=0;return;
404 end
405end
406
407
[27]408%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% PACKAGE CHECKS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[1]409
[2164]410%NAN VALUES
411fields={'sparsity'};
412for i=1:length(fields),
413 if ~isempty(md.(fields{i})),
414 if any(isnan(md.(fields{i}))),
415 disp(['model ' md.name ' has an NaN value in field ' fields{i} '!']);
416 bool=0; return;
417 end
418 end
419end
[1]420
[2164]421%FIELD > 0
422fields={'sparsity'};
423for i=1:length(fields),
424 if ~isempty(md.(fields{i})),
425 if any(md.(fields{i})<0),
426 disp(['model ' md.name ' has a <0 value in field ' fields{i} '!']);
427 bool=0; return;
428 end
429 end
430end
431
432%FIELD ~= 0
433fields={'sparsity'};
434for i=1:length(fields),
435 if ~isempty(md.(fields{i})),
436 if any(md.(fields{i})==0),
437 disp(['model ' md.name ' has a =0 value in field ' fields{i} '!']);
438 bool=0; return;
439 end
440 end
441end
442
443%SPARSITY BETWEEN 0 AND 1
444if ( (md.sparsity<=0) | (md.sparsity>1)),
445 disp(['model ' md.name ' sparsity should be inside the [0 1] range']);
446 bool=0; return;
447end
448
449%CONNECTIVITY
450if strcmpi(md.type,'2d'),
451 if md.connectivity<9,
452 disp('connectivity should be at least 9 for 2d models');
453 bool=0;return;
454 end
455end
456if strcmpi(md.type,'3d'),
457 if md.connectivity<24,
458 disp('connectivity should be at least 24 for 3d models');
459 bool=0;return;
460 end
461end
462
463%LOWMEM = 0 or 1
464if ((md.lowmem ~= 1) & (md.lowmem~=0)),
465 disp(['model ' md.name ' lowmem field should be 0 or 1']);
466 bool=0; return;
467end
468
469%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% PARALLEL CHECKS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
470
471if ~strcmpi(md.cluster,'none'),
472
[27]473 %NAN VALUES
[2164]474 fields={'time','np'};
[27]475 for i=1:length(fields),
[806]476 if ~isempty(md.(fields{i})),
477 if any(isnan(md.(fields{i}))),
[681]478 disp(['model ' md.name ' has an NaN value in field ' fields{i} '!']);
[27]479 bool=0; return;
480 end
481 end
482 end
[1]483
[27]484 %FIELD > 0
[2164]485 fields={'time','np'};
[27]486 for i=1:length(fields),
[806]487 if ~isempty(md.(fields{i})),
488 if any(md.(fields{i})<0),
[681]489 disp(['model ' md.name ' has a <0 value in field ' fields{i} '!']);
[27]490 bool=0; return;
491 end
492 end
493 end
[1]494
[27]495 %FIELD ~= 0
[2164]496 fields={'time','np'};
[27]497 for i=1:length(fields),
[806]498 if ~isempty(md.(fields{i})),
499 if any(md.(fields{i})==0),
[681]500 disp(['model ' md.name ' has a =0 value in field ' fields{i} '!']);
[27]501 bool=0; return;
502 end
503 end
[1]504 end
505
506end
Note: See TracBrowser for help on using the repository browser.