Salome HOME
Minor: replacing annoying tabulations with whitespaces ...
[modules/paravis.git] / src / Plugins / MedReader / IO / vtkMedDriver.cxx
1 // Copyright (C) 2010-2013  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "vtkMedDriver.h"
21
22 #include "vtkObjectFactory.h"
23 #include "vtkStringArray.h"
24 #include "vtkDataArray.h"
25 #include "vtkIdTypeArray.h"
26 #include "vtkMath.h"
27
28 #include "vtkMedFile.h"
29 #include "vtkMedCartesianGrid.h"
30 #include "vtkMedPolarGrid.h"
31 #include "vtkMedCurvilinearGrid.h"
32 #include "vtkMedUnstructuredGrid.h"
33 #include "vtkMedField.h"
34 #include "vtkMedMesh.h"
35 #include "vtkMedFamily.h"
36 #include "vtkMedUtilities.h"
37 #include "vtkMedEntityArray.h"
38 #include "vtkMedLocalization.h"
39 #include "vtkMedProfile.h"
40 #include "vtkMedFieldOverEntity.h"
41 #include "vtkMedFieldStep.h"
42 #include "vtkMedGroup.h"
43 #include "vtkMedIntArray.h"
44 #include "vtkMedLink.h"
45
46 #ifdef MedReader_HAVE_PARALLEL_INFRASTRUCTURE
47 #include "vtkMultiProcessController.h"
48 #include "vtkMPIController.h"
49 #include <vtkMPICommunicator.h>
50 #include <vtkMPI.h>
51 #endif
52
53 vtkCxxSetObjectMacro(vtkMedDriver, MedFile, vtkMedFile);
54
55 //vtkCxxRevisionMacro(vtkMedDriver, "$Revision$")
56 vtkStandardNewMacro(vtkMedDriver)
57
58 vtkMedDriver::vtkMedDriver()
59 {
60   this->MedFile = NULL;
61   this->OpenLevel = 0;
62   this->FileId = -1;
63 }
64
65 vtkMedDriver::~vtkMedDriver()
66 {
67   if (this->OpenLevel > 0)
68     {
69     vtkWarningMacro("The file has not be closed before destructor.")
70     this->OpenLevel = 1;
71     this->Close();
72     }
73   this->SetMedFile(NULL);
74 }
75
76 int vtkMedDriver::RestrictedOpen()
77 {
78   int res = 0;
79   if (this->MedFile == NULL || this->MedFile->GetFileName() == NULL)
80     {
81     vtkDebugMacro("Error : FileName has not been set ");
82     return -1;
83     }
84
85   if (this->OpenLevel <= 0)
86     {
87
88     med_bool hdfok;
89     med_bool medok;
90
91     med_err conforme = MEDfileCompatibility(this->MedFile->GetFileName(),
92                                             &hdfok, &medok);
93     if (!hdfok)
94       {
95       vtkErrorMacro("The file " << this->MedFile->GetFileName()
96           << " is not a HDF5 file, aborting.");
97       return -1;
98       }
99
100     if (!medok)
101       {
102       vtkErrorMacro("The file " << this->MedFile->GetFileName()
103           << " has not been written with the"
104           << " same version as the one currently used to read it, this may lead"
105           << " to errors. Please use the medimport tool.");
106       return -1;
107       }
108
109     if(conforme < 0)
110       {
111       vtkErrorMacro("The file " << this->MedFile->GetFileName()
112                     << " is not compatible, please import it to the new version using medimport.");
113       return -1;
114       }
115
116     this->FileId = MEDfileOpen(this->MedFile->GetFileName(), MED_ACC_RDONLY);
117     if (this->FileId < 0)
118       {
119       vtkDebugMacro("Error : unable to open file "
120                     << this->MedFile->GetFileName());
121       res = -2;
122       }
123     this->OpenLevel = 0;
124
125     } // OpenLevel
126   this->OpenLevel++;
127   this->ParallelFileId = -1;
128   return res;
129 }
130
131 int vtkMedDriver::Open()
132 {
133   int res = 0;
134   if (this->MedFile == NULL || this->MedFile->GetFileName() == NULL)
135     {
136     vtkDebugMacro("Error : FileName has not been set ");
137     return -1;
138     }
139
140   if (this->OpenLevel <= 0)
141     {
142
143     med_bool hdfok;
144     med_bool medok;
145
146     med_err conforme = MEDfileCompatibility(this->MedFile->GetFileName(),
147                                             &hdfok, &medok);
148     if (!hdfok)
149       {
150       vtkErrorMacro("The file " << this->MedFile->GetFileName()
151           << " is not a HDF5 file, aborting.");
152       return -1;
153       }
154
155     if (!medok)
156       {
157       vtkErrorMacro("The file " << this->MedFile->GetFileName()
158           << " has not been written with the"
159           << " same version as the one currently used to read it, this may lead"
160           << " to errors. Please use the medimport tool.");
161       return -1;
162       }
163
164     if(conforme < 0)
165       {
166       vtkErrorMacro("The file " << this->MedFile->GetFileName()
167                     << " is not compatible, please import it to the new version using medimport.");
168       return -1;
169       }
170
171     this->FileId = MEDfileOpen(this->MedFile->GetFileName(), MED_ACC_RDONLY);
172     if (this->FileId < 0)
173       {
174       vtkDebugMacro("Error : unable to open file "
175                     << this->MedFile->GetFileName());
176       res = -2;
177       }
178     this->OpenLevel = 0;
179
180     this->ParallelFileId = -1;
181
182 #ifdef MedReader_HAVE_PARALLEL_INFRASTRUCTURE
183     // the following code opens the file in parallel
184     vtkMultiProcessController* controller =
185         vtkMultiProcessController::GetGlobalController();
186     int lpID = 0;
187     if (controller == NULL)
188       {
189     return -3;
190       }
191     else
192       {
193       lpID = controller->GetLocalProcessId();
194       }
195
196     vtkMPICommunicator* commu = vtkMPICommunicator::SafeDownCast(
197                   controller->GetCommunicator() );
198     if (commu == NULL)
199       {
200       //vtkErrorMacro("Communicator is NULL in Open");
201       return -3;
202       }
203     MPI_Comm* mpi_com = NULL;
204     mpi_com = commu->GetMPIComm()->GetHandle();
205     if (mpi_com == NULL)
206       {
207       vtkErrorMacro("MPI communicator is NULL in Open");
208       return -3;
209       }
210
211     if (controller->GetNumberOfProcesses() > 1)
212       {
213       int major, minor, release;
214       if (MEDfileNumVersionRd(this->FileId, &major, &minor, &release) < 0)
215         {
216         vtkErrorMacro("Impossible to read the version of this file");
217         return -1;
218         }
219
220     if (major >= 3)
221       {
222         this->ParallelFileId = MEDparFileOpen(this->MedFile->GetFileName(),
223                             MED_ACC_RDONLY,
224                             *mpi_com,
225                             MPI_INFO_NULL);
226         }
227     else
228         {
229         vtkErrorMacro("Parallel access is not allowed in MED files prior to version 3");
230         return -1;
231         }
232       }
233
234     if (this->ParallelFileId < 0)
235       {
236       vtkDebugMacro("Error : unable to parallel-open file "
237                     << this->MedFile->GetFileName());
238       }
239 #endif
240
241     } // OpenLevel
242   this->OpenLevel++;
243   return res;
244 }
245
246 void vtkMedDriver::Close()
247 {
248   this->OpenLevel--;
249   if (this->OpenLevel == 0)
250     {
251     if (MEDfileClose(this->FileId) < 0)
252       {
253       vtkErrorMacro("Error: unable to close the current file.");
254       }
255     this->FileId = -1;
256
257     if (this->ParallelFileId != -1)
258     {
259       if (MEDfileClose(this->ParallelFileId) < 0)
260       {
261       vtkErrorMacro("Error: unable to parallel-close the current file.");
262       }
263     }
264     this->ParallelFileId = -1;
265     }
266 }
267
268 bool vtkMedDriver::CanReadFile()
269 {
270   bool canRead = (this->RestrictedOpen() >= 0);
271   this->Close();
272   return canRead;
273 }
274
275 void vtkMedDriver::ReadFileVersion(int* major, int* minor, int* release)
276 {
277   FileRestrictedOpen open(this);
278
279   med_int amajor, aminor, arelease;
280   if (MEDfileNumVersionRd(this->FileId, &amajor, &aminor, &arelease) < 0)
281     {
282     vtkErrorMacro("Impossible to read the version of this file");
283     return;
284     }
285   *major = amajor;
286   *minor = aminor;
287   *release = arelease;
288 }
289
290 void vtkMedDriver::ReadRegularGridInformation(vtkMedRegularGrid* grid)
291 {
292   vtkErrorMacro("vtkMedDriver::ReadInformation not Implemented !");
293   return;
294 }
295
296 void vtkMedDriver::ReadCurvilinearGridInformation(vtkMedCurvilinearGrid* grid)
297 {
298   vtkErrorMacro("vtkMedDriver::ReadInformation not Implemented !");
299   return;
300 }
301
302 void vtkMedDriver::ReadUnstructuredGridInformation(vtkMedUnstructuredGrid* grid)
303 {
304   vtkErrorMacro("vtkMedDriver::ReadInformation not Implemented !");
305   return;
306 }
307
308 // Description:
309 // load all Information data associated with this standard grid.
310 void vtkMedDriver::ReadGridInformation(vtkMedGrid* grid)
311 {
312   if(vtkMedRegularGrid::SafeDownCast(grid) != NULL)
313     {
314     this->ReadRegularGridInformation(vtkMedRegularGrid::SafeDownCast(grid));
315     }
316   if(vtkMedCurvilinearGrid::SafeDownCast(grid) != NULL)
317     {
318     this->ReadCurvilinearGridInformation(vtkMedCurvilinearGrid::SafeDownCast(grid));
319     }
320   if(vtkMedUnstructuredGrid::SafeDownCast(grid) != NULL)
321     {
322     this->ReadUnstructuredGridInformation(vtkMedUnstructuredGrid::SafeDownCast(grid));
323     }
324 }
325
326 void vtkMedDriver::ReadFamilyInformation(vtkMedMesh* mesh, vtkMedFamily* family)
327 {
328   vtkErrorMacro("vtkMedDriver::ReadFamilyInformation not Implemented !");
329   return;
330 }
331
332 void vtkMedDriver::ReadFileInformation(vtkMedFile* file)
333 {
334   vtkErrorMacro("vtkMedDriver::ReadFileInformation not Implemented !");
335   return;
336 }
337
338 void vtkMedDriver::ReadProfileInformation(vtkMedProfile* profile)
339 {
340   vtkErrorMacro("vtkMedDriver::ReadProfileInformation not Implemented !");
341   return;
342 }
343
344 void vtkMedDriver::ReadFieldInformation(vtkMedField* field)
345 {
346   vtkErrorMacro("vtkMedDriver::ReadFieldInformation not Implemented !");
347   return;
348 }
349
350 void vtkMedDriver::ReadFieldOverEntityInformation(vtkMedFieldOverEntity* fieldOverEntity)
351 {
352   vtkErrorMacro("vtkMedDriver::ReadFieldOverEntityInformation not Implemented !");
353   return;
354 }
355
356 void vtkMedDriver::ReadMeshInformation(vtkMedMesh* mesh)
357 {
358   vtkErrorMacro("vtkMedDriver::ReadMeshInformation not Implemented !");
359   return;
360 }
361
362 void vtkMedDriver::ReadLocalizationInformation(vtkMedLocalization* loc)
363 {
364   vtkErrorMacro("vtkMedDriver::ReadLocalizationInformation not Implemented !");
365   return;
366 }
367
368 void vtkMedDriver::ReadInterpolationInformation(vtkMedInterpolation* interp)
369 {
370   vtkErrorMacro("vtkMedDriver::ReadInterpolationInformation not Implemented !");
371   return;
372 }
373
374 void vtkMedDriver::ReadFieldStepInformation(vtkMedFieldStep* step, bool readAllEntityInfo)
375 {
376   vtkErrorMacro("vtkMedDriver::ReadFieldStepInformation not Implemented !");
377   return;
378 }
379
380 void vtkMedDriver::ReadFieldOnProfileInformation(vtkMedFieldOnProfile* fop)
381 {
382   vtkErrorMacro("vtkMedDriver::ReadFieldOnProfileInformation not Implemented !");
383   return;
384 }
385
386 void vtkMedDriver::ReadStructElementInformation(
387     vtkMedStructElement*)
388 {
389   vtkErrorMacro("vtkMedDriver::ReadStructElementInformation not Implemented !");
390   return;
391 }
392
393 void vtkMedDriver::ReadSupportMeshInformation(
394     vtkMedMesh*)
395 {
396   vtkErrorMacro("vtkMedDriver::ReadSupportMeshInformation not Implemented !");
397   return;
398 }
399
400 void vtkMedDriver::ReadConstantAttributeInformation(vtkMedConstantAttribute*)
401 {
402   vtkErrorMacro("vtkMedDriver::ReadConstantAttributeInformation not Implemented !");
403   return;
404 }
405
406 void vtkMedDriver::ReadVariableAttributeInformation(vtkMedVariableAttribute*)
407 {
408   vtkErrorMacro("vtkMedDriver::ReadVariableAttributeInformation not Implemented !");
409   return;
410 }
411
412 void vtkMedDriver::LoadPointGlobalIds(vtkMedGrid* grid)
413 {
414   vtkErrorMacro("vtkMedDriver::LoadPointGlobalIds not Implemented !");
415   return;
416 }
417
418 void vtkMedDriver::LoadFamilyIds(vtkMedEntityArray* array)
419 {
420   vtkErrorMacro("vtkMedDriver::LoadFamilyIds not Implemented !");
421   return;
422 }
423
424 void vtkMedDriver::LoadCoordinates(vtkMedGrid* grid)
425 {
426   vtkErrorMacro("vtkMedDriver::LoadCoordinates not Implemented !");
427   return;
428 }
429
430 void vtkMedDriver::LoadProfile(vtkMedProfile* profile)
431 {
432   vtkErrorMacro("vtkMedDriver::LoadProfile not Implemented !");
433   return;
434 }
435
436 void vtkMedDriver::LoadConnectivity(vtkMedEntityArray* array)
437 {
438   vtkErrorMacro("vtkMedDriver::LoadConnectivity not Implemented !");
439   return;
440 }
441
442 void vtkMedDriver::LoadCellGlobalIds(vtkMedEntityArray* array)
443 {
444   vtkErrorMacro("vtkMedDriver::LoadGlobalIds not Implemented !");
445   return;
446 }
447
448 void vtkMedDriver::LoadField(vtkMedFieldOnProfile* foe, med_storage_mode mode)
449 {
450   vtkErrorMacro("vtkMedDriver::LoadFieldOnProfile not Implemented !");
451   return;
452 }
453
454 void vtkMedDriver::LoadVariableAttribute(vtkMedVariableAttribute*,
455                                          vtkMedEntityArray*)
456 {
457   vtkErrorMacro("vtkMedDriver::LoadVariableAttribute not Implemented !");
458   return;
459 }
460
461 void vtkMedDriver::PrintSelf(ostream& os, vtkIndent indent)
462 {
463   this->Superclass::PrintSelf(os, indent);
464   PRINT_IVAR(os, indent, OpenLevel);
465   PRINT_IVAR(os, indent, FileId);
466 }