source: issm/trunk-jpl/src/m/model/marshall.m@ 10937

Last change on this file since 10937 was 9725, checked in by Mathieu Morlighem, 14 years ago

Some more objects in mesh

File size: 10.1 KB
Line 
1function marshall(md)
2%MARSHALL - output JPL-package compatible binary file from @model md, for certain solution type.
3%
4% The routine creates a JPL-package compatible binary file from @model md
5% This binary file will be used for parallel runs in JPL-package
6%
7% Usage:
8% marshall(md)
9
10disp(['marshalling file ' md.miscellaneous.name '.bin']);
11
12%open file for binary writing
13fid=fopen([ md.miscellaneous.name '.bin'],'wb');
14if fid==-1,
15 error(['marshall error message: could not open ' [md.miscellaneous.name '.bin'],' file for binary writing']);
16end
17
18%automatically marshall model md, using template information available from an empty model class.
19template=model.template();
20MarshallObject(fid,template,md,'');
21
22%close file
23st=fclose(fid);
24if st==-1,
25 error(['marshall error message: could not close file ' [md.miscellaneous.name '.bin']]);
26end
27
28function MarshallObject(fid,template,object,prefix) % {{{
29fields=fieldnames(template);
30for i=1:length(fields),
31 fieldname=fields{i};
32 if ~isa(template.(fieldname),'modelfield'),
33 %Recursive call
34 MarshallObject(fid,template.(fieldname),object.(fieldname),[prefix fieldname])
35 elseif template.(fieldname).marshall,
36 if ~isempty(template.(fieldname).preprocess),
37 eval(['fieldvalue=' template.(fieldname).preprocess '(object.(fieldname));']);
38 else
39 fieldvalue=object.(fieldname);
40 end
41
42 %Capitalize for enums
43 fieldnamecap=fieldname;
44 fieldnamecap(1)=upper(fieldname(1));
45 prefixcap=prefix;
46 if ~isempty(prefix), prefixcap(1)=upper(prefix(1)); end
47
48 %Write Data
49 WriteData(fid,[prefixcap fieldnamecap],fieldvalue,template.(fieldname));
50 end
51end
52 % }}}
53function WriteData(fid,fieldname,fieldvalue,fieldprop) % {{{
54%WRITEDATA - write model field in binary file
55%
56% Usage:
57% WriteData(fid,fieldname,fieldvalue,fieldprop)
58%
59
60%first recover data, enum of the data and type of data
61data=fieldvalue;
62if fieldprop.enum==NoneEnum,
63 enum=BuildEnum(fieldname);
64else
65 %Field enum overloaded
66 enum=fieldprop.enum;
67end
68data_type=fieldprop.format;
69
70if issparse(data),
71 data=full(data);
72end
73
74%Ok! write the enum (name) to identify this record uniquely
75fwrite(fid,enum,'int');
76
77%Now, write the data itself.
78if strcmpi(data_type,'Boolean'),% {{{
79 if(numel(data)~=1), error(['field ' field ' cannot be marshalled as it has more than one element!']); end
80
81 %first write length of record
82 fwrite(fid,4+4,'int'); %1 bool (disguised as an int)+code
83
84 %write data code:
85 fwrite(fid,TypeToCode(data_type),'int');
86
87 %now write integer
88 fwrite(fid,data,'int'); %send an int, not easy to send a bool
89 % }}}
90elseif strcmpi(data_type,'Integer'), % {{{
91 if(numel(data)~=1), error(['field ' field ' cannot be marshalled as it has more than one element!']); end
92
93 %first write length of record
94 fwrite(fid,4+4,'int'); %1 integer + code
95
96 %write data code:
97 fwrite(fid,TypeToCode(data_type),'int');
98
99 %now write integer
100 fwrite(fid,data,'int');
101 % }}}
102elseif strcmpi(data_type,'Double'), % {{{
103 if(numel(data)~=1), error(['field ' field ' cannot be marshalled as it has more than one element!']); end
104
105 %first write length of record
106 fwrite(fid,8+4,'int'); %1 double+code
107
108 %write data code:
109 fwrite(fid,TypeToCode(data_type),'int');
110
111 %now write double
112 fwrite(fid,data,'double');
113 % }}}
114elseif strcmpi(data_type,'String'), % {{{
115 %first write length of record
116 fwrite(fid,length(data)+4+4,'int'); %string + string size + code
117
118 %write data code:
119 fwrite(fid,TypeToCode(data_type),'int');
120
121 %now write string
122 fwrite(fid,length(data),'int');
123 fwrite(fid,data,'char');
124 % }}}
125elseif strcmpi(data_type,'BooleanMat'), % {{{
126
127 %matrix type:
128 mattype=fieldprop.mattype;
129
130 %Get size
131 s=size(data);
132 %if matrix = NaN, then do not write anything
133 if (s(1)==1 & s(2)==1 & isnan(data)),
134 s(1)=0; s(2)=0;
135 end
136
137 %first write length of record
138 fwrite(fid,4+4+8*s(1)*s(2)+4+4,'int'); %2 integers (32 bits) + the double matrix + code + matrix type
139
140 %write data code and matrix type:
141 fwrite(fid,TypeToCode(data_type),'int');
142 fwrite(fid,mattype,'int');
143
144 %now write matrix
145 fwrite(fid,s(1),'int');
146 fwrite(fid,s(2),'int');
147 if s(1)*s(2),
148 fwrite(fid,data','double'); %get to the "c" convention, hence the transpose
149 end
150 % }}}
151elseif strcmpi(data_type,'IntMat'), % {{{
152
153 %matrix type:
154 mattype=fieldtype{2};
155
156 %Get size
157 s=size(data);
158 %if matrix = NaN, then do not write anything
159 if (s(1)==1 & s(2)==1 & isnan(data)),
160 s(1)=0; s(2)=0;
161 end
162
163 %first write length of record
164 fwrite(fid,4+4+8*s(1)*s(2)+4+4,'int'); %2 integers (32 bits) + the double matrix + code + matrix type
165
166 %write data code and matrix type:
167 fwrite(fid,TypeToCode(data_type),'int');
168 fwrite(fid,mattype,'int');
169
170 %now write matrix
171 fwrite(fid,s(1),'int');
172 fwrite(fid,s(2),'int');
173 if s(1)*s(2),
174 fwrite(fid,data','double'); %get to the "c" convention, hence the transpose
175 end
176 % }}}
177elseif strcmpi(data_type,'DoubleMat'), % {{{
178
179 %matrix type:
180 mattype=fieldprop.mattype;
181
182 %Get size
183 s=size(data);
184 %if matrix = NaN, then do not write anything
185 if (s(1)==1 & s(2)==1 & isnan(data)),
186 s(1)=0; s(2)=0;
187 end
188
189 %first write length of record
190 fwrite(fid,4+4+8*s(1)*s(2)+4+4,'int'); %2 integers (32 bits) + the double matrix + code + matrix type
191
192 %write data code and matrix type:
193 fwrite(fid,TypeToCode(data_type),'int');
194 fwrite(fid,mattype,'int');
195
196 %now write matrix
197 fwrite(fid,s(1),'int');
198 fwrite(fid,s(2),'int');
199 if s(1)*s(2),
200 fwrite(fid,data','double'); %get to the "c" convention, hence the transpose
201 end
202 % }}}
203elseif strcmpi(data_type,'MatArray'), % {{{
204
205 numrecords=numel(data);
206
207 %first get length of record
208 recordlength=4+4; %number of records + code
209 for i=1:numrecords,
210 matrix=data{i};
211 s=size(matrix);
212 recordlength=recordlength+4*2+... %row and col of matrix
213 s(1)*s(2)*8; %matrix of doubles
214 end
215
216 %write length of record
217 fwrite(fid,recordlength,'int');
218
219 %write data code:
220 fwrite(fid,TypeToCode(data_type),'int');
221
222 %write data, first number of records
223 fwrite(fid,numrecords,'int');
224
225 %write each matrix:
226 for i=1:numrecords,
227 matrix=data{i};
228 s=size(matrix);
229 fwrite(fid,s(1),'int');
230 fwrite(fid,s(2),'int');
231 fwrite(fid,matrix','double');
232 end
233 % }}}
234elseif strcmpi(data_type,'StringArray'), % {{{
235
236 %first get length of string array:
237 num=numel(data);
238 %now get length of record:
239 recordlength=4+4; %for length of array + code
240 for i=1:num,
241 string=data{i};
242 recordlength=recordlength+4+length(string); %for each string
243 end
244
245 %write length of record
246 fwrite(fid,recordlength,'int');
247
248 %write data code:
249 fwrite(fid,TypeToCode(data_type),'int');
250
251 %now write length of string array
252 fwrite(fid,num,'int');
253
254 %now write the strings
255 for i=1:num,
256 string=data{i};
257 fwrite(fid,length(string),'int');
258 fwrite(fid,string,'char');
259 end
260 % }}}
261else
262 error(['WriteData error message: data type: ' num2str(data_type) ' not supported yet! (' EnumToString(enum) ')']);
263end
264% }}}
265function enum=BuildEnum(string) % {{{
266%BUILDENUM - build enum out of string
267%
268% Usage:
269% enum=BuildEnum(string)
270
271if findstr(string,'_'),
272 indices=findstr(string,'_');
273 for i=1:length(indices),
274 string(indices(i)+1)=upper(string(indices(i)+1));
275 end
276 string(indices)=[];
277end
278
279%take first letter of string and make it uppercase:
280string(1)=upper(string(1));
281
282%Get Enum
283enum=eval([string 'Enum']);
284% }}}
285function code=TypeToCode(data_type) % {{{1
286%This routine takes the data_type string, and hardcodes it into an integer, which
287%is passed along the record, in order to identify the nature of the dataset being
288%sent.
289if strcmpi(data_type,'Boolean'),
290 code=1;
291elseif strcmpi(data_type,'Integer'),
292 code=2;
293elseif strcmpi(data_type,'Double'),
294 code=3;
295elseif strcmpi(data_type,'String'),
296 code=4;
297elseif strcmpi(data_type,'BooleanMat'),
298 code=5;
299elseif strcmpi(data_type,'IntMat'),
300 code=6;
301elseif strcmpi(data_type,'DoubleMat'),
302 code=7;
303elseif strcmpi(data_type,'MatArray'),
304 code=8;
305elseif strcmpi(data_type,'StringArray'),
306 code=9;
307else
308 error('TypeToCode error message: data type not supported yet!');
309end% }}}
310
311%FIXME Some processing, should be moved to the corresponding classes in the future
312function out=marshallverbose(in)
313 out = VerboseToBinary(in);
314function out=marshallicefront(in)
315 out=in;
316 pos=find(in(:,end)==0); out(pos,end)=AirEnum;
317 pos=find(in(:,end)==1); out(pos,end)=WaterEnum;
318 pos=find(in(:,end)==2); out(pos,end)=IceEnum;
319
320function out=marshallrifts(in)
321 if isempty(in) | isnans(in),
322 numrifts=0;
323 else
324 numrifts=numel(in);
325 end
326 numpairs=0;
327 for i=1:numrifts,
328 numpairs=numpairs+size(in(i).penaltypairs,1);
329 end
330
331 out=zeros(numpairs,12); % 2 for nodes + 2 for elements+ 2 for normals + 1 for length + 1 for fill + 1 for friction + 1 for fraction + 1 for fractionincrement + 1 for state.
332
333 count=1;
334 for i=1:numrifts,
335 numpairsforthisrift=size(in(i).penaltypairs,1);
336 out(count:count+numpairsforthisrift-1,1:7)=in(i).penaltypairs;
337 out(count:count+numpairsforthisrift-1,8)=in(i).fill;
338 out(count:count+numpairsforthisrift-1,9)=in(i).friction;
339 out(count:count+numpairsforthisrift-1,10)=in(i).fraction;
340 out(count:count+numpairsforthisrift-1,11)=in(i).fractionincrement;
341 out(count:count+numpairsforthisrift-1,12)=in(i).state;
342 count=count+numpairsforthisrift;
343 end
344function out=marshallapproximations(in),
345 out=in;
346 pos=find(in==0); out(pos,end)=NoneApproximationEnum;
347 pos=find(in==1); out(pos,end)=HutterApproximationEnum;
348 pos=find(in==2); out(pos,end)=MacAyealApproximationEnum;
349 pos=find(in==3); out(pos,end)=PattynApproximationEnum;
350 pos=find(in==4); out(pos,end)=StokesApproximationEnum;
351 pos=find(in==5); out(pos,end)=MacAyealPattynApproximationEnum;
352 pos=find(in==6); out(pos,end)=MacAyealStokesApproximationEnum;
353 pos=find(in==7); out(pos,end)=PattynStokesApproximationEnum;
354
355function out=marshallcontroltype(in)
356 out=zeros(1,numel(in));
357 for i=1:numel(in),
358 out(i)=StringToEnum(in{i});
359 end
360function out=marshallcmresponses(in),
361 out=in;
362 pos=find(in==101); out(pos)=SurfaceAbsVelMisfitEnum;
363 pos=find(in==102); out(pos)=SurfaceRelVelMisfitEnum;
364 pos=find(in==103); out(pos)=SurfaceLogVelMisfitEnum;
365 pos=find(in==104); out(pos)=SurfaceLogVxVyMisfitEnum;
366 pos=find(in==105); out(pos)=SurfaceAverageVelMisfitEnum;
367 pos=find(in==201); out(pos)=ThicknessAbsMisfitEnum;
368 pos=find(in==501); out(pos)=DragCoefficientAbsGradientEnum;
369 pos=find(in==502); out(pos)=RheologyBbarAbsGradientEnum;
370 pos=find(in==503); out(pos)=ThicknessAbsGradientEnum;
Note: See TracBrowser for help on using the repository browser.