#include "MEDFileBlowStrEltUp.hxx"
#include "MEDCouplingFieldDouble.hxx"
+#include "MEDFileFieldVisitor.hxx"
using namespace MEDCoupling;
MEDFileUMesh *umesh(dynamic_cast<MEDFileUMesh *>(mesh));
if(!umesh)
throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::generateMeshes : Blow up of Stru Elt not managed yet for unstructured meshes !");
- MCAuto<MEDFileUMesh> mOut;
- MCAuto<MEDFileFields> fsOut1;
- MCAuto<MEDFileEltStruct4Mesh> zeStr(dealWithSEInMesh(ps[0].second,umesh,mOut,fsOut1));
- msOut->pushMesh(mOut);
- dealWithSEInFields(ps[0].second,*elt,zeStr,fsOut1,allZeOutFields);
+ //
+ std::vector< MCAuto<MEDFileFields> > elts2;
+ std::vector< MCAuto<MEDFileUMesh> > elts3;
+ MCAuto<MEDFileFields> classicalSEFields(splitFieldsPerLoc(*elt,elts2,elts3));
+ if(classicalSEFields.isNotNull())
+ {
+ MCAuto<MEDFileUMesh> mOut;
+ MCAuto<MEDFileFields> fsOut1;
+ MCAuto<MEDFileEltStruct4Mesh> zeStr(dealWithSEInMesh(ps[0].second,umesh,mOut,fsOut1));
+ msOut->pushMesh(mOut);
+ dealWithSEInFields(ps[0].second,classicalSEFields,zeStr,fsOut1,allZeOutFields);
+ }
+ /*for(std::vector< MCAuto<MEDFileFields> >::iterator elt2=elts2.begin();elt2!=elts2.end();elt2++)
+ {
+ }*/
}
}
MEDFileBlowStrEltUp bu(fsSEOnly,ms,ses);
bu.generate(ms,fs);
}
+
+//
+
+class LocInfo
+{
+public:
+ LocInfo() { }
+ bool operator==(const LocInfo& other) const { return _locs==other._locs && _pfl==other._pfl; }
+ void push(const std::string& loc, const std::string& pfl) { checkUniqueLoc(loc); _locs.push_back(loc); _pfl.push_back(pfl); }
+private:
+ void checkUniqueLoc(const std::string& loc) const;
+private:
+ std::vector<std::string> _locs;
+ std::vector<std::string> _pfl;
+};
+
+void LocInfo::checkUniqueLoc(const std::string& loc) const
+{
+ if(std::find(_locs.begin(),_locs.end(),loc)!=_locs.end())
+ {
+ std::ostringstream oss; oss << "LocInfo::checkUniqueLoc : loc \"" << loc << "\" already exists !";
+ throw INTERP_KERNEL::Exception(oss.str());
+ }
+}
+
+class FieldWalker2
+{
+public:
+ FieldWalker2(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd);
+ bool isClassic() const { return _is_classic; }
+ bool operator!=(const FieldWalker2& other) const;
+private:
+ std::string _loc;
+ std::string _pfl;
+ bool _is_classic;
+};
+
+FieldWalker2::FieldWalker2(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd)
+{
+ _loc=pmptpd->getLocalization();
+ _pfl=pmptpd->getProfile();
+ _is_classic=pmptpd->getType()==ON_GAUSS_PT;
+}
+
+bool FieldWalker2::operator!=(const FieldWalker2& other) const
+{
+ bool ret(_loc==other._loc && _pfl==other._pfl && _is_classic==other._is_classic);
+ return !ret;
+}
+
+class FieldWalker1
+{
+public:
+ FieldWalker1(const MEDFileAnyTypeField1TSWithoutSDA *ts):_ts(ts),_pm_pt(0),_nb_mesh(0) { }
+ void newMeshEntry(const MEDFileFieldPerMesh *fpm);
+ void endMeshEntry(const MEDFileFieldPerMesh *fpm) { }
+ void newPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt);
+ void endPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt);
+ void newPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd);
+ void checkOK(const FieldWalker1& other) const;
+ bool isClassical() const;
+private:
+ const MEDFileAnyTypeField1TSWithoutSDA *_ts;
+ const MEDFileFieldPerMeshPerTypeDyn *_pm_pt;
+ std::vector<FieldWalker2> _fw;
+ int _nb_mesh;
+};
+
+void FieldWalker1::newMeshEntry(const MEDFileFieldPerMesh *fpm)
+{
+ if(_nb_mesh++==1)
+ throw INTERP_KERNEL::Exception("FieldWalker1::newMeshEntry : multi mesh not supported !");
+}
+
+void FieldWalker1::newPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt)
+{
+ if(_pm_pt)
+ throw INTERP_KERNEL::Exception("FieldWalker1::newPerMeshPerTypeEntry : multi SE loc not managed yet !");
+ const MEDFileFieldPerMeshPerTypeDyn *pmpt2(dynamic_cast<const MEDFileFieldPerMeshPerTypeDyn *>(pmpt));
+ if(!pmpt2)
+ throw INTERP_KERNEL::Exception("newPerMeshPerTypeEntry : internal error !");
+ _pm_pt=pmpt2;
+}
+
+void FieldWalker1::endPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *)
+{
+ isClassical();
+}
+
+void FieldWalker1::newPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd)
+{
+ _fw.push_back(FieldWalker2(pmptpd));
+}
+
+void FieldWalker1::checkOK(const FieldWalker1& other) const
+{
+ std::size_t sz(_fw.size());
+ if(other._fw.size()!=sz)
+ throw INTERP_KERNEL::Exception("checkOK : not OK because size are not the same !");
+ for(std::size_t i=0;i<sz;i++)
+ if(_fw[i]!=other._fw[i])
+ throw INTERP_KERNEL::Exception("checkOK : not OK because an element mismatches !");
+}
+
+bool FieldWalker1::isClassical() const
+{
+ if(_fw.empty())
+ throw INTERP_KERNEL::Exception("FieldWalker1::endPerMeshPerTypeEntry : internal error !");
+ std::size_t ic(0),inc(0);
+ for(std::vector<FieldWalker2>::const_iterator it=_fw.begin();it!=_fw.end();it++)
+ {
+ if((*it).isClassic())
+ ic++;
+ else
+ inc++;
+ }
+ if(ic!=0 && inc!=0)
+ throw INTERP_KERNEL::Exception("FieldWalker1::endPerMeshPerTypeEntry : mix is not allowed yet !");
+ return inc==0;
+}
+
+class FieldWalker
+{
+public:
+ FieldWalker(const MEDFileAnyTypeFieldMultiTSWithoutSDA *f):_f(f) { }
+ void newTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts);
+ void endTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts);
+ void newMeshEntry(const MEDFileFieldPerMesh *fpm);
+ void endMeshEntry(const MEDFileFieldPerMesh *fpm);
+ void newPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt);
+ void endPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt);
+ void newPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd);
+public:
+ bool isEmpty() const;
+ bool isClassical() const;
+private:
+ const MEDFileAnyTypeFieldMultiTSWithoutSDA *_f;
+ mutable INTERP_KERNEL::AutoCppPtr<FieldWalker1> _fw;
+ mutable INTERP_KERNEL::AutoCppPtr<FieldWalker1> _fw_prev;
+};
+
+bool FieldWalker::isEmpty() const
+{
+ return _fw_prev.isNull();
+}
+
+bool FieldWalker::isClassical() const
+{
+ return _fw_prev->isClassical();
+}
+
+void FieldWalker::newTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts)
+{
+ _fw=new FieldWalker1(ts);
+}
+
+void FieldWalker::endTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts)
+{
+ if(_fw_prev.isNull())
+ _fw_prev=new FieldWalker1(*_fw);
+ else
+ _fw_prev->checkOK(*_fw);
+ _fw=0;
+}
+
+void FieldWalker::newMeshEntry(const MEDFileFieldPerMesh *fpm)
+{
+ _fw->newMeshEntry(fpm);
+}
+
+void FieldWalker::endMeshEntry(const MEDFileFieldPerMesh *fpm)
+{
+ _fw->endMeshEntry(fpm);
+}
+
+void FieldWalker::newPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt)
+{
+ _fw->newPerMeshPerTypeEntry(pmpt);
+}
+
+void FieldWalker::endPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt)
+{
+ _fw->endPerMeshPerTypeEntry(pmpt);
+}
+
+void FieldWalker::newPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd)
+{
+ _fw->newPerMeshPerTypePerDisc(pmptpd);
+}
+
+// this class splits fields into same
+class LocSpliter : public MEDFileFieldVisitor
+{
+public:
+ LocSpliter(const MEDFileFieldGlobsReal *globs):_globs(globs),_fw(0) { }
+private:
+ void newFieldEntry(const MEDFileAnyTypeFieldMultiTSWithoutSDA *field);
+ void endFieldEntry(const MEDFileAnyTypeFieldMultiTSWithoutSDA *field);
+ //
+ void newTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts);
+ void endTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts);
+ //
+ void newMeshEntry(const MEDFileFieldPerMesh *fpm);
+ void endMeshEntry(const MEDFileFieldPerMesh *fpm);
+ //
+ void newPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt);
+ void endPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt);
+ //
+ void newPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd);
+private:
+ const MEDFileFieldGlobsReal *_globs;
+ std::vector< LocInfo > _locs;
+ std::vector< MCAuto<MEDFileFields> > _fields_on_locs;//size of _locs== size of _fields_on_locs
+ MCAuto<MEDFileFields> _classical;
+private:
+ mutable INTERP_KERNEL::AutoCppPtr<FieldWalker> _fw;
+};
+
+void LocSpliter::newFieldEntry(const MEDFileAnyTypeFieldMultiTSWithoutSDA *field)
+{
+ _fw=new FieldWalker(field);
+}
+
+void LocSpliter::endFieldEntry(const MEDFileAnyTypeFieldMultiTSWithoutSDA *field)
+{
+ if(_fw->isEmpty())
+ return ;
+ if(_fw->isClassical())
+ {
+ if(_classical.isNull())
+ {
+ _classical=MEDFileFields::New();
+ _classical->shallowCpyGlobs(*_globs);
+ }
+ }
+}
+
+void LocSpliter::newTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts)
+{
+ _fw->newTimeStepEntry(ts);
+}
+
+void LocSpliter::endTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts)
+{
+ _fw->endTimeStepEntry(ts);
+}
+
+void LocSpliter::newMeshEntry(const MEDFileFieldPerMesh *fpm)
+{
+ _fw->newMeshEntry(fpm);
+}
+
+void LocSpliter::endMeshEntry(const MEDFileFieldPerMesh *fpm)
+{
+ _fw->endMeshEntry(fpm);
+}
+
+void LocSpliter::newPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt)
+{
+ _fw->newPerMeshPerTypeEntry(pmpt);
+}
+
+void LocSpliter::endPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt)
+{
+ _fw->endPerMeshPerTypeEntry(pmpt);
+}
+
+void LocSpliter::newPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd)
+{
+ _fw->newPerMeshPerTypePerDisc(pmptpd);
+}
+
+MCAuto<MEDFileFields> MEDFileBlowStrEltUp::splitFieldsPerLoc(const MEDFileFields *fields, std::vector< MCAuto<MEDFileFields> >& outFields, std::vector< MCAuto<MEDFileUMesh> >& outMeshes)
+{
+ LocSpliter ls(fields);
+ fields->accept(ls);
+}