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