1 /*******************************************************************/
2 /* XDMF */
3 /* eXtensible Data Model and Format */
4 /* */
5 /* Id : Id */
6 /* Date : $Date$ */
7 /* Version : $Revision$ */
8 /* */
9 /* Author: */
10 /* Kenneth Leiter
11 /* kenneth.leiter@arl.army.mil */
12 /* US Army Research Laboratory */
13 /* Aberdeen Proving Ground, MD */
14 /* */
15 /* Copyright @ 2009 US Army Research Laboratory */
16 /* All Rights Reserved */
17 /* See Copyright.txt or http://www.arl.hpc.mil/ice for details */
18 /* */
19 /* This software is distributed WITHOUT ANY WARRANTY; without */
20 /* even the implied warranty of MERCHANTABILITY or FITNESS */
21 /* FOR A PARTICULAR PURPOSE. See the above copyright notice */
22 /* for more information. */
23 /* */
24 /*******************************************************************/
25 ////////////////////////////////
26 /*
27
28 Serializes STL objects to Xdmf
29
30 CURRENTLY SUPPORTED:
31
32 WRITING:
33
34 STL TYPES:
35 vector, deque, list, set, multiset, map, multimap
36
37 DATA TYPES:
38 char, short, int, long long, float, double, unsigned char, unsigned short, unsigned int
39
40 READING:
41 STL TYPES:
42 vector, deque, list, set, multiset, map, multimap
43
44 DATA TYPES:
45 char, short, int, long long, float, double, unsigned char, unsigned short, unsigned int
46
47 TODO:
48 Add support for stacks, queues, and priority queues
49 (no const_iterator... must find alternative way of getting data)
50 Currently user should move data into a supported stl template...
51
52 //////////////////////////////*/
53 #ifndef __XdmfXdmfSTLConverter_txx
54 #define __XdmfXdmfSTLConverter_txx
55 #include <XdmfArray.h>
56 #include <XdmfAttribute.h>
57 #include <XdmfDOM.h>
58 #include <XdmfGrid.h>
59 #include <XdmfMap.h>
60 #include <XdmfSet.h>
61
62 #include <vector>
63 #include <deque>
64 #include <list>
65 #include <set>
66 #include <sstream>
67
68 class XdmfSTLConverter
69 {
70
71 public:
72 inline
73 XdmfSTLConverter();
74
75 inline
76 ~XdmfSTLConverter();
77
78 template<template<typename > class Container, class T>
79 void inline
80 writeSetToXdmf(Container<T> const& myContainer, XdmfElement * parent, std::string myName,
81 std::string heavyName = "Xdmf.h5");
82
83 template<template<typename , typename > class Container, class T, class U>
84 void inline
85 writeMapToXdmf(Container<T, U> const& myContainer, XdmfElement * parent, std::string myName,
86 std::string heavyName = "Xdmf.h5");
87
88 template<template<typename > class Container, class T>
89 void inline
90 getSetFromXdmf(Container<T> &myContainer, XdmfSet * currSet);
91
92 template<template<typename , typename > class Container, class T, class U>
93 void inline
94 getMapFromXdmf(Container<T, U> &myContainer, XdmfSet * currSet);
95
96 private:
97 template<class T>
98 void inline
99 copyFromXdmfArray(std::vector<T> &myContainer, XdmfArray * myIds);
100
101 template<class T>
102 void inline
103 copyFromXdmfArray(std::deque<T> &myContainer, XdmfArray * myIds);
104
105 template<class T>
106 void inline
107 copyFromXdmfArray(std::list<T> &myContainer, XdmfArray * myIds);
108
109 template<class T>
110 void inline
111 copyFromXdmfArray(std::set<T> &myContainer, XdmfArray * myIds);
112
113 template<class T>
114 void inline
115 copyFromXdmfArray(std::multiset<T> &myContainer, XdmfArray * myIds);
116
117 template<template<typename > class Container>
118 void inline
119 generateXdmfArray(XdmfArray * currentArray, const Container<char> &myContainer);
120
121 template<template<typename > class Container>
122 void inline
123 generateXdmfArray(XdmfArray * currentArray, const Container<short> &myContainer);
124
125 template<template<typename > class Container>
126 void inline
127 generateXdmfArray(XdmfArray * currentArray, const Container<int> &myContainer);
128
129 template<template<typename > class Container>
130 void inline
131 generateXdmfArray(XdmfArray * currentArray, const Container<long long> &myContainer);
132
133 template<template<typename > class Container>
134 void inline
135 generateXdmfArray(XdmfArray * currentArray, const Container<float> &myContainer);
136
137 template<template<typename > class Container>
138 void inline
139 generateXdmfArray(XdmfArray * currentArray, const Container<double> &myContainer);
140
141 template<template<typename > class Container>
142 void inline
143 generateXdmfArray(XdmfArray * currentArray, const Container<unsigned char> &myContainer);
144
145 template<template<typename > class Container>
146 void inline
147 generateXdmfArray(XdmfArray * currentArray, const Container<unsigned short> &myContainer);
148
149 template<template<typename > class Container>
150 void inline
151 generateXdmfArray(XdmfArray * currentArray, const Container<unsigned int> &myContainer);
152
153 template<template<typename > class Container, class T>
154 void inline
155 writeArrayValues(XdmfArray * currentArray, const Container<T> &myContainer);
156
157 template<class T>
158 T inline
159 getArrayValue(XdmfArray * currentArray, int index);
160 };
161
XdmfSTLConverter()162 XdmfSTLConverter::XdmfSTLConverter()
163 {
164
165 }
166
~XdmfSTLConverter()167 XdmfSTLConverter::~XdmfSTLConverter()
168 {
169
170 }
171
172 // FOR NON-ASSOCIATIVE SETS
173 template<template<typename > class Container, class T>
174 void
writeSetToXdmf(Container<T> const & myContainer,XdmfElement * parent,std::string myName,std::string heavyName)175 XdmfSTLConverter::writeSetToXdmf(Container<T> const& myContainer, XdmfElement * parent,
176 std::string myName, std::string heavyName)
177 {
178 XdmfSet * currSet = new XdmfSet();
179 currSet->SetSetType(XDMF_SET_TYPE_NODE);
180 currSet->SetName(myName.c_str());
181 currSet->SetDeleteOnGridDelete(true);
182
183 // Copy Elements from Set to XdmfArray
184 std::stringstream name;
185 name << heavyName;
186 if (heavyName.length() >= 3)
187 {
188 if (heavyName.substr(heavyName.length() - 3).compare(".h5") == 0)
189 {
190 name << ":";
191 }
192 }
193 name << "/" << myName;
194 currSet->GetIds()->SetHeavyDataSetName(name.str().c_str());
195 generateXdmfArray(currSet->GetIds(), myContainer);
196
197 parent->Insert(currSet);
198 currSet->Build();
199 }
200
201 // FOR ASSOCIATIVE SETS (Maps)
202 // Writing values as set attributes with keys as set dataitems...
203 template<template<typename , typename > class Container, class T, class U>
204 void
writeMapToXdmf(Container<T,U> const & myContainer,XdmfElement * parent,std::string myName,std::string heavyName)205 XdmfSTLConverter::writeMapToXdmf(Container<T, U> const& myContainer, XdmfElement * parent,
206 std::string myName, std::string heavyName)
207 {
208 XdmfSet * currSet = new XdmfSet();
209 currSet->SetSetType(XDMF_SET_TYPE_NODE);
210 currSet->SetName(myName.c_str());
211 currSet->SetDeleteOnGridDelete(true);
212
213 // Store Keys and Values in Separate Sets
214 std::vector<T> keys(myContainer.size());
215 std::vector<U> vals(myContainer.size());
216 int index = 0;
217 typename Container<T, U>::const_iterator i;
218
219 for (i = myContainer.begin(); i != myContainer.end(); i++)
220 {
221 keys[index] = i->first;
222 vals[index] = i->second;
223 index++;
224 }
225
226 XdmfAttribute * myAttribute = new XdmfAttribute();
227 myAttribute->SetName("Values");
228 myAttribute->SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE);
229 myAttribute->SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
230 myAttribute->SetDeleteOnGridDelete(true);
231
232 // Copy Elements from each vector to XdmfArrays
233 std::stringstream keyName;
234 std::stringstream valName;
235 keyName << heavyName;
236 valName << heavyName;
237
238 if (heavyName.length() >= 3)
239 {
240 if (heavyName.substr(heavyName.length() - 3).compare(".h5") == 0)
241 {
242 keyName << ":";
243 valName << ":";
244 }
245 }
246 keyName << "/" << myName << "/Keys";
247 valName << "/" << myName << "/Vals";
248
249 currSet->GetIds()->SetHeavyDataSetName(keyName.str().c_str());
250 myAttribute->GetValues()->SetHeavyDataSetName(valName.str().c_str());
251 generateXdmfArray(currSet->GetIds(), keys);
252 generateXdmfArray(myAttribute->GetValues(), vals);
253
254 parent->Insert(currSet);
255
256 currSet->Insert(myAttribute);
257 currSet->Build();
258 }
259
260 template<template<typename > class Container, class T>
261 void
getSetFromXdmf(Container<T> & myContainer,XdmfSet * currSet)262 XdmfSTLConverter::getSetFromXdmf(Container<T> & myContainer, XdmfSet * currSet)
263 {
264 XdmfArray * myIds = currSet->GetIds();
265 copyFromXdmfArray(myContainer, myIds);
266 }
267
268 template<template<typename , typename > class Container, class T, class U>
269 void
getMapFromXdmf(Container<T,U> & myContainer,XdmfSet * currSet)270 XdmfSTLConverter::getMapFromXdmf(Container<T, U> & myContainer, XdmfSet * currSet)
271 {
272 XdmfArray * myKeys = currSet->GetIds();
273 XdmfAttribute * myAttribute = currSet->GetAttribute(0);
274 myAttribute->Update();
275 XdmfArray * myVals = myAttribute->GetValues(0);
276 for (int i = 0; i < myKeys->GetNumberOfElements(); i++)
277 {
278 myContainer.insert(
279 std::pair<T, U>(getArrayValue<T> (myKeys, i), getArrayValue<U> (myVals, i)));
280 }
281 }
282
283 template<class T>
284 void
copyFromXdmfArray(std::vector<T> & myContainer,XdmfArray * myIds)285 XdmfSTLConverter::copyFromXdmfArray(std::vector<T> &myContainer, XdmfArray * myIds)
286 {
287 for (int i = 0; i < myIds->GetNumberOfElements(); i++)
288 {
289 myContainer.push_back(getArrayValue<T> (myIds, i));
290 }
291 }
292
293 template<class T>
294 void
copyFromXdmfArray(std::deque<T> & myContainer,XdmfArray * myIds)295 XdmfSTLConverter::copyFromXdmfArray(std::deque<T> &myContainer, XdmfArray * myIds)
296 {
297 for (int j = 0; j < myIds->GetNumberOfElements(); j++)
298 {
299 myContainer.push_back(getArrayValue<T> (myIds, j));
300 }
301 }
302
303 template<class T>
304 void
copyFromXdmfArray(std::list<T> & myContainer,XdmfArray * myIds)305 XdmfSTLConverter::copyFromXdmfArray(std::list<T> &myContainer, XdmfArray * myIds)
306 {
307 for (int j = 0; j < myIds->GetNumberOfElements(); j++)
308 {
309 myContainer.push_back(getArrayValue<T> (myIds, j));
310 }
311 }
312
313 template<class T>
314 void
copyFromXdmfArray(std::set<T> & myContainer,XdmfArray * myIds)315 XdmfSTLConverter::copyFromXdmfArray(std::set<T> &myContainer, XdmfArray * myIds)
316 {
317 for (int j = 0; j < myIds->GetNumberOfElements(); j++)
318 {
319 myContainer.insert(getArrayValue<T> (myIds, j));
320 }
321 }
322
323 template<class T>
324 void
copyFromXdmfArray(std::multiset<T> & myContainer,XdmfArray * myIds)325 XdmfSTLConverter::copyFromXdmfArray(std::multiset<T> & myContainer, XdmfArray * myIds)
326 {
327 for (int j = 0; j < myIds->GetNumberOfElements(); j++)
328 {
329 myContainer.insert(getArrayValue<T> (myIds, j));
330 }
331 }
332
333 template<template<typename > class Container>
334 void
generateXdmfArray(XdmfArray * currentArray,const Container<char> & myContainer)335 XdmfSTLConverter::generateXdmfArray(XdmfArray * currentArray, const Container<char> & myContainer)
336 {
337 currentArray->SetNumberType(XDMF_INT8_TYPE);
338 writeArrayValues(currentArray, myContainer);
339 }
340
341 template<template<typename > class Container>
342 void
generateXdmfArray(XdmfArray * currentArray,const Container<short> & myContainer)343 XdmfSTLConverter::generateXdmfArray(XdmfArray * currentArray,
344 const Container<short> & myContainer)
345 {
346 currentArray->SetNumberType(XDMF_INT16_TYPE);
347 writeArrayValues(currentArray, myContainer);
348 }
349
350 template<template<typename > class Container>
351 void
generateXdmfArray(XdmfArray * currentArray,const Container<int> & myContainer)352 XdmfSTLConverter::generateXdmfArray(XdmfArray * currentArray, const Container<int> & myContainer)
353 {
354 currentArray->SetNumberType(XDMF_INT32_TYPE);
355 writeArrayValues(currentArray, myContainer);
356 }
357
358 template<template<typename > class Container>
359 void
generateXdmfArray(XdmfArray * currentArray,const Container<long long> & myContainer)360 XdmfSTLConverter::generateXdmfArray(XdmfArray * currentArray,
361 const Container<long long> & myContainer)
362 {
363 currentArray->SetNumberType(XDMF_INT64_TYPE);
364 writeArrayValues(currentArray, myContainer);
365 }
366
367 template<template<typename > class Container>
368 void
generateXdmfArray(XdmfArray * currentArray,const Container<float> & myContainer)369 XdmfSTLConverter::generateXdmfArray(XdmfArray * currentArray,
370 const Container<float> & myContainer)
371 {
372 currentArray->SetNumberType(XDMF_FLOAT32_TYPE);
373 writeArrayValues(currentArray, myContainer);
374 }
375
376 template<template<typename > class Container>
377 void
generateXdmfArray(XdmfArray * currentArray,const Container<double> & myContainer)378 XdmfSTLConverter::generateXdmfArray(XdmfArray * currentArray,
379 const Container<double> & myContainer)
380 {
381 currentArray->SetNumberType(XDMF_FLOAT64_TYPE);
382 writeArrayValues(currentArray, myContainer);
383 }
384
385 template<template<typename > class Container>
386 void
generateXdmfArray(XdmfArray * currentArray,const Container<unsigned char> & myContainer)387 XdmfSTLConverter::generateXdmfArray(XdmfArray * currentArray,
388 const Container<unsigned char> & myContainer)
389 {
390 currentArray->SetNumberType(XDMF_UINT8_TYPE);
391 writeArrayValues(currentArray, myContainer);
392 }
393
394 template<template<typename > class Container>
395 void
generateXdmfArray(XdmfArray * currentArray,const Container<unsigned short> & myContainer)396 XdmfSTLConverter::generateXdmfArray(XdmfArray * currentArray,
397 const Container<unsigned short> & myContainer)
398 {
399 currentArray->SetNumberType(XDMF_UINT16_TYPE);
400 writeArrayValues(currentArray, myContainer);
401 }
402
403 template<template<typename > class Container>
404 void
generateXdmfArray(XdmfArray * currentArray,const Container<unsigned int> & myContainer)405 XdmfSTLConverter::generateXdmfArray(XdmfArray * currentArray,
406 const Container<unsigned int> & myContainer)
407 {
408 currentArray->SetNumberType(XDMF_UINT32_TYPE);
409 writeArrayValues(currentArray, myContainer);
410 }
411
412 template<template<typename > class Container, class T>
413 void
writeArrayValues(XdmfArray * currentArray,const Container<T> & myContainer)414 XdmfSTLConverter::writeArrayValues(XdmfArray * currentArray, const Container<T> & myContainer)
415 {
416 currentArray->SetNumberOfElements(myContainer.size());
417 int index = 0;
418 typename Container<T>::const_iterator i;
419 for (i = myContainer.begin(); i != myContainer.end(); i++)
420 {
421 currentArray->SetValue(index, *i);
422 index++;
423 }
424 }
425
426 template<class T>
427 T
getArrayValue(XdmfArray * currentArray,int index)428 XdmfSTLConverter::getArrayValue(XdmfArray * currentArray, int index)
429 {
430 switch (currentArray->GetNumberType())
431 {
432 case XDMF_INT8_TYPE:
433 return (T) currentArray->GetValueAsInt8(index);
434 case XDMF_INT16_TYPE:
435 return (T) currentArray->GetValueAsInt16(index);
436 case XDMF_INT32_TYPE:
437 return (T) currentArray->GetValueAsInt32(index);
438 case XDMF_INT64_TYPE:
439 return (T) currentArray->GetValueAsInt64(index);
440 case XDMF_FLOAT32_TYPE:
441 return (T) currentArray->GetValueAsFloat32(index);
442 case XDMF_FLOAT64_TYPE:
443 return (T) currentArray->GetValueAsFloat64(index);
444 case XDMF_UINT8_TYPE:
445 return (T) currentArray->GetValueAsInt8(index);
446 case XDMF_UINT16_TYPE:
447 return (T) currentArray->GetValueAsInt16(index);
448 case XDMF_UINT32_TYPE:
449 return (T) currentArray->GetValueAsInt32(index);
450 default:
451 return (T) currentArray->GetValueAsFloat64(index);
452 }
453 }
454 #endif // __XdmfXdmfSTLConverter_txx
455