Serializer.h 7.14 KB
Newer Older
1
// ============================================================================
2
3
4
// ==                                                                        ==
// == AMDiS - Adaptive multidimensional simulations                          ==
// ==                                                                        ==
5
// ==  http://www.amdis-fem.org                                              ==
6
7
// ==                                                                        ==
// ============================================================================
8
9
10
11
12
13
14
15
16
17
18
19
//
// Software License for AMDiS
//
// Copyright (c) 2010 Dresden University of Technology 
// All rights reserved.
// Authors: Simon Vey, Thomas Witkowski et al.
//
// This file is part of AMDiS
//
// See also license.opensource.txt in the distribution.


20
21
22
23
24
25

/** \file Serializer.h */

#ifndef AMDIS_SERIALIZER_H
#define AMDIS_SERIALIZER_H

26
27
28
29
#if HAVE_PARALLEL_DOMAIN_AMDIS
#include <mpi.h>
#endif

30
#include <map>
31
#include <boost/lexical_cast.hpp>
32

33
#include "Global.h"
34
#include "Initfile.h"
35
#include "AdaptInfo.h"
36
#include "io/FileWriter.h"
37
38
39
40
41
42
43

namespace AMDiS {

  template<typename ProblemType>
  class Serializer : public FileWriterInterface
  {
  public:
44
45
46
47
    Serializer(ProblemType *prob) 
      : name(""), 
	problem(prob),
	tsModulo(1), 
Thomas Witkowski's avatar
Thomas Witkowski committed
48
49
	appendIndex(0),
	indexLength(5),
Thomas Witkowski's avatar
Thomas Witkowski committed
50
51
	indexDecimals(3),
	timestepNumber(-1)
Thomas Witkowski's avatar
Thomas Witkowski committed
52
    {
53
54
      FUNCNAME("Serializer::Serializer()");

55
56
57
58
      Parameters::get(problem->getName() + "->output->serialization filename", 
		      name);
      Parameters::get(problem->getName() + "->output->write every i-th timestep", 
		      tsModulo);
59
      TEST_EXIT(name != "")("No filename!\n");
60

Thomas Witkowski's avatar
Thomas Witkowski committed
61
62
63
      Parameters::get(problem->getName() + "->output->append index", appendIndex);
      Parameters::get(problem->getName() + "->output->index length", indexLength);
      Parameters::get(problem->getName() + "->output->index decimals", indexDecimals);
Thomas Witkowski's avatar
Thomas Witkowski committed
64
    }
65

66
67
68
69
70

    Serializer(ProblemType *prob, std::string filename, int writeEveryIth)
      : name(filename),
	problem(prob),
	tsModulo(writeEveryIth),
Thomas Witkowski's avatar
Thomas Witkowski committed
71
72
	appendIndex(0),
	indexLength(5),
Thomas Witkowski's avatar
Thomas Witkowski committed
73
74
	indexDecimals(3),
	timestepNumber(-1)
75
76
77
78
79
    {
      FUNCNAME("Serializer::Serializer()");

      TEST_EXIT(name != "")("No filename!\n");

Thomas Witkowski's avatar
Thomas Witkowski committed
80
81
82
      Parameters::get(problem->getName() + "->output->append index", appendIndex);
      Parameters::get(problem->getName() + "->output->index length", indexLength);
      Parameters::get(problem->getName() + "->output->index decimals", indexDecimals);
83
84
85
    }


Thomas Witkowski's avatar
Thomas Witkowski committed
86
    virtual ~Serializer() {}
87
88
89
90
91
92
93
94
95

    virtual void writeFiles(AdaptInfo *adaptInfo, 
			    bool force,
			    int level = -1,
			    Flag traverseFlag = Mesh::CALL_LEAF_EL,
			    bool (*writeElem)(ElInfo*) = NULL) 
    {
      FUNCNAME("Serializer::writeFiles()");

96
97
98
      TEST_EXIT(tsModulo > 0)
	("Parameter 'write every ith timestep' must be larger than zero!\n");

99
100
101
      timestepNumber++;
      timestepNumber %= tsModulo;
      if ((timestepNumber != 0) && !force)
102
103
104
105
	return;

      TEST_EXIT(adaptInfo)("No AdaptInfo\n");

Thomas Witkowski's avatar
Thomas Witkowski committed
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
      string filename = name;
      if (appendIndex) {
	TEST_EXIT(indexLength <= 99)("index lenght > 99\n");
	TEST_EXIT(indexDecimals <= 97)("index decimals > 97\n");
	TEST_EXIT(indexDecimals < indexLength)("index length <= index decimals\n");
	
	char formatStr[9];
	char timeStr[20];
	
	sprintf(formatStr, "%%0%d.%df", indexLength, indexDecimals);
	sprintf(timeStr, formatStr, adaptInfo ? adaptInfo->getTime() : 0.0);
	
	filename += string(timeStr);
      }

      filename += ".ser";
      
#if HAVE_PARALLEL_DOMAIN_AMDIS
      filename += ".p" + boost::lexical_cast<std::string>(MPI::COMM_WORLD.Get_rank());
#endif

      std::ofstream out(filename.c_str());
128
      TEST_EXIT(out.is_open())("Cannot open serialization file!\n");
129
      out.write(reinterpret_cast<const char*>(&amdisRevisionNumber), sizeof(int));
130
      problem->serialize(out);
131
132
133
      adaptInfo->serialize(out);
      out.close();

Thomas Witkowski's avatar
Thomas Witkowski committed
134
      MSG("Problem serialized to %s \n", filename.c_str());
Thomas Witkowski's avatar
Thomas Witkowski committed
135
    }
136
137

  protected:
138
    /// Name of file to which the problem is serialized.
139
    std::string name;
140

141
    /// Pointer to the problem.
142
    ProblemType *problem;
143

144
    /// The problem is serialized every tsModulo-th timestep.
145
    int tsModulo;
146

Thomas Witkowski's avatar
Thomas Witkowski committed
147
148
149
150
151
152
153
154
155
156
    /// 0: Don't append time index to filename prefix.
    /// 1: Append time index to filename prefix.
    int appendIndex;

    /// Total length of appended time index.
    int indexLength;

    /// Number of decimals in time index.
    int indexDecimals;

157
    /// Current timestep number.
158
    int timestepNumber;
159
160
  };

161
  namespace SerUtil {
162

163
    template<typename T>
164
    void serialize(std::ostream& out, T& data)
165
    {
166
      out.write(reinterpret_cast<const char*>(&data), sizeof(T));
167
    }   
168

169
    template<typename T>
170
    void deserialize(std::istream& in, T& data)
171
    {
172
      in.read(reinterpret_cast<char*>(&data), sizeof(T));
173
    }   
174

175

176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204

    void serialize(std::ostream& out, DofEdge& data);

    void deserialize(std::istream& in, DofEdge& data);



    void serialize(std::ostream& out, DofFace& data);

    void deserialize(std::istream& in, DofFace& data);



    template<typename T, typename U>
    void serialize(std::ostream& out, std::pair<T, U>& data)
    {
      serialize(out, data.first);
      serialize(out, data.second);
    }

    template<typename T, typename U>
    void deserialize(std::istream& in, std::pair<T, U>& data)
    {
      deserialize(in, data.first);
      deserialize(in, data.second);
    }



205
    template<typename T>
206
    void serialize(std::ostream& out, std::vector<T>& data)
207
208
    {
      int vecSize = data.size();
209
      serialize(out, vecSize);
210
211
212
      for (typename std::vector<T>::iterator it = data.begin(); 
	   it != data.end(); ++it) {
	T v = *it;
213
	serialize(out, v);
214
215
216
217
      }
    }

    template<typename T>
218
    void deserialize(std::istream& in, std::vector<T>& data)
219
    {
220
221
      data.clear();

222
      int vecSize = 0;
223
      deserialize(in, vecSize);
224
225
226
227
      data.resize(vecSize);

      for (int i = 0; i < vecSize; i++) {
	T v;
228
	deserialize(in, v);
229
230
231
232
	data[i] = v;
      }
    }

233
234


235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
    template<typename T>
    void serialize(std::ostream& out, std::set<T>& data)
    {
      int setSize = data.size();
      serialize(out, setSize);
      for (typename std::set<T>::iterator it = data.begin(); 
	   it != data.end(); ++it) {
	T v = *it;
	serialize(out, v);
      }
    }

    template<typename T>
    void deserialize(std::istream& in, std::set<T>& data)
    {
250
251
      data.clear();

252
253
254
255
256
257
258
259
260
      int setSize = 0;
      deserialize(in, setSize);

      for (int i = 0; i < setSize; i++) {
	T v;
	deserialize(in, v);
	data.insert(v);
      }
    }
261

262
263


264
    template<typename T1, typename T2>
265
    void serialize(std::ostream& out, std::map<T1, T2>& data)
266
    {
267
      int mapSize = data.size();
268
      serialize(out, mapSize);
269
270
271
272
273

      for (typename std::map<T1,T2>::iterator it = data.begin(); 
	   it != data.end(); ++it) {
	T1 v1 = it->first;
	T2 v2 = it->second;
274
275
	serialize(out, v1);
	serialize(out, v2);
276
      }
Thomas Witkowski's avatar
Thomas Witkowski committed
277
    }
278
279

    template<typename T1, typename T2>
280
    void deserialize(std::istream& in, std::map<T1, T2>& data)
281
    {
282
283
      data.clear();

284
      int mapSize = 0;
285
      deserialize(in, mapSize);
286
287
288
289

      for (int i = 0; i < mapSize; i++) {
	T1 v1;
	T2 v2;
290
291
	deserialize(in, v1);
	deserialize(in, v2);
292
293
294
295
	data[v1] = v2;
      }
    }

296
  }
297
298
299

}
#endif