gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
PViewIO.cpp
Go to the documentation of this file.
1 // Gmsh - Copyright (C) 1997-2022 C. Geuzaine, J.-F. Remacle
2 //
3 // See the LICENSE.txt file in the Gmsh root directory for license information.
4 // Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
5 
6 #include "GmshConfig.h"
7 #include "GmshMessage.h"
8 #include "PView.h"
9 #include "PViewData.h"
10 #include "PViewOptions.h"
11 #include "PViewDataList.h"
12 #include "PViewDataGModel.h"
13 #include "VertexArray.h"
14 #include "StringUtils.h"
15 #include "Context.h"
16 #include "OS.h"
17 #include "adaptiveData.h"
18 
19 bool PView::readPOS(const std::string &fileName, int fileIndex)
20 {
21  FILE *fp = Fopen(fileName.c_str(), "rb");
22  if(!fp) {
23  Msg::Error("Unable to open file '%s'", fileName.c_str());
24  return false;
25  }
26 
27  char str[256] = "XXX";
28  double version = -1.;
29  int format = -1, size = -1, index = -1;
30 
31  while(1) {
32  while(str[0] != '$') {
33  if(!fgets(str, sizeof(str), fp) || feof(fp)) break;
34  }
35 
36  if(feof(fp)) break;
37 
38  if(!strncmp(&str[1], "PostFormat", 10)) {
39  if(!fscanf(fp, "%lf %d %d\n", &version, &format, &size)) {
40  Msg::Error("Read error");
41  fclose(fp);
42  return false;
43  }
44  if(version < 1.0) {
45  Msg::Error("Post-processing file too old (ver. %g < 1.0)", version);
46  fclose(fp);
47  return false;
48  }
49  if(size == sizeof(double))
50  Msg::Debug("Data is in double precision format (size==%d)", size);
51  else {
52  Msg::Error("Unknown data size (%d) in post-processing file", size);
53  fclose(fp);
54  return false;
55  }
56  }
57  else if(!strncmp(&str[1], "View", 4)) {
58  index++;
59  if(fileIndex < 0 || fileIndex == index) {
60  PViewDataList *d = new PViewDataList();
61  if(!d->readPOS(fp, version, format ? true : false)) {
62  Msg::Error("Could not read data in list format");
63  delete d;
64  fclose(fp);
65  return false;
66  }
67  else {
68  d->setFileName(fileName);
69  d->setFileIndex(index);
70  new PView(d);
71  }
72  }
73  }
74 
75  do {
76  if(!fgets(str, sizeof(str), fp) || feof(fp)) break;
77  } while(str[0] != '$');
78  }
79 
80  fclose(fp);
81  return true;
82 }
83 
84 bool PView::readMSH(const std::string &fileName, int fileIndex,
85  int partitionToRead)
86 {
87  FILE *fp = Fopen(fileName.c_str(), "rb");
88  if(!fp) {
89  Msg::Error("Unable to open file '%s'", fileName.c_str());
90  return false;
91  }
92 
93  GModel *model = GModel::current();
94  if(model->empty()) {
95  Msg::Error("Model is empty: please load a mesh before loading the dataset");
96  fclose(fp);
97  return false;
98  }
99 
100  char str[256] = "XXX";
101  int index = -1;
102  bool binary = false, swap = false;
103 
104  while(1) {
105  while(str[0] != '$') {
106  if(!fgets(str, sizeof(str), fp) || feof(fp)) break;
107  }
108 
109  if(feof(fp)) break;
110 
111  if(!strncmp(&str[1], "MeshFormat", 10)) {
112  double version;
113  if(!fgets(str, sizeof(str), fp)) {
114  fclose(fp);
115  return false;
116  }
117  int format, size;
118  if(sscanf(str, "%lf %d %d", &version, &format, &size) != 3) {
119  fclose(fp);
120  return false;
121  }
122  if(format) {
123  binary = true;
124  Msg::Debug("View data is in binary format");
125  int one;
126  if(fread(&one, sizeof(int), 1, fp) != 1) {
127  fclose(fp);
128  return 0;
129  }
130  if(one != 1) {
131  swap = true;
132  Msg::Debug("Swapping bytes from binary file");
133  }
134  }
135  }
136  else if(!strncmp(&str[1], "InterpolationScheme", 19)) {
137  std::string name;
138  if(!fgets(str, sizeof(str), fp)) {
139  fclose(fp);
140  return false;
141  }
142  name = ExtractDoubleQuotedString(str, sizeof(str));
143  Msg::Debug("Reading interpolation scheme '%s'", name.c_str());
145  int numTypes;
146  if(fscanf(fp, "%d", &numTypes) != 1) {
147  fclose(fp);
148  return false;
149  }
150  for(int i = 0; i < numTypes; i++) {
151  int type, numMatrices;
152  if(fscanf(fp, "%d %d", &type, &numMatrices) != 2) {
153  fclose(fp);
154  return false;
155  }
156  for(int j = 0; j < numMatrices; j++) {
157  int m, n;
158  if(fscanf(fp, "%d %d", &m, &n) != 2) {
159  fclose(fp);
160  return false;
161  }
162  fullMatrix<double> mat(m, n);
163  for(int k = 0; k < m; k++) {
164  for(int l = 0; l < n; l++) {
165  double d;
166  if(fscanf(fp, "%lf", &d) != 1) {
167  fclose(fp);
168  return false;
169  }
170  mat.set(k, l, d);
171  }
172  }
174  }
175  }
176  }
177  else if(!strncmp(&str[1], "NodeData", 8) ||
178  !strncmp(&str[1], "ElementData", 11) ||
179  !strncmp(&str[1], "ElementNodeData", 15)) {
180  index++;
181  if(fileIndex < 0 || fileIndex == index) {
183  if(!strncmp(&str[1], "NodeData", 8))
185  else if(!strncmp(&str[1], "ElementData", 11))
187  else
189  int numTags;
190  // string tags
191  std::string viewName, interpolationScheme;
192  if(!fgets(str, sizeof(str), fp)) {
193  fclose(fp);
194  return false;
195  }
196  if(sscanf(str, "%d", &numTags) != 1) {
197  fclose(fp);
198  return false;
199  }
200  for(int i = 0; i < numTags; i++) {
201  if(!fgets(str, sizeof(str), fp)) {
202  fclose(fp);
203  return false;
204  }
205  if(i == 0)
206  viewName = ExtractDoubleQuotedString(str, sizeof(str));
207  else if(i == 1)
208  interpolationScheme = ExtractDoubleQuotedString(str, sizeof(str));
209  }
210  // double tags
211  double time = 0.;
212  if(!fgets(str, sizeof(str), fp)) {
213  fclose(fp);
214  return false;
215  }
216  if(sscanf(str, "%d", &numTags) != 1) {
217  fclose(fp);
218  return false;
219  }
220  for(int i = 0; i < numTags; i++) {
221  if(!fgets(str, sizeof(str), fp)) {
222  fclose(fp);
223  return false;
224  }
225  if(i == 0) {
226  if(sscanf(str, "%lf", &time) != 1) {
227  fclose(fp);
228  return false;
229  }
230  }
231  }
232  // integer tags
233  int timeStep = 0, numComp = 0, numEnt = 0, partition = 0;
234  long int blocksize = 0;
235  if(!fgets(str, sizeof(str), fp)) {
236  fclose(fp);
237  return false;
238  }
239  if(sscanf(str, "%d", &numTags) != 1) {
240  fclose(fp);
241  return false;
242  }
243  for(int i = 0; i < numTags; i++) {
244  if(!fgets(str, sizeof(str), fp)) {
245  fclose(fp);
246  return false;
247  }
248  if(i == 0) {
249  if(sscanf(str, "%d", &timeStep) != 1) {
250  fclose(fp);
251  return false;
252  }
253  }
254  else if(i == 1) {
255  if(sscanf(str, "%d", &numComp) != 1) {
256  fclose(fp);
257  return false;
258  }
259  }
260  else if(i == 2) {
261  if(sscanf(str, "%d", &numEnt) != 1) {
262  fclose(fp);
263  return false;
264  }
265  }
266  else if(i == 3) {
267  if(sscanf(str, "%d", &partition) != 1) {
268  fclose(fp);
269  return false;
270  }
271  }
272  else if(i == 4) {
273  if(sscanf(str, "%ld", &blocksize) != 1) {
274  fclose(fp);
275  return false;
276  }
277  }
278  }
279  if(partitionToRead == -1 || partitionToRead == partition) {
280  // if default (no particular partition requested from MergeFile -> -1)
281  // or if current partition corresponds to the requested partition,
282  // read the data
283  if(numEnt > 0) {
284  // either get existing viewData, or create new one
285  PView *p = getViewByName(viewName, timeStep, partition);
286  PViewDataGModel *d = nullptr;
287  if(p) d = dynamic_cast<PViewDataGModel *>(p->getData());
288  bool create = d ? false : true;
289  if(create) d = new PViewDataGModel(type);
290  if(!d->readMSH(viewName, fileName, fileIndex, fp, binary, swap,
291  timeStep, time, partition, numComp, numEnt,
292  interpolationScheme)) {
293  Msg::Error("Could not read data in msh file");
294  if(create) delete d;
295  fclose(fp);
296  return false;
297  }
298  else {
299  d->setName(viewName);
300  d->setFileName(fileName);
301  d->setFileIndex(index);
302  if(create) new PView(d);
303  }
304  }
305  }
306  else if(blocksize > 0 && partitionToRead != partition) {
307  // if current partition does not correspond to the requested partition
308  // and if its blocksise has been read (5th integer in the header),
309  // jump over it
310  fseek(fp, blocksize, SEEK_CUR);
311  }
312  }
313  }
314 
315  do {
316  if(!fgets(str, sizeof(str), fp) || feof(fp)) break;
317  } while(str[0] != '$');
318  }
319 
320  fclose(fp);
321  return true;
322 }
323 
324 #if defined(HAVE_MED)
325 
326 extern std::vector<std::string> medGetFieldNames(const std::string &fileName);
327 
328 bool PView::readMED(const std::string &fileName, int fileIndex)
329 {
330  std::vector<std::string> fieldNames = medGetFieldNames(fileName);
331 
332  for(std::size_t index = 0; index < fieldNames.size(); index++) {
333  if(fileIndex < 0 || (int)index == fileIndex) {
334  PViewDataGModel *d = nullptr;
335  // we use the filename as a kind of "partition" indicator, allowing to
336  // complete datasets provided in separate files (e.g. coming from DDM)
337  PView *p = getViewByName(fieldNames[index], -1, -1, fileName);
338  if(p) d = dynamic_cast<PViewDataGModel *>(p->getData());
339  bool create = d ? false : true;
340  if(create) d = new PViewDataGModel();
341  if(!d->readMED(fileName, index)) {
342  Msg::Error("Could not read data in MED file");
343  if(create) delete d;
344  return false;
345  }
346  else {
347  if(create) new PView(d);
348  }
349  }
350  }
351 
352  return true;
353 }
354 
355 #else
356 
357 bool PView::readMED(const std::string &fileName, int fileIndex)
358 {
359  Msg::Error("Gmsh must be compiled with MED support to read '%s'",
360  fileName.c_str());
361  return false;
362 }
363 
364 #endif
365 
366 bool PView::readPCH(const std::string &fileName, int fileIndex)
367 {
369  // PViewDataGModel::ElementData;
370  // PViewDataGModel::ElementNodeData;
371  PViewDataGModel *d = new PViewDataGModel(type);
372  d->setFileName(fileName);
373  d->readPCH(fileName, fileIndex);
374  new PView(d);
375  return true;
376 }
377 
378 bool PView::write(const std::string &fileName, int format, bool append)
379 {
380  Msg::StatusBar(true, "Writing '%s'...", fileName.c_str());
381 
382  bool ret;
383  switch(format) {
384  case 0: ret = _data->writePOS(fileName, false, false, append); break; // ASCII
385  case 1: ret = _data->writePOS(fileName, true, false, append); break; // binary
386  case 2: ret = _data->writePOS(fileName, false, true, append); break; // parsed
387  case 3: ret = _data->writeSTL(fileName); break;
388  case 4: ret = _data->writeTXT(fileName); break;
389  case 5:
390  ret = _data->writeMSH(fileName, CTX::instance()->mesh.mshFileVersion,
392  CTX::instance()->post.saveMesh, append, 0,
396  break;
397  case 6: ret = _data->writeMED(fileName); break;
398  case 7: ret = writeX3D(fileName); break;
399  case 10: {
400  std::string ext = SplitFileName(fileName)[2];
401  if(ext == ".pos")
402  ret = _data->writePOS(fileName, CTX::instance()->post.binary,
403  !CTX::instance()->post.binary, append);
404  else if(ext == ".stl")
405  ret = _data->writeSTL(fileName);
406  else if(ext == ".msh")
407  ret = _data->writeMSH(fileName, CTX::instance()->mesh.mshFileVersion,
409  CTX::instance()->post.saveMesh, append, 0,
413  else if(ext == ".med")
414  ret = _data->writeMED(fileName);
415  else if(ext == ".x3d")
416  ret = writeX3D(fileName);
417  else
418  ret = _data->writeTXT(fileName);
419  break;
420  }
421  default:
422  ret = false;
423  Msg::Error("Unknown view format %d", format);
424  break;
425  }
426 
427  if(ret) Msg::StatusBar(true, "Done writing '%s'", fileName.c_str());
428  return ret;
429 }
430 
431 // Routines for export of adapted views to pvtu file format for parallel
432 // visualization with paraview.
433 bool PView::writeAdapt(const std::string &guifileName, int useDefaultName,
434  bool isBinary, int adaptLev, double adaptErr, int npart,
435  bool append)
436 {
437  Msg::StatusBar(true, "Writing '%s'...", guifileName.c_str());
438  _data->saveAdaptedViewForVTK(guifileName, useDefaultName, _options->timeStep,
439  adaptLev, adaptErr, npart, isBinary);
440  return true;
441 }
442 
443 void PView::sendToServer(const std::string &name)
444 {
445  Msg::Info("Sending View[%d] to ONELAB as parameter '%s'", _index,
446  name.c_str());
447  _data->sendToServer(name);
448 }
PViewOptions::timeStep
int timeStep
Definition: PViewOptions.h:61
PViewData::writeSTL
virtual bool writeSTL(const std::string &fileName)
Definition: PViewDataIO.cpp:15
SplitFileName
std::vector< std::string > SplitFileName(const std::string &fileName)
Definition: StringUtils.cpp:93
PView
Definition: PView.h:27
PViewDataGModel::ElementData
@ ElementData
Definition: PViewDataGModel.h:195
fullMatrix::set
void set(int r, int c, scalar v)
Definition: fullMatrix.h:289
PViewDataGModel
Definition: PViewDataGModel.h:191
PViewData::writeTXT
virtual bool writeTXT(const std::string &fileName)
Definition: PViewDataIO.cpp:74
PViewDataGModel::NodeData
@ NodeData
Definition: PViewDataGModel.h:194
PView::getViewByName
static PView * getViewByName(const std::string &name, int timeStep=-1, int partition=-1, const std::string &fileName="")
Definition: PView.cpp:347
PViewDataGModel::readPCH
bool readPCH(const std::string &fileName, int fileIndex)
Definition: PViewDataGModelIO.cpp:1107
Msg::Info
static void Info(const char *fmt,...)
Definition: GmshMessage.cpp:587
OS.h
Msg::Debug
static void Debug(const char *fmt,...)
Definition: GmshMessage.cpp:752
PViewDataList
Definition: PViewDataList.h:17
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
CTX::post
struct CTX::@0 post
Msg::StatusBar
static void StatusBar(bool log, const char *fmt,...)
Definition: GmshMessage.cpp:686
VertexArray.h
PView::_options
PViewOptions * _options
Definition: PView.h:41
PView::readPOS
static bool readPOS(const std::string &fileName, int fileIndex=-1)
Definition: PViewIO.cpp:19
GModel::empty
bool empty() const
Definition: GModel.cpp:311
PViewData::writePOS
virtual bool writePOS(const std::string &fileName, bool binary=false, bool parsed=true, bool append=false)
Definition: PViewDataIO.cpp:106
PView.h
PViewData::writeMED
virtual bool writeMED(const std::string &fileName)
Definition: PViewDataIO.cpp:211
GmshMessage.h
PViewData.h
PViewData::setFileName
virtual void setFileName(const std::string &val)
Definition: PViewData.h:75
Fopen
FILE * Fopen(const char *f, const char *mode)
Definition: OS.cpp:273
adaptiveData.h
CTX::instance
static CTX * instance()
Definition: Context.cpp:122
fullMatrix< double >
PViewDataList::readPOS
bool readPOS(FILE *fp, double version, bool binary)
Definition: PViewDataListIO.cpp:90
PView::_index
int _index
Definition: PView.h:33
swap
void swap(double &a, double &b)
Definition: meshTriangulation.cpp:27
PViewData::sendToServer
virtual void sendToServer(const std::string &name)
Definition: PViewDataIO.cpp:287
GModel
Definition: GModel.h:44
PView::getData
PViewData * getData(bool useAdaptiveIfAvailable=false)
Definition: PView.cpp:233
PView::PView
PView(int tag=-1)
Definition: PView.cpp:53
PViewData::addMatrixToInterpolationScheme
static void addMatrixToInterpolationScheme(const std::string &name, int type, fullMatrix< double > &mat)
Definition: PViewData.cpp:219
PViewOptions.h
PViewDataList.h
CTX::binary
int binary
Definition: Context.h:316
PView::writeX3D
static bool writeX3D(const std::string &fileName)
Definition: PViewX3D.cpp:72
PViewData::writeMSH
virtual bool writeMSH(const std::string &fileName, double version=2.2, bool binary=false, bool saveMesh=true, bool multipleView=false, int partitionNum=-1, bool saveInterpolationMatrices=true, bool forceNodeData=false, bool forceElementData=false)
Definition: PViewDataIO.cpp:202
CTX::saveInterpolationMatrices
int saveInterpolationMatrices
Definition: Context.h:320
PViewData::setName
virtual void setName(const std::string &val)
Definition: PViewData.h:71
CTX::mesh
contextMeshOptions mesh
Definition: Context.h:313
PViewDataGModel.h
ExtractDoubleQuotedString
std::string ExtractDoubleQuotedString(const char *str, int len)
Definition: StringUtils.cpp:27
PViewData::removeInterpolationScheme
static void removeInterpolationScheme(const std::string &name)
Definition: PViewData.cpp:199
PView::_data
PViewData * _data
Definition: PView.h:43
PView::sendToServer
void sendToServer(const std::string &name)
Definition: PViewIO.cpp:443
CTX::forceElementData
int forceElementData
Definition: Context.h:319
StringUtils.h
PViewDataGModel::ElementNodeData
@ ElementNodeData
Definition: PViewDataGModel.h:196
PView::write
bool write(const std::string &fileName, int format, bool append=false)
Definition: PViewIO.cpp:378
Context.h
PView::readMED
static bool readMED(const std::string &fileName, int fileIndex=-1)
Definition: PViewIO.cpp:357
PViewDataGModel::readMED
bool readMED(const std::string &fileName, int fileIndex)
Definition: PViewDataGModelIO.cpp:1091
PView::readMSH
static bool readMSH(const std::string &fileName, int fileIndex=-1, int partitionToRead=-1)
Definition: PViewIO.cpp:84
PView::readPCH
static bool readPCH(const std::string &fileName, int fileIndex=-1)
Definition: PViewIO.cpp:366
PViewDataGModel::DataType
DataType
Definition: PViewDataGModel.h:193
contextMeshOptions::binary
int binary
Definition: Context.h:62
PViewData::setFileIndex
virtual void setFileIndex(int val)
Definition: PViewData.h:87
PViewData::saveAdaptedViewForVTK
void saveAdaptedViewForVTK(const std::string &guifileName, int useDefaultName, int step, int level, double tol, int npart, bool isBinary)
Definition: PViewData.cpp:61
PView::writeAdapt
bool writeAdapt(const std::string &fileName, int useDefaultName, bool isBinary, int adaptLev, double adaptErr, int npart, bool append=false)
Definition: PViewIO.cpp:433
CTX::saveMesh
int saveMesh
Definition: Context.h:320
GModel::current
static GModel * current(int index=-1)
Definition: GModel.cpp:136
PViewDataGModel::readMSH
bool readMSH(const std::string &viewName, const std::string &fileName, int fileIndex, FILE *fp, bool binary, bool swap, int step, double time, int partition, int numComp, int numNodes, const std::string &interpolationScheme)
Definition: PViewDataGModelIO.cpp:135
CTX::forceNodeData
int forceNodeData
Definition: Context.h:319