+/*!
+ * This method groups not null items in \a vectFMTS per time step series. Two time series are considered equal if the list of their pair of integers iteration,order are equal.
+ * The float64 value of time attached to the pair of integers are not considered here.
+ * WARNING the returned pointers are not incremented. The caller is \b not responsible to deallocate them ! This method only reorganizes entries in \a vectFMTS.
+ *
+ * \param [in] vectFMTS - vector of not null fields defined on a same global data pointer.
+ * \throw If there is a null pointer in \a vectFMTS.
+ */
+std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > MEDFileAnyTypeFieldMultiTS::SplitIntoCommonTimeSeries(const std::vector<MEDFileAnyTypeFieldMultiTS *>& vectFMTS)
+{
+ static const char msg[]="MEDFileAnyTypeFieldMultiTS::SplitIntoCommonTimeSeries : presence of null instance in input vector !";
+ std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > ret;
+ std::list<MEDFileAnyTypeFieldMultiTS *> lstFMTS(vectFMTS.begin(),vectFMTS.end());
+ while(!lstFMTS.empty())
+ {
+ std::list<MEDFileAnyTypeFieldMultiTS *>::iterator it(lstFMTS.begin());
+ MEDFileAnyTypeFieldMultiTS *curIt(*it);
+ if(!curIt)
+ throw INTERP_KERNEL::Exception(msg);
+ std::vector< std::pair<int,int> > refIts=curIt->getIterations();
+ std::vector<MEDFileAnyTypeFieldMultiTS *> elt;
+ elt.push_back(curIt); it=lstFMTS.erase(it);
+ while(it!=lstFMTS.end())
+ {
+ curIt=*it;
+ if(!curIt)
+ throw INTERP_KERNEL::Exception(msg);
+ std::vector< std::pair<int,int> > curIts=curIt->getIterations();
+ if(refIts==curIts)
+ { elt.push_back(curIt); it=lstFMTS.erase(it); }
+ else
+ it++;
+ }
+ ret.push_back(elt);
+ }
+ return ret;
+}
+
+/*!
+ * This method splits the input list \a vectFMTS considering the aspect of the geometrical support over time.
+ * All returned instances in a subvector can be safely loaded, rendered along time
+ * All items must be defined on the same time step ids ( see MEDFileAnyTypeFieldMultiTS::SplitIntoCommonTimeSeries method ).
+ * Each item in \a vectFMTS is expected to have one and exactly one spatial discretization along time.
+ * All items in \a vectFMTS must lie on the mesh (located by meshname and time step) and compatible with the input mesh \a mesh (having the same name than those in items).
+ * All items in \a vectFMTS whose spatial discretization is not ON_NODES will appear once.
+ * For items in \a vectFMTS that are ON_NODES it is possible to appear several times (more than once or once) in the returned vector.
+ *
+ * \param [in] vectFMTS - list of multi times step part all defined each on a same spatial discretization along time and pointing to a mesh whose name is equal to \c mesh->getName().
+ * \param [in] mesh - the mesh shared by all items in \a vectFMTS across time.
+ * \param [out] fsc - A vector having same size than returned vector. It specifies the support comporator of the corresponding vector of MEDFileAnyTypeFieldMultiTS in returned vector of vector.
+ * \return - A vector of vector of objects that contains the same pointers (objects) than thoose in \a vectFMTS except that there are organized differently. So pointers included in returned vector of vector should \b not been dealt by the caller.
+ *
+ * \throw If an element in \a vectFMTS has not only one spatial discretization set.
+ * \throw If an element in \a vectFMTS change of spatial discretization along time.
+ * \throw If an element in \a vectFMTS lies on a mesh with meshname different from those in \a mesh.
+ * \thorw If some elements in \a vectFMTS do not have the same times steps.
+ * \throw If mesh is null.
+ * \throw If an element in \a vectFMTS is null.
+ * \sa MEDFileAnyTypeFieldMultiTS::AreOnSameSupportAcrossTime
+ */
+std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport(const std::vector<MEDFileAnyTypeFieldMultiTS *>& vectFMTS, const MEDFileMesh *mesh, std::vector< MCAuto<MEDFileFastCellSupportComparator> >& fsc)
+{
+ static const char msg[]="MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport : presence of a null instance in the input vector !";
+ if(!mesh)
+ throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport : input mesh is null !");
+ std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > ret;
+ if(vectFMTS.empty())
+ return ret;
+ std::vector<MEDFileAnyTypeFieldMultiTS *>::const_iterator it(vectFMTS.begin());
+ MEDFileAnyTypeFieldMultiTS *frstElt(*it);
+ if(!frstElt)
+ throw INTERP_KERNEL::Exception(msg);
+ std::size_t i=0;
+ std::vector<MEDFileAnyTypeFieldMultiTS *> vectFMTSNotNodes;
+ std::vector<MEDFileAnyTypeFieldMultiTS *> vectFMTSNodes;
+ for(;it!=vectFMTS.end();it++,i++)
+ {
+ if(!(*it))
+ throw INTERP_KERNEL::Exception(msg);
+ TypeOfField tof0,tof1;
+ if(CheckSupportAcrossTime(frstElt,*it,mesh,tof0,tof1)>0)
+ {
+ if(tof1!=ON_NODES)
+ vectFMTSNotNodes.push_back(*it);
+ else
+ vectFMTSNodes.push_back(*it);
+ }
+ else
+ vectFMTSNotNodes.push_back(*it);
+ }
+ std::vector< MCAuto<MEDFileFastCellSupportComparator> > cmps;
+ std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > retCell=SplitPerCommonSupportNotNodesAlg(vectFMTSNotNodes,mesh,cmps);
+ ret=retCell;
+ for(std::vector<MEDFileAnyTypeFieldMultiTS *>::const_iterator it2=vectFMTSNodes.begin();it2!=vectFMTSNodes.end();it2++)
+ {
+ i=0;
+ bool isFetched(false);
+ for(std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> >::const_iterator it0=retCell.begin();it0!=retCell.end();it0++,i++)
+ {
+ if((*it0).empty())
+ throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport : internal error !");
+ if(cmps[i]->isCompatibleWithNodesDiscr(*it2))
+ { ret[i].push_back(*it2); isFetched=true; }
+ }
+ if(!isFetched)
+ {
+ std::vector<MEDFileAnyTypeFieldMultiTS *> tmp(1,*it2);
+ MCAuto<MEDFileMeshStruct> tmp2(MEDFileMeshStruct::New(mesh));
+ ret.push_back(tmp); retCell.push_back(tmp); cmps.push_back(MEDFileFastCellSupportComparator::New(tmp2,*it2));
+ }
+ }
+ fsc=cmps;
+ return ret;
+}
+
+/*!
+ * WARNING no check here. The caller must be sure that all items in vectFMTS are coherent each other in time steps, only one same spatial discretization and not ON_NODES.
+ * \param [out] cmps - same size than the returned vector.
+ */
+std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupportNotNodesAlg(const std::vector<MEDFileAnyTypeFieldMultiTS *>& vectFMTS, const MEDFileMesh *mesh, std::vector< MCAuto<MEDFileFastCellSupportComparator> >& cmps)
+{
+ std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > ret;
+ std::list<MEDFileAnyTypeFieldMultiTS *> lstFMTS(vectFMTS.begin(),vectFMTS.end());
+ while(!lstFMTS.empty())
+ {
+ std::list<MEDFileAnyTypeFieldMultiTS *>::iterator it(lstFMTS.begin());
+ MEDFileAnyTypeFieldMultiTS *ref(*it);
+ std::vector<MEDFileAnyTypeFieldMultiTS *> elt;
+ elt.push_back(ref); it=lstFMTS.erase(it);
+ MCAuto<MEDFileMeshStruct> mst(MEDFileMeshStruct::New(mesh));
+ MCAuto<MEDFileFastCellSupportComparator> cmp(MEDFileFastCellSupportComparator::New(mst,ref));
+ while(it!=lstFMTS.end())
+ {
+ MEDFileAnyTypeFieldMultiTS *curIt(*it);
+ if(cmp->isEqual(curIt))
+ { elt.push_back(curIt); it=lstFMTS.erase(it); }
+ else
+ it++;
+ }
+ ret.push_back(elt); cmps.push_back(cmp);
+ }
+ return ret;
+}
+
+/*!
+ * This method scan the two main structs along time of \a f0 and \a f1 to see if there are all lying on the same mesh along time than those in \a mesh.
+ * \a f0 and \a f1 must be defined each only on a same spatial discretization even if this can be different each other.
+ *
+ * \throw If \a f0 or \a f1 has not only one spatial discretization set.
+ * \throw If \a f0 or \a f1 change of spatial discretization along time.
+ * \throw If \a f0 or \a f1 on a mesh with meshname different from those in \a mesh.
+ * \thorw If \a f0 and \a f1 do not have the same times steps.
+ * \throw If mesh is null.
+ * \throw If \a f0 or \a f1 is null.
+ * \sa MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport
+ */
+int MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime(MEDFileAnyTypeFieldMultiTS *f0, MEDFileAnyTypeFieldMultiTS *f1, const MEDFileMesh *mesh, TypeOfField& tof0, TypeOfField& tof1)
+{
+ if(!mesh)
+ throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : input mesh is null !");
+ if(!f0 || !f1)
+ throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : presence of null instance in fields over time !");
+ if(f0->getMeshName()!=mesh->getName())
+ {
+ std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : first field points to mesh \""<< f0->getMeshName() << "\" and input mesh to compare has name \"" << mesh->getName() << "\" !";
+ throw INTERP_KERNEL::Exception(oss.str());
+ }
+ if(f1->getMeshName()!=mesh->getName())
+ {
+ std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : second field points to mesh \""<< f1->getMeshName() << "\" and input mesh to compare has name \"" << mesh->getName() << "\" !";
+ throw INTERP_KERNEL::Exception(oss.str());
+ }
+ int nts=f0->getNumberOfTS();
+ if(nts!=f1->getNumberOfTS())
+ throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : number of time steps are not the same !");
+ if(nts==0)
+ return nts;
+ for(int i=0;i<nts;i++)
+ {
+ MCAuto<MEDFileAnyTypeField1TS> f0cur=f0->getTimeStepAtPos(i);
+ MCAuto<MEDFileAnyTypeField1TS> f1cur=f1->getTimeStepAtPos(i);
+ std::vector<TypeOfField> tofs0(f0cur->getTypesOfFieldAvailable()),tofs1(f1cur->getTypesOfFieldAvailable());
+ if(tofs0.size()!=1 || tofs1.size()!=1)
+ throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : All time steps must be defined on only one spatial discretization !");
+ if(i!=0)
+ {
+ if(tof0!=tofs0[0] || tof1!=tofs1[0])
+ throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : Across times steps MEDFileAnyTypeFieldMultiTS instances have to keep the same unique spatial discretization !");
+ }
+ else
+ { tof0=tofs0[0]; tof1=tofs1[0]; }
+ if(f0cur->getMeshIteration()!=mesh->getIteration() || f0cur->getMeshOrder()!=mesh->getOrder())
+ {
+ std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : first field points to mesh time step (" << f0cur->getMeshIteration() << ","<< f0cur->getMeshOrder() << ") whereas input mesh points to time step (" << mesh->getIteration() << "," << mesh->getOrder() << ") !";
+ throw INTERP_KERNEL::Exception(oss.str());
+ }
+ if(f1cur->getMeshIteration()!=mesh->getIteration() || f1cur->getMeshOrder()!=mesh->getOrder())
+ {
+ std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : second field points to mesh time step (" << f1cur->getMeshIteration() << ","<< f1cur->getMeshOrder() << ") whereas input mesh points to time step (" << mesh->getIteration() << "," << mesh->getOrder() << ") !";
+ throw INTERP_KERNEL::Exception(oss.str());
+ }
+ if(f0cur->getIteration()!=f1cur->getIteration() || f0cur->getOrder()!=f1cur->getOrder())
+ {
+ std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : all the time steps must be the same ! it is not the case (" << f0cur->getIteration() << "," << f0cur->getOrder() << ")!=(" << f1cur->getIteration() << "," << f1cur->getOrder() << ") !";
+ throw INTERP_KERNEL::Exception(oss.str());
+ }
+ }
+ return nts;
+}
+
+/*!
+ * Return an extraction of \a this using \a extractDef map to specify the extraction.
+ * The keys of \a extractDef is level relative to max ext of \a mm mesh.
+ *
+ * \return A new object that the caller is responsible to deallocate.
+ */
+MEDFileAnyTypeFieldMultiTS *MEDFileAnyTypeFieldMultiTS::extractPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef, MEDFileMesh *mm) const
+{
+ if(!mm)
+ throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::extractPart : mesh is null !");
+ MCAuto<MEDFileAnyTypeFieldMultiTS> fmtsOut(buildNewEmpty());
+ int nbTS(getNumberOfTS());
+ for(int i=0;i<nbTS;i++)
+ {
+ MCAuto<MEDFileAnyTypeField1TS> f1ts(getTimeStepAtPos(i));
+ MCAuto<MEDFileAnyTypeField1TS> f1tsOut(f1ts->extractPart(extractDef,mm));
+ fmtsOut->pushBackTimeStep(f1tsOut);
+ }
+ return fmtsOut.retn();
+}
+
+template<class T>
+MCAuto<MEDFileAnyTypeField1TS> AggregateHelperF1TS(const std::vector< typename MLFieldTraits<T>::F1TSType const *>& f1tss, const std::vector< std::vector< std::pair<int,int> > >& dts)
+{
+ MCAuto< typename MLFieldTraits<T>::F1TSType > ret(MLFieldTraits<T>::F1TSType::New());
+ if(f1tss.empty())
+ throw INTERP_KERNEL::Exception("AggregateHelperF1TS : empty vector !");
+ std::size_t sz(f1tss.size()),i(0);
+ std::vector< typename MLFieldTraits<T>::F1TSWSDAType const *> f1tsw(sz);
+ for(typename std::vector< typename MLFieldTraits<T>::F1TSType const *>::const_iterator it=f1tss.begin();it!=f1tss.end();it++,i++)
+ {
+ typename MLFieldTraits<T>::F1TSType const *elt(*it);
+ if(!elt)
+ throw INTERP_KERNEL::Exception("AggregateHelperF1TS : presence of a null pointer !");
+ f1tsw[i]=dynamic_cast<typename MLFieldTraits<T>::F1TSWSDAType const *>(elt->contentNotNullBase());
+ }
+ typename MLFieldTraits<T>::F1TSWSDAType *retc(dynamic_cast<typename MLFieldTraits<T>::F1TSWSDAType *>(ret->contentNotNullBase()));
+ if(!retc)
+ throw INTERP_KERNEL::Exception("AggregateHelperF1TS : internal error 1 !");
+ retc->aggregate(f1tsw,dts);
+ ret->setDtUnit(f1tss[0]->getDtUnit());
+ return DynamicCast<typename MLFieldTraits<T>::F1TSType , MEDFileAnyTypeField1TS>(ret);
+}
+
+template<class T>
+MCAuto< MEDFileAnyTypeFieldMultiTS > AggregateHelperFMTS(const std::vector< typename MLFieldTraits<T>::FMTSType const *>& fmtss, const std::vector< std::vector< std::pair<int,int> > >& dts)
+{
+ MCAuto< typename MLFieldTraits<T>::FMTSType > ret(MLFieldTraits<T>::FMTSType::New());
+ if(fmtss.empty())
+ throw INTERP_KERNEL::Exception("AggregateHelperFMTS : empty vector !");
+ std::size_t sz(fmtss.size());
+ for(typename std::vector< typename MLFieldTraits<T>::FMTSType const *>::const_iterator it=fmtss.begin();it!=fmtss.end();it++)
+ {
+ typename MLFieldTraits<T>::FMTSType const *elt(*it);
+ if(!elt)
+ throw INTERP_KERNEL::Exception("AggregateHelperFMTS : presence of null pointer !");
+ }
+ int nbTS(fmtss[0]->getNumberOfTS());
+ for(typename std::vector< typename MLFieldTraits<T>::FMTSType const *>::const_iterator it=fmtss.begin();it!=fmtss.end();it++)
+ if((*it)->getNumberOfTS()!=nbTS)
+ throw INTERP_KERNEL::Exception("AggregateHelperFMTS : all fields must have the same number of TS !");
+ for(int iterTS=0;iterTS<nbTS;iterTS++)
+ {
+ std::size_t i(0);
+ std::vector< typename MLFieldTraits<T>::F1TSType const *> f1tss(sz);
+ std::vector< MCAuto<typename MLFieldTraits<T>::F1TSType> > f1tss2(sz);
+ for(typename std::vector< typename MLFieldTraits<T>::FMTSType const *>::const_iterator it=fmtss.begin();it!=fmtss.end();it++,i++)
+ { f1tss2[i]=(*it)->getTimeStepAtPos(iterTS); f1tss[i]=f1tss2[i]; }
+ MCAuto<MEDFileAnyTypeField1TS> f1ts(AggregateHelperF1TS<T>(f1tss,dts));
+ ret->pushBackTimeStep(f1ts);
+ ret->setDtUnit(f1ts->getDtUnit());
+ }
+ return DynamicCast<typename MLFieldTraits<T>::FMTSType , MEDFileAnyTypeFieldMultiTS>(ret);
+}
+
+/*!
+ * \a dts and \a ftmss are expected to have same size.
+ */
+MCAuto<MEDFileAnyTypeFieldMultiTS> MEDFileAnyTypeFieldMultiTS::Aggregate(const std::vector<const MEDFileAnyTypeFieldMultiTS *>& fmtss, const std::vector< std::vector< std::pair<int,int> > >& dts)
+{
+ if(fmtss.empty())
+ throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::Aggregate : input vector is empty !");
+ std::size_t sz(fmtss.size());
+ std::vector<const MEDFileFieldMultiTS *> fmtss1;
+ std::vector<const MEDFileIntFieldMultiTS *> fmtss2;
+ for(std::vector<const MEDFileAnyTypeFieldMultiTS *>::const_iterator it=fmtss.begin();it!=fmtss.end();it++)
+ {
+ if(!(*it))
+ throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::Aggregate : presence of null instance in input vector !");
+ const MEDFileFieldMultiTS *elt1(dynamic_cast<const MEDFileFieldMultiTS *>(*it));
+ if(elt1)
+ {
+ fmtss1.push_back(elt1);
+ continue;
+ }
+ const MEDFileIntFieldMultiTS *elt2(dynamic_cast<const MEDFileIntFieldMultiTS *>(*it));
+ if(elt2)
+ {
+ fmtss2.push_back(elt2);
+ continue;
+ }
+ throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::Aggregate : not recognized type !");
+ }
+ if(fmtss1.size()!=sz && fmtss2.size()!=sz)
+ throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::Aggregate : type of data is not homogeneous !");
+ if(fmtss1.size()==sz)
+ return AggregateHelperFMTS<double>(fmtss1,dts);
+ if(fmtss2.size()!=sz)
+ return AggregateHelperFMTS<int>(fmtss2,dts);
+ throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::Aggregate : not implemented yet !");
+}
+
+MEDFileAnyTypeFieldMultiTSIterator *MEDFileAnyTypeFieldMultiTS::iterator()