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

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

Better check of rifts structure

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