vtkGAMBITReader.cxx 14.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkGAMBITReader.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
15
// Thanks to Jean M. Favre (CSCS, Swiss Center for Scientific Computing) who
16 17 18 19
// developed this class.
// Please address all comments to Jean Favre (jfavre at cscs.ch)

#include "vtkGAMBITReader.h"
20

21 22 23 24
#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkDoubleArray.h"
#include "vtkErrorCode.h"
25 26
#include "vtkInformation.h"
#include "vtkInformationVector.h"
27
#include "vtkIntArray.h"
28
#include "vtkObjectFactory.h"
29
#include "vtkPointData.h"
30
#include "vtkUnstructuredGrid.h"
31 32 33

vtkStandardNewMacro(vtkGAMBITReader);

34
//----------------------------------------------------------------------------
35 36
vtkGAMBITReader::vtkGAMBITReader()
{
37
  this->FileName = nullptr;
38 39
  this->NumberOfCells = 0;
  this->NumberOfNodes = 0;
40 41
  this->NumberOfNodeFields = 0;
  this->NumberOfCellFields = 0;
42
  this->FileStream = nullptr;
43 44

  this->SetNumberOfInputPorts(0);
45 46
}

47
//----------------------------------------------------------------------------
48 49
vtkGAMBITReader::~vtkGAMBITReader()
{
50
  delete[] this->FileName;
51 52
}

53
//----------------------------------------------------------------------------
54 55
int vtkGAMBITReader::RequestData(vtkInformation* vtkNotUsed(request),
  vtkInformationVector** vtkNotUsed(inputVector), vtkInformationVector* outputVector)
56
{
57
  // get the info object
58
  vtkInformation* outInfo = outputVector->GetInformationObject(0);
59

luz.paz's avatar
luz.paz committed
60
  // get the output
61 62
  vtkUnstructuredGrid* output =
    vtkUnstructuredGrid::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
63

64
  vtkDebugMacro(<< "Reading GAMBIT Neutral file");
65

66
  // If ExecuteInformation() failed the FileStream will be nullptr and
67
  // ExecuteInformation() will have spit out an error.
68
  if (this->FileStream == nullptr)
69
  {
70
    return 0;
71
  }
72

73
  this->ReadFile(output);
74

75
  return 1;
76 77
}

78
//----------------------------------------------------------------------------
79 80
void vtkGAMBITReader::PrintSelf(ostream& os, vtkIndent indent)
{
81
  this->Superclass::PrintSelf(os, indent);
82

83
  os << indent << "File Name: " << (this->FileName ? this->FileName : "(none)") << "\n";
84 85

  os << indent << "Number Of Nodes: " << this->NumberOfNodes << endl;
86
  os << indent << "Number Of Node Fields: " << this->NumberOfNodeFields << endl;
87 88

  os << indent << "Number Of Cells: " << this->NumberOfCells << endl;
89
  os << indent << "Number Of Cell Fields: " << this->NumberOfCellFields << endl;
90 91
}

92
//----------------------------------------------------------------------------
93
void vtkGAMBITReader::ReadFile(vtkUnstructuredGrid* output)
94
{
95
  this->ReadGeometry(output);
96 97 98 99

  // yes, but, we cannot find any examples containing data.
  // GAMBIT users seem to say that they use the Fluent solver and do not
  // use Gambit as an output format, thus no data when used as input to solver
100
  if (this->NumberOfNodeFields)
101
  {
102
    this->ReadNodeData(output);
103
  }
104

105
  if (this->NumberOfCellFields)
106
  {
107
    this->ReadCellData(output);
108
  }
109 110

  delete this->FileStream;
111
  this->FileStream = nullptr;
112 113
}

114
//----------------------------------------------------------------------------
115
void vtkGAMBITReader::ReadNodeData(vtkUnstructuredGrid* vtkNotUsed(output))
116 117 118 119
{
  vtkWarningMacro("Not implemented due to lack of examples");
}

120
//----------------------------------------------------------------------------
121
void vtkGAMBITReader::ReadCellData(vtkUnstructuredGrid* vtkNotUsed(output))
122 123 124 125
{
  vtkWarningMacro("Not implemented due to lack of examples");
}

126
//----------------------------------------------------------------------------
127 128
int vtkGAMBITReader::RequestInformation(vtkInformation* vtkNotUsed(request),
  vtkInformationVector** vtkNotUsed(inputVector), vtkInformationVector* vtkNotUsed(outputVector))
129
{
130
  if (!this->FileName)
131
  {
132 133 134 135 136 137
    this->NumberOfNodes = 0;
    this->NumberOfCells = 0;
    this->NumberOfNodeFields = 0;
    this->NumberOfCellFields = 0;

    vtkErrorMacro("No filename specified");
138
    return 0;
139
  }
140

141 142 143
  this->FileStream = new ifstream(this->FileName, ios::in);

  if (this->FileStream->fail())
144
  {
145 146
    this->SetErrorCode(vtkErrorCode::FileNotFoundError);
    delete this->FileStream;
147
    this->FileStream = nullptr;
148
    vtkErrorMacro("Specified filename not found");
149
    return 0;
150
  }
151

152
  char c = '\0', buf[128];
153

154 155 156 157 158 159 160 161 162 163 164 165
  this->FileStream->get(buf, 128, '\n');
  this->FileStream->get(c);
  this->FileStream->get(buf, 128, '\n');
  this->FileStream->get(c);
  this->FileStream->get(buf, 128, '\n');
  this->FileStream->get(c);
  this->FileStream->get(buf, 128, '\n');
  this->FileStream->get(c);
  this->FileStream->get(buf, 128, '\n');
  this->FileStream->get(c);
  this->FileStream->get(buf, 128, '\n');
  this->FileStream->get(c);
166 167 168 169 170 171 172 173 174 175

  *(this->FileStream) >> this->NumberOfNodes;
  *(this->FileStream) >> this->NumberOfCells;
  *(this->FileStream) >> this->NumberOfElementGroups;
  *(this->FileStream) >> this->NumberOfBoundaryConditionSets;
  *(this->FileStream) >> this->NumberOfCoordinateDirections;
  *(this->FileStream) >> this->NumberOfVelocityComponents;
  this->FileStream->get(c);

  // read here the end of section
176 177 178
  this->FileStream->get(buf, 128, '\n');
  this->FileStream->get(c);
  if (strncmp(buf, "ENDOFSECTION", 12))
179
  {
180
    vtkErrorMacro(<< "Error reading file");
181
  }
182 183 184 185 186
  vtkDebugMacro(<< "\nNumberOfNodes " << this->NumberOfNodes << "\nNumberOfCells "
                << this->NumberOfCells << "\nNumberOfElementGroups " << this->NumberOfElementGroups
                << "\nNumberOfBoundaryConditionSets " << this->NumberOfBoundaryConditionSets
                << "\nNumberOfCoordinateDirections " << this->NumberOfCoordinateDirections
                << "\nNumberOfVelocityComponents " << this->NumberOfVelocityComponents);
187 188

  return 1;
189 190
}

191
//----------------------------------------------------------------------------
192
void vtkGAMBITReader::ReadGeometry(vtkUnstructuredGrid* output)
193
{
194
  vtkDoubleArray* coords = vtkDoubleArray::New();
195 196
  coords->SetNumberOfComponents(3);
  // allocate one more pt and store node id=0
197
  coords->SetNumberOfTuples(this->NumberOfNodes);
198 199

  this->ReadXYZCoords(coords);
200
  this->ReadCellConnectivity(output);
201
  if (this->NumberOfElementGroups > 0)
202
  {
203
    this->ReadMaterialTypes(output);
204
  }
205
  if (this->NumberOfBoundaryConditionSets > 0)
206
  {
207
    this->ReadBoundaryConditionSets(output);
208
  }
209
  vtkPoints* points = vtkPoints::New();
210 211
  points->SetData(coords);
  coords->Delete();
212

213 214 215 216
  output->SetPoints(points);
  points->Delete();
}

217
//----------------------------------------------------------------------------
218
void vtkGAMBITReader::ReadBoundaryConditionSets(vtkUnstructuredGrid* output)
219 220
{
  int bcs, f, itype, nentry, nvalues;
221
  int isUsable = 0;
222 223 224 225 226
  int node, elt, eltype, facenumber;
  char c, buf[128];

  // no idea about how to treat element/cell, so we allocate a single array

227
  vtkIntArray* bcscalar = vtkIntArray::New();
228
  bcscalar->SetNumberOfComponents(1);
229
  bcscalar->SetNumberOfTuples(this->NumberOfNodes);
230
  bcscalar->SetName("Boundary Condition");
231
  int* ptr = bcscalar->GetPointer(0);
232
  // initialise with null values. When set later, will set to 1
233
  memset((void*)ptr, 0, sizeof(int) * this->NumberOfNodes);
234

235
  for (bcs = 1; bcs <= this->NumberOfBoundaryConditionSets; bcs++)
236
  {
237 238 239 240 241 242
    this->FileStream->get(buf, 128, '\n');
    this->FileStream->get(c);
    this->FileStream->get(buf, 128, '\n');
    this->FileStream->get(c);
    sscanf(&buf[32], "%10d%10d%10d", &itype, &nentry, &nvalues);
    vtkDebugMacro(<< "\nitype " << itype << "\tnentry " << nentry << "\tnvalues " << nvalues);
243
    // I have no example o how nvalues is used....So no implementation.
244
    if (itype == 0) // nodes
245
    {
246
      isUsable = 1;
247
      for (f = 0; f < nentry; f++)
248
      {
249
        *(this->FileStream) >> node;
250
        node--;
251
        if (node >= 0 && node < this->NumberOfNodes)
252
        {
253
          bcscalar->SetValue(node, 1);
254
        }
255
        else
256
        {
257
          vtkErrorMacro(<< "Node value is outside of range");
258
        }
259
      }
260 261
      this->FileStream->get(c);
      // read here the end of section
262 263 264
      this->FileStream->get(buf, 128, '\n');
      this->FileStream->get(c);
      if (strncmp(buf, "ENDOFSECTION", 12))
265
      {
266
        vtkErrorMacro(<< "Error reading ENDOFSECTION tag at end of group");
267
      }
268
    }
269
    else // element/cell are parsed but nothing is done with the info read
270
    {
271
      for (f = 0; f < nentry; f++)
272
      {
273
        *(this->FileStream) >> elt >> eltype >> facenumber;
274
      }
275 276
      this->FileStream->get(c);
      // read here the end of section
277 278 279
      this->FileStream->get(buf, 128, '\n');
      this->FileStream->get(c);
      if (strncmp(buf, "ENDOFSECTION", 12))
280
      {
281
        vtkErrorMacro(<< "Error reading ENDOFSECTION tag at end of group");
282
      }
283
    }
284
  }
Kyle Lutz's avatar
Kyle Lutz committed
285
  vtkDebugMacro(<< "All BCS read successfully");
286
  if (isUsable)
287
  {
288 289
    output->GetPointData()->AddArray(bcscalar);
    if (!output->GetPointData()->GetScalars())
290
    {
291 292
      output->GetPointData()->SetScalars(bcscalar);
    }
293
  }
294 295 296
  bcscalar->Delete();
}

297
//----------------------------------------------------------------------------
298
void vtkGAMBITReader::ReadMaterialTypes(vtkUnstructuredGrid* output)
299 300 301 302
{
  int grp, f, flag, id, nbelts, elt, mat, nbflags;
  char c, buf[128];

303
  vtkIntArray* materials = vtkIntArray::New();
304 305 306 307
  materials->SetNumberOfComponents(1);
  materials->SetNumberOfTuples(this->NumberOfCells);
  materials->SetName("Material Type");

308
  for (grp = 1; grp <= this->NumberOfElementGroups; grp++)
309
  {
310 311 312 313 314 315 316 317 318 319 320 321 322
    this->FileStream->get(buf, 128, '\n');
    this->FileStream->get(c);
    this->FileStream->get(buf, 128, '\n');
    this->FileStream->get(c);
    sscanf(
      buf, "GROUP:%10d ELEMENTS: %10d MATERIAL: %10d NFLAGS:%10d", &id, &nbelts, &mat, &nbflags);

    vtkDebugMacro(<< "\nid " << id << "\tnbelts " << nbelts << "\tmat " << mat << "\tnbflags "
                  << nbflags);

    this->FileStream->get(buf, 128, '\n');
    this->FileStream->get(c);
    for (f = 0; f < nbflags; f++)
323
    {
324
      *(this->FileStream) >> flag;
325
    }
326
    this->FileStream->get(c);
327
    for (f = 0; f < nbelts; f++)
328
    {
329
      *(this->FileStream) >> elt;
330
      materials->SetValue(elt - 1, mat);
331
    }
332 333
    this->FileStream->get(c);
    // read here the end of section
334 335 336
    this->FileStream->get(buf, 128, '\n');
    this->FileStream->get(c);
    if (strncmp(buf, "ENDOFSECTION", 12))
337
    {
338
      vtkErrorMacro(<< "Error reading ENDOFSECTION tag at end of group");
339
    }
340
  }
341
  vtkDebugMacro(<< "All groups read successfully");
342 343 344

  output->GetCellData()->AddArray(materials);
  if (!output->GetCellData()->GetScalars())
345
  {
346
    output->GetCellData()->SetScalars(materials);
347
  }
348 349 350
  materials->Delete();
}

351
//----------------------------------------------------------------------------
352
void vtkGAMBITReader::ReadCellConnectivity(vtkUnstructuredGrid* output)
353 354 355 356 357 358 359
{
  int i, k;
  vtkIdType list[27];
  char c, buf[128];

  output->Allocate();

360 361
  this->FileStream->get(buf, 128, '\n');
  this->FileStream->get(c);
362

363
  for (i = 1; i <= this->NumberOfCells; i++)
364
  {
365
    int id; // no check is done to see that they are monotonously increasing
366 367 368
    int ntype, ndp;
    *(this->FileStream) >> id >> ntype >> ndp;

369
    switch (ntype)
370
    {
371
      case EDGE:
372
      {
373 374 375 376 377 378
        for (k = 0; k < 2; k++)
        {
          *(this->FileStream) >> list[k];
          list[k]--;
        }
        output->InsertNextCell(VTK_LINE, 2, list);
379
      }
380 381
      break;
      case TRI:
382
      {
383 384 385 386 387 388
        for (k = 0; k < 3; k++)
        {
          *(this->FileStream) >> list[k];
          list[k]--;
        }
        output->InsertNextCell(VTK_TRIANGLE, 3, list);
389
      }
390 391 392 393 394 395 396 397 398 399 400 401
      break;
      case QUAD:
      {
        for (k = 0; k < 4; k++)
        {
          *(this->FileStream) >> list[k];
          list[k]--;
        }
        output->InsertNextCell(VTK_QUAD, 4, list);
      }
      break;
      case TETRA:
402
      {
403 404 405 406 407 408
        for (k = 0; k < 4; k++)
        {
          *(this->FileStream) >> list[k];
          list[k]--;
        }
        output->InsertNextCell(VTK_TETRA, 4, list);
409
      }
410 411
      break;
      case PYRAMID:
412
      {
413 414 415 416 417 418
        for (k = 0; k < 5; k++)
        {
          *(this->FileStream) >> list[k];
          list[k]--;
        }
        output->InsertNextCell(VTK_PYRAMID, 5, list);
419
      }
420 421
      break;
      case PRISM:
422
      {
423 424 425 426 427 428
        for (k = 0; k < 6; k++)
        {
          *(this->FileStream) >> list[k];
          list[k]--;
        }
        output->InsertNextCell(VTK_WEDGE, 6, list);
429
      }
430 431
      break;
      case BRICK:
432
      {
433 434 435 436 437 438
        for (k = 0; k < 8; k++)
        {
          *(this->FileStream) >> list[k];
          list[k]--;
        }
        output->InsertNextCell(VTK_HEXAHEDRON, 8, list);
439
      }
440 441
      break;
      default:
442
      {
443 444
        vtkErrorMacro(<< "cell type: " << ntype << " is not supported\n");
        return;
445
      }
446
    } // for all cell, read the indices
447 448
  }
  // read here the end of section
449 450 451 452
  this->FileStream->get(c);
  this->FileStream->get(buf, 128, '\n');
  this->FileStream->get(c);
  if (strncmp(buf, "ENDOFSECTION", 12))
453
  {
454
    vtkErrorMacro(<< "Error reading ENDOFSECTION tag at end of connectivity");
455
  }
456 457
}

458
//----------------------------------------------------------------------------
459
void vtkGAMBITReader::ReadXYZCoords(vtkDoubleArray* coords)
460 461
{
  int i;
462
  double* ptr = coords->GetPointer(0);
463 464
  char c, buf[64];

465 466 467
  int id; // no check is done to see that they are monotonously increasing
  this->FileStream->get(buf, 64, '\n');
  this->FileStream->get(c);
468

469
  if (this->NumberOfCoordinateDirections == 3)
470
  {
471
    for (i = 0; i < this->NumberOfNodes; i++)
472
    {
473
      *(this->FileStream) >> id;
474
      *(this->FileStream) >> ptr[3 * i] >> ptr[3 * i + 1] >> ptr[3 * i + 2];
475
    }
476
  }
477
  else
478
  {
479
    for (i = 0; i < this->NumberOfNodes; i++)
480
    {
481
      *(this->FileStream) >> id;
482 483
      *(this->FileStream) >> ptr[3 * i] >> ptr[3 * i + 1];
      ptr[3 * i + 2] = 0.0;
484
    }
485
  }
486 487 488 489
  this->FileStream->get(c);
  this->FileStream->get(buf, 128, '\n');
  this->FileStream->get(c);
  if (strncmp(buf, "ENDOFSECTION", 12))
490
  {
491
    vtkErrorMacro("Error reading ENDOFSECTION tag at end of coordinates section");
492
  }
493
}