ArhReader.cc 8.81 KB
Newer Older
1 2 3 4 5 6 7
/******************************************************************************
 *
 * AMDiS - Adaptive multidimensional simulations
 *
 * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved.
 * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis
 *
8
 * Authors:
9 10 11 12 13 14 15 16 17
 * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 *
 * This file is part of AMDiS
 *
 * See also license.opensource.txt in the distribution.
18
 *
19
 ******************************************************************************/
20 21


22
#include <fstream>
23
#include <stdint.h>
24
#include <boost/filesystem.hpp>
25 26 27 28

#include "ArhReader.h"
#include "Mesh.h"
#include "MeshStructure.h"
29 30
#include "Traverse.h"
#include "DOFVector.h"
31
#include "Debug.h"
32
#include "detail/ArhReader.h"
33

34
namespace AMDiS { namespace io {
35

36
  namespace ArhReader
37
  {
38
    using namespace std;
39

40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
    void readFile(string filename,
			DOFVector<double>* vec0,
			DOFVector<double>* vec1,
			DOFVector<double>* vec2,
			bool writeParallel,
			int nProcs)
    {
      vector<DOFVector<double>*> vecs(0);
      if (vec0)
	vecs.push_back(vec0);
      if (vec1)
	vecs.push_back(vec1);
      if (vec2)
	vecs.push_back(vec2);

55
      detail::readFile(filename, NULL, vecs, writeParallel, nProcs);
56
    }
57 58

    void readFile(string filename,
59 60 61 62
		     vector<DOFVector<double>*> vecs,
		     bool writeParallel,
		     int nProcs)
    {
63
      detail::readFile(filename, NULL, vecs, writeParallel, nProcs);
64
    }
65

66 67 68 69 70 71 72 73
    void readFile(string filename,
	    Mesh* mesh,
	    bool writeParallel,
	    int nProcs)
    {
      vector<DOFVector<double>*> vecs(0);
      detail::readFile(filename, mesh, vecs, writeParallel, nProcs);
    }
Thomas Witkowski's avatar
Thomas Witkowski committed
74

75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
    void readMeta(string filename,
			    DOFVector<double>* vec0,
			    DOFVector<double>* vec1,
			    DOFVector<double>* vec2)
    {
      vector<DOFVector<double>*> vecs;
      if (vec0)
	vecs.push_back(vec0);
      if (vec1)
	vecs.push_back(vec1);
      if (vec2)
	vecs.push_back(vec2);

      readMeta(filename, vecs);
    }
Thomas Witkowski's avatar
Thomas Witkowski committed
90

91 92 93 94
    void readMeta(string filename, vector<DOFVector<double>*> vecs)
    {
      FUNCNAME("ArhReader::readMeta()");

95
      Mesh* mesh = NULL;
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
      for(size_t i = 0; i < vecs.size(); i++)
      {
	if(vecs[i])
	{
	  if(!mesh)
	    mesh = vecs[i]->getFeSpace()->getMesh();
	  else
	    TEST_EXIT(mesh == vecs[i]->getFeSpace()->getMesh())
	      ("The mesh of the DOFVectors should be the same for Reader because in one file there is only one mesh.\n");
	}
      }
      if(!mesh)
      {
	WARNING("You haven't specified the target.\n");
	return;
      }
      // === Read the meta arh file. ===
Thomas Witkowski's avatar
Thomas Witkowski committed
113

114 115 116 117
      string arhPrefix = "";
      map<int, int> elInRank;
      map<int, int> elCodeSize;
      int nProc = readMetaData(filename, elInRank, elCodeSize, arhPrefix);
118

119

120
      // === Check which arh files must be read by current rank. ===
121

122 123
      // Set of all file indices which should be read to restore all macro elements.
      std::set<int> readArhFiles;
Thomas Witkowski's avatar
Thomas Witkowski committed
124

125 126 127 128 129 130 131
      TraverseStack stack;
      ElInfo *elInfo = stack.traverseFirst(mesh, 0, Mesh::CALL_EL_LEVEL);
      while (elInfo) {
	int macroElIndex = elInfo->getElement()->getIndex();
	TEST_EXIT(elInRank.count(macroElIndex))("Should not happen!\n");
	readArhFiles.insert(elInRank[macroElIndex]);
	elInfo = stack.traverseNext(elInfo);
132
      }
Thomas Witkowski's avatar
Thomas Witkowski committed
133

134

135
      // === Read the individual arh files. ===
136

137 138
      boost::filesystem::path p(filename.c_str());
      boost::filesystem::path directory = p.parent_path();
139

140 141 142 143 144 145 146
      for (std::set<int>::iterator it = readArhFiles.begin();
	  it != readArhFiles.end(); ++it) {
	string arhFilename = directory.string() + "/" + arhPrefix;
	if (nProc == 1)
	  arhFilename += ".arh";
	else
	  arhFilename += "-p" + boost::lexical_cast<string>(*it) + "-.arh";
147

148 149 150
	MSG("ARH file read from: %s\n", arhFilename.c_str());
	detail::read(arhFilename, mesh, vecs);
      }
151 152
    }

153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
    int readMetaData(string filename,
				map<int, int> &elInRank,
				map<int, int> &elCodeSize,
				string &arhPrefix)
    {
      ifstream file;
      file.open(filename.c_str());
      TEST_EXIT(file.is_open())
	("Cannot open arh meta file \"%s\"\n", filename.c_str());

      string readStr = "";
      file >> readStr;
      arhPrefix = "";
      file >> arhPrefix;
      int nProc;
      file >> nProc;

      // Maps to each macro element index the arh file index it is stored in.
      for (int i = 0; i < nProc; i++) {
	int tmp;
	file >> tmp;
	TEST_EXIT(tmp == i)("Should not happen!\n");
	int nMacroEl;
	file >> nMacroEl;
	for (int j = 0; j < nMacroEl; j++) {
	  int elIndex, codeSize;
	  file >> elIndex;
	  file >> codeSize;
	  elInRank[elIndex] = i;
	  elCodeSize[elIndex] = codeSize;
183
	}
184 185
      }

186
      file.close();
187

188 189
      return nProc;
    }
190 191


192 193 194
    int readMetaData(string filename)
    {
      FUNCNAME("ArhReader::readMetaData()");
195

196 197 198 199
      ifstream file;
      file.open(filename.c_str());
      TEST_EXIT(file.is_open())
	("Cannot open arh meta file \"%s\"\n", filename.c_str());
200

201 202 203 204 205 206 207
      string readStr = "";
      file >> readStr;
      file >> readStr;
      int nProc;
      file >> nProc;
      file.close();
      return nProc;
208
    }
209

210 211 212 213
    int readNumOfValueVectors(string filename)
    {
      ifstream file;
      file.open(filename.c_str(), ios::in | ios::binary);
214

215 216 217
      string typeId = "";
      uint32_t nMacroElements = 0;
      uint32_t nValueVectors = 0;
218

219 220 221
      file.read(const_cast<char*>(typeId.data()), 4);
      file.read(reinterpret_cast<char*>(&nMacroElements), 4);
      file.read(reinterpret_cast<char*>(&nValueVectors), 4);
222

223
      file.close();
224

225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
      return nValueVectors;
    }

    //the following three functions are identical to read/readfile except that they read from
    //a block of memory instead of from a file
    void readFromMemoryBlock(vector<char> &data, Mesh *mesh,
					DOFVector<double>* vec0,
					DOFVector<double>* vec1,
					DOFVector<double>* vec2,
					bool writeParallel,
					int nProcs)
    {
      uint32_t nValueVectors;
      memcpy(reinterpret_cast<char*>(&nValueVectors), &data[8], 4);
      vector<DOFVector<double>*> vecs(0);
      if (nValueVectors > 0)
	vecs.push_back(vec0);
      if (nValueVectors > 1)
	vecs.push_back(vec1);
      if (nValueVectors > 2)
	vecs.push_back(vec2);
      for (uint32_t i = 3; i < nValueVectors; i++)
247
	vecs.push_back(NULL);
248 249 250

      readFromMemoryBlock(data, mesh, vecs, writeParallel, nProcs);
    }
251

252 253 254 255 256 257 258 259 260 261 262 263 264
    void readFromMemoryBlock(vector<char> &data, Mesh *mesh,
					vector<DOFVector<double>*> vecs,
					bool writeParallel,
					int nProcs)
    {
      FUNCNAME("ArhReader::readFromMemoryBlock()");

      if (writeParallel) {
	ERROR_EXIT("Reading a hierarchy from several memory blocks is not implemented yet!\n");
      } else {
	detail::readBlock(data, mesh, vecs);
      }
    }
265

266 267 268 269 270
    int getNumValueVectors(string filename)
    {
      FUNCNAME("ArhReader::getNumValueVectors()")
      WARNING("this function is obsolete.\n");
      return readNumOfValueVectors(filename);
271
    }
272

273
    void readFile(string filename,
274 275
			    Mesh *mesh,
			    vector<DOFVector<double>*> vecs)
276 277 278 279 280
    {
      FUNCNAME("ArhReader::readFile()");
      WARNING("this function is obsolete.\n");
      detail::read(filename, mesh, vecs);
    }
281

282 283 284 285 286 287 288 289
    void read(string filename, Mesh *mesh,
			vector<DOFVector<double>*> vecs,
			bool writeParallel,
			int nProcs)
    {
      FUNCNAME("ArhReader::read()");
      WARNING("this function is obsolete.\n");
      readFile(filename, vecs, writeParallel, nProcs);
290 291
    }

292 293 294 295 296 297 298 299 300 301 302
    void read(string filename, Mesh *mesh,
			DOFVector<double>* vec0,
			DOFVector<double>* vec1,
			DOFVector<double>* vec2,
			bool writeParallel,
			int nProcs)
    {
      FUNCNAME("ArhReader::read()")
      WARNING("this function is obsolete.\n");
      readFile(filename, vec0, vec1, vec2, writeParallel, nProcs);
    }
303

304 305 306 307 308 309
    void setDofValues(int macroElIndex, Mesh *mesh,
				vector<double>& values, DOFVector<double>* vec)
    {
      FUNCNAME("ArhReader::seDofValues()");
      WARNING("this function is obsolete.\n");
      detail::setDofValues(macroElIndex, mesh, values, vec);
310 311
    }

312 313 314 315 316 317 318 319
    void readBlock(vector<char> &data,
			      Mesh *mesh,
			      vector<DOFVector<double>*> vecs)
    {
      FUNCNAME("ArhReader::readBlock()");
      WARNING("this function is obsolete.\n");
      detail::readBlock(data, mesh, vecs);
    }
320

321 322 323 324 325 326 327 328
    void readMeta(string filename,
			 Mesh *mesh,
			 vector<DOFVector<double>*> vecs)
    {
       FUNCNAME("ArhReader::readMeta()");
       WARNING("this function is obsolete.\n");
       readMeta(filename, vecs);
    }
329

330 331 332 333 334 335 336 337 338 339 340 341
    void readMeta(string filename,
		         Mesh* mesh,
			 DOFVector<double>* vec0,
			 DOFVector<double>* vec1,
			 DOFVector<double>* vec2)
    {
       FUNCNAME("ArhReader::readMeta()");
       WARNING("this function is obsolete.\n");
       readMeta(filename, vec0, vec1, vec2);
    }
  } // end namespace ArhReader
} } // end namespace io, AMDiS