X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FPlugins%2FMEDReader%2FIO%2FvtkMEDReader.cxx;h=129ec3b3c223fe462b7ed439f971625c5fe90c19;hb=116f9ba48b5e85b8d20d51916c7428c99123bca3;hp=07d89f1b74021ad6f331516b6542e793cb8e47e2;hpb=a833b1388f958c887b2b0886fc40a8be0256e2c8;p=modules%2Fparavis.git diff --git a/src/Plugins/MEDReader/IO/vtkMEDReader.cxx b/src/Plugins/MEDReader/IO/vtkMEDReader.cxx index 07d89f1b..129ec3b3 100644 --- a/src/Plugins/MEDReader/IO/vtkMEDReader.cxx +++ b/src/Plugins/MEDReader/IO/vtkMEDReader.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2010-2015 CEA/DEN, EDF R&D +// Copyright (C) 2010-2019 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -20,6 +20,7 @@ #include "vtkMEDReader.h" #include "vtkGenerateVectors.h" +#include "MEDUtilities.hxx" #include "vtkMultiBlockDataSet.h" #include "vtkInformation.h" @@ -37,6 +38,7 @@ #include "vtkMultiTimeStepAlgorithm.h" #include "vtkUnstructuredGrid.h" #include "vtkInformationQuadratureSchemeDefinitionVectorKey.h" +#include "vtkInformationDoubleVectorKey.h" #include "vtkQuadratureSchemeDefinition.h" #include "vtkPointData.h" #include "vtkCellData.h" @@ -44,8 +46,11 @@ #include "vtkCellArray.h" #include "vtkDoubleArray.h" #include "vtkObjectFactory.h" +#include "vtkInformationDataObjectMetaDataKey.h" + #ifdef MEDREADER_USE_MPI #include "vtkMultiProcessController.h" +#include "vtkPUnstructuredGridGhostCellsGenerator.h" #endif #include "MEDFileFieldRepresentationTree.hxx" @@ -58,13 +63,13 @@ /*! * This class stores properties in loading state mode (pvsm) when the MED file has not been read yet. - * The file is not read beacause FileName has not been informed yet ! So this class stores properties of vtkMEDReader instance that + * The file is not read beacause FileName has not been informed yet ! So this class stores properties of vtkMEDReader instance that * owns it and wait the vtkMEDReader::SetFileName to apply properties afterwards. */ class PropertyKeeper { public: - PropertyKeeper(vtkMEDReader *master):_master(master),IsGVActivated(false),GVValue(0),IsCMActivated(false),CMValue(0) { } + PropertyKeeper(vtkMEDReader *master):IsGVActivated(false),GVValue(0),IsCMActivated(false),CMValue(0),IsGhostActivated(false),GCGCP(1),_master(master) { } void assignPropertiesIfNeeded(); bool arePropertiesOnTreeToSetAfter() const; // @@ -72,6 +77,7 @@ public: void pushGenerateVectorsValue(int value); void pushChangeModeValue(int value); void pushTimesFlagsStatusEntry(const char* name, int status); + void pushGhost(int value); protected: // pool of pairs to assign in SetFieldsStatus if needed. The use case is the load using pvsm. std::vector< std::pair > SetFieldsStatusPairs; @@ -81,6 +87,9 @@ protected: // change mode bool IsCMActivated; int CMValue; + // ghost cells + bool IsGhostActivated; + int GCGCP; // std::vector< std::pair > TimesFlagsStatusPairs; vtkMEDReader *_master; @@ -110,6 +119,11 @@ void PropertyKeeper::assignPropertiesIfNeeded() _master->ChangeMode(this->CMValue); this->IsCMActivated=false; } + if(this->IsGhostActivated) + { + _master->GhostCellGeneratorCallForPara(this->GCGCP); + this->IsGhostActivated=false; + } } void PropertyKeeper::pushFieldStatusEntry(const char* name, int status) @@ -142,6 +156,12 @@ void PropertyKeeper::pushChangeModeValue(int value) this->CMValue=value; } +void PropertyKeeper::pushGhost(int value) +{ + this->IsGhostActivated=true; + this->GCGCP=value; +} + bool PropertyKeeper::arePropertiesOnTreeToSetAfter() const { return !SetFieldsStatusPairs.empty(); @@ -151,18 +171,19 @@ class vtkMEDReader::vtkMEDReaderInternal { public: - vtkMEDReaderInternal(vtkMEDReader *master):TK(0),IsMEDOrSauv(true),IsStdOrMode(false),GenerateVect(false),SIL(0),LastLev0(-1),FirstCall0(2),PK(master),MyMTime(0) + vtkMEDReaderInternal(vtkMEDReader *master):TK(0),IsMEDOrSauv(true),IsStdOrMode(false),GenerateVect(false),SIL(0),LastLev0(-1),PK(master),MyMTime(0),GCGCP(true),FirstCall0(2) { } - + bool PluginStart0() { + return false; // TODO Useless and buggy if(FirstCall0==0) return false; FirstCall0--; return true; } - + ~vtkMEDReaderInternal() { if(this->SIL) @@ -188,12 +209,48 @@ public: int MyMTime; std::set _wonderful_set;// this set is used by SetFieldsStatus method to detect the fact that SetFieldsStatus has been called for all items ! Great Items are not sorted ! Why ? std::map _wonderful_ref;// this map stores the state before a SetFieldsStatus status. + bool GCGCP; + private: unsigned char FirstCall0; }; vtkStandardNewMacro(vtkMEDReader); +// vtkInformationKeyMacro(vtkMEDReader, META_DATA, DataObjectMetaData); // Here we need to customize vtkMEDReader::META_DATA method +// start of overload of vtkInformationKeyMacro +static vtkInformationDataObjectMetaDataKey *vtkMEDReader_META_DATA=new vtkInformationDataObjectMetaDataKey("META_DATA","vtkMEDReader"); + +vtkInformationDataObjectMetaDataKey *vtkMEDReader::META_DATA() +{ + static const char ZE_KEY[]="vtkMEDReader::META_DATA"; + vtkInformationDataObjectMetaDataKey *ret(vtkMEDReader_META_DATA); + MEDCoupling::GlobalDict *gd(MEDCoupling::GlobalDict::GetInstance()); + if(!gd->hasKey(ZE_KEY)) + {// here META_DATA is put on global var to be exchanged with other filters without dependancy of MEDReader. Please do not change ZE_KEY ! + std::ostringstream oss; oss << ret; + gd->setKeyValue(ZE_KEY,oss.str()); + } + return ret; +} + +static vtkInformationGaussDoubleVectorKey *vtkMEDReader_GAUSS_DATA=new vtkInformationGaussDoubleVectorKey("GAUSS_DATA","vtkMEDReader"); + +vtkInformationGaussDoubleVectorKey *vtkMEDReader::GAUSS_DATA() +{ + static const char ZE_KEY[]="vtkMEDReader::GAUSS_DATA"; + vtkInformationGaussDoubleVectorKey *ret(vtkMEDReader_GAUSS_DATA); + MEDCoupling::GlobalDict *gd(MEDCoupling::GlobalDict::GetInstance()); + if(!gd->hasKey(ZE_KEY)) + {// here META_DATA is put on global var to be exchanged with other filters without dependancy of MEDReader. Please do not change ZE_KEY ! + vtkInformationDoubleVectorKey *ret2(ret); + std::ostringstream oss; oss << ret2; + gd->setKeyValue(ZE_KEY,oss.str()); + } + return ret; +} +// end of overload of vtkInformationKeyMacro + vtkMEDReader::vtkMEDReader():Internal(new vtkMEDReaderInternal(this)) { this->SetNumberOfInputPorts(0); @@ -206,11 +263,8 @@ vtkMEDReader::~vtkMEDReader() this->Internal = 0; } -void vtkMEDReader::Reload(int a) +void vtkMEDReader::Reload() { - if(a==0) - return; - std::cerr << "vtkMEDReader::Reload" << a << std::endl; std::string fName((const char *)this->GetFileName()); delete this->Internal; this->Internal=new vtkMEDReaderInternal(this); @@ -255,10 +309,27 @@ void vtkMEDReader::ChangeMode(int newMode) } //not pvsm mode (general case) this->Internal->IsStdOrMode=newMode!=0; - //std::cerr << "vtkMEDReader::ChangeMode : " << this->Internal->IsStdOrMode << std::endl; this->Modified(); } +void vtkMEDReader::GhostCellGeneratorCallForPara(int gcgcp) +{ + if ( !this->Internal ) + return; + + if(this->Internal->FileName.empty()) + {//pvsm mode + this->Internal->PK.pushGhost(gcgcp); + return ; + } + bool newVal(gcgcp!=0); + if(newVal!=this->Internal->GCGCP) + { + this->Internal->GCGCP=newVal; + this->Modified(); + } +} + const char *vtkMEDReader::GetSeparator() { return MEDFileFieldRepresentationLeavesArrays::ZE_SEP; @@ -320,15 +391,20 @@ char *vtkMEDReader::GetFileName() int vtkMEDReader::RequestInformation(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) { - //std::cerr << "########################################## RequestInformation ##########################################" << std::endl; +// std::cout << "########################################## vtkMEDReader::RequestInformation ##########################################" << std::endl; if(!this->Internal) return 0; try { +// request->Print(cout); vtkInformation *outInfo(outputVector->GetInformationObject(0)); outInfo->Set(vtkDataObject::DATA_TYPE_NAME(),"vtkMultiBlockDataSet"); - this->UpdateSIL(outInfo); - // + this->UpdateSIL(request, outInfo); + + // Set the meta data graph as a meta data key in the information + // That's all that is needed to transfer it along the pipeline + outInfo->Set(vtkMEDReader::META_DATA(),this->Internal->SIL); + bool dummy(false); this->PublishTimeStepsIfNeeded(outInfo,dummy); } @@ -348,22 +424,47 @@ int vtkMEDReader::RequestInformation(vtkInformation *request, vtkInformationVect int vtkMEDReader::RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) { - //std::cerr << "########################################## RequestData ##########################################"; +// std::cout << "########################################## vtkMEDReader::RequestData ##########################################" << std::endl; if(!this->Internal) return 0; try { +// request->Print(cout); vtkInformation *outInfo(outputVector->GetInformationObject(0)); vtkMultiBlockDataSet *output(vtkMultiBlockDataSet::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()))); bool isUpdated(false); double reqTS(0.); if(outInfo->Has(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP())) reqTS=outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP()); - //std::cerr << reqTS << std::endl; - this->FillMultiBlockDataSetInstance(output,reqTS); + ExportedTinyInfo ti; +#ifndef MEDREADER_USE_MPI + this->FillMultiBlockDataSetInstance(output,reqTS,&ti); +#else + if(this->Internal->GCGCP) + { + vtkSmartPointer gcg(vtkSmartPointer::New()); + { + vtkDataSet *ret(RetrieveDataSetAtTime(reqTS,&ti)); + gcg->SetInputData(ret); + ret->Delete(); + } + gcg->SetUseGlobalPointIds(true); + gcg->SetBuildIfRequired(false); + gcg->Update(); + output->SetBlock(0,gcg->GetOutput()); + } + else + this->FillMultiBlockDataSetInstance(output,reqTS,&ti); +#endif + if(!ti.empty()) + { + const std::vector& data(ti.getData()); + outInfo->Set(vtkMEDReader::GAUSS_DATA(),&data[0],(int)data.size()); + request->Append(vtkExecutive::KEYS_TO_COPY(),vtkMEDReader::GAUSS_DATA());// Thank you to SciberQuest and DIPOLE_CENTER ! Don't understand why ! In RequestInformation it does not work ! + } output->GetInformation()->Set(vtkDataObject::DATA_TIME_STEP(),reqTS); - this->UpdateSIL(outInfo); - //this->UpdateProgress((float) progress/((float) maxprogress-1)); + // Is it really needed ? TODO + this->UpdateSIL(request, outInfo); } catch(INTERP_KERNEL::Exception& e) { @@ -391,7 +492,7 @@ void vtkMEDReader::SetFieldsStatus(const char* name, int status) try { this->Internal->Tree.changeStatusOfAndUpdateToHaveCoherentVTKDataSet(this->Internal->Tree.getIdHavingZeName(name),status); - if(this->Internal->_wonderful_set.size()==GetNumberOfFieldsTreeArrays()) + if((int)this->Internal->_wonderful_set.size()==GetNumberOfFieldsTreeArrays()) { if(this->Internal->_wonderful_ref!=this->Internal->Tree.dumpState()) { @@ -419,7 +520,6 @@ int vtkMEDReader::GetNumberOfFieldsTreeArrays() if(!this->Internal) return 0; return this->Internal->Tree.getNumberOfLeavesArrays(); - //std::cerr << "vtkMEDReader::GetNumberOfFieldsTreeArrays called ! " << ret << std::endl; } const char *vtkMEDReader::GetFieldsTreeArrayName(int index) @@ -427,7 +527,6 @@ const char *vtkMEDReader::GetFieldsTreeArrayName(int index) if(!this->Internal) return 0; return this->Internal->Tree.getNameOfC(index); - //std::cerr << "vtkMEDReader::GetFieldsTreeArrayName(" << index << ") called ! " << ret << std::endl; } int vtkMEDReader::GetFieldsTreeArrayStatus(const char *name) @@ -454,7 +553,7 @@ void vtkMEDReader::SetTimesFlagsStatus(const char *name, int status) int pos(0); std::istringstream iss(name); iss >> pos; this->Internal->TK.getTimesFlagArray()[pos].first=(bool)status; - if(pos==this->Internal->TK.getTimesFlagArray().size()-1) + if(pos==(int)this->Internal->TK.getTimesFlagArray().size()-1) if(!this->Internal->PluginStart0()) { this->Modified(); @@ -483,24 +582,19 @@ int vtkMEDReader::GetTimesFlagsArrayStatus(const char *name) return (int)this->Internal->TK.getTimesFlagArray()[pos].first; } -void vtkMEDReader::UpdateSIL(vtkInformation *info) +void vtkMEDReader::UpdateSIL(vtkInformation* request, vtkInformation *info) { if(!this->Internal) return; - vtkMutableDirectedGraph *sil(vtkMutableDirectedGraph::New()); - std::string meshName(this->BuildSIL(sil)); - if(meshName!=this->Internal->DftMeshName) + std::string meshName(this->Internal->Tree.getActiveMeshName()); + if(!this->Internal->SIL || meshName!=this->Internal->DftMeshName) { + vtkMutableDirectedGraph *sil(vtkMutableDirectedGraph::New()); + this->BuildSIL(sil); if(this->Internal->SIL) this->Internal->SIL->Delete(); this->Internal->SIL=sil; this->Internal->DftMeshName=meshName; - info->Set(vtkDataObject::SIL(),this->Internal->SIL); - //request->AppendUnique(vtkExecutive::KEYS_TO_COPY(),vtkDataObject::SIL()); - } - else - { - sil->Delete(); } } @@ -563,27 +657,38 @@ double vtkMEDReader::PublishTimeStepsIfNeeded(vtkInformation *outInfo, bool& isU double timeRange[2]; timeRange[0]=tsteps.front(); timeRange[1]=tsteps.back(); - outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_STEPS(),&tsteps[0],tsteps.size()); + outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_STEPS(),&tsteps[0],(int)tsteps.size()); outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_RANGE(),timeRange,2); this->Internal->LastLev0=lev0; } return tsteps.front(); } -void vtkMEDReader::FillMultiBlockDataSetInstance(vtkMultiBlockDataSet *output, double reqTS) +void vtkMEDReader::FillMultiBlockDataSetInstance(vtkMultiBlockDataSet *output, double reqTS, ExportedTinyInfo *internalInfo) { if( !this->Internal ) return; + vtkDataSet *ret(RetrieveDataSetAtTime(reqTS,internalInfo)); + output->SetBlock(0,ret); + ret->Delete(); +} + +vtkDataSet *vtkMEDReader::RetrieveDataSetAtTime(double reqTS, ExportedTinyInfo *internalInfo) +{ + if( !this->Internal ) + return 0; std::string meshName; - vtkDataSet *ret(this->Internal->Tree.buildVTKInstance(this->Internal->IsStdOrMode,reqTS,meshName,this->Internal->TK)); + vtkDataSet *ret(this->Internal->Tree.buildVTKInstance(this->Internal->IsStdOrMode,reqTS,meshName,this->Internal->TK,internalInfo)); if(this->Internal->GenerateVect) { vtkGenerateVectors::Operate(ret->GetPointData()); vtkGenerateVectors::Operate(ret->GetCellData()); vtkGenerateVectors::Operate(ret->GetFieldData()); + // The operations above have potentially created new arrays -> This breaks the optimization of StaticMesh that expects the same field arrays over time. + // To enforce the cache recomputation declare modification of mesh. + //vtkGenerateVectors::ChangeMeshTimeToUpdateCache(ret); } - output->SetBlock(0,ret); - ret->Delete(); + return ret; } void vtkMEDReader::PrintSelf(ostream& os, vtkIndent indent)