1 #include "vtkFileSeriesGroupReader.h"
3 #include <vtkInformation.h>
4 #include <vtkInformationVector.h>
5 #include <vtkMultiBlockDataSet.h>
6 #include <vtkMultiProcessController.h>
7 #include <vtkObjectFactory.h>
8 #include <vtkSmartPointer.h>
9 #include <vtkStreamingDemandDrivenPipeline.h>
11 #include "vtkMEDReader.h"
16 vtkStandardNewMacro(vtkFileSeriesGroupReader);
18 //=============================================================================
19 struct vtkFileSeriesGroupReaderInternals
21 std::vector<std::string> FileNames;
24 //=============================================================================
25 vtkFileSeriesGroupReader::vtkFileSeriesGroupReader()
26 : Internals(new vtkFileSeriesGroupReaderInternals())
28 this->SetNumberOfInputPorts(0);
29 this->SetNumberOfOutputPorts(1);
32 //-----------------------------------------------------------------------------
33 vtkFileSeriesGroupReader::~vtkFileSeriesGroupReader() = default;
35 //----------------------------------------------------------------------------
36 void vtkFileSeriesGroupReader::AddFileName(const char* name)
38 // Make sure the reader always has a filename set
39 this->ReaderSetFileName(name);
41 this->AddFileNameInternal(name);
45 //----------------------------------------------------------------------------
46 void vtkFileSeriesGroupReader::RemoveAllFileNames()
48 this->RemoveAllFileNamesInternal();
52 //----------------------------------------------------------------------------
53 void vtkFileSeriesGroupReader::RemoveAllFileNamesInternal()
55 this->Internals->FileNames.clear();
58 //----------------------------------------------------------------------------
59 void vtkFileSeriesGroupReader::AddFileNameInternal(const char* name)
61 this->Internals->FileNames.emplace_back(name);
64 //----------------------------------------------------------------------------
65 unsigned int vtkFileSeriesGroupReader::GetNumberOfFileNames()
67 return static_cast<unsigned int>(this->Internals->FileNames.size());
70 //----------------------------------------------------------------------------
71 const char* vtkFileSeriesGroupReader::GetFileName(unsigned int idx)
73 if (idx >= this->Internals->FileNames.size())
77 return this->Internals->FileNames[idx].c_str();
80 //----------------------------------------------------------------------------
81 int vtkFileSeriesGroupReader::CanReadFile(const char* filename)
88 return this->ReaderCanReadFile(filename);
91 //----------------------------------------------------------------------------
92 int vtkFileSeriesGroupReader::RequestInformation(
93 vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector)
95 return this->Reader->ProcessRequest(request, inputVector, outputVector);
98 //----------------------------------------------------------------------------
99 int vtkFileSeriesGroupReader::RequestData(vtkInformation* vtkNotUsed(request),
100 vtkInformationVector** vtkNotUsed(inputVector), vtkInformationVector* outputVector)
102 auto output = vtkMultiBlockDataSet::GetData(outputVector, 0);
103 unsigned int nBlock = this->GetNumberOfFileNames();
104 output->SetNumberOfBlocks(nBlock);
106 vtkInformation* info = outputVector->GetInformationObject(0);
107 double time = info->Get(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP());
109 vtkMultiProcessController *vmpc(vtkMultiProcessController::GetGlobalController());
110 unsigned int iProc = vmpc ? vmpc->GetLocalProcessId() : 0;
111 unsigned int nProc = vmpc ? vmpc->GetNumberOfProcesses() : 1;
113 // Simple case, one file/bloc for n proc
116 // No need to set the FileName, already set by the subproxy mechanism
117 this->Reader->UpdateTimeStep(time);
118 vtkDataObject* outputReader = vtkMultiBlockDataSet::SafeDownCast(this->Reader->GetOutputDataObject(0))->GetBlock(0);
119 output->SetBlock(0, outputReader);
121 // N file/block read by m proc, with n <= m, means 0/1 file/block per proc
122 else if (nBlock <= nProc && iProc < nBlock)
124 // Distribute in MEDReader only when reading a single file in a single block
125 vtkMEDReader::SafeDownCast(this->Reader)->SetDistributeWithMPI(false);
127 // Needed as the MEDReader do not support changing its filename
128 // without reloading everything.
129 this->ReaderSetFileName(this->GetFileName(iProc));
130 vtkMEDReader::SafeDownCast(this->Reader)->ReloadInternals();
131 this->Reader->UpdateInformation();
133 this->Reader->UpdateTimeStep(time);
134 vtkDataObject* outputReader = vtkMultiBlockDataSet::SafeDownCast(this->Reader->GetOutputDataObject(0))->GetBlock(0);
135 output->SetBlock(iProc, outputReader);
137 // Multiple files/block per proc
140 unsigned int nFiles = nBlock / nProc;
141 unsigned int offFile = iProc * nFiles;
142 unsigned int supFiles = nBlock % nProc;
144 // Last proc handle remaining files/block
145 if (iProc + 1 == nProc)
150 for (unsigned int i = 0; i < nFiles; i++)
152 this->ReaderSetFileName(this->GetFileName(i + offFile));
153 vtkMEDReader::SafeDownCast(this->Reader)->SetDistributeWithMPI(false);
154 vtkMEDReader::SafeDownCast(this->Reader)->ReloadInternals();
155 this->Reader->UpdateInformation();
156 this->Reader->UpdateTimeStep(time);
157 vtkDataObject* outputReader = vtkMultiBlockDataSet::SafeDownCast(this->Reader->GetOutputDataObject(0))->GetBlock(0);
160 // Last reader, just use the reader output directly
161 output->SetBlock(i + offFile, outputReader);
165 // Need to deep copy as the reader will be reused
166 vtkSmartPointer<vtkDataObject> outputLeaf = vtkSmartPointer<vtkDataObject>::Take(outputReader->NewInstance());
167 outputLeaf->DeepCopy(outputReader);
168 output->SetBlock(i + offFile, outputLeaf);
175 //------------------------------------------------------------------------------
176 int vtkFileSeriesGroupReader::FillOutputPortInformation(
177 int vtkNotUsed(port), vtkInformation* info)
179 info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkMultiBlockDataSet");
183 //-----------------------------------------------------------------------------
184 void vtkFileSeriesGroupReader::PrintSelf(ostream& os, vtkIndent indent)
186 this->Superclass::PrintSelf(os, indent);
188 os << indent << "MetaFileName: " << (this->_MetaFileName ? this->_MetaFileName : "(none)")