+ MCAuto<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
+ m->renumberCells(o2nCellsPart2->getConstPointer(),false);
+ ret=true;
+ MCAuto<DataArrayInt> famField2,numField2;
+ const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
+ const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
+ setMeshAtLevel(*it,m);
+ std::vector<int> code2=m->getDistributionOfTypes();
+ end=PutInThirdComponentOfCodeOffset(code2,start);
+ newCode.insert(newCode.end(),code2.begin(),code2.end());
+ //
+ if(o2nCellsPart2->isIota(o2nCellsPart2->getNumberOfTuples()))
+ continue;
+ if(famField)
+ {
+ MCAuto<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
+ setFamilyFieldArr(*it,newFamField);
+ }
+ if(numField)
+ {
+ MCAuto<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
+ setRenumFieldArr(*it,newNumField);
+ }
+ }
+ else
+ {
+ newCode.insert(newCode.end(),code1.begin(),code1.end());
+ }
+ start=end;
+ }
+ if(ret)
+ {
+ MCAuto<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
+ MCAuto<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
+ o2nRenumCell=o2nRenumCellRet.retn();
+ }
+ return ret;
+}
+
+/*! \cond HIDDEN_ITEMS */
+struct MEDLoaderAccVisit1
+{
+ MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
+ int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
+ int _new_nb_of_nodes;
+};
+/*! \endcond */
+
+/*!
+ * Array returned is the correspondance in \b old \b to \b new format. The returned array is newly created and should be dealt by the caller.
+ * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
+ * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
+ * -1 values in returned array means that the corresponding old node is no more used.
+ *
+ * \return newly allocated array containing correspondance in \b old \b to \b new format. If all nodes in \a this are fetched \c NULL pointer is returned and nothing
+ * is modified in \a this.
+ * \throw If no coordinates are set in \a this or if there is in any available mesh in \a this a cell having a nodal connectivity containing a node id not in the range of
+ * set coordinates.
+ */
+DataArrayInt *MEDFileUMesh::zipCoords()
+{
+ const DataArrayDouble *coo(getCoords());
+ if(!coo)
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
+ int nbOfNodes(coo->getNumberOfTuples());
+ std::vector<bool> nodeIdsInUse(nbOfNodes,false);
+ std::vector<int> neLevs(getNonEmptyLevels());
+ for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
+ {
+ const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
+ if(zeLev->isMeshStoredSplitByType())
+ {
+ std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
+ for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
+ if(*it)
+ (*it)->computeNodeIdsAlg(nodeIdsInUse);
+ }
+ else
+ {
+ MCAuto<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
+ mesh->computeNodeIdsAlg(nodeIdsInUse);
+ }
+ }
+ int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
+ if(nbrOfNodesInUse==nbOfNodes)
+ return 0;//no need to update _part_coords
+ MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1);
+ std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
+ MCAuto<DataArrayInt> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
+ MCAuto<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
+ MCAuto<DataArrayInt> newFamCoords;
+ MCAuto<DataArrayAsciiChar> newNameCoords;
+ if((const DataArrayInt *)_fam_coords)
+ newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
+ MCAuto<DataArrayInt> newNumCoords,newGlobalNumCoords;
+ if(_num_coords.isNotNull())
+ newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
+ if(_global_num_coords.isNotNull())
+ newGlobalNumCoords=_global_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
+ if(_name_coords.isNotNull())
+ newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
+ _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _global_num_coords=newGlobalNumCoords; _name_coords=newNameCoords; _rev_num_coords.nullify();
+ for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
+ {
+ if((MEDFileUMeshSplitL1*)*it)
+ {
+ (*it)->renumberNodesInConn(ret->begin());
+ (*it)->setCoords(_coords);
+ }
+ }
+ // updates _part_coords
+ const PartDefinition *pc(_part_coords);
+ if(pc)
+ {
+ MCAuto<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
+ _part_coords=tmpPD->composeWith(pc);
+ }
+ return ret.retn();
+}
+
+/*!
+ * This method is a const method. It computes the minimal set of node ids covered by the cell extraction of \a this.
+ * The extraction of \a this is specified by the extractDef \a input map.
+ * This map tells for each level of cells, the cells kept in the extraction.
+ *
+ * \return - a new reference of DataArrayInt that represents sorted node ids, the extraction is lying on.
+ * \sa MEDFileField1TS::extractPart, MEDFileUMesh::extractPart
+ */
+DataArrayInt *MEDFileUMesh::deduceNodeSubPartFromCellSubPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
+{
+ std::vector<int> levs(getNonEmptyLevels());
+ std::vector<bool> fetchedNodes(getNumberOfNodes(),false);
+ for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
+ {
+ if((*it).first>1)
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid key ! Must be <=1 !");
+ if((*it).second.isNull())
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : presence of a value with null pointer !");
+ if((*it).first==1)
+ continue;
+ if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
+ {
+ std::ostringstream oss; oss << "MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid level " << (*it).first << " ! Not present in this !";
+ throw INTERP_KERNEL::Exception(oss.str());
+ }
+ MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
+ MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
+ mPart->computeNodeIdsAlg(fetchedNodes);
+ }
+ return DataArrayInt::BuildListOfSwitchedOn(fetchedNodes);
+}
+
+/*!
+ * This method returns a new MEDFileUMesh that is the result of the extraction of cells/nodes in \a this.
+ *
+ * \return - a new reference of MEDFileUMesh
+ * \sa MEDFileUMesh::deduceNodeSubPartFromCellSubPart, MEDFileFields::extractPart
+ */
+MEDFileUMesh *MEDFileUMesh::extractPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
+{
+ MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New()); ret->setName(getName()); ret->copyFamGrpMapsFrom(*this);
+ std::vector<int> levs(getNonEmptyLevels());
+ for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
+ {
+ if((*it).first>1)
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : invalid key ! Must be <=1 !");
+ if((*it).second.isNull())
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : presence of a value with null pointer !");
+ if((*it).first==1)
+ continue;
+ if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
+ {
+ std::ostringstream oss; oss << "MEDFileUMesh::extractPart : invalid level " << (*it).first << " ! Not present in this !";
+ throw INTERP_KERNEL::Exception(oss.str());
+ }
+ MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
+ MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
+ ret->setMeshAtLevel((*it).first,mPart);
+ const DataArrayInt *fam(getFamilyFieldAtLevel((*it).first)),*num(getNumberFieldAtLevel((*it).first));
+ if(fam)
+ {
+ MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
+ ret->setFamilyFieldArr((*it).first,famPart);
+ }
+ if(num)
+ {
+ MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
+ ret->setFamilyFieldArr((*it).first,numPart);
+ }
+ }
+ std::map<int, MCAuto<DataArrayInt> >::const_iterator it2(extractDef.find(1));
+ if(it2!=extractDef.end())
+ {
+ const DataArrayDouble *coo(ret->getCoords());
+ if(!coo)
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : trying to extract nodes whereas there is no nodes !");
+ MCAuto<DataArrayInt> o2nNodes(((*it2).second)->invertArrayN2O2O2N(coo->getNumberOfTuples()));
+ MCAuto<DataArrayDouble> cooPart(coo->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
+ ret->setCoords(cooPart);
+ const DataArrayInt *fam(getFamilyFieldAtLevel(1)),*num(getNumberFieldAtLevel(1));
+ if(fam)
+ {
+ MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
+ ret->setFamilyFieldArr(1,famPart);
+ }
+ if(num)
+ {
+ MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
+ ret->setFamilyFieldArr(1,numPart);
+ }
+ for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it3=extractDef.begin();it3!=extractDef.end();it3++)
+ {
+ if((*it3).first==1)
+ continue;
+ MCAuto<MEDCouplingUMesh> m(ret->getMeshAtLevel((*it3).first));
+ m->renumberNodesInConn(o2nNodes->begin());
+ ret->setMeshAtLevel((*it3).first,m);
+ }
+ }
+ return ret.retn();
+}
+
+/*!
+ * This method performs an extrusion along a path defined by \a m1D.
+ * \a this is expected to be a mesh with max mesh dimension equal to 2.
+ * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1.
+ * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this.
+ * This method scans all levels in \a this
+ * and put them in the returned mesh. All groups in \a this are also put in the returned mesh.
+ *
+ * \param [in] m1D - the mesh defining the extrusion path.
+ * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details)
+ * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this.
+ *
+ * \sa MEDCouplingUMesh::buildExtrudedMesh
+ */
+MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
+{
+ checkCartesian();
+ if(getMeshDimension()!=2)
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
+ MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
+ m1D->checkConsistencyLight();
+ if(m1D->getMeshDimension()!=1)
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
+ int nbRep(m1D->getNumberOfCells());
+ std::vector<int> levs(getNonEmptyLevels());
+ std::vector<std::string> grps(getGroupsNames());
+ std::vector< MCAuto<MEDCouplingUMesh> > zeList;
+ DataArrayDouble *coords(0);
+ std::size_t nbOfLevsOut(levs.size()+1);
+ std::vector< MCAuto<DataArrayInt> > o2ns(nbOfLevsOut);
+ for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
+ {
+ MCAuto<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
+ item=item->clone(false);
+ item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
+ MCAuto<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCopy()));
+ tmp->changeSpaceDimension(3+(*lev),0.);
+ MCAuto<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
+ zeList.push_back(elt);
+ if(*lev==0)
+ coords=elt->getCoords();
+ }
+ if(!coords)
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
+ for(std::vector< MCAuto<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
+ {
+ (*it)->setName(getName());
+ (*it)->setCoords(coords);
+ }
+ for(std::size_t ii=0;ii!=zeList.size();ii++)
+ {
+ int lev(levs[ii]);
+ MCAuto<MEDCouplingUMesh> elt(zeList[ii]);
+ if(lev<=-1)
+ {
+ MCAuto<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
+ MCAuto<MEDCouplingUMesh> elt2(elt1->clone(false));
+ MCAuto<DataArrayInt> tmp(elt2->getNodalConnectivity()->deepCopy());
+ elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
+ elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
+ elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
+ std::vector<const MEDCouplingUMesh *> elts(3);
+ elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
+ elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
+ elt->setName(getName());
+ }
+ //
+ o2ns[ii]=elt->sortCellsInMEDFileFrmt();
+ ret->setMeshAtLevel(lev,elt);
+ }
+ MCAuto<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
+ endLev=endLev->clone(false); endLev->setCoords(coords);
+ MCAuto<DataArrayInt> tmp(endLev->getNodalConnectivity()->deepCopy());
+ endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
+ endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
+ endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
+ o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
+ endLev->setName(getName());
+ ret->setMeshAtLevel(levs.back()-1,endLev);
+ //
+ for(std::size_t ii=0;ii!=zeList.size();ii++)
+ {
+ int lev(levs[ii]);
+ std::vector< MCAuto<DataArrayInt> > outGrps;
+ std::vector< const DataArrayInt * > outGrps2;
+ if(lev<=-1)
+ {
+ for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
+ {
+ MCAuto<DataArrayInt> grpArr(getGroupArr(lev+1,*grp));
+ if(!grpArr->empty())
+ {
+ MCAuto<DataArrayInt> grpArr1(grpArr->deepCopy()),grpArr2(grpArr->deepCopy());
+ int offset0(zeList[ii]->getNumberOfCells());
+ int offset1(offset0+getNumberOfCellsAtLevel(lev+1));
+ grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
+ std::ostringstream oss; oss << grpArr2->getName() << "_top";
+ grpArr2->setName(oss.str());
+ grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
+ grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
+ outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
+ outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
+ }
+ }
+ }
+ //
+ for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
+ {
+ MCAuto<DataArrayInt> grpArr(getGroupArr(lev,*grp));
+ if(!grpArr->empty())
+ {
+ int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
+ std::vector< MCAuto<DataArrayInt> > grpArrs(nbRep);
+ std::vector< const DataArrayInt *> grpArrs2(nbRep);
+ for(int iii=0;iii<nbRep;iii++)
+ {
+ grpArrs[iii]=grpArr->deepCopy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
+ grpArrs2[iii]=grpArrs[iii];
+ }
+ MCAuto<DataArrayInt> grpArrExt(DataArrayInt::Aggregate(grpArrs2));
+ grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
+ std::ostringstream grpName; grpName << *grp << "_extruded";
+ grpArrExt->setName(grpName.str());
+ outGrps.push_back(grpArrExt);
+ outGrps2.push_back(grpArrExt);
+ }
+ }
+ ret->setGroupsAtLevel(lev,outGrps2);
+ }
+ std::vector< MCAuto<DataArrayInt> > outGrps;
+ std::vector< const DataArrayInt * > outGrps2;
+ for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
+ {
+ MCAuto<DataArrayInt> grpArr1(getGroupArr(levs.back(),*grp));
+ if(grpArr1->empty())
+ continue;
+ MCAuto<DataArrayInt> grpArr2(grpArr1->deepCopy());
+ std::ostringstream grpName; grpName << *grp << "_top";
+ grpArr2->setName(grpName.str());
+ grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
+ outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
+ outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
+ }
+ ret->setGroupsAtLevel(levs.back()-1,outGrps2);
+ return ret.retn();
+}
+
+/*!
+ * 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();
+ MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
+ int initialNbNodes(getNumberOfNodes());
+ MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
+ MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
+ {
+ MCAuto<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)
+ {
+ MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
+ ret->setFamilyFieldArr(0,famFieldCpy);
+ }
+ famField=getFamilyFieldAtLevel(1);
+ if(famField)
+ {
+ MCAuto<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);
+ MCAuto<DataArrayDouble> partZeCoords(zeCoords->selectByTupleIdSafeSlice(initialNbNodes,zeCoords->getNumberOfTuples(),1));
+ for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
+ {
+ if(*lev==0)
+ continue;
+ MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
+ MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
+ if(m1->getMeshDimension()!=0)
+ {
+ {
+ MCAuto<DataArrayInt> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
+ }//kill unused notUsed var
+ MCAuto<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleIdSafeSlice(initialNbNodes,m1->getNumberOfNodes(),1));
+ DataArrayInt *b(0);
+ bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
+ MCAuto<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);
+ MCAuto<DataArrayInt> l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota();
+ std::vector<const DataArrayInt *> v(2); v[0]=l0; v[1]=b;
+ MCAuto<DataArrayInt> renum(DataArrayInt::Aggregate(v));
+ m1->renumberNodesInConn(renum->begin());
+ }
+ m1->setCoords(zeCoords);
+ ret->setMeshAtLevel(*lev,m1);
+ famField=getFamilyFieldAtLevel(*lev);
+ if(famField)
+ {
+ MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
+ 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();
+ MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
+ MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
+ MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
+ m0->convertQuadraticCellsToLinear();
+ m0->zipCoords();
+ DataArrayDouble *zeCoords(m0->getCoords());
+ ret->setMeshAtLevel(0,m0);
+ std::vector<int> levs(getNonEmptyLevels());
+ const DataArrayInt *famField(getFamilyFieldAtLevel(0));
+ if(famField)
+ {
+ MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
+ ret->setFamilyFieldArr(0,famFieldCpy);
+ }
+ famField=getFamilyFieldAtLevel(1);
+ if(famField)
+ {
+ MCAuto<DataArrayInt> fam(famField->selectByTupleIdSafeSlice(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;
+ MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
+ MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
+ m1->convertQuadraticCellsToLinear();
+ m1->zipCoords();
+ DataArrayInt *b(0);
+ bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
+ MCAuto<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)
+ {
+ MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
+ ret->setFamilyFieldArr(*lev,famFieldCpy);
+ }
+ }
+ return ret.retn();
+}
+
+/*!
+ * Computes the symmetry of \a this.
+ * \return a new object.
+ */
+MCAuto<MEDFileUMesh> MEDFileUMesh::symmetry3DPlane(const double point[3], const double normalVector[3]) const
+{
+ MCAuto<MEDFileUMesh> ret(deepCopy());
+ DataArrayDouble *myCoo(getCoords());
+ if(myCoo)
+ {
+ MCAuto<DataArrayDouble> newCoo(myCoo->symmetry3DPlane(point,normalVector));
+ ret->setCoordsForced(newCoo);
+ }
+ return ret;
+}
+
+MCAuto<MEDFileUMesh> MEDFileUMesh::Aggregate(const std::vector<const MEDFileUMesh *>& meshes)
+{
+ if(meshes.empty())
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : empty input vector !");
+ std::size_t sz(meshes.size()),i(0);
+ std::vector<const DataArrayDouble *> coos(sz);
+ std::vector<const DataArrayInt *> fam_coos(sz),num_coos(sz);
+ for(std::vector<const MEDFileUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,i++)
+ {
+ if(!(*it))
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : presence of NULL pointer in input vector !");
+ coos[i]=(*it)->getCoords();
+ fam_coos[i]=(*it)->getFamilyFieldAtLevel(1);
+ num_coos[i]=(*it)->getNumberFieldAtLevel(1);
+ }
+ const MEDFileUMesh *ref(meshes[0]);
+ int spaceDim(ref->getSpaceDimension()),meshDim(ref->getMeshDimension());
+ std::vector<int> levs(ref->getNonEmptyLevels());
+ std::map<int, std::vector<const DataArrayInt *> > m_fam,m_renum;
+ std::map<int, std::vector< MCAuto< MEDCouplingUMesh > > > m_mesh2;
+ std::map<int, std::vector<const MEDCouplingUMesh *> > m_mesh;
+ std::map<std::string,int> map1;
+ std::map<std::string, std::vector<std::string> > map2;
+ for(std::vector<const MEDFileUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,i++)
+ {
+ if((*it)->getSpaceDimension()!=spaceDim)
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : space dimension must be homogeneous !");
+ if((*it)->getMeshDimension()!=meshDim)
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : mesh dimension must be homogeneous !");
+ if((*it)->getNonEmptyLevels()!=levs)
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : levels must be the same for elements in input vector !");
+ for(std::vector<int>::const_iterator it2=levs.begin();it2!=levs.end();it2++)
+ {
+ MCAuto<MEDCouplingUMesh> locMesh((*it)->getMeshAtLevel(*it2));
+ m_mesh[*it2].push_back(locMesh); m_mesh2[*it2].push_back(locMesh);
+ m_fam[*it2].push_back((*it)->getFamilyFieldAtLevel(*it2));
+ m_renum[*it2].push_back((*it)->getNumberFieldAtLevel(*it2));
+ }
+ const std::map<std::string,int>& locMap1((*it)->getFamilyInfo());
+ for(std::map<std::string,int>::const_iterator it3=locMap1.begin();it3!=locMap1.end();it3++)
+ map1[(*it3).first]=(*it3).second;
+ const std::map<std::string, std::vector<std::string> >& locMap2((*it)->getGroupInfo());
+ for(std::map<std::string, std::vector<std::string> >::const_iterator it4=locMap2.begin();it4!=locMap2.end();it4++)
+ map2[(*it4).first]=(*it4).second;
+ }
+ // Easy part : nodes
+ MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
+ MCAuto<DataArrayDouble> coo(DataArrayDouble::Aggregate(coos));
+ ret->setCoords(coo);
+ if(std::find(fam_coos.begin(),fam_coos.end(),(const DataArrayInt *)0)==fam_coos.end())
+ {
+ MCAuto<DataArrayInt> fam_coo(DataArrayInt::Aggregate(fam_coos));
+ ret->setFamilyFieldArr(1,fam_coo);
+ }
+ if(std::find(num_coos.begin(),num_coos.end(),(const DataArrayInt *)0)==num_coos.end())
+ {
+ MCAuto<DataArrayInt> num_coo(DataArrayInt::Aggregate(num_coos));
+ ret->setRenumFieldArr(1,num_coo);
+ }
+ // cells
+ for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
+ {
+ std::map<int, std::vector<const MEDCouplingUMesh *> >::const_iterator it2(m_mesh.find(*it));
+ if(it2==m_mesh.end())
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 1 !");
+ MCAuto<MEDCouplingUMesh> mesh(MEDCouplingUMesh::MergeUMeshes((*it2).second));
+ mesh->setCoords(coo); mesh->setName(ref->getName());
+ MCAuto<DataArrayInt> renum(mesh->sortCellsInMEDFileFrmt());
+ ret->setMeshAtLevel(*it,mesh);
+ std::map<int, std::vector<const DataArrayInt *> >::const_iterator it3(m_fam.find(*it)),it4(m_renum.find(*it));
+ if(it3!=m_fam.end())
+ {
+ const std::vector<const DataArrayInt *>& fams((*it3).second);
+ if(std::find(fams.begin(),fams.end(),(const DataArrayInt *)0)==fams.end())