+/*!
+ * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy).
+ * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
+ * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
+ *
+ * \param [in] conversionType - conversionType specifies the type of conversion expected. Only 0 (default) and 1 are supported presently. 0 those that creates the 'most' simple
+ * corresponding quadratic cells. 1 is those creating the 'most' complex.
+ * \param [in] eps - detection threshold for coordinates.
+ * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
+ *
+ * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear
+ */
+MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
+{
+ checkCartesian();
+ MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
+ int initialNbNodes(getNumberOfNodes());
+ MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
+ MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCpy()));
+ {
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
+ }
+ DataArrayDouble *zeCoords(m0->getCoords());
+ ret->setMeshAtLevel(0,m0);
+ std::vector<int> levs(getNonEmptyLevels());
+ const DataArrayInt *famField(getFamilyFieldAtLevel(0));
+ if(famField)
+ {
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
+ ret->setFamilyFieldArr(0,famFieldCpy);
+ }
+ famField=getFamilyFieldAtLevel(1);
+ if(famField)
+ {
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
+ fam->fillWithZero();
+ fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
+ ret->setFamilyFieldArr(1,fam);
+ }
+ ret->copyFamGrpMapsFrom(*this);
+ MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> partZeCoords(zeCoords->selectByTupleId2(initialNbNodes,zeCoords->getNumberOfTuples(),1));
+ for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
+ {
+ if(*lev==0)
+ continue;
+ MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
+ MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCpy()));
+ if(m1->getMeshDimension()!=0)
+ {
+ {
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
+ }//kill unused notUsed var
+ MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleId2(initialNbNodes,m1->getNumberOfNodes(),1));
+ DataArrayInt *b(0);
+ bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> bSafe(b);
+ if(!a)
+ {
+ std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ b->applyLin(1,initialNbNodes);
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota();
+ std::vector<const DataArrayInt *> v(2); v[0]=l0; v[1]=b;
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renum(DataArrayInt::Aggregate(v));
+ m1->renumberNodesInConn(renum->begin());
+ }
+ m1->setCoords(zeCoords);
+ ret->setMeshAtLevel(*lev,m1);
+ famField=getFamilyFieldAtLevel(*lev);
+ if(famField)
+ {
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
+ ret->setFamilyFieldArr(*lev,famFieldCpy);
+ }
+ }
+ return ret.retn();
+}
+
+/*!
+ * This method converts all quadratic cells in \a this into linear cells.
+ * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
+ * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
+ *
+ * \param [in] eps - detection threshold for coordinates.
+ * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
+ *
+ * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic
+ */
+MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
+{
+ checkCartesian();
+ MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
+ MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
+ MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCpy()));
+ m0->convertQuadraticCellsToLinear();
+ m0->zipCoords();
+ DataArrayDouble *zeCoords(m0->getCoords());
+ ret->setMeshAtLevel(0,m0);
+ std::vector<int> levs(getNonEmptyLevels());
+ const DataArrayInt *famField(getFamilyFieldAtLevel(0));
+ if(famField)
+ {
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
+ ret->setFamilyFieldArr(0,famFieldCpy);
+ }
+ famField=getFamilyFieldAtLevel(1);
+ if(famField)
+ {
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam(famField->selectByTupleId2(0,zeCoords->getNumberOfTuples(),1));
+ ret->setFamilyFieldArr(1,fam);
+ }
+ ret->copyFamGrpMapsFrom(*this);
+ for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
+ {
+ if(*lev==0)
+ continue;
+ MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
+ MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCpy()));
+ m1->convertQuadraticCellsToLinear();
+ m1->zipCoords();
+ DataArrayInt *b(0);
+ bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> bSafe(b);
+ if(!a)
+ {
+ std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ m1->renumberNodesInConn(b->begin());
+ m1->setCoords(zeCoords);
+ ret->setMeshAtLevel(*lev,m1);
+ famField=getFamilyFieldAtLevel(*lev);
+ if(famField)
+ {
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
+ ret->setFamilyFieldArr(*lev,famFieldCpy);
+ }
+ }
+ return ret.retn();
+}
+
+void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD)
+{
+ clearNonDiscrAttributes();
+ forceComputationOfParts();
+ tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
+ std::vector<int> layer0;
+ layer0.push_back(getAxType());//0 i
+ layer0.push_back(_order); //1 i
+ layer0.push_back(_iteration);//2 i
+ layer0.push_back(getSpaceDimension());//3 i
+ tinyDouble.push_back(_time);//0 d
+ tinyStr.push_back(_name);//0 s
+ tinyStr.push_back(_desc_name);//1 s
+ for(int i=0;i<getSpaceDimension();i++)
+ tinyStr.push_back(_coords->getInfoOnComponent(i));
+ layer0.push_back((int)_families.size());//4 i <- key info aa layer#0
+ for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
+ {
+ tinyStr.push_back((*it).first);
+ layer0.push_back((*it).second);
+ }
+ layer0.push_back((int)_groups.size());//4+aa i <- key info bb layer#0
+ for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
+ {
+ layer0.push_back((int)(*it0).second.size());
+ tinyStr.push_back((*it0).first);
+ for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
+ tinyStr.push_back(*it1);
+ }
+ // sizeof(layer0)==4+aa+1+bb layer#0
+ bigArrayD=_coords;// 0 bd
+ bigArraysI.push_back(_fam_coords);// 0 bi
+ bigArraysI.push_back(_num_coords);// 1 bi
+ const PartDefinition *pd(_part_coords);
+ if(!pd)
+ layer0.push_back(-1);
+ else
+ {
+ std::vector<int> tmp0;
+ pd->serialize(tmp0,bigArraysI);
+ tinyInt.push_back(tmp0.size());
+ tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
+ }
+ //
+ std::vector<int> layer1;
+ std::vector<int> levs(getNonEmptyLevels());
+ layer1.push_back((int)levs.size());// 0 i <- key
+ layer1.insert(layer1.end(),levs.begin(),levs.end());
+ for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
+ {
+ const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
+ lev->serialize(layer1,bigArraysI);
+ }
+ // put layers all together.
+ tinyInt.push_back(layer0.size());
+ tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
+ tinyInt.push_back(layer1.size());
+ tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
+}
+
+void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr,
+ std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD)
+{
+ int sz0(tinyInt[0]);
+ std::vector<int> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
+ int sz1(tinyInt[sz0+1]);
+ std::vector<int> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
+ //
+ std::reverse(layer0.begin(),layer0.end());
+ std::reverse(layer1.begin(),layer1.end());
+ std::reverse(tinyDouble.begin(),tinyDouble.end());
+ std::reverse(tinyStr.begin(),tinyStr.end());
+ std::reverse(bigArraysI.begin(),bigArraysI.end());
+ //
+ setAxType((MEDCouplingAxisType)layer0.back()); layer0.pop_back();
+ _order=layer0.back(); layer0.pop_back();
+ _iteration=layer0.back(); layer0.pop_back();
+ int spaceDim(layer0.back()); layer0.pop_back();
+ _time=tinyDouble.back(); tinyDouble.pop_back();
+ _name=tinyStr.back(); tinyStr.pop_back();
+ _desc_name=tinyStr.back(); tinyStr.pop_back();
+ _coords=bigArrayD; _coords->rearrange(spaceDim);
+ for(int i=0;i<spaceDim;i++)
+ {
+ _coords->setInfoOnComponent(i,tinyStr.back());
+ tinyStr.pop_back();
+ }
+ int nbOfFams(layer0.back()); layer0.pop_back();
+ _families.clear();
+ for(int i=0;i<nbOfFams;i++)
+ {
+ _families[tinyStr.back()]=layer0.back();
+ tinyStr.pop_back(); layer0.pop_back();
+ }
+ int nbGroups(layer0.back()); layer0.pop_back();
+ _groups.clear();
+ for(int i=0;i<nbGroups;i++)
+ {
+ std::string grpName(tinyStr.back()); tinyStr.pop_back();
+ int nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
+ std::vector<std::string> fams(nbOfFamsOnGrp);
+ for(int j=0;j<nbOfFamsOnGrp;j++)
+ {
+ fams[j]=tinyStr.back(); tinyStr.pop_back();
+ }
+ _groups[grpName]=fams;
+ }
+ _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
+ _num_coords=bigArraysI.back(); bigArraysI.pop_back();
+ _part_coords=0;
+ int isPd(layer0.back()); layer0.pop_back();
+ if(isPd!=-1)
+ {
+ std::vector<int> tmp0(layer0.begin(),layer0.begin()+isPd);
+ layer0.erase(layer0.begin(),layer0.begin()+isPd);
+ _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
+ }
+ if(!layer0.empty())
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
+ //
+ int nbLevs(layer1.back()); layer1.pop_back();
+ std::vector<int> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
+ _ms.clear();
+ int maxLev(-(*std::min_element(levs.begin(),levs.end())));
+ _ms.resize(maxLev+1);
+ for(int i=0;i<nbLevs;i++)
+ {
+ int lev(levs[i]);
+ int pos(-lev);
+ _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
+ }
+}
+