From 2e163534d8a425241d13c6f7da35eefd462de9a7 Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@ulg.ac.be> Date: Wed, 19 May 2010 09:25:41 +0000 Subject: [PATCH] - speedup reading of multi-step/partition .msh datasets - Plugin(Skin) now works on adapted datasets - addData() should now also work for high order datasets [we still need to add a new type+ref to FS in PViewDataGModel] --- Plugin/Skin.cpp | 2 +- Post/PView.cpp | 8 ++--- Post/PViewData.cpp | 2 +- Post/PViewData.h | 2 +- Post/PViewDataGModel.cpp | 62 ++++++++++++++++++++------------------ Post/PViewDataGModel.h | 7 ++--- Post/PViewDataGModelIO.cpp | 33 ++++++++++---------- Post/PViewDataList.cpp | 2 +- Post/PViewDataList.h | 2 +- 9 files changed, 61 insertions(+), 59 deletions(-) diff --git a/Plugin/Skin.cpp b/Plugin/Skin.cpp index 5335388e8a..a9f32f9639 100644 --- a/Plugin/Skin.cpp +++ b/Plugin/Skin.cpp @@ -143,7 +143,7 @@ PView *GMSH_SkinPlugin::execute(PView *v) PView *v1 = getView(iView, v); if(!v1) return v; - PViewData *data1 = v1->getData(); + PViewData *data1 = v1->getData(true); // get adaptive data if available if(data1->hasMultipleMeshes()){ Msg::Error("Skin plugin cannot be applied to multi-mesh views"); diff --git a/Post/PView.cpp b/Post/PView.cpp index f580e63d8c..3135456160 100644 --- a/Post/PView.cpp +++ b/Post/PView.cpp @@ -112,7 +112,7 @@ PView::PView(std::string xname, std::string yname, PView::PView(std::string name, std::string type, GModel *model, std::map<int, std::vector<double> > &data, - double time, int numC) + double time, int numComp) { _init(); PViewDataGModel::DataType t; @@ -127,7 +127,7 @@ PView::PView(std::string name, std::string type, return; } PViewDataGModel *d = new PViewDataGModel(t); - d->addData(model, data, 0, time, 1, numC); + d->addData(model, data, 0, time, 1, numComp); d->setName(name); d->setFileName(name + ".msh"); _data = d; @@ -138,10 +138,10 @@ PView::PView(std::string name, std::string type, } void PView::addStep(GModel *model, std::map<int, std::vector<double> > &data, - double time, int numC) + double time, int numComp) { PViewDataGModel *d = dynamic_cast<PViewDataGModel*>(_data); - if(d) d->addData(model, data, d->getNumTimeSteps(), time, 1, numC); + if(d) d->addData(model, data, d->getNumTimeSteps(), time, 1, numComp); else Msg::Error("Can only add step data to model-based datasets"); } diff --git a/Post/PViewData.cpp b/Post/PViewData.cpp index cffc18491d..93f6cfaa4d 100644 --- a/Post/PViewData.cpp +++ b/Post/PViewData.cpp @@ -22,7 +22,7 @@ PViewData::~PViewData() delete it->second[i]; } -bool PViewData::finalize() +bool PViewData::finalize(bool computeMinMax) { _dirty = false; return true; diff --git a/Post/PViewData.h b/Post/PViewData.h index baeacf25c0..d64e9982ab 100644 --- a/Post/PViewData.h +++ b/Post/PViewData.h @@ -45,7 +45,7 @@ class PViewData { virtual void setDirty(bool val){ _dirty = val; } // finalize the view data (compute min/max, etc.) - virtual bool finalize(); + virtual bool finalize(bool computeMinMax=true); // get/set name virtual std::string getName(){ return _name; } diff --git a/Post/PViewDataGModel.cpp b/Post/PViewDataGModel.cpp index 882ba1df48..94fae4dda8 100644 --- a/Post/PViewDataGModel.cpp +++ b/Post/PViewDataGModel.cpp @@ -25,41 +25,43 @@ PViewDataGModel::~PViewDataGModel() for(unsigned int i = 0; i < _steps.size(); i++) delete _steps[i]; } -bool PViewDataGModel::finalize() -{ - _min = VAL_INF; - _max = -VAL_INF; - for(int step = 0; step < getNumTimeSteps(); step++){ - _steps[step]->setMin(VAL_INF); - _steps[step]->setMax(-VAL_INF); - if(_type == NodeData || _type == ElementData){ - // treat these 2 special cases separately for maximum efficiency - int numComp = _steps[step]->getNumComponents(); - for(int i = 0; i < _steps[step]->getNumData(); i++){ - double *d = _steps[step]->getData(i); - if(d){ - double val = ComputeScalarRep(numComp, d); - _steps[step]->setMin(std::min(_steps[step]->getMin(), val)); - _steps[step]->setMax(std::max(_steps[step]->getMax(), val)); - } - } - } - else{ - // general case (slower) - for(int ent = 0; ent < getNumEntities(step); ent++){ - for(int ele = 0; ele < getNumElements(step, ent); ele++){ - if(skipElement(step, ent, ele)) continue; - for(int nod = 0; nod < getNumNodes(step, ent, ele); nod++){ - double val; - getScalarValue(step, ent, ele, nod, val); +bool PViewDataGModel::finalize(bool computeMinMax) +{ + if(computeMinMax){ + _min = VAL_INF; + _max = -VAL_INF; + for(int step = 0; step < getNumTimeSteps(); step++){ + _steps[step]->setMin(VAL_INF); + _steps[step]->setMax(-VAL_INF); + if(_type == NodeData || _type == ElementData){ + // treat these 2 special cases separately for maximum efficiency + int numComp = _steps[step]->getNumComponents(); + for(int i = 0; i < _steps[step]->getNumData(); i++){ + double *d = _steps[step]->getData(i); + if(d){ + double val = ComputeScalarRep(numComp, d); _steps[step]->setMin(std::min(_steps[step]->getMin(), val)); _steps[step]->setMax(std::max(_steps[step]->getMax(), val)); } } } + else{ + // general case (slower) + for(int ent = 0; ent < getNumEntities(step); ent++){ + for(int ele = 0; ele < getNumElements(step, ent); ele++){ + if(skipElement(step, ent, ele)) continue; + for(int nod = 0; nod < getNumNodes(step, ent, ele); nod++){ + double val; + getScalarValue(step, ent, ele, nod, val); + _steps[step]->setMin(std::min(_steps[step]->getMin(), val)); + _steps[step]->setMax(std::max(_steps[step]->getMax(), val)); + } + } + } + } + _min = std::min(_min, _steps[step]->getMin()); + _max = std::max(_max, _steps[step]->getMax()); } - _min = std::min(_min, _steps[step]->getMin()); - _max = std::max(_max, _steps[step]->getMax()); } // add interpolation data for known element types (this might be @@ -381,7 +383,7 @@ int PViewDataGModel::getNumValues(int step, int ent, int ele) return getNumComponents(step, ent, ele); } else{ - Msg::Error("getNumValue() should not be used on this type of view"); + Msg::Error("getNumValues() should not be used on this type of view"); return getNumComponents(step, ent, ele); } } diff --git a/Post/PViewDataGModel.h b/Post/PViewDataGModel.h index 8a85a462db..75aa808e51 100644 --- a/Post/PViewDataGModel.h +++ b/Post/PViewDataGModel.h @@ -170,7 +170,7 @@ class PViewDataGModel : public PViewData { public: PViewDataGModel(DataType type=NodeData); ~PViewDataGModel(); - bool finalize(); + bool finalize(bool computeMinMax=true); std::string getFileName(int step=-1); int getNumTimeSteps(); double getTime(int step); @@ -228,10 +228,9 @@ class PViewDataGModel : public PViewData { GModel* getModel(int step){ return _steps[step]->getModel(); } // Add some data "on the fly" (data is stored in a map, indexed by - // node or element number depending on the type of dataset; all the - // vectors are supposed to have the same length) + // node or element number depending on the type of dataset) bool addData(GModel *model, std::map<int, std::vector<double> > &data, - int step, double time, int partition, int numC); + int step, double time, int partition, int numComp); // I/O routines bool readMSH(std::string fileName, int fileIndex, FILE *fp, bool binary, diff --git a/Post/PViewDataGModelIO.cpp b/Post/PViewDataGModelIO.cpp index 9104575608..46dbc30e6e 100644 --- a/Post/PViewDataGModelIO.cpp +++ b/Post/PViewDataGModelIO.cpp @@ -12,18 +12,10 @@ #include "StringUtils.h" bool PViewDataGModel::addData(GModel *model, std::map<int, std::vector<double> > &data, - int step, double time, int partition, int numC) + int step, double time, int partition, int numComp) { if(data.empty()) return false; - int numComp = 9; - if (numC < 0){ - for(std::map<int, std::vector<double> >::iterator it = data.begin(); - it != data.end(); it++) - numComp = std::min(numComp, (int)it->second.size()); - } - else numComp = numC; - while(step >= (int)_steps.size()) _steps.push_back(new stepData<double>(model, numComp)); @@ -35,8 +27,9 @@ bool PViewDataGModel::addData(GModel *model, std::map<int, std::vector<double> > for(std::map<int, std::vector<double> >::iterator it = data.begin(); it != data.end(); it++){ - double *d = _steps[step]->getData(it->first, true); - for(int j = 0; j < numComp; j++) + int mult = it->second.size() / numComp; + double *d = _steps[step]->getData(it->first, true, mult); + for(int j = 0; j < numComp * mult; j++) d[j] = it->second[j]; } _steps[step]->getPartitions().insert(partition); @@ -96,17 +89,25 @@ bool PViewDataGModel::readMSH(std::string fileName, int fileIndex, FILE *fp, for(int j = 0; j < numComp * mult; j++) if(fscanf(fp, "%lf", &d[j]) != 1) return false; } + // compute min/max here to avoid calling finalize(true) later: + // this would be very slow for large multi-step, multi-partition + // datasets (since we would recompute the min/max for all the + // previously loaded steps/partitions, and thus loop over all the + // elements many times) + for(int j = 0; j < mult; j++){ + double val = ComputeScalarRep(numComp, &d[numComp * j]); + _steps[step]->setMin(std::min(_steps[step]->getMin(), val)); + _steps[step]->setMax(std::max(_steps[step]->getMax(), val)); + _min = std::min(_min, val); + _max = std::max(_max, val); + } if(numEnt > 100000) Msg::ProgressMeter(i + 1, numEnt, "Reading data"); } _steps[step]->getPartitions().insert(partition); - // FIXME: we should do this at a higher-level, since this will be - // very slow for large multi-step, multi-partition datasets (we - // recompute the min/max for all the previously loaded - // steps/partitions -> loop over all elements many many times...) - finalize(); + finalize(false); return true; } diff --git a/Post/PViewDataList.cpp b/Post/PViewDataList.cpp index 3913a546b9..8c39b8d7f9 100644 --- a/Post/PViewDataList.cpp +++ b/Post/PViewDataList.cpp @@ -25,7 +25,7 @@ PViewDataList::PViewDataList() for(int i = 0; i < 24; i++) _index[i] = 0; } -bool PViewDataList::finalize() +bool PViewDataList::finalize(bool computeMinMax) { BBox.reset(); Min = VAL_INF; diff --git a/Post/PViewDataList.h b/Post/PViewDataList.h index 9deec5dbe0..ef0bdbfd46 100644 --- a/Post/PViewDataList.h +++ b/Post/PViewDataList.h @@ -57,7 +57,7 @@ class PViewDataList : public PViewData { public: PViewDataList(); ~PViewDataList(){} - bool finalize(); + bool finalize(bool computeMinMax=true); int getNumTimeSteps(){ return NbTimeStep; } double getTime(int step); double getMin(int step=-1); -- GitLab