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

61
      Parameters::get(problem->getName() + "->output->append serialization index", appendIndex);
Thomas Witkowski's avatar
Thomas Witkowski committed
62
63
      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");

80
      Parameters::get(problem->getName() + "->output->append serialization index", appendIndex);
Thomas Witkowski's avatar
Thomas Witkowski committed
81
82
      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
      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);
      }

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

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

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

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

139
    /// Pointer to the problem.
140
    ProblemType *problem;
141

142
    /// The problem is serialized every tsModulo-th timestep.
143
    int tsModulo;
144

Thomas Witkowski's avatar
Thomas Witkowski committed
145
146
147
148
149
150
151
152
153
154
    /// 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;

155
    /// Current timestep number.
156
    int timestepNumber;
157
158
  };

159
  namespace SerUtil {
160

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

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

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

    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);
    }



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

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

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

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

231
232


233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
    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)
    {
248
249
      data.clear();

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

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

260
261


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

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

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

282
      int mapSize = 0;
283
      deserialize(in, mapSize);
284
285
286
287

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

294
  }
295
296
297

}
#endif