vtkExodusFileSeriesReader.cxx 9.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
// -*- c++ -*-
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkExodusFileSeriesReader.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.

=========================================================================*/

/*
 * Copyright 2008 Sandia Corporation.
 * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
 * license for use of this work by or on behalf of the
 * U.S. Government. Redistribution and use in source and binary forms, with
 * or without modification, are permitted provided that this Notice and any
 * statement of authorship are reproduced on all copies.
 */

#include "vtkExodusFileSeriesReader.h"

28
#include "vtkDirectory.h"
29
#include "vtkObjectFactory.h"
30
#include "vtkPExodusIIReader.h"
31 32
#include "vtkStdString.h"

33
#include "vtkSmartPointer.h"
Kitware Robot's avatar
Kitware Robot committed
34
#define VTK_CREATE(type, name) vtkSmartPointer<type> name = vtkSmartPointer<type>::New()
35

36
#include <vector>
37
#include <vtksys/RegularExpression.hxx>
38

Kitware Robot's avatar
Kitware Robot committed
39 40 41 42 43 44 45 46 47 48 49 50 51 52
static const int ExodusArrayTypeIndices[] = { vtkExodusIIReader::GLOBAL, vtkExodusIIReader::NODAL,
  vtkExodusIIReader::EDGE_BLOCK, vtkExodusIIReader::FACE_BLOCK, vtkExodusIIReader::ELEM_BLOCK,
  vtkExodusIIReader::NODE_SET, vtkExodusIIReader::SIDE_SET, vtkExodusIIReader::EDGE_SET,
  vtkExodusIIReader::FACE_SET, vtkExodusIIReader::ELEM_SET };
static const int NumExodusArrayTypeIndices =
  sizeof(ExodusArrayTypeIndices) / sizeof(ExodusArrayTypeIndices[0]);

static const int ExodusObjectTypeIndices[] = { vtkExodusIIReader::EDGE_BLOCK,
  vtkExodusIIReader::FACE_BLOCK, vtkExodusIIReader::ELEM_BLOCK, vtkExodusIIReader::NODE_SET,
  vtkExodusIIReader::SIDE_SET, vtkExodusIIReader::EDGE_SET, vtkExodusIIReader::FACE_SET,
  vtkExodusIIReader::ELEM_SET, vtkExodusIIReader::NODE_MAP, vtkExodusIIReader::EDGE_MAP,
  vtkExodusIIReader::FACE_MAP, vtkExodusIIReader::ELEM_MAP };
static const int NumExodusObjectTypeIndices =
  sizeof(ExodusObjectTypeIndices) / sizeof(ExodusObjectTypeIndices[0]);
53 54 55 56 57

//=============================================================================
class vtkExodusFileSeriesReaderStatus
{
public:
Kitware Robot's avatar
Kitware Robot committed
58 59 60
  void RecordStatus(vtkExodusIIReader* reader);
  void RestoreStatus(vtkExodusIIReader* reader);

61
protected:
Kitware Robot's avatar
Kitware Robot committed
62 63
  class ObjectStatus
  {
64
  public:
Kitware Robot's avatar
Kitware Robot committed
65 66 67 68 69
    ObjectStatus(const char* n, int s)
      : name(n)
      , status(s)
    {
    }
70 71 72
    vtkStdString name;
    int status;
  };
73
  typedef std::vector<ObjectStatus> ObjectStatusList;
74 75 76 77 78
  ObjectStatusList ArrayStatuses[NumExodusArrayTypeIndices];
  ObjectStatusList ObjectStatuses[NumExodusObjectTypeIndices];
};

//-----------------------------------------------------------------------------
Kitware Robot's avatar
Kitware Robot committed
79
void vtkExodusFileSeriesReaderStatus::RecordStatus(vtkExodusIIReader* reader)
80 81 82 83
{
  int i;

  for (i = 0; i < NumExodusArrayTypeIndices; i++)
Kitware Robot's avatar
Kitware Robot committed
84
  {
85 86 87
    int arrayType = ExodusArrayTypeIndices[i];
    this->ArrayStatuses[i].clear();
    for (int j = 0; j < reader->GetNumberOfObjectArrays(arrayType); j++)
Kitware Robot's avatar
Kitware Robot committed
88 89 90
    {
      this->ArrayStatuses[i].push_back(ObjectStatus(
        reader->GetObjectArrayName(arrayType, j), reader->GetObjectArrayStatus(arrayType, j)));
91
    }
Kitware Robot's avatar
Kitware Robot committed
92
  }
93 94

  for (i = 0; i < NumExodusObjectTypeIndices; i++)
Kitware Robot's avatar
Kitware Robot committed
95
  {
96 97 98
    int objectType = ExodusObjectTypeIndices[i];
    this->ObjectStatuses[i].clear();
    for (int j = 0; j < reader->GetNumberOfObjects(objectType); j++)
Kitware Robot's avatar
Kitware Robot committed
99
    {
100
      this->ObjectStatuses[i].push_back(
Kitware Robot's avatar
Kitware Robot committed
101
        ObjectStatus(reader->GetObjectName(objectType, j), reader->GetObjectStatus(objectType, j)));
102
    }
Kitware Robot's avatar
Kitware Robot committed
103
  }
104 105 106
}

//-----------------------------------------------------------------------------
Kitware Robot's avatar
Kitware Robot committed
107
void vtkExodusFileSeriesReaderStatus::RestoreStatus(vtkExodusIIReader* reader)
108 109 110 111
{
  int i;

  for (i = 0; i < NumExodusArrayTypeIndices; i++)
Kitware Robot's avatar
Kitware Robot committed
112
  {
113 114 115
    int arrayType = ExodusArrayTypeIndices[i];
    for (ObjectStatusList::iterator j = this->ArrayStatuses[i].begin();
         j != this->ArrayStatuses[i].end(); j++)
Kitware Robot's avatar
Kitware Robot committed
116
    {
117 118
      reader->SetObjectArrayStatus(arrayType, j->name, j->status);
    }
Kitware Robot's avatar
Kitware Robot committed
119
  }
120 121

  for (i = 0; i < NumExodusObjectTypeIndices; i++)
Kitware Robot's avatar
Kitware Robot committed
122
  {
123 124 125
    int objectType = ExodusObjectTypeIndices[i];
    for (ObjectStatusList::iterator j = this->ObjectStatuses[i].begin();
         j != this->ObjectStatuses[i].end(); j++)
Kitware Robot's avatar
Kitware Robot committed
126
    {
127 128
      reader->SetObjectStatus(objectType, j->name, j->status);
    }
Kitware Robot's avatar
Kitware Robot committed
129
  }
130 131 132 133 134 135 136 137 138 139 140 141 142 143
}

//=============================================================================
vtkStandardNewMacro(vtkExodusFileSeriesReader);

//-----------------------------------------------------------------------------
vtkExodusFileSeriesReader::vtkExodusFileSeriesReader()
{
}

vtkExodusFileSeriesReader::~vtkExodusFileSeriesReader()
{
}

Kitware Robot's avatar
Kitware Robot committed
144
void vtkExodusFileSeriesReader::PrintSelf(ostream& os, vtkIndent indent)
145 146 147 148
{
  this->Superclass::PrintSelf(os, indent);
}

149 150
//-----------------------------------------------------------------------------
int vtkExodusFileSeriesReader::RequestInformation(
Kitware Robot's avatar
Kitware Robot committed
151
  vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector)
152 153
{
  if (!this->UseMetaFile)
Kitware Robot's avatar
Kitware Robot committed
154
  {
155
    this->FindRestartedResults();
Kitware Robot's avatar
Kitware Robot committed
156
  }
157

Kitware Robot's avatar
Kitware Robot committed
158
  return this->Superclass::RequestInformation(request, inputVector, outputVector);
159 160
}

161 162
//-----------------------------------------------------------------------------
int vtkExodusFileSeriesReader::RequestInformationForInput(
Kitware Robot's avatar
Kitware Robot committed
163
  int index, vtkInformation* request, vtkInformationVector* outputVector)
164
{
165
  if (index != this->_FileIndex)
Kitware Robot's avatar
Kitware Robot committed
166 167
  {
    vtkExodusIIReader* reader = vtkExodusIIReader::SafeDownCast(this->Reader);
168
    if (!reader)
Kitware Robot's avatar
Kitware Robot committed
169
    {
170 171
      vtkWarningMacro(<< "Using a non-exodus reader (" << reader->GetClassName()
                      << ") with vtkExodusFileSeriesReader.");
Kitware Robot's avatar
Kitware Robot committed
172 173
      return this->Superclass::RequestInformationForInput(index, request, outputVector);
    }
174 175 176 177

    // Save the state of what to read in.
    vtkExodusFileSeriesReaderStatus readerStatus;
    readerStatus.RecordStatus(reader);
178 179 180 181 182 183 184

    // It is sometimes the case that the server manager state mechanism will
    // push values to FilePattern and FilePrefix when in fact these should be
    // set internally (bug #10570).  This is a problem when we really have a
    // time file series.  Since the FilePattern/Prefix don't work with a time
    // file series, just set them to NULL.
    if (this->GetNumberOfFileNames() > 1)
Kitware Robot's avatar
Kitware Robot committed
185 186
    {
      vtkPExodusIIReader* preader = vtkPExodusIIReader::SafeDownCast(reader);
187
      if (preader)
Kitware Robot's avatar
Kitware Robot committed
188
      {
189 190 191
        preader->SetFilePattern(NULL);
        preader->SetFilePrefix(NULL);
      }
Kitware Robot's avatar
Kitware Robot committed
192
    }
193

Kitware Robot's avatar
Kitware Robot committed
194
    int retVal = this->Superclass::RequestInformationForInput(index, request, outputVector);
195 196 197 198 199

    // Restore the state.
    readerStatus.RestoreStatus(reader);

    return retVal;
Kitware Robot's avatar
Kitware Robot committed
200
  }
201

Kitware Robot's avatar
Kitware Robot committed
202
  return this->Superclass::RequestInformationForInput(index, request, outputVector);
203
}
204 205 206 207 208

//-----------------------------------------------------------------------------
void vtkExodusFileSeriesReader::FindRestartedResults()
{
  if (this->GetNumberOfFileNames() < 1)
Kitware Robot's avatar
Kitware Robot committed
209
  {
210 211
    vtkWarningMacro(<< "No files given.");
    return;
Kitware Robot's avatar
Kitware Robot committed
212
  }
213 214

  vtkStdString originalFile = this->GetFileName(0);
215
  this->RemoveAllFileNamesInternal();
216 217 218 219 220

  vtkStdString path;
  vtkStdString baseName;
  vtkStdString::size_type dirseppos = originalFile.find_last_of("/\\");
  if (dirseppos == vtkStdString::npos)
Kitware Robot's avatar
Kitware Robot committed
221
  {
222 223
    path = "./";
    baseName = originalFile;
Kitware Robot's avatar
Kitware Robot committed
224
  }
225
  else
Kitware Robot's avatar
Kitware Robot committed
226 227 228 229
  {
    path = originalFile.substr(0, dirseppos + 1);
    baseName = originalFile.substr(dirseppos + 1);
  }
230 231 232 233 234 235 236 237 238 239

  // We are looking for files following the convention of
  //
  //   <file>.e-s.<rs#>.<numproc>.<rank>
  //
  // When the simulation was run on a single process, the .<numproc>.<rank> is
  // optional.  If it exists, we will look exclusively for files with that
  // extension as all restarts should have been run on that process.
  //
  // Additionally, the -s.<rs#> (which captures the restart number) is often not
luz paz's avatar
luz paz committed
240
  // there on the first file set (before the first restart occurred).  Thus it is
241 242
  // optional (although there can only be one as this is the only place we check
  // numbering).
243 244
  //
  // The `e` in the above pattern can be any of exodus supported extensions e.g.
245 246
  // exo, ex2, etc. Hence we keep the regex generic (ref: paraview/paraview#19056,
  // paraview/paraview#19202).
247
  vtksys::RegularExpression regEx("^(.*\\.[eg][^-.]*)(-s.[0-9]+)?(\\.[0-9]+\\.[0-9]+)?$");
248
  if (!regEx.find(baseName))
Kitware Robot's avatar
Kitware Robot committed
249
  {
250
    // Filename does not follow convention.  Just use it.
251
    this->AddFileNameInternal(originalFile);
252
    return;
Kitware Robot's avatar
Kitware Robot committed
253
  }
254 255 256 257 258 259

  vtkStdString prefix = regEx.match(1);
  vtkStdString suffix = regEx.match(3);

  VTK_CREATE(vtkDirectory, dir);
  if (!dir->Open(path))
Kitware Robot's avatar
Kitware Robot committed
260
  {
261 262
    vtkWarningMacro(<< "Could not open directory " << originalFile.c_str()
                    << " is supposed to be from (" << path.c_str() << ")");
263
    this->AddFileNameInternal(originalFile);
264
    return;
Kitware Robot's avatar
Kitware Robot committed
265
  }
266 267

  for (vtkIdType i = 0; i < dir->GetNumberOfFiles(); i++)
Kitware Robot's avatar
Kitware Robot committed
268 269 270 271 272 273 274 275
  {
    const char* file = dir->GetFile(i);
    if (!regEx.find(file))
      continue;
    if (regEx.match(1) != prefix)
      continue;
    if (regEx.match(3) != suffix)
      continue;
276
    this->AddFileNameInternal((path + file).c_str());
Kitware Robot's avatar
Kitware Robot committed
277
  }
278
  this->CopyRealFileNamesFromFileNames();
279 280 281

  // Check to make sure we found something.
  if (this->GetNumberOfFileNames() < 1)
Kitware Robot's avatar
Kitware Robot committed
282 283
  {
    vtkWarningMacro(<< "Could not find any actual files matching " << originalFile.c_str());
284
    this->AddFileNameInternal(originalFile);
285
    this->CopyRealFileNamesFromFileNames();
Kitware Robot's avatar
Kitware Robot committed
286
  }
287
}