1 // Copyright (C) 2007-2023 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (EDF R&D)
21 #include "MEDCoupling1GTUMesh.txx"
22 #include "MEDCouplingUMesh.hxx"
23 #include "MEDCouplingFieldDouble.hxx"
24 #include "MEDCouplingCMesh.hxx"
26 #include "SplitterTetra.hxx"
27 #include "DiameterCalculator.hxx"
28 #include "OrientationInverter.hxx"
29 #include "InterpKernelAutoPtr.hxx"
30 #include "VolSurfUser.txx"
32 using namespace MEDCoupling;
34 const int MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[6]={0,1,2,4,3,5};
36 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh():_cm(0)
40 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):_cm(&cm)
45 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const MEDCoupling1GTUMesh& other, bool recDeepCpy):MEDCouplingPointSet(other,recDeepCpy),_cm(other._cm)
49 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
51 if(type==INTERP_KERNEL::NORM_ERROR)
52 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
53 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
55 return MEDCoupling1SGTUMesh::New(name,type);
57 return MEDCoupling1DGTUMesh::New(name,type);
60 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const MEDCouplingUMesh *m)
63 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh is null !");
64 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
66 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh must have exactly one geometric type !");
67 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*gts.begin());
69 return MEDCoupling1SGTUMesh::New(m);
71 return MEDCoupling1DGTUMesh::New(m);
74 const INTERP_KERNEL::CellModel& MEDCoupling1GTUMesh::getCellModel() const
79 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getCellModelEnum() const
81 return _cm->getEnum();
84 int MEDCoupling1GTUMesh::getMeshDimension() const
86 return (int)_cm->getDimension();
90 * This method returns a newly allocated array containing cell ids (ascendingly sorted) whose geometric type are equal to type.
91 * This method does not throw exception if geometric type \a type is not in \a this.
92 * This method throws an INTERP_KERNEL::Exception if meshdimension of \b this is not equal to those of \b type.
93 * The coordinates array is not considered here.
95 * \param [in] type the geometric type
96 * \return cell ids in this having geometric type \a type.
98 DataArrayIdType *MEDCoupling1GTUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
100 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
101 if(type==getCellModelEnum())
102 ret->alloc(getNumberOfCells(),1);
110 * Returns nb of cells having the geometric type \a type. No throw if no cells in \a this has the geometric type \a type.
112 mcIdType MEDCoupling1GTUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
114 return type==getCellModelEnum()?getNumberOfCells():0;
118 * Returns a type of a cell by its id.
119 * \param [in] cellId - the id of the cell of interest.
120 * \return INTERP_KERNEL::NormalizedCellType - enumeration item describing the cell type.
121 * \throw If \a cellId is invalid. Valid range is [0, \a this->getNumberOfCells() ).
123 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getTypeOfCell(mcIdType cellId) const
125 if(cellId<getNumberOfCells())
126 return getCellModelEnum();
127 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::getTypeOfCell : Requesting type of cell #" << cellId << " but it should be in [0," << getNumberOfCells() << ") !";
128 throw INTERP_KERNEL::Exception(oss.str().c_str());
132 * Returns a set of all cell types available in \a this mesh.
133 * \return std::set<INTERP_KERNEL::NormalizedCellType> - the set of cell types.
134 * \warning this method does not throw any exception even if \a this is not defined.
136 std::set<INTERP_KERNEL::NormalizedCellType> MEDCoupling1GTUMesh::getAllGeoTypes() const
138 std::set<INTERP_KERNEL::NormalizedCellType> ret;
139 ret.insert(getCellModelEnum());
144 * This method expects that \a this is sorted by types. If not an exception will be thrown.
145 * This method returns in the same format as code (see MEDCouplingUMesh::checkTypeConsistencyAndContig or MEDCouplingUMesh::splitProfilePerType) how
146 * \a this is composed in cell types.
147 * The returned array is of size 3*n where n is the number of different types present in \a this.
148 * For every k in [0,n] ret[3*k+2]==-1 because it has no sense here.
149 * This parameter is kept only for compatibility with other method listed above.
151 std::vector<mcIdType> MEDCoupling1GTUMesh::getDistributionOfTypes() const
153 std::vector<mcIdType> ret(3);
154 ret[0]=ToIdType(getCellModelEnum()); ret[1]=getNumberOfCells(); ret[2]=-1;
159 * This method is the opposite of MEDCouplingUMesh::checkTypeConsistencyAndContig method. Given a list of cells in \a profile it returns a list of sub-profiles sorted by geo type.
160 * The result is put in the array \a idsPerType. In the returned parameter \a code, foreach i \a code[3*i+2] refers (if different from -1) to a location into the \a idsPerType.
161 * This method has 1 input \a profile and 3 outputs \a code \a idsInPflPerType and \a idsPerType.
163 * \param [out] code is a vector of size 3*n where n is the number of different geometric type in \a this \b reduced to the profile \a profile. \a code has exactly the same semantic than in MEDCouplingUMesh::checkTypeConsistencyAndContig method.
164 * \param [out] idsInPflPerType is a vector of size of different geometric type in the subpart defined by \a profile of \a this ( equal to \a code.size()/3). For each i,
165 * \a idsInPflPerType[i] stores the tuple ids in \a profile that correspond to the geometric type code[3*i+0]
166 * \param [out] idsPerType is a vector of size of different sub profiles needed to be defined to represent the profile \a profile for a given geometric type.
167 * This vector can be empty in case of all geometric type cells are fully covered in ascending in the given input \a profile.
169 * \warning for performance reasons no deep copy will be performed, if \a profile can been used as this in output parameters \a idsInPflPerType and \a idsPerType.
171 * \throw if \a profile has not exactly one component. It throws too, if \a profile contains some values not in [0,getNumberOfCells()) or if \a this is not fully defined
174 * - Before \a this has 3 cells \a profile contains [0,1,2]
175 * - After \a code contains [NORM_...,nbCells,-1], \a idsInPflPerType [[0,1,2]] and \a idsPerType is empty <br>
178 * - Before \a this has 3 cells \a profile contains [1,2]
179 * - After \a code contains [NORM_...,nbCells,0], \a idsInPflPerType [[0,1]] and \a idsPerType is [[1,2]] <br>
182 void MEDCoupling1GTUMesh::splitProfilePerType(const DataArrayIdType *profile, std::vector<mcIdType>& code, std::vector<DataArrayIdType *>& idsInPflPerType, std::vector<DataArrayIdType *>& idsPerType, bool smartPflKiller) const
185 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile is NULL !");
186 if(profile->getNumberOfComponents()!=1)
187 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile should have exactly one component !");
188 mcIdType nbTuples=profile->getNumberOfTuples(),nbOfCells=getNumberOfCells();
189 code.resize(3); idsInPflPerType.resize(1);
190 code[0]=ToIdType(getCellModelEnum()); code[1]=nbTuples;
191 idsInPflPerType.resize(1);
192 if(smartPflKiller && profile->isIota(nbOfCells))
195 idsInPflPerType[0]=const_cast<DataArrayIdType *>(profile); idsInPflPerType[0]->incrRef();
200 profile->checkAllIdsInRange(0,nbOfCells);
201 idsPerType.resize(1);
202 idsPerType[0]=const_cast<DataArrayIdType *>(profile); idsPerType[0]->incrRef();
203 idsInPflPerType[0]=DataArrayIdType::Range(0,nbTuples,1);
207 * This method tries to minimize at most the number of deep copy.
208 * So if \a idsPerType is not empty it can be returned directly (without copy, but with ref count incremented) in return.
210 * \sa MEDCouplingUMesh::checkTypeConsistencyAndContig
212 DataArrayIdType *MEDCoupling1GTUMesh::checkTypeConsistencyAndContig(const std::vector<mcIdType>& code, const std::vector<const DataArrayIdType *>& idsPerType) const
214 mcIdType nbOfCells=getNumberOfCells();
216 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : invalid input code should be exactly of size 3 !");
217 if(code[0]!=ToIdType(getCellModelEnum()))
219 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : Mismatch of geometric type ! Asking for " << code[0] << " whereas the geometric type is \a this is " << getCellModelEnum() << " (" << _cm->getRepr() << ") !";
220 throw INTERP_KERNEL::Exception(oss.str().c_str());
224 if(code[1]==nbOfCells)
228 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : mismatch between the number of cells in this (" << nbOfCells << ") and the number of non profile (" << code[1] << ") !";
229 throw INTERP_KERNEL::Exception(oss.str().c_str());
233 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : single geo type mesh ! 0 or -1 is expected at pos #2 of input code !");
234 if(idsPerType.size()!=1)
235 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input code points to DataArrayIdType #0 whereas the size of idsPerType is not equal to 1 !");
236 const DataArrayIdType *pfl=idsPerType[0];
238 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : the input code points to a NULL DataArrayIdType at rank 0 !");
239 if(pfl->getNumberOfComponents()!=1)
240 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input profile should have exactly one component !");
241 pfl->checkAllIdsInRange(0,nbOfCells);
243 return const_cast<DataArrayIdType *>(pfl);
246 void MEDCoupling1GTUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const
248 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
249 m->writeVTKLL(ofs,cellData,pointData,byteData);
252 std::string MEDCoupling1GTUMesh::getVTKDataSetType() const
254 return std::string("UnstructuredGrid");
257 std::string MEDCoupling1GTUMesh::getVTKFileExtension() const
259 return std::string("vtu");
262 std::size_t MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren() const
264 return MEDCouplingPointSet::getHeapMemorySizeWithoutChildren();
267 bool MEDCoupling1GTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
269 if(!MEDCouplingPointSet::isEqualIfNotWhy(other,prec,reason))
272 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualIfNotWhy : input other pointer is null !");
273 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
276 reason="mesh given in input is not castable in MEDCouplingSGTUMesh !";
281 reason="mismatch in geometric type !";
287 bool MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
289 if(!MEDCouplingPointSet::isEqualWithoutConsideringStr(other,prec))
292 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
293 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
301 void MEDCoupling1GTUMesh::checkConsistencyLight() const
303 MEDCouplingPointSet::checkConsistencyLight();
306 DataArrayDouble *MEDCoupling1GTUMesh::computeCellCenterOfMass() const
308 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
309 MCAuto<DataArrayDouble> ret=m->computeCellCenterOfMass();
313 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureField(bool isAbs) const
315 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
316 MCAuto<MEDCouplingFieldDouble> ret=m->getMeasureField(isAbs);
321 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureFieldOnNode(bool isAbs) const
323 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
324 MCAuto<MEDCouplingFieldDouble> ret=m->getMeasureFieldOnNode(isAbs);
332 mcIdType MEDCoupling1GTUMesh::getCellContainingPoint(const double *pos, double eps) const
334 MCAuto<MEDCouplingUMesh> m(buildUnstructured());
335 return m->getCellContainingPoint(pos,eps);
341 void MEDCoupling1GTUMesh::getCellsContainingPoint(const double *pos, double eps, std::vector<mcIdType>& elts) const
343 MCAuto<MEDCouplingUMesh> m(buildUnstructured());
344 return m->getCellsContainingPoint(pos,eps,elts);
347 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::buildOrthogonalField() const
349 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
350 MCAuto<MEDCouplingFieldDouble> ret=m->buildOrthogonalField();
355 DataArrayIdType *MEDCoupling1GTUMesh::getCellsInBoundingBox(const double *bbox, double eps) const
357 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
358 return m->getCellsInBoundingBox(bbox,eps);
361 DataArrayIdType *MEDCoupling1GTUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps)
363 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
364 return m->getCellsInBoundingBox(bbox,eps);
367 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildFacePartOfMySelfNode(const mcIdType *start, const mcIdType *end, bool fullyIn) const
369 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
370 return m->buildFacePartOfMySelfNode(start,end,fullyIn);
373 DataArrayIdType *MEDCoupling1GTUMesh::findBoundaryNodes() const
375 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
376 return m->findBoundaryNodes();
379 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildBoundaryMesh(bool keepCoords) const
381 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
382 return m->buildBoundaryMesh(keepCoords);
385 void MEDCoupling1GTUMesh::findCommonCells(int compType, mcIdType startCellId, DataArrayIdType *& commonCellsArr, DataArrayIdType *& commonCellsIArr) const
387 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
388 m->findCommonCells(compType,startCellId,commonCellsArr,commonCellsIArr);
391 mcIdType MEDCoupling1GTUMesh::getNodalConnectivityLength() const
393 const DataArrayIdType *c1(getNodalConnectivity());
395 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : no connectivity set !");
396 if(c1->getNumberOfComponents()!=1)
397 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array set must have exactly one component !");
398 if(!c1->isAllocated())
399 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array must be allocated !");
400 return c1->getNumberOfTuples();
404 * This method aggregates all the meshes in \a parts to put them in a single unstructured mesh (those returned).
405 * The order of cells is the returned instance is those in the order of instances in \a parts.
407 * \param [in] parts - all not null parts of single geo type meshes to be aggreagated having the same mesh dimension and same coordinates.
408 * \return MEDCouplingUMesh * - new object to be dealt by the caller.
410 * \throw If one element is null in \a parts.
411 * \throw If not all the parts do not have the same mesh dimension.
412 * \throw If not all the parts do not share the same coordinates.
413 * \throw If not all the parts have their connectivity set properly.
414 * \throw If \a parts is empty.
416 MEDCouplingUMesh *MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh(const std::vector< const MEDCoupling1GTUMesh *>& parts)
419 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : input parts vector is empty !");
420 const MEDCoupling1GTUMesh *firstPart(parts[0]);
422 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : the first instance in input parts is null !");
423 const DataArrayDouble *coords(firstPart->getCoords());
424 int meshDim(firstPart->getMeshDimension());
425 MCAuto<MEDCouplingUMesh> ret(MEDCouplingUMesh::New(firstPart->getName(),meshDim)); ret->setDescription(firstPart->getDescription());
426 ret->setCoords(coords);
427 mcIdType nbOfCells(0),connSize(0);
428 for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
431 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of null pointer in input vector !");
432 if((*it)->getMeshDimension()!=meshDim)
433 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances in input vector must have same mesh dimension !");
434 if((*it)->getCoords()!=coords)
435 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances must share the same coordinates pointer !");
436 nbOfCells+=(*it)->getNumberOfCells();
437 connSize+=(*it)->getNodalConnectivityLength();
439 MCAuto<DataArrayIdType> conn(DataArrayIdType::New()),connI(DataArrayIdType::New());
440 connI->alloc(nbOfCells+1,1); conn->alloc(connSize+nbOfCells,1);
441 mcIdType *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
442 for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
444 mcIdType curNbCells=(*it)->getNumberOfCells();
445 mcIdType geoType(ToIdType((*it)->getCellModelEnum()));
446 const mcIdType *cinPtr((*it)->getNodalConnectivity()->begin());
447 const MEDCoupling1SGTUMesh *ps(dynamic_cast<const MEDCoupling1SGTUMesh *>(*it));
448 const MEDCoupling1DGTUMesh *pd(dynamic_cast<const MEDCoupling1DGTUMesh *>(*it));
451 mcIdType nNodesPerCell(ps->getNumberOfNodesPerCell());
452 for(int i=0;i<curNbCells;i++,ci++,cinPtr+=nNodesPerCell)
455 c=std::copy(cinPtr,cinPtr+nNodesPerCell,c);
456 ci[1]=ci[0]+nNodesPerCell+1;
461 const mcIdType *ciinPtr(pd->getNodalConnectivityIndex()->begin());
462 for(int i=0;i<curNbCells;i++,ci++,ciinPtr++)
465 c=std::copy(cinPtr+ciinPtr[0],cinPtr+ciinPtr[1],c);
466 ci[1]=ci[0]+ciinPtr[1]-ciinPtr[0]+1;
470 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of instance which type is not in [MEDCoupling1SGTUMesh,MEDCoupling1DGTUMesh] !");
472 ret->setConnectivity(conn,connI,true);
478 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const MEDCoupling1SGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
482 const DataArrayIdType *c(other._conn);
488 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
492 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh()
496 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New()
498 return new MEDCoupling1SGTUMesh;
501 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
503 if(type==INTERP_KERNEL::NORM_ERROR)
504 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
505 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
508 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New : the input geometric type " << cm.getRepr() << " is dynamic ! Only static types are allowed here !";
509 throw INTERP_KERNEL::Exception(oss.str().c_str());
511 return new MEDCoupling1SGTUMesh(name,cm);
514 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m)
517 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh is null !");
518 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
520 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh must have exactly one geometric type !");
521 mcIdType geoType(ToIdType(*gts.begin()));
522 MCAuto<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(m->getName(),*gts.begin()));
523 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription());
524 mcIdType nbCells=m->getNumberOfCells();
525 mcIdType nbOfNodesPerCell(ret->getNumberOfNodesPerCell());
526 MCAuto<DataArrayIdType> conn(DataArrayIdType::New()); conn->alloc(nbCells*nbOfNodesPerCell,1);
527 mcIdType *c(conn->getPointer());
528 const mcIdType *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
529 for(mcIdType i=0;i<nbCells;i++,ciin++)
531 if(cin[ciin[0]]==geoType)
533 if(ciin[1]-ciin[0]==nbOfNodesPerCell+1)
534 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
537 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m) : something is wrong in the input mesh at cell #" << i << " ! The size of cell is not those expected (" << nbOfNodesPerCell << ") !";
538 throw INTERP_KERNEL::Exception(oss.str().c_str());
543 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m) : something is wrong in the input mesh at cell #" << i << " ! The geometric type is not those expected !";
544 throw INTERP_KERNEL::Exception(oss.str().c_str());
547 ret->setNodalConnectivity(conn);
549 { ret->copyTinyInfoFrom(m); }
550 catch(INTERP_KERNEL::Exception&) { }
554 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::clone(bool recDeepCpy) const
556 return new MEDCoupling1SGTUMesh(*this,recDeepCpy);
560 * This method behaves mostly like MEDCoupling1SGTUMesh::deepCopy method, except that only nodal connectivity arrays are deeply copied.
561 * The coordinates are shared between \a this and the returned instance.
563 * \return MEDCoupling1SGTUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
564 * \sa MEDCoupling1SGTUMesh::deepCopy
566 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::deepCopyConnectivityOnly() const
568 checkConsistencyLight();
569 MCAuto<MEDCoupling1SGTUMesh> ret(clone(false));
570 MCAuto<DataArrayIdType> c(_conn->deepCopy());
571 ret->setNodalConnectivity(c);
575 void MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
578 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
579 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
581 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1SGTUMesh instance !");
582 setNodalConnectivity(otherC->getNodalConnectivity());
585 void MEDCoupling1SGTUMesh::updateTime() const
587 MEDCoupling1GTUMesh::updateTime();
588 const DataArrayIdType *c(_conn);
593 std::size_t MEDCoupling1SGTUMesh::getHeapMemorySizeWithoutChildren() const
595 return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren();
598 std::vector<const BigMemoryObject *> MEDCoupling1SGTUMesh::getDirectChildrenWithNull() const
600 std::vector<const BigMemoryObject *> ret(MEDCoupling1GTUMesh::getDirectChildrenWithNull());
601 ret.push_back((const DataArrayIdType *)_conn);
605 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::deepCopy() const
610 bool MEDCoupling1SGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
613 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualIfNotWhy : input other pointer is null !");
614 std::ostringstream oss; oss.precision(15);
615 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
618 reason="mesh given in input is not castable in MEDCoupling1SGTUMesh !";
621 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
623 const DataArrayIdType *c1(_conn),*c2(otherC->_conn);
628 reason="in connectivity of single static geometric type exactly one among this and other is null !";
631 if(!c1->isEqualIfNotWhy(*c2,reason))
633 reason.insert(0,"Nodal connectivity DataArrayIdType differ : ");
639 bool MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
642 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
643 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
646 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
648 const DataArrayIdType *c1(_conn),*c2(otherC->_conn);
653 if(!c1->isEqualWithoutConsideringStr(*c2))
658 void MEDCoupling1SGTUMesh::checkConsistencyOfConnectivity() const
660 const DataArrayIdType *c1(_conn);
663 if(c1->getNumberOfComponents()!=1)
664 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
665 if(c1->getInfoOnComponent(0)!="")
666 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
667 c1->checkAllocated();
670 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
673 void MEDCoupling1SGTUMesh::checkConsistencyLight() const
675 MEDCouplingPointSet::checkConsistencyLight();
676 checkConsistencyOfConnectivity();
679 void MEDCoupling1SGTUMesh::checkConsistency(double eps) const
681 checkConsistencyLight();
682 const DataArrayIdType *c1(_conn);
683 mcIdType nbOfTuples(c1->getNumberOfTuples());
684 mcIdType nbOfNodesPerCell=_cm->getNumberOfNodes();
685 if(nbOfTuples%nbOfNodesPerCell!=0)
687 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::checkConsistency : the nb of tuples in conn is " << nbOfTuples << " and number of nodes per cell is " << nbOfNodesPerCell << ". But " << nbOfTuples << "%" << nbOfNodesPerCell << " !=0 !";
688 throw INTERP_KERNEL::Exception(oss.str().c_str());
690 mcIdType nbOfNodes=getNumberOfNodes();
691 mcIdType nbOfCells=nbOfTuples/nbOfNodesPerCell;
692 const mcIdType *w(c1->begin());
693 for(mcIdType i=0;i<nbOfCells;i++)
694 for(int j=0;j<nbOfNodesPerCell;j++,w++)
696 if(*w<0 || *w>=nbOfNodes)
698 std::ostringstream oss; oss << "At node #" << j << " of cell #" << i << ", is equal to " << *w << " must be in [0," << nbOfNodes << ") !";
699 throw INTERP_KERNEL::Exception(oss.str().c_str());
704 mcIdType MEDCoupling1SGTUMesh::getNumberOfCells() const
706 mcIdType nbOfTuples(getNodalConnectivityLength());
707 mcIdType nbOfNodesPerCell(getNumberOfNodesPerCell());
708 if(nbOfTuples%nbOfNodesPerCell!=0)
710 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh:getNumberOfCells: : the nb of tuples in conn is " << nbOfTuples << " and number of nodes per cell is " << nbOfNodesPerCell << ". But " << nbOfTuples << "%" << nbOfNodesPerCell << " !=0 !";
711 throw INTERP_KERNEL::Exception(oss.str().c_str());
713 return nbOfTuples/nbOfNodesPerCell;
716 mcIdType MEDCoupling1SGTUMesh::getNumberOfNodesInCell(mcIdType cellId) const
718 return getNumberOfNodesPerCell();
721 mcIdType MEDCoupling1SGTUMesh::getNumberOfNodesPerCell() const
723 checkNonDynamicGeoType();
724 return _cm->getNumberOfNodes();
727 DataArrayIdType *MEDCoupling1SGTUMesh::computeNbOfNodesPerCell() const
729 checkNonDynamicGeoType();
730 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
731 ret->alloc(getNumberOfCells(),1);
732 ret->fillWithValue(_cm->getNumberOfNodes());
736 DataArrayIdType *MEDCoupling1SGTUMesh::computeNbOfFacesPerCell() const
738 checkNonDynamicGeoType();
739 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
740 ret->alloc(getNumberOfCells(),1);
741 ret->fillWithValue(ToIdType(_cm->getNumberOfSons()));
745 DataArrayIdType *MEDCoupling1SGTUMesh::computeEffectiveNbOfNodesPerCell() const
747 checkNonDynamicGeoType();
748 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
749 mcIdType nbCells=getNumberOfCells();
750 ret->alloc(nbCells,1);
751 mcIdType *retPtr(ret->getPointer());
752 mcIdType nbNodesPerCell(getNumberOfNodesPerCell());
753 const mcIdType *conn(_conn->begin());
754 for(mcIdType i=0;i<nbCells;i++,conn+=nbNodesPerCell,retPtr++)
756 std::set<mcIdType> s(conn,conn+nbNodesPerCell);
757 *retPtr=ToIdType(s.size());
762 void MEDCoupling1SGTUMesh::getNodeIdsOfCell(mcIdType cellId, std::vector<mcIdType>& conn) const
764 mcIdType sz=getNumberOfNodesPerCell();
766 if(cellId<getNumberOfCells())
767 std::copy(_conn->begin()+cellId*sz,_conn->begin()+(cellId+1)*sz,conn.begin());
770 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << getNumberOfCells() << ") !";
771 throw INTERP_KERNEL::Exception(oss.str().c_str());
775 void MEDCoupling1SGTUMesh::checkNonDynamicGeoType() const
778 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkNonDynamicGeoType : internal error ! the internal geo type is dynamic ! should be static !");
781 std::string MEDCoupling1SGTUMesh::simpleRepr() const
783 static const char msg0[]="No coordinates specified !";
784 std::ostringstream ret;
787 ret << "No geometric type specified" << std::endl;
790 ret << "Single static geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
791 ret << "Description of mesh : \"" << getDescription() << "\"\n";
793 double tt=getTime(tmpp1,tmpp2);
794 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
795 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
796 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
799 const int spaceDim=getSpaceDimension();
800 ret << spaceDim << "\nInfo attached on space dimension : ";
801 for(int i=0;i<spaceDim;i++)
802 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
807 ret << "Number of nodes : ";
809 ret << getNumberOfNodes() << "\n";
812 ret << "Number of cells : ";
813 if((const DataArrayIdType *)_conn)
815 if(_conn->isAllocated())
817 if(_conn->getNumberOfComponents()==1)
818 ret << getNumberOfCells() << "\n";
820 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
823 ret << "Nodal connectivity array specified but not allocated !" << "\n";
826 ret << "No connectivity specified !" << "\n";
827 ret << "Cell type : " << _cm->getRepr() << "\n";
831 std::string MEDCoupling1SGTUMesh::advancedRepr() const
833 std::ostringstream ret;
835 ret << "\nCoordinates array : \n___________________\n\n";
837 _coords->reprWithoutNameStream(ret);
839 ret << "No array set !\n";
840 ret << "\n\nConnectivity array : \n____________________\n\n";
842 if((const DataArrayIdType *)_conn)
844 if(_conn->isAllocated())
846 if(_conn->getNumberOfComponents()==1)
848 mcIdType nbOfCells=getNumberOfCells();
849 mcIdType sz=getNumberOfNodesPerCell();
850 const mcIdType *connPtr=_conn->begin();
851 for(mcIdType i=0;i<nbOfCells;i++,connPtr+=sz)
853 ret << "Cell #" << i << " : ";
854 std::copy(connPtr,connPtr+sz,std::ostream_iterator<mcIdType>(ret," "));
859 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
862 ret << "Nodal connectivity array specified but not allocated !" << "\n";
865 ret << "No connectivity specified !" << "\n";
869 DataArrayDouble *MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell() const
871 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
872 int spaceDim=getSpaceDimension();
873 mcIdType nbOfCells=getNumberOfCells();//checkConsistencyLight()
874 mcIdType nbOfNodes=getNumberOfNodes();
875 ret->alloc(nbOfCells,spaceDim);
876 double *ptToFill=ret->getPointer();
877 const double *coor=_coords->begin();
878 const mcIdType *nodal=_conn->begin();
879 mcIdType sz=getNumberOfNodesPerCell();
880 double coeff=1./FromIdType<double>(sz);
881 for(mcIdType i=0;i<nbOfCells;i++,ptToFill+=spaceDim)
883 std::fill(ptToFill,ptToFill+spaceDim,0.);
884 for(mcIdType j=0;j<sz;j++,nodal++)
885 if(*nodal>=0 && *nodal<nbOfNodes)
886 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
889 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
890 throw INTERP_KERNEL::Exception(oss.str().c_str());
892 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind(std::multiplies<double>(),std::placeholders::_1,coeff));
897 void MEDCoupling1SGTUMesh::renumberCells(const mcIdType *old2NewBg, bool check)
899 mcIdType nbCells=getNumberOfCells();
900 MCAuto<DataArrayIdType> o2n=DataArrayIdType::New();
901 o2n->useArray(old2NewBg,false,DeallocType::C_DEALLOC,nbCells,1);
903 o2n=o2n->checkAndPreparePermutation();
905 const mcIdType *conn=_conn->begin();
906 MCAuto<DataArrayIdType> n2o=o2n->invertArrayO2N2N2O(nbCells);
907 const mcIdType *n2oPtr=n2o->begin();
908 MCAuto<DataArrayIdType> newConn=DataArrayIdType::New();
909 newConn->alloc(_conn->getNumberOfTuples(),1);
910 newConn->copyStringInfoFrom(*_conn);
911 mcIdType sz=getNumberOfNodesPerCell();
913 mcIdType *newC=newConn->getPointer();
914 for(mcIdType i=0;i<nbCells;i++,newC+=sz)
916 mcIdType pos=n2oPtr[i];
917 std::copy(conn+pos*sz,conn+(pos+1)*sz,newC);
923 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
924 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
925 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
926 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
928 * \param [in] begin input start of array of node ids.
929 * \param [in] end input end of array of node ids.
930 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
931 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
933 void MEDCoupling1SGTUMesh::fillCellIdsToKeepFromNodeIds(const mcIdType *begin, const mcIdType *end, bool fullyIn, DataArrayIdType *&cellIdsKeptArr) const
935 mcIdType nbOfCells=getNumberOfCells();
936 MCAuto<DataArrayIdType> cellIdsKept=DataArrayIdType::New(); cellIdsKept->alloc(0,1);
938 mcIdType sz=_conn->getMaxValue(tmp); sz=std::max(sz,ToIdType(0))+1;
939 std::vector<bool> fastFinder(sz,false);
940 for(const mcIdType *work=begin;work!=end;work++)
941 if(*work>=0 && *work<sz)
942 fastFinder[*work]=true;
943 const mcIdType *conn=_conn->begin();
944 mcIdType nbNodesPerCell=getNumberOfNodesPerCell();
945 for(mcIdType i=0;i<nbOfCells;i++,conn+=nbNodesPerCell)
948 for(mcIdType j=0;j<nbNodesPerCell;j++)
952 if(fastFinder[conn[j]])
955 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
956 cellIdsKept->pushBackSilent(i);
958 cellIdsKeptArr=cellIdsKept.retn();
961 MEDCouplingMesh *MEDCoupling1SGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
963 if(other->getType()!=SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED)
964 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single static geo type each other !");
965 const MEDCoupling1SGTUMesh *otherC=static_cast<const MEDCoupling1SGTUMesh *>(other);
966 return Merge1SGTUMeshes(this,otherC);
969 MEDCouplingUMesh *MEDCoupling1SGTUMesh::buildUnstructured() const
971 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
972 ret->setCoords(getCoords());
973 const mcIdType *nodalConn=_conn->begin();
974 mcIdType nbCells=getNumberOfCells();
975 mcIdType nbNodesPerCell=getNumberOfNodesPerCell();
976 mcIdType geoType=ToIdType(getCellModelEnum());
977 MCAuto<DataArrayIdType> c=DataArrayIdType::New(); c->alloc(nbCells*(nbNodesPerCell+1),1);
978 mcIdType *cPtr=c->getPointer();
979 for(mcIdType i=0;i<nbCells;i++,nodalConn+=nbNodesPerCell)
982 cPtr=std::copy(nodalConn,nodalConn+nbNodesPerCell,cPtr);
984 MCAuto<DataArrayIdType> cI=DataArrayIdType::Range(0,(nbCells+1)*(nbNodesPerCell+1),nbNodesPerCell+1);
985 ret->setConnectivity(c,cI,true);
987 { ret->copyTinyInfoFrom(this); }
988 catch(INTERP_KERNEL::Exception&) { }
992 DataArrayIdType *MEDCoupling1SGTUMesh::simplexize(int policy)
997 return simplexizePol0();
999 return simplexizePol1();
1000 case INTERP_KERNEL::PLANAR_FACE_5:
1001 return simplexizePlanarFace5();
1002 case INTERP_KERNEL::PLANAR_FACE_6:
1003 return simplexizePlanarFace6();
1005 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::simplexize : unrecognized policy ! Must be :\n - 0 or 1 (only available for meshdim=2) \n - PLANAR_FACE_5, PLANAR_FACE_6 (only for meshdim=3)");
1011 struct MEDCouplingAccVisit
1013 MEDCouplingAccVisit():_new_nb_of_nodes(0) { }
1014 mcIdType operator()(mcIdType val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; }
1015 mcIdType _new_nb_of_nodes;
1021 * This method returns all node ids used in \b this. The data array returned has to be dealt by the caller.
1022 * The returned node ids are sortes ascendingly. This method is closed to MEDCoupling1SGTUMesh::getNodeIdsInUse except
1023 * the format of returned DataArrayIdType instance.
1025 * \return a newly allocated DataArrayIdType sorted ascendingly of fetched node ids.
1026 * \sa MEDCoupling1SGTUMesh::getNodeIdsInUse, areAllNodesFetched
1028 DataArrayIdType *MEDCoupling1SGTUMesh::computeFetchedNodeIds() const
1030 checkConsistencyOfConnectivity();
1031 mcIdType nbNodes(getNumberOfNodes());
1032 std::vector<bool> fetchedNodes(nbNodes,false);
1033 computeNodeIdsAlg(fetchedNodes);
1034 mcIdType sz(ToIdType(std::count(fetchedNodes.begin(),fetchedNodes.end(),true)));
1035 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(sz,1);
1036 mcIdType *retPtr(ret->getPointer());
1037 for(mcIdType i=0;i<nbNodes;i++)
1044 * Finds nodes not used in any cell and returns an array giving a new id to every node
1045 * by excluding the unused nodes, for which the array holds -1. The result array is
1046 * a mapping in "Old to New" mode.
1047 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
1048 * \return DataArrayIdType * - a new instance of DataArrayIdType. Its length is \a
1049 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
1050 * if the node is unused or a new id else. The caller is to delete this
1051 * array using decrRef() as it is no more needed.
1052 * \throw If the coordinates array is not set.
1053 * \throw If the nodal connectivity of cells is not defined.
1054 * \throw If the nodal connectivity includes an invalid id.
1055 * \sa MEDCoupling1SGTUMesh::computeFetchedNodeIds, areAllNodesFetched
1057 DataArrayIdType *MEDCoupling1SGTUMesh::getNodeIdsInUse(mcIdType& nbrOfNodesInUse) const
1060 mcIdType nbOfNodes=getNumberOfNodes();
1061 mcIdType nbOfCells=getNumberOfCells();
1062 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
1063 ret->alloc(nbOfNodes,1);
1064 mcIdType *traducer=ret->getPointer();
1065 std::fill(traducer,traducer+nbOfNodes,-1);
1066 const mcIdType *conn=_conn->begin();
1067 mcIdType nbNodesPerCell=getNumberOfNodesPerCell();
1068 for(mcIdType i=0;i<nbOfCells;i++)
1069 for(int j=0;j<nbNodesPerCell;j++,conn++)
1070 if(*conn>=0 && *conn<nbOfNodes)
1074 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << conn[j] << " not in [0," << nbOfNodes << ") !";
1075 throw INTERP_KERNEL::Exception(oss.str().c_str());
1077 nbrOfNodesInUse=ToIdType(std::count(traducer,traducer+nbOfNodes,1));
1078 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
1083 * This method renumbers only nodal connectivity in \a this. The renumbering is only an offset applied. So this method is a specialization of
1084 * \a renumberNodesInConn. \b WARNING, this method does not check that the resulting node ids in the nodal connectivity is in a valid range !
1086 * \param [in] offset - specifies the offset to be applied on each element of connectivity.
1088 * \sa renumberNodesInConn
1090 void MEDCoupling1SGTUMesh::renumberNodesWithOffsetInConn(mcIdType offset)
1092 getNumberOfCells();//only to check that all is well defined.
1093 _conn->applyLin(1,offset);
1098 * Same than renumberNodesInConn(const mcIdType *) except that here the format of old-to-new traducer is using map instead
1099 * of array. This method is dedicated for renumbering from a big set of nodes the a tiny set of nodes which is the case during extraction
1102 void MEDCoupling1SGTUMesh::renumberNodesInConn(const INTERP_KERNEL::HashMap<mcIdType,mcIdType>& newNodeNumbersO2N)
1104 this->renumberNodesInConnT< INTERP_KERNEL::HashMap<mcIdType,mcIdType> >(newNodeNumbersO2N);
1108 * Same than renumberNodesInConn(const mcIdType *) except that here the format of old-to-new traducer is using map instead
1109 * of array. This method is dedicated for renumbering from a big set of nodes the a tiny set of nodes which is the case during extraction
1112 void MEDCoupling1SGTUMesh::renumberNodesInConn(const std::map<mcIdType,mcIdType>& newNodeNumbersO2N)
1114 this->renumberNodesInConnT< std::map<mcIdType,mcIdType> >(newNodeNumbersO2N);
1118 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
1119 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
1120 * This method is a generalization of shiftNodeNumbersInConn().
1121 * \warning This method performs no check of validity of new ids. **Use it with care !**
1122 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
1123 * this->getNumberOfNodes(), in "Old to New" mode.
1124 * See \ref numbering for more info on renumbering modes.
1125 * \throw If the nodal connectivity of cells is not defined.
1127 void MEDCoupling1SGTUMesh::renumberNodesInConn(const mcIdType *newNodeNumbersO2N)
1129 getNumberOfCells();//only to check that all is well defined.
1130 _conn->transformWithIndArr(newNodeNumbersO2N,newNodeNumbersO2N+getNumberOfNodes());
1134 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2)
1136 std::vector<const MEDCoupling1SGTUMesh *> tmp(2);
1137 tmp[0]=const_cast<MEDCoupling1SGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1SGTUMesh *>(mesh2);
1138 return Merge1SGTUMeshes(tmp);
1141 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(std::vector<const MEDCoupling1SGTUMesh *>& a)
1143 std::size_t sz=a.size();
1145 return Merge1SGTUMeshesLL(a);
1146 for(std::size_t ii=0;ii<sz;ii++)
1149 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::Merge1SGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
1150 throw INTERP_KERNEL::Exception(oss.str().c_str());
1152 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
1153 for(std::size_t ii=0;ii<sz;ii++)
1154 if(&(a[ii]->getCellModel())!=cm)
1155 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : all items must have the same geo type !");
1156 std::vector< MCAuto<MEDCoupling1SGTUMesh> > bb(sz);
1157 std::vector< const MEDCoupling1SGTUMesh * > aa(sz);
1158 std::size_t spaceDimUndef=-3, spaceDim=spaceDimUndef;
1159 for(std::size_t i=0;i<sz && spaceDim==spaceDimUndef;i++)
1161 const MEDCoupling1SGTUMesh *cur=a[i];
1162 const DataArrayDouble *coo=cur->getCoords();
1164 spaceDim=coo->getNumberOfComponents();
1166 if(spaceDim==spaceDimUndef)
1167 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : no spaceDim specified ! unable to perform merge !");
1168 for(std::size_t i=0;i<sz;i++)
1170 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
1173 return Merge1SGTUMeshesLL(aa);
1177 * \throw If presence of a null instance in the input vector \a a.
1178 * \throw If a is empty
1180 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::vector<const MEDCoupling1SGTUMesh *>& a)
1183 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : input array must be NON EMPTY !");
1184 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1186 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : null instance in the first element of input vector !");
1187 std::vector<const DataArrayIdType *> ncs(a.size());
1188 (*it)->getNumberOfCells();//to check that all is OK
1189 const DataArrayDouble *coords=(*it)->getCoords();
1190 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1191 ncs[0]=(*it)->getNodalConnectivity();
1193 for(int i=1;it!=a.end();i++,it++)
1196 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : presence of a null instance in the input vector !");
1197 if(cm!=&((*it)->getCellModel()))
1198 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1199 (*it)->getNumberOfCells();//to check that all is OK
1200 ncs[i]=(*it)->getNodalConnectivity();
1201 if(coords!=(*it)->getCoords())
1202 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : not lying on same coords !");
1204 MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1205 ret->setCoords(coords);
1206 ret->_conn=DataArrayIdType::Aggregate(ncs);
1211 * Assume that all instances in \a a are non null. If null it leads to a crash. That's why this method is assigned to be low level (LL)
1213 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector<const MEDCoupling1SGTUMesh *>& a)
1216 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : input array must be NON EMPTY !");
1217 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1218 mcIdType nbOfCells=(*it)->getNumberOfCells();
1219 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1220 mcIdType nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
1222 for(;it!=a.end();it++)
1224 if(cm!=&((*it)->getCellModel()))
1225 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1226 nbOfCells+=(*it)->getNumberOfCells();
1228 std::vector<const MEDCouplingPointSet *> aps(a.size());
1229 std::copy(a.begin(),a.end(),aps.begin());
1230 MCAuto<DataArrayDouble> pts=MergeNodesArray(aps);
1231 MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1232 ret->setCoords(pts);
1233 MCAuto<DataArrayIdType> c=DataArrayIdType::New();
1234 c->alloc(nbOfCells*nbNodesPerCell,1);
1235 mcIdType *cPtr=c->getPointer();
1237 for(it=a.begin();it!=a.end();it++)
1239 mcIdType curConnLgth=(*it)->getNodalConnectivityLength();
1240 const mcIdType *curC=(*it)->_conn->begin();
1241 cPtr=std::transform(curC,curC+curConnLgth,cPtr,std::bind(std::plus<mcIdType>(),std::placeholders::_1,offset));
1242 offset+=(*it)->getNumberOfNodes();
1245 ret->setNodalConnectivity(c);
1249 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const mcIdType *begin, const mcIdType *end) const
1251 mcIdType ncell=getNumberOfCells();
1252 MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1253 ret->setCoords(_coords);
1254 std::size_t nbOfElemsRet=std::distance(begin,end);
1255 const mcIdType *inConn=_conn->getConstPointer();
1256 mcIdType sz=getNumberOfNodesPerCell();
1257 MCAuto<DataArrayIdType> connRet=DataArrayIdType::New(); connRet->alloc(nbOfElemsRet*sz,1);
1258 mcIdType *connPtr=connRet->getPointer();
1259 for(const mcIdType *work=begin;work!=end;work++,connPtr+=sz)
1261 if(*work>=0 && *work<ncell)
1262 std::copy(inConn+(work[0])*sz,inConn+(work[0]+1)*sz,connPtr);
1265 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !";
1266 throw INTERP_KERNEL::Exception(oss.str().c_str());
1270 ret->copyTinyInfoFrom(this);
1274 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoordsSlice(mcIdType start, mcIdType end, mcIdType step) const
1276 mcIdType ncell=getNumberOfCells();
1277 mcIdType nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoordsSlice : ");
1278 MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1279 ret->setCoords(_coords);
1280 const mcIdType *inConn=_conn->getConstPointer();
1281 mcIdType sz=getNumberOfNodesPerCell();
1282 MCAuto<DataArrayIdType> connRet=DataArrayIdType::New(); connRet->alloc(nbOfElemsRet*sz,1);
1283 mcIdType *connPtr=connRet->getPointer();
1284 mcIdType curId=start;
1285 for(mcIdType i=0;i<nbOfElemsRet;i++,connPtr+=sz,curId+=step)
1287 if(curId>=0 && curId<ncell)
1288 std::copy(inConn+curId*sz,inConn+(curId+1)*sz,connPtr);
1291 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoordsSlice : On pos #" << i << " input cell id =" << curId << " should be in [0," << ncell << ") !";
1292 throw INTERP_KERNEL::Exception(oss.str().c_str());
1296 ret->copyTinyInfoFrom(this);
1300 void MEDCoupling1SGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
1302 mcIdType sz(ToIdType(nodeIdsInUse.size()));
1303 for(const mcIdType *conn=_conn->begin();conn!=_conn->end();conn++)
1305 if(*conn>=0 && *conn<sz)
1306 nodeIdsInUse[*conn]=true;
1309 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeFetchedNodeIds : At pos #" << std::distance(_conn->begin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !";
1310 throw INTERP_KERNEL::Exception(oss.str().c_str());
1315 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(std::size_t spaceDim) const
1317 MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1318 MCAuto<DataArrayIdType> tmp1;
1319 const DataArrayIdType *nodalConn(_conn);
1322 tmp1=DataArrayIdType::New(); tmp1->alloc(0,1);
1329 MCAuto<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
1330 ret->setCoords(coords);
1333 ret->setCoords(_coords);
1337 DataArrayIdType *MEDCoupling1SGTUMesh::simplexizePol0()
1339 mcIdType nbOfCells=getNumberOfCells();
1340 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1341 return DataArrayIdType::Range(0,nbOfCells,1);
1342 MCAuto<DataArrayIdType> newConn=DataArrayIdType::New(); newConn->alloc(2*3*nbOfCells,1);
1343 MCAuto<DataArrayIdType> ret=DataArrayIdType::New(); ret->alloc(2*nbOfCells,1);
1344 const mcIdType *c(_conn->begin());
1345 mcIdType *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1346 for(mcIdType i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1348 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[2];
1349 newConnPtr[3]=c[0]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1350 retPtr[0]=i; retPtr[1]=i;
1353 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1358 DataArrayIdType *MEDCoupling1SGTUMesh::simplexizePol1()
1360 mcIdType nbOfCells=getNumberOfCells();
1361 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1362 return DataArrayIdType::Range(0,nbOfCells,1);
1363 MCAuto<DataArrayIdType> newConn=DataArrayIdType::New(); newConn->alloc(2*3*nbOfCells,1);
1364 MCAuto<DataArrayIdType> ret=DataArrayIdType::New(); ret->alloc(2*nbOfCells,1);
1365 const mcIdType *c(_conn->begin());
1366 mcIdType *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1367 for(mcIdType i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1369 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[3];
1370 newConnPtr[3]=c[1]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1371 retPtr[0]=i; retPtr[1]=i;
1374 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1379 DataArrayIdType *MEDCoupling1SGTUMesh::simplexizePlanarFace5()
1381 mcIdType nbOfCells=getNumberOfCells();
1382 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1383 return DataArrayIdType::Range(0,nbOfCells,1);
1384 MCAuto<DataArrayIdType> newConn=DataArrayIdType::New(); newConn->alloc(5*4*nbOfCells,1);
1385 MCAuto<DataArrayIdType> ret=DataArrayIdType::New(); ret->alloc(5*nbOfCells,1);
1386 const mcIdType *c(_conn->begin());
1387 mcIdType *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1388 for(mcIdType i=0;i<nbOfCells;i++,c+=8,newConnPtr+=20,retPtr+=5)
1390 for(int j=0;j<20;j++)
1391 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_5_WO[j]];
1392 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i;
1395 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1400 DataArrayIdType *MEDCoupling1SGTUMesh::simplexizePlanarFace6()
1402 mcIdType nbOfCells=getNumberOfCells();
1403 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1404 return DataArrayIdType::Range(0,nbOfCells,1);
1405 MCAuto<DataArrayIdType> newConn=DataArrayIdType::New(); newConn->alloc(6*4*nbOfCells,1);
1406 MCAuto<DataArrayIdType> ret=DataArrayIdType::New(); ret->alloc(6*nbOfCells,1);
1407 const mcIdType *c(_conn->begin());
1408 mcIdType *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1409 for(mcIdType i=0;i<nbOfCells;i++,c+=8,newConnPtr+=24,retPtr+=6)
1411 for(int j=0;j<24;j++)
1412 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_6_WO[j]];
1413 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i; retPtr[5]=i;
1416 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1421 void MEDCoupling1SGTUMesh::reprQuickOverview(std::ostream& stream) const
1423 stream << "MEDCoupling1SGTUMesh C++ instance at " << this << ". Type=";
1426 stream << "Not set";
1429 stream << _cm->getRepr() << ". Name : \"" << getName() << "\".";
1430 stream << " Mesh dimension : " << getMeshDimension() << ".";
1432 { stream << " No coordinates set !"; return ; }
1433 if(!_coords->isAllocated())
1434 { stream << " Coordinates set but not allocated !"; return ; }
1435 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
1436 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
1437 if(!(const DataArrayIdType *)_conn)
1438 { stream << std::endl << "Nodal connectivity NOT set !"; return ; }
1439 if(_conn->isAllocated())
1441 if(_conn->getNumberOfComponents()==1)
1442 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
1446 void MEDCoupling1SGTUMesh::checkFullyDefined() const
1448 if(!((const DataArrayIdType *)_conn) || !((const DataArrayDouble *)_coords))
1449 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFullyDefined : part of this is not fully defined.");
1453 * First step of unserialization process.
1455 bool MEDCoupling1SGTUMesh::isEmptyMesh(const std::vector<mcIdType>& tinyInfo) const
1457 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEmptyMesh : not implemented yet !");
1460 void MEDCoupling1SGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<mcIdType>& tinyInfo, std::vector<std::string>& littleStrings) const
1463 double time=getTime(it,order);
1464 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
1466 littleStrings.push_back(getName());
1467 littleStrings.push_back(getDescription());
1468 littleStrings.push_back(getTimeUnit());
1470 std::vector<std::string> littleStrings2,littleStrings3;
1471 if((const DataArrayDouble *)_coords)
1472 _coords->getTinySerializationStrInformation(littleStrings2);
1473 if((const DataArrayIdType *)_conn)
1474 _conn->getTinySerializationStrInformation(littleStrings3);
1475 mcIdType sz0(ToIdType(littleStrings2.size())),sz1(ToIdType(littleStrings3.size()));
1476 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
1477 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
1479 tinyInfo.push_back(getCellModelEnum());
1480 tinyInfo.push_back(it);
1481 tinyInfo.push_back(order);
1482 std::vector<mcIdType> tinyInfo2,tinyInfo3;
1483 if((const DataArrayDouble *)_coords)
1484 _coords->getTinySerializationIntInformation(tinyInfo2);
1485 if((const DataArrayIdType *)_conn)
1486 _conn->getTinySerializationIntInformation(tinyInfo3);
1487 mcIdType sz2(ToIdType(tinyInfo2.size())),sz3(ToIdType(tinyInfo3.size()));
1488 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3);
1489 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1490 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
1492 tinyInfoD.push_back(time);
1495 void MEDCoupling1SGTUMesh::resizeForUnserialization(const std::vector<mcIdType>& tinyInfo, DataArrayIdType *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
1497 std::vector<mcIdType> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+tinyInfo[5]);
1498 std::vector<mcIdType> tinyInfo1(tinyInfo.begin()+7+tinyInfo[5],tinyInfo.begin()+7+tinyInfo[5]+tinyInfo[6]);
1499 a1->resizeForUnserialization(tinyInfo1);
1500 a2->resizeForUnserialization(tinyInfo2);
1503 void MEDCoupling1SGTUMesh::serialize(DataArrayIdType *&a1, DataArrayDouble *&a2) const
1506 if((const DataArrayIdType *)_conn)
1507 if(_conn->isAllocated())
1508 sz=_conn->getNbOfElems();
1509 a1=DataArrayIdType::New();
1511 if(sz!=0 && (const DataArrayIdType *)_conn)
1512 std::copy(_conn->begin(),_conn->end(),a1->getPointer());
1514 if((const DataArrayDouble *)_coords)
1515 if(_coords->isAllocated())
1516 sz=_coords->getNbOfElems();
1517 a2=DataArrayDouble::New();
1519 if(sz!=0 && (const DataArrayDouble *)_coords)
1520 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
1523 void MEDCoupling1SGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<mcIdType>& tinyInfo, const DataArrayIdType *a1, DataArrayDouble *a2,
1524 const std::vector<std::string>& littleStrings)
1526 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
1527 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
1528 setName(littleStrings[0]);
1529 setDescription(littleStrings[1]);
1530 setTimeUnit(littleStrings[2]);
1531 setTime(tinyInfoD[0],FromIdType<int>(tinyInfo[1]),FromIdType<int>(tinyInfo[2]));
1532 mcIdType sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]);
1534 _coords=DataArrayDouble::New();
1535 std::vector<mcIdType> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+sz2);
1536 _coords->resizeForUnserialization(tinyInfo2);
1537 std::copy(a2->begin(),a2->end(),_coords->getPointer());
1538 _conn=DataArrayIdType::New();
1539 std::vector<mcIdType> tinyInfo3(tinyInfo.begin()+7+sz2,tinyInfo.begin()+7+sz2+sz3);
1540 _conn->resizeForUnserialization(tinyInfo3);
1541 std::copy(a1->begin(),a1->end(),_conn->getPointer());
1542 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
1543 _coords->finishUnserialization(tinyInfo2,littleStrings2);
1544 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
1545 _conn->finishUnserialization(tinyInfo3,littleStrings3);
1549 * Checks if \a this and \a other meshes are geometrically equivalent with high
1550 * probability, else an exception is thrown. The meshes are considered equivalent if
1551 * (1) meshes contain the same number of nodes and the same number of elements of the
1552 * same types (2) three cells of the two meshes (first, last and middle) are based
1553 * on coincident nodes (with a specified precision).
1554 * \param [in] other - the mesh to compare with.
1555 * \param [in] prec - the precision used to compare nodes of the two meshes.
1556 * \throw If the two meshes do not match.
1558 void MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
1560 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1561 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1563 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single static geometric type !");
1564 const DataArrayIdType *c1(_conn),*c2(otherC->_conn);
1568 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1569 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1570 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1571 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1572 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1573 if(c1->getHashCode()!=c2->getHashCode())
1574 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1577 MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
1580 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
1581 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1583 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
1584 std::vector<const MEDCoupling1SGTUMesh *> ms(2);
1587 return Merge1SGTUMeshesOnSameCoords(ms);
1590 void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayIdType *revNodal, DataArrayIdType *revNodalIndx) const
1592 checkFullyDefined();
1593 mcIdType nbOfNodes=getNumberOfNodes();
1594 mcIdType *revNodalIndxPtr=(mcIdType *)malloc((nbOfNodes+1)*sizeof(mcIdType));
1595 revNodalIndx->useArray(revNodalIndxPtr,true,DeallocType::C_DEALLOC,nbOfNodes+1,1);
1596 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
1597 const mcIdType *conn=_conn->begin();
1598 mcIdType nbOfCells=getNumberOfCells();
1599 mcIdType nbOfEltsInRevNodal=0;
1600 mcIdType nbOfNodesPerCell=getNumberOfNodesPerCell();
1601 for(mcIdType eltId=0;eltId<nbOfCells;eltId++)
1603 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1605 if(conn[0]>=0 && conn[0]<nbOfNodes)
1607 nbOfEltsInRevNodal++;
1608 revNodalIndxPtr[conn[0]+1]++;
1612 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
1613 throw INTERP_KERNEL::Exception(oss.str().c_str());
1617 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<mcIdType>());
1618 conn=_conn->begin();
1619 mcIdType *revNodalPtr=(mcIdType *)malloc(nbOfEltsInRevNodal*sizeof(mcIdType));
1620 revNodal->useArray(revNodalPtr,true,DeallocType::C_DEALLOC,nbOfEltsInRevNodal,1);
1621 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
1622 for(mcIdType eltId=0;eltId<nbOfCells;eltId++)
1624 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1626 *std::find_if(revNodalPtr+revNodalIndxPtr[*conn],revNodalPtr+revNodalIndxPtr[*conn+1],std::bind(std::equal_to<mcIdType>(),std::placeholders::_1,-1))=eltId;
1632 * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null.
1634 void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayIdType *nodalConn)
1637 nodalConn->incrRef();
1643 * \return DataArrayIdType * - the internal reference to the nodal connectivity. The caller is not responsible to deallocate it.
1645 DataArrayIdType *MEDCoupling1SGTUMesh::getNodalConnectivity() const
1647 const DataArrayIdType *ret(_conn);
1648 return const_cast<DataArrayIdType *>(ret);
1652 * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted,
1653 * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter.
1654 * If a nodal connectivity previously existed before the call of this method, it will be reset.
1656 * \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain.
1658 void MEDCoupling1SGTUMesh::allocateCells(mcIdType nbOfCells)
1661 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !");
1662 _conn=DataArrayIdType::New();
1663 _conn->reserve(getNumberOfNodesPerCell()*nbOfCells);
1668 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
1670 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
1671 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
1672 * \throw If the length of the input nodal connectivity array of the cell to add is not equal to number of nodes per cell relative to the unique geometric type
1673 * attached to \a this.
1674 * \throw If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
1676 void MEDCoupling1SGTUMesh::insertNextCell(const mcIdType *nodalConnOfCellBg, const mcIdType *nodalConnOfCellEnd)
1678 mcIdType sz=ToIdType(std::distance(nodalConnOfCellBg,nodalConnOfCellEnd));
1679 mcIdType ref=getNumberOfNodesPerCell();
1682 DataArrayIdType *c(_conn);
1684 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
1686 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !");
1690 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this (";
1691 oss << ref << ") !";
1692 throw INTERP_KERNEL::Exception(oss.str().c_str());
1697 * This method builds the dual mesh of \a this and returns it.
1699 * \return MEDCoupling1SGTUMesh * - newly object created to be managed by the caller.
1700 * \throw If \a this is not a mesh containing only simplex cells.
1701 * \throw If \a this is not correctly allocated (coordinates and connectivities have to be correctly set !).
1702 * \throw If at least one node in \a this is orphan (without any simplex cell lying on it !)
1704 MEDCoupling1GTUMesh *MEDCoupling1SGTUMesh::computeDualMesh() const
1706 const INTERP_KERNEL::CellModel& cm(getCellModel());
1708 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : this mesh is not a simplex mesh ! Please invoke simplexize of tetrahedrize on this before calling this method !");
1709 switch(getMeshDimension())
1712 return computeDualMesh3D();
1714 return computeDualMesh2D();
1716 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : meshdimension must be in [2,3] !");
1721 * This method explode each NORM_HEXA8 cells in \a this into 6 NORM_QUAD4 cells and put the result into the MEDCoupling1SGTUMesh returned instance.
1723 * \return MEDCoupling1SGTUMesh * - a newly allocated instances (to be managed by the caller) storing the result of the explosion.
1724 * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
1725 * \throw If \a this is not properly allocated.
1727 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4() const
1729 const INTERP_KERNEL::CellModel& cm(getCellModel());
1730 if(cm.getEnum()!=INTERP_KERNEL::NORM_HEXA8)
1731 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4 : this method can be applied only on HEXA8 mesh !");
1732 mcIdType nbHexa8=getNumberOfCells();
1733 const mcIdType *inConnPtr(getNodalConnectivity()->begin());
1734 MCAuto<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(getName(),INTERP_KERNEL::NORM_QUAD4));
1735 MCAuto<DataArrayIdType> c(DataArrayIdType::New()); c->alloc(nbHexa8*6*4,1);
1736 mcIdType *cPtr(c->getPointer());
1737 for(mcIdType i=0;i<nbHexa8;i++,inConnPtr+=8)
1739 for(int j=0;j<6;j++,cPtr+=4)
1740 cm.fillSonCellNodalConnectivity(j,inConnPtr,cPtr);
1742 ret->setCoords(getCoords());
1743 ret->setNodalConnectivity(c);
1748 * This method for each cell in \a this the triangle height for each edge in a newly allocated/created array instance.
1750 * \return DataArrayDouble * - a newly allocated instance with this->getNumberOfCells() tuples and 3 components storing for each cell in \a this the corresponding height.
1751 * \throw If \a this is not a mesh containing only NORM_TRI3 cells.
1752 * \throw If \a this is not properly allocated.
1753 * \throw If spaceDimension is not in 2 or 3.
1755 MCAuto<DataArrayDouble> MEDCoupling1SGTUMesh::computeTriangleHeight() const
1757 checkConsistencyLight();
1758 const INTERP_KERNEL::CellModel& cm(getCellModel());
1759 if(cm.getEnum()!=INTERP_KERNEL::NORM_TRI3)
1760 THROW_IK_EXCEPTION("MEDCoupling1SGTUMesh::computeTriangleHeight : this method can be applied only on TRI3 mesh !");
1761 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
1762 mcIdType nbTri3( getNumberOfCells() );
1763 const double *coordPtr( this->getCoords()->begin() );
1764 const mcIdType *inConnPtr(getNodalConnectivity()->begin());
1765 ret->alloc(nbTri3,3);
1766 double *retPtr( ret->getPointer() );
1767 switch( this->getSpaceDimension())
1771 constexpr unsigned SPACEDIM = 2;
1772 for(mcIdType iCell = 0 ; iCell < nbTri3 ; ++iCell)
1774 INTERP_KERNEL::ComputeTriangleHeight<SPACEDIM>(coordPtr + SPACEDIM*inConnPtr[3*iCell+0], coordPtr + SPACEDIM*inConnPtr[3*iCell+1], coordPtr + SPACEDIM*inConnPtr[3*iCell+2],retPtr+3*iCell);
1780 constexpr unsigned SPACEDIM = 3;
1781 for(mcIdType iCell = 0 ; iCell < nbTri3 ; ++iCell)
1783 INTERP_KERNEL::ComputeTriangleHeight<SPACEDIM>(coordPtr + SPACEDIM*inConnPtr[3*iCell+0], coordPtr + SPACEDIM*inConnPtr[3*iCell+1], coordPtr + SPACEDIM*inConnPtr[3*iCell+2],retPtr+3*iCell);
1788 THROW_IK_EXCEPTION("MEDCoupling1SGTUMesh::computeTriangleHeight : only spacedim in [2,3] supported !");
1794 * This method starts from an unstructured mesh that hides in reality a cartesian mesh.
1795 * If it is not the case, an exception will be thrown.
1796 * This method returns three objects : The cartesian mesh geometrically equivalent to \a this (within a precision of \a eps) and a permutation of cells
1797 * and a permutation of nodes.
1799 * - this[cellPerm[i]]=ret[i]
1801 * \param [out] cellPerm the permutation array of size \c this->getNumberOfCells()
1802 * \param [out] nodePerm the permutation array of size \c this->getNumberOfNodes()
1803 * \return MEDCouplingCMesh * - a newly allocated mesh that is the result of the structurization of \a this.
1805 MEDCouplingCMesh *MEDCoupling1SGTUMesh::structurizeMe(DataArrayIdType *& cellPerm, DataArrayIdType *& nodePerm, double eps) const
1807 checkConsistencyLight();
1808 int spaceDim(getSpaceDimension()),meshDim(getMeshDimension()); mcIdType nbNodes(getNumberOfNodes());
1809 if(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim)!=getCellModelEnum())
1810 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::structurizeMe : the unique geo type in this is not compatible with the geometric type regarding mesh dimension !");
1811 MCAuto<MEDCouplingCMesh> cm(MEDCouplingCMesh::New());
1812 for(int i=0;i<spaceDim;i++)
1814 std::vector<std::size_t> tmp(1,i);
1815 MCAuto<DataArrayDouble> elt(static_cast<DataArrayDouble*>(getCoords()->keepSelectedComponents(tmp)));
1816 elt=elt->getDifferentValues(eps);
1818 cm->setCoordsAt(i,elt);
1820 if(nbNodes!=cm->getNumberOfNodes())
1821 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::structurizeMe : considering the number of nodes after split per components in space this can't be a cartesian mesh ! Maybe your epsilon parameter is invalid ?");
1823 { cm->copyTinyInfoFrom(this); }
1824 catch(INTERP_KERNEL::Exception&) { }
1825 MCAuto<MEDCouplingUMesh> um(cm->buildUnstructured()),self(buildUnstructured());
1826 self->checkGeoEquivalWith(um,12,eps,cellPerm,nodePerm);
1832 bool UpdateHexa8Cell(int validAxis, mcIdType neighId, const mcIdType *validConnQuad4NeighSide, mcIdType *allFacesNodalConn, mcIdType *myNeighbours)
1834 static const int TAB[48]={
1842 static const int TAB2[6]={0,0,3,3,3,3};
1843 if(myNeighbours[validAxis]==neighId && allFacesNodalConn[4*validAxis+0]==validConnQuad4NeighSide[TAB2[validAxis]])
1845 mcIdType oldAxis(ToIdType(std::distance(myNeighbours,std::find(myNeighbours,myNeighbours+6,neighId))));
1846 std::size_t pos(std::distance(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,std::find(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS+6,oldAxis)));
1847 std::size_t pos0(pos/2),pos1(pos%2);
1848 int oldAxisOpp(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[2*pos0+(pos1+1)%2]);
1849 mcIdType oldConn[8],myConn2[8]={-1,-1,-1,-1,-1,-1,-1,-1},myConn[8],edgeConn[2],allFacesTmp[24],neighTmp[6];
1850 oldConn[0]=allFacesNodalConn[0]; oldConn[1]=allFacesNodalConn[1]; oldConn[2]=allFacesNodalConn[2]; oldConn[3]=allFacesNodalConn[3];
1851 oldConn[4]=allFacesNodalConn[4]; oldConn[5]=allFacesNodalConn[7]; oldConn[6]=allFacesNodalConn[6]; oldConn[7]=allFacesNodalConn[5];
1852 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_HEXA8));
1853 for(int i=0;i<4;i++)
1854 myConn2[i]=validConnQuad4NeighSide[(4-i+TAB2[validAxis])%4];
1855 for(int i=0;i<4;i++)
1857 mcIdType nodeId(myConn2[i]);//the node id for which the opposite one will be found
1859 INTERP_KERNEL::NormalizedCellType typeOfSon;
1860 for(int j=0;j<12 && !found;j++)
1862 cm.fillSonEdgesNodalConnectivity3D(j,oldConn,-1,edgeConn,typeOfSon);
1863 if(edgeConn[0]==nodeId || edgeConn[1]==nodeId)
1865 if(std::find(allFacesNodalConn+4*oldAxisOpp,allFacesNodalConn+4*oldAxisOpp+4,edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0])!=allFacesNodalConn+4*oldAxisOpp+4)
1867 myConn2[i+4]=edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0];
1873 throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error !");
1875 const int *myTab(TAB+8*validAxis);
1876 for(int i=0;i<8;i++)
1877 myConn[i]=myConn2[myTab[i]];
1878 for(int i=0;i<6;i++)
1880 cm.fillSonCellNodalConnectivity(i,myConn,allFacesTmp+4*i);
1881 std::set<mcIdType> s(allFacesTmp+4*i,allFacesTmp+4*i+4);
1883 for(int j=0;j<6 && !found;j++)
1885 std::set<mcIdType> s1(allFacesNodalConn+4*j,allFacesNodalConn+4*j+4);
1888 neighTmp[i]=myNeighbours[j];
1893 throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error #2 !");
1895 std::copy(allFacesTmp,allFacesTmp+24,allFacesNodalConn);
1896 std::copy(neighTmp,neighTmp+6,myNeighbours);
1903 * This method expects the \a this contains NORM_HEXA8 cells only. This method will sort each cells in \a this so that their numbering was
1904 * homogeneous. If it succeeds the result of MEDCouplingUMesh::tetrahedrize will return a conform mesh.
1906 * \return DataArrayIdType * - a newly allocated array (to be managed by the caller) containing renumbered cell ids.
1908 * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
1909 * \throw If \a this is not properly allocated.
1910 * \sa MEDCouplingUMesh::tetrahedrize, MEDCouplingUMesh::simplexize.
1912 DataArrayIdType *MEDCoupling1SGTUMesh::sortHexa8EachOther()
1914 MCAuto<MEDCoupling1SGTUMesh> quads(explodeEachHexa8To6Quad4());//checks that only hexa8
1915 mcIdType nbHexa8=getNumberOfCells();
1916 mcIdType *cQuads(quads->getNodalConnectivity()->getPointer());
1917 MCAuto<DataArrayIdType> neighOfQuads(DataArrayIdType::New()); neighOfQuads->alloc(nbHexa8*6,1); neighOfQuads->fillWithValue(-1);
1918 mcIdType *ptNeigh(neighOfQuads->getPointer());
1919 {//neighOfQuads tells for each face of each Quad8 which cell (if!=-1) is connected to this face.
1920 MCAuto<MEDCouplingUMesh> quadsTmp(quads->buildUnstructured());
1921 MCAuto<DataArrayIdType> ccSafe,cciSafe;
1922 DataArrayIdType *cc(0),*cci(0);
1923 quadsTmp->findCommonCells(3,0,cc,cci);
1924 ccSafe=cc; cciSafe=cci;
1925 const mcIdType *ccPtr(ccSafe->begin());
1926 mcIdType nbOfPair=cci->getNumberOfTuples()-1;
1927 for(mcIdType i=0;i<nbOfPair;i++)
1928 { ptNeigh[ccPtr[2*i+0]]=ccPtr[2*i+1]/6; ptNeigh[ccPtr[2*i+1]]=ccPtr[2*i+0]/6; }
1930 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(0,1);
1931 std::vector<bool> fetched(nbHexa8,false);
1932 std::vector<bool>::iterator it(std::find(fetched.begin(),fetched.end(),false));
1933 while(it!=fetched.end())//it will turns as time as number of connected zones
1935 mcIdType cellId(ToIdType(std::distance(fetched.begin(),it)));//it is the seed of the connected zone.
1936 std::set<mcIdType> s; s.insert(cellId);//s contains already organized.
1939 std::set<mcIdType> sNext;
1940 for(std::set<mcIdType>::const_iterator it0=s.begin();it0!=s.end();it0++)
1943 mcIdType *myNeighb(ptNeigh+6*(*it0));
1944 for(int i=0;i<6;i++)
1946 if(myNeighb[i]!=-1 && !fetched[myNeighb[i]])
1948 std::size_t pos(std::distance(HEXA8_FACE_PAIRS,std::find(HEXA8_FACE_PAIRS,HEXA8_FACE_PAIRS+6,i)));
1949 std::size_t pos0(pos/2),pos1(pos%2);
1950 if(!UpdateHexa8Cell(HEXA8_FACE_PAIRS[2*pos0+(pos1+1)%2],*it0,cQuads+6*4*(*it0)+4*i,cQuads+6*4*myNeighb[i],ptNeigh+6*myNeighb[i]))
1951 ret->pushBackSilent(myNeighb[i]);
1952 fetched[myNeighb[i]]=true;
1953 sNext.insert(myNeighb[i]);
1959 it=std::find(fetched.begin(),fetched.end(),false);
1963 mcIdType *conn(getNodalConnectivity()->getPointer());
1964 for(const mcIdType *pt=ret->begin();pt!=ret->end();pt++)
1966 mcIdType cellId(*pt);
1967 conn[8*cellId+0]=cQuads[24*cellId+0]; conn[8*cellId+1]=cQuads[24*cellId+1]; conn[8*cellId+2]=cQuads[24*cellId+2]; conn[8*cellId+3]=cQuads[24*cellId+3];
1968 conn[8*cellId+4]=cQuads[24*cellId+4]; conn[8*cellId+5]=cQuads[24*cellId+7]; conn[8*cellId+6]=cQuads[24*cellId+6]; conn[8*cellId+7]=cQuads[24*cellId+5];
1975 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh3D() const
1977 static const int DUAL_TETRA_0[36]={
1978 4,1,0, 6,0,3, 7,3,1,
1979 4,0,1, 5,2,0, 8,1,2,
1980 6,3,0, 5,0,2, 9,2,3,
1983 static const int DUAL_TETRA_1[36]={
1984 8,4,10, 11,5,8, 10,7,11,
1985 9,4,8, 8,5,12, 12,6,9,
1986 10,4,9, 9,6,13, 13,7,10,
1987 12,5,11, 13,6,12, 11,7,13
1989 static const int FACEID_NOT_SH_NODE[4]={2,3,1,0};
1990 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TETRA4)
1991 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh3D : only TETRA4 supported !");
1992 checkFullyDefined();
1993 MCAuto<MEDCouplingUMesh> thisu(buildUnstructured());
1994 MCAuto<DataArrayIdType> revNodArr(DataArrayIdType::New()),revNodIArr(DataArrayIdType::New());
1995 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1996 const mcIdType *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1997 MCAuto<DataArrayIdType> d1Arr(DataArrayIdType::New()),di1Arr(DataArrayIdType::New()),rd1Arr(DataArrayIdType::New()),rdi1Arr(DataArrayIdType::New());
1998 MCAuto<MEDCouplingUMesh> edges(thisu->explode3DMeshTo1D(d1Arr,di1Arr,rd1Arr,rdi1Arr));
1999 const mcIdType *d1(d1Arr->begin());
2000 MCAuto<DataArrayIdType> d2Arr(DataArrayIdType::New()),di2Arr(DataArrayIdType::New()),rd2Arr(DataArrayIdType::New()),rdi2Arr(DataArrayIdType::New());
2001 MCAuto<MEDCouplingUMesh> faces(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
2002 const mcIdType *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
2003 MCAuto<DataArrayDouble> edgesBaryArr(edges->computeCellCenterOfMass()),facesBaryArr(faces->computeCellCenterOfMass()),baryArr(computeCellCenterOfMass());
2004 const mcIdType nbOfNodes(getNumberOfNodes());
2005 const mcIdType offset0=nbOfNodes+faces->getNumberOfCells();
2006 const mcIdType offset1=offset0+edges->getNumberOfCells();
2008 std::vector<const DataArrayDouble *> v(4); v[0]=getCoords(); v[1]=facesBaryArr; v[2]=edgesBaryArr; v[3]=baryArr;
2009 MCAuto<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0; facesBaryArr=0;
2010 std::string name("DualOf_"); name+=getName();
2011 MCAuto<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYHED)); ret->setCoords(zeArr);
2012 MCAuto<DataArrayIdType> cArr(DataArrayIdType::New()),ciArr(DataArrayIdType::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
2013 for(mcIdType i=0;i<nbOfNodes;i++,revNodI++)
2015 mcIdType nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
2016 if(nbOfCellsSharingNode==0)
2018 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh3D : Node #" << i << " is orphan !";
2019 throw INTERP_KERNEL::Exception(oss.str().c_str());
2021 for(int j=0;j<nbOfCellsSharingNode;j++)
2023 mcIdType curCellId(revNod[revNodI[0]+j]);
2024 const mcIdType *connOfCurCell(nodal+4*curCellId);
2025 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
2026 if(j!=0) cArr->pushBackSilent(-1);
2029 tmp[0]=d1[6*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+0]-4]+offset0; tmp[1]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+1]]+nbOfNodes;
2030 tmp[2]=curCellId+offset1; tmp[3]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+2]]+nbOfNodes;
2032 tmp[5]=d1[6*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+3]-4]+offset0; tmp[6]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+4]]+nbOfNodes;
2033 tmp[7]=curCellId+offset1; tmp[8]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+5]]+nbOfNodes;
2035 tmp[10]=d1[6*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+6]-4]+offset0; tmp[11]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+7]]+nbOfNodes;
2036 tmp[12]=curCellId+offset1; tmp[13]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+8]]+nbOfNodes;
2037 cArr->insertAtTheEnd(tmp,tmp+14);
2039 for(int k=0;k<4;k++)
2041 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
2043 const mcIdType *faceId(d2+4*curCellId+k);
2044 if(rdi2[*faceId+1]-rdi2[*faceId]==1)
2046 mcIdType tmp2[5]; tmp2[0]=-1; tmp2[1]=i;
2047 tmp2[2]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+0]-8]+offset0;
2048 tmp2[3]=d2[4*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+1]-4]+nbOfNodes;
2049 tmp2[4]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+2]-8]+offset0;
2050 cArr->insertAtTheEnd(tmp2,tmp2+5);
2056 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
2058 ret->setNodalConnectivity(cArr,ciArr);
2062 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh2D() const
2064 static const int DUAL_TRI_0[6]={0,2, 1,0, 2,1};
2065 static const int DUAL_TRI_1[6]={-3,+5, +3,-4, +4,-5};
2066 static const int FACEID_NOT_SH_NODE[3]={1,2,0};
2067 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TRI3)
2068 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh2D : only TRI3 supported !");
2069 checkFullyDefined();
2070 MCAuto<MEDCouplingUMesh> thisu(buildUnstructured());
2071 MCAuto<DataArrayIdType> revNodArr(DataArrayIdType::New()),revNodIArr(DataArrayIdType::New());
2072 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
2073 const mcIdType *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
2074 MCAuto<DataArrayIdType> d2Arr(DataArrayIdType::New()),di2Arr(DataArrayIdType::New()),rd2Arr(DataArrayIdType::New()),rdi2Arr(DataArrayIdType::New());
2075 MCAuto<MEDCouplingUMesh> edges(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
2076 const mcIdType *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
2077 MCAuto<DataArrayDouble> edgesBaryArr(edges->computeCellCenterOfMass()),baryArr(computeCellCenterOfMass());
2078 const mcIdType nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+edges->getNumberOfCells());
2080 std::vector<const DataArrayDouble *> v(3); v[0]=getCoords(); v[1]=edgesBaryArr; v[2]=baryArr;
2081 MCAuto<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0;
2082 std::string name("DualOf_"); name+=getName();
2083 MCAuto<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYGON)); ret->setCoords(zeArr);
2084 MCAuto<DataArrayIdType> cArr(DataArrayIdType::New()),ciArr(DataArrayIdType::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
2085 for(mcIdType i=0;i<nbOfNodes;i++,revNodI++)
2087 mcIdType nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
2088 if(nbOfCellsSharingNode==0)
2090 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh2D : Node #" << i << " is orphan !";
2091 throw INTERP_KERNEL::Exception(oss.str().c_str());
2093 std::vector< std::vector<mcIdType> > polyg;
2094 for(int j=0;j<nbOfCellsSharingNode;j++)
2096 mcIdType curCellId(revNod[revNodI[0]+j]);
2097 const mcIdType *connOfCurCell(nodal+3*curCellId);
2098 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
2099 std::vector<mcIdType> locV(3);
2100 locV[0]=d2[3*curCellId+DUAL_TRI_0[2*nodePosInCurCell+0]]+nbOfNodes; locV[1]=curCellId+offset0; locV[2]=d2[3*curCellId+DUAL_TRI_0[2*nodePosInCurCell+1]]+nbOfNodes;
2101 polyg.push_back(locV);
2103 for(int k=0;k<3;k++)
2105 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
2107 const mcIdType *edgeId(d2+3*curCellId+k);
2108 if(rdi2[*edgeId+1]-rdi2[*edgeId]==1)
2110 std::vector<mcIdType> locV2(2);
2111 int zeLocEdgeIdRel(DUAL_TRI_1[2*nodePosInCurCell+kk]);
2112 if(zeLocEdgeIdRel>0)
2113 { locV2[0]=d2[3*curCellId+zeLocEdgeIdRel-3]+nbOfNodes; locV2[1]=i; }
2115 { locV2[0]=i; locV2[1]=d2[3*curCellId-zeLocEdgeIdRel-3]+nbOfNodes; }
2116 polyg.push_back(locV2);
2122 std::vector<mcIdType> zePolyg(MEDCoupling1DGTUMesh::BuildAPolygonFromParts(polyg));
2123 cArr->insertAtTheEnd(zePolyg.begin(),zePolyg.end());
2124 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
2126 ret->setNodalConnectivity(cArr,ciArr);
2131 * This method aggregate the bbox of each cell and put it into bbox
2133 * \param [in] arcDetEps - a parameter specifying in case of 2D quadratic polygon cell the detection limit between linear and arc circle. (By default 1e-12)
2134 * For all other cases this input parameter is ignored.
2135 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
2137 * \throw If \a this is not fully set (coordinates and connectivity).
2138 * \throw If a cell in \a this has no valid nodeId.
2140 DataArrayDouble *MEDCoupling1SGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
2142 mcIdType spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()),nbOfNodesPerCell(getNumberOfNodesPerCell());
2143 MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
2144 double *bbox(ret->getPointer());
2145 for(mcIdType i=0;i<nbOfCells*spaceDim;i++)
2147 bbox[2*i]=std::numeric_limits<double>::max();
2148 bbox[2*i+1]=-std::numeric_limits<double>::max();
2150 const double *coordsPtr(_coords->getConstPointer());
2151 const mcIdType *conn(_conn->getConstPointer());
2152 for(mcIdType i=0;i<nbOfCells;i++)
2155 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
2157 mcIdType nodeId(*conn);
2158 if(nodeId>=0 && nodeId<nbOfNodes)
2160 for(int k=0;k<spaceDim;k++)
2162 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
2163 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
2170 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
2171 throw INTERP_KERNEL::Exception(oss.str().c_str());
2178 * Returns the cell field giving for each cell in \a this its diameter. Diameter means the max length of all possible SEG2 in the cell.
2180 * \return a new instance of field containing the result. The returned instance has to be deallocated by the caller.
2182 MEDCouplingFieldDouble *MEDCoupling1SGTUMesh::computeDiameterField() const
2184 checkFullyDefined();
2185 MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME));
2186 mcIdType nbCells=getNumberOfCells();
2187 MCAuto<DataArrayDouble> arr(DataArrayDouble::New());
2188 arr->alloc(nbCells,1);
2189 INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::DiameterCalculator> dc(_cm->buildInstanceOfDiameterCalulator(getSpaceDimension()));
2190 dc->computeFor1SGTUMeshFrmt(nbCells,_conn->begin(),getCoords()->begin(),arr->getPointer());
2193 ret->setName("Diameter");
2198 * This method invert orientation of all cells in \a this.
2199 * After calling this method the absolute value of measure of cells in \a this are the same than before calling.
2200 * This method only operates on the connectivity so coordinates are not touched at all.
2202 void MEDCoupling1SGTUMesh::invertOrientationOfAllCells()
2204 checkConsistencyOfConnectivity();
2205 INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::OrientationInverter> oi(INTERP_KERNEL::OrientationInverter::BuildInstanceFrom(getCellModelEnum()));
2206 mcIdType nbOfNodesPerCell=ToIdType(_cm->getNumberOfNodes()),nbCells=getNumberOfCells();
2207 mcIdType *conn(_conn->getPointer());
2208 for(mcIdType i=0;i<nbCells;i++)
2209 oi->operate(conn+i*nbOfNodesPerCell,conn+(i+1)*nbOfNodesPerCell);
2215 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New()
2217 return new MEDCoupling1DGTUMesh;
2220 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
2222 if(type==INTERP_KERNEL::NORM_ERROR)
2223 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
2224 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
2227 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !";
2228 throw INTERP_KERNEL::Exception(oss.str().c_str());
2230 return new MEDCoupling1DGTUMesh(name,cm);
2233 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh()
2237 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
2241 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn_indx(other._conn_indx),_conn(other._conn)
2245 const DataArrayIdType *c(other._conn);
2247 _conn=c->deepCopy();
2250 _conn_indx=c->deepCopy();
2254 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const
2256 return new MEDCoupling1DGTUMesh(*this,recDeepCpy);
2260 * This method behaves mostly like MEDCoupling1DGTUMesh::deepCopy method, except that only nodal connectivity arrays are deeply copied.
2261 * The coordinates are shared between \a this and the returned instance.
2263 * \return MEDCoupling1DGTUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
2264 * \sa MEDCoupling1DGTUMesh::deepCopy
2266 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::deepCopyConnectivityOnly() const
2268 checkConsistencyLight();
2269 MCAuto<MEDCoupling1DGTUMesh> ret(clone(false));
2270 MCAuto<DataArrayIdType> c(_conn->deepCopy()),ci(_conn_indx->deepCopy());
2271 ret->setNodalConnectivity(c,ci);
2275 void MEDCoupling1DGTUMesh::updateTime() const
2277 MEDCoupling1GTUMesh::updateTime();
2278 const DataArrayIdType *c(_conn);
2286 std::size_t MEDCoupling1DGTUMesh::getHeapMemorySizeWithoutChildren() const
2288 return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren();
2291 std::vector<const BigMemoryObject *> MEDCoupling1DGTUMesh::getDirectChildrenWithNull() const
2293 std::vector<const BigMemoryObject *> ret(MEDCoupling1GTUMesh::getDirectChildrenWithNull());
2294 ret.push_back((const DataArrayIdType *)_conn);
2295 ret.push_back((const DataArrayIdType *)_conn_indx);
2299 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::deepCopy() const
2304 bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
2307 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !");
2308 std::ostringstream oss; oss.precision(15);
2309 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2312 reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !";
2315 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
2317 const DataArrayIdType *c1(_conn),*c2(otherC->_conn);
2322 reason="in connectivity of single dynamic geometric type exactly one among this and other is null !";
2325 if(!c1->isEqualIfNotWhy(*c2,reason))
2327 reason.insert(0,"Nodal connectivity DataArrayIdType differs : ");
2330 c1=_conn_indx; c2=otherC->_conn_indx;
2335 reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !";
2338 if(!c1->isEqualIfNotWhy(*c2,reason))
2340 reason.insert(0,"Nodal connectivity index DataArrayIdType differs : ");
2346 bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
2349 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
2350 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2353 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
2355 const DataArrayIdType *c1(_conn),*c2(otherC->_conn);
2360 if(!c1->isEqualWithoutConsideringStr(*c2))
2366 * Checks if \a this and \a other meshes are geometrically equivalent with high
2367 * probability, else an exception is thrown. The meshes are considered equivalent if
2368 * (1) meshes contain the same number of nodes and the same number of elements of the
2369 * same types (2) three cells of the two meshes (first, last and middle) are based
2370 * on coincident nodes (with a specified precision).
2371 * \param [in] other - the mesh to compare with.
2372 * \param [in] prec - the precision used to compare nodes of the two meshes.
2373 * \throw If the two meshes do not match.
2375 void MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
2377 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
2378 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2380 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single dynamic geometric type !");
2381 const DataArrayIdType *c1(_conn),*c2(otherC->_conn);
2385 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
2386 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2387 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
2388 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2389 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
2390 if(c1->getHashCode()!=c2->getHashCode())
2391 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs");
2393 c1=_conn_indx; c2=otherC->_conn_indx;
2397 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !");
2398 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2399 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !");
2400 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2401 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !");
2402 if(c1->getHashCode()!=c2->getHashCode())
2403 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs");
2407 void MEDCoupling1DGTUMesh::checkConsistencyOfConnectivity() const
2409 const DataArrayIdType *c1(_conn);
2412 if(c1->getNumberOfComponents()!=1)
2413 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
2414 if(c1->getInfoOnComponent(0)!="")
2415 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
2416 c1->checkAllocated();
2419 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
2421 mcIdType sz2(_conn->getNumberOfTuples());
2425 if(c1->getNumberOfComponents()!=1)
2426 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
2427 c1->checkAllocated();
2428 if(c1->getNumberOfTuples()<1)
2429 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !");
2430 if(c1->getInfoOnComponent(0)!="")
2431 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
2432 mcIdType f=c1->front(),ll=c1->back();
2433 if(f<0 || (sz2>0 && f>=sz2))
2435 std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !";
2436 throw INTERP_KERNEL::Exception(oss.str().c_str());
2440 std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !";
2441 throw INTERP_KERNEL::Exception(oss.str().c_str());
2445 std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !";
2446 throw INTERP_KERNEL::Exception(oss.str().c_str());
2450 throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !");
2451 mcIdType szOfC1Exp=_conn_indx->back();
2454 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::checkConsistencyOfConnectivity : The expected length of nodal connectivity array regarding index is " << szOfC1Exp << " but the actual size of it is " << c1->getNumberOfTuples() << " !";
2455 throw INTERP_KERNEL::Exception(oss.str().c_str());
2460 * If \a this pass this method, you are sure that connectivity arrays are not null, with exactly one component, no name, no component name, allocated.
2461 * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one.
2462 * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array.
2464 void MEDCoupling1DGTUMesh::checkConsistencyLight() const
2466 MEDCouplingPointSet::checkConsistencyLight();
2467 checkConsistencyOfConnectivity();
2470 void MEDCoupling1DGTUMesh::checkConsistency(double eps) const
2472 checkConsistencyLight();
2473 const DataArrayIdType *c1(_conn),*c2(_conn_indx);
2474 if(!c2->isMonotonic(true))
2475 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkConsistency : the nodal connectivity index is expected to be increasing monotinic !");
2477 mcIdType nbOfTuples(c1->getNumberOfTuples());
2478 mcIdType nbOfNodes=getNumberOfNodes();
2479 const mcIdType *w(c1->begin());
2480 for(mcIdType i=0;i<nbOfTuples;i++,w++)
2482 if(*w==-1) continue;
2483 if(*w<0 || *w>=nbOfNodes)
2485 std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !";
2486 throw INTERP_KERNEL::Exception(oss.str().c_str());
2491 mcIdType MEDCoupling1DGTUMesh::getNumberOfCells() const
2493 checkConsistencyOfConnectivity();//do not remove
2494 return _conn_indx->getNumberOfTuples()-1;
2498 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2499 * For each cell in \b this the number of nodes constituting cell is computed.
2500 * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned.
2501 * So for pohyhedrons some nodes can be counted several times in the returned result.
2503 * \return a newly allocated array
2505 DataArrayIdType *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const
2507 checkConsistencyLight();
2508 _conn_indx->checkMonotonic(true);
2509 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2510 return _conn_indx->deltaShiftIndex();
2512 mcIdType nbOfCells=_conn_indx->getNumberOfTuples()-1;
2513 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
2514 ret->alloc(nbOfCells,1);
2515 mcIdType *retPtr=ret->getPointer();
2516 const mcIdType *ci=_conn_indx->begin(),*c=_conn->begin();
2517 for(mcIdType i=0;i<nbOfCells;i++,retPtr++,ci++)
2518 *retPtr=int(ci[1]-ci[0]-ToIdType(std::count(c+ci[0],c+ci[1],-1)));
2523 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2524 * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed.
2526 * \return a newly allocated array
2528 DataArrayIdType *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const
2530 checkConsistencyLight();
2531 _conn_indx->checkMonotonic(true);
2532 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG)
2533 return _conn_indx->deltaShiftIndex();
2534 if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG)
2536 MCAuto<DataArrayIdType> ret=_conn_indx->deltaShiftIndex();
2537 ret->applyDivideBy(2);
2541 mcIdType nbOfCells=_conn_indx->getNumberOfTuples()-1;
2542 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
2543 ret->alloc(nbOfCells,1);
2544 mcIdType *retPtr=ret->getPointer();
2545 const mcIdType *ci=_conn_indx->begin(),*c=_conn->begin();
2546 for(mcIdType i=0;i<nbOfCells;i++,retPtr++,ci++)
2547 *retPtr=ToIdType(std::count(c+ci[0],c+ci[1],-1))+1;
2552 * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell,
2553 * will be counted only once here whereas it will be counted several times in MEDCoupling1DGTUMesh::computeNbOfNodesPerCell method.
2555 * \return DataArrayIdType * - new object to be deallocated by the caller.
2556 * \sa MEDCoupling1DGTUMesh::computeNbOfNodesPerCell
2558 DataArrayIdType *MEDCoupling1DGTUMesh::computeEffectiveNbOfNodesPerCell() const
2560 checkConsistencyLight();
2561 _conn_indx->checkMonotonic(true);
2562 mcIdType nbOfCells=_conn_indx->getNumberOfTuples()-1;
2563 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
2564 ret->alloc(nbOfCells,1);
2565 mcIdType *retPtr(ret->getPointer());
2566 const mcIdType *ci(_conn_indx->begin()),*c(_conn->begin());
2567 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2569 for(mcIdType i=0;i<nbOfCells;i++,retPtr++,ci++)
2571 std::set<mcIdType> s(c+ci[0],c+ci[1]);
2572 *retPtr=ToIdType(s.size());
2577 for(mcIdType i=0;i<nbOfCells;i++,retPtr++,ci++)
2579 std::set<mcIdType> s(c+ci[0],c+ci[1]); s.erase(-1);
2580 *retPtr=ToIdType(s.size());
2586 void MEDCoupling1DGTUMesh::getNodeIdsOfCell(mcIdType cellId, std::vector<mcIdType>& conn) const
2588 mcIdType nbOfCells(getNumberOfCells());//performs checks
2589 if(cellId<nbOfCells)
2591 mcIdType strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2592 mcIdType nbOfNodes=stp-strt;
2594 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !");
2595 conn.resize(nbOfNodes);
2596 std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin());
2600 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2601 throw INTERP_KERNEL::Exception(oss.str().c_str());
2605 mcIdType MEDCoupling1DGTUMesh::getNumberOfNodesInCell(mcIdType cellId) const
2607 mcIdType nbOfCells=getNumberOfCells();//performs checks
2608 if(cellId>=0 && cellId<nbOfCells)
2610 const mcIdType *conn(_conn->begin());
2611 mcIdType strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2612 return stp-strt-ToIdType(std::count(conn+strt,conn+stp,-1));
2616 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNumberOfNodesInCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2617 throw INTERP_KERNEL::Exception(oss.str().c_str());
2621 std::string MEDCoupling1DGTUMesh::simpleRepr() const
2623 static const char msg0[]="No coordinates specified !";
2625 return std::string("Cell type not specified");
2626 std::ostringstream ret;
2627 ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
2628 ret << "Description of mesh : \"" << getDescription() << "\"\n";
2630 double tt=getTime(tmpp1,tmpp2);
2631 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
2632 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
2633 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
2636 const int spaceDim=getSpaceDimension();
2637 ret << spaceDim << "\nInfo attached on space dimension : ";
2638 for(int i=0;i<spaceDim;i++)
2639 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
2643 ret << msg0 << "\n";
2644 ret << "Number of nodes : ";
2646 ret << getNumberOfNodes() << "\n";
2648 ret << msg0 << "\n";
2649 ret << "Number of cells : ";
2651 try { checkConsistencyLight(); } catch(INTERP_KERNEL::Exception& /* e */)
2653 ret << "Nodal connectivity arrays are not set or badly set !\n";
2657 ret << getNumberOfCells() << "\n";
2658 ret << "Cell type : " << _cm->getRepr() << "\n";
2662 std::string MEDCoupling1DGTUMesh::advancedRepr() const
2664 std::ostringstream ret;
2665 ret << simpleRepr();
2666 ret << "\nCoordinates array : \n___________________\n\n";
2668 _coords->reprWithoutNameStream(ret);
2670 ret << "No array set !\n";
2671 ret << "\n\nNodal Connectivity : \n____________________\n\n";
2674 try { checkConsistency(); } catch(INTERP_KERNEL::Exception& /* e */)
2676 ret << "Nodal connectivity arrays are not set or badly set !\n";
2681 mcIdType nbOfCells=getNumberOfCells();
2682 const mcIdType *ci=_conn_indx->begin(),*c=_conn->begin();
2683 for(mcIdType i=0;i<nbOfCells;i++,ci++)
2685 ret << "Cell #" << i << " : ";
2686 std::copy(c+ci[0],c+ci[1],std::ostream_iterator<int>(ret," "));
2692 DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const
2694 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2695 int spaceDim=getSpaceDimension();
2696 mcIdType nbOfCells=getNumberOfCells();//checkConsistencyLight()
2697 mcIdType nbOfNodes=getNumberOfNodes();
2698 ret->alloc(nbOfCells,spaceDim);
2699 double *ptToFill=ret->getPointer();
2700 const double *coor=_coords->begin();
2701 const mcIdType *nodal=_conn->begin(),*nodali=_conn_indx->begin();
2703 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2705 for(mcIdType i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2707 std::fill(ptToFill,ptToFill+spaceDim,0.);
2708 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2710 for(mcIdType j=nodali[0];j<nodali[1];j++,nodal++)
2712 if(*nodal>=0 && *nodal<nbOfNodes)
2713 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2716 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2717 throw INTERP_KERNEL::Exception(oss.str().c_str());
2719 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind(std::multiplies<double>(),std::placeholders::_1,1./double(nodali[1]-nodali[0])));
2724 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !";
2725 throw INTERP_KERNEL::Exception(oss.str().c_str());
2731 for(mcIdType i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2733 std::fill(ptToFill,ptToFill+spaceDim,0.);
2734 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2737 for(mcIdType j=nodali[0];j<nodali[1];j++,nodal++)
2739 if(*nodal==-1) continue;
2740 if(*nodal>=0 && *nodal<nbOfNodes)
2742 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2747 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2748 throw INTERP_KERNEL::Exception(oss.str().c_str());
2752 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind(std::multiplies<double>(),std::placeholders::_1,1./nbOfNod));
2755 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !";
2756 throw INTERP_KERNEL::Exception(oss.str().c_str());
2761 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : at cell #" << i << " the nodal index array is invalid !";
2762 throw INTERP_KERNEL::Exception(oss.str().c_str());
2769 void MEDCoupling1DGTUMesh::renumberCells(const mcIdType *old2NewBg, bool check)
2771 mcIdType nbCells=getNumberOfCells();
2772 MCAuto<DataArrayIdType> o2n=DataArrayIdType::New();
2773 o2n->useArray(old2NewBg,false,DeallocType::C_DEALLOC,nbCells,1);
2775 o2n=o2n->checkAndPreparePermutation();
2777 const mcIdType *o2nPtr=o2n->getPointer();
2778 const mcIdType *conn=_conn->begin(),*conni=_conn_indx->begin();
2779 MCAuto<DataArrayIdType> newConn=DataArrayIdType::New();
2780 MCAuto<DataArrayIdType> newConnI=DataArrayIdType::New();
2781 newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1);
2782 newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx);
2784 mcIdType *newC=newConn->getPointer(),*newCI=newConnI->getPointer();
2785 for(mcIdType i=0;i<nbCells;i++)
2787 mcIdType newPos=o2nPtr[i];
2788 mcIdType sz=conni[i+1]-conni[i];
2793 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !";
2794 throw INTERP_KERNEL::Exception(oss.str().c_str());
2797 newConnI->computeOffsetsFull(); newCI=newConnI->getPointer();
2799 for(mcIdType i=0;i<nbCells;i++,conni++)
2801 mcIdType newp=o2nPtr[i];
2802 std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]);
2805 _conn_indx=newConnI;
2808 MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
2810 if(other->getType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED)
2811 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !");
2812 const MEDCoupling1DGTUMesh *otherC=static_cast<const MEDCoupling1DGTUMesh *>(other);
2813 return Merge1DGTUMeshes(this,otherC);
2816 MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const
2818 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
2819 ret->setCoords(getCoords());
2820 const mcIdType *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin();
2821 mcIdType nbCells=getNumberOfCells();//checkConsistencyLight
2822 mcIdType geoType=ToIdType(getCellModelEnum());
2823 MCAuto<DataArrayIdType> c=DataArrayIdType::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1);
2824 MCAuto<DataArrayIdType> cI=DataArrayIdType::New(); cI->alloc(nbCells+1);
2825 mcIdType *cPtr=c->getPointer(),*ciPtr=cI->getPointer();
2827 for(mcIdType i=0;i<nbCells;i++,ciPtr++)
2829 mcIdType sz=nodalConnI[i+1]-nodalConnI[i];
2833 cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr);
2834 ciPtr[1]=ciPtr[0]+sz+1;
2838 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !";
2839 throw INTERP_KERNEL::Exception(oss.str().c_str());
2842 ret->setConnectivity(c,cI,true);
2844 { ret->copyTinyInfoFrom(this); }
2845 catch(INTERP_KERNEL::Exception&) { }
2850 * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes
2852 DataArrayIdType *MEDCoupling1DGTUMesh::simplexize(int policy)
2854 mcIdType nbOfCells=getNumberOfCells();
2855 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
2856 ret->alloc(nbOfCells,1);
2861 void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const
2863 stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=";
2866 stream << "Not defined";
2869 stream << _cm->getRepr() << ". Name : \"" << getName() << "\".";
2870 stream << " Mesh dimension : " << getMeshDimension() << ".";
2872 { stream << " No coordinates set !"; return ; }
2873 if(!_coords->isAllocated())
2874 { stream << " Coordinates set but not allocated !"; return ; }
2875 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
2876 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
2878 try { checkConsistencyLight(); } catch(INTERP_KERNEL::Exception& /* e */)
2880 stream << std::endl << "Nodal connectivity NOT set properly !\n";
2884 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
2887 void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
2890 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
2891 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2893 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !");
2894 setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex());
2897 MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
2900 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
2901 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2903 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
2904 std::vector<const MEDCoupling1DGTUMesh *> ms(2);
2907 return Merge1DGTUMeshesOnSameCoords(ms);
2910 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const mcIdType *begin, const mcIdType *end) const
2912 checkConsistencyLight();
2913 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2914 ret->setCoords(_coords);
2915 DataArrayIdType *c=0,*ci=0;
2916 DataArrayIdType::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci);
2917 MCAuto<DataArrayIdType> cSafe(c),ciSafe(ci);
2918 ret->setNodalConnectivity(c,ci);
2922 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoordsSlice(mcIdType start, mcIdType end, mcIdType step) const
2924 checkConsistencyLight();
2925 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2926 ret->setCoords(_coords);
2927 DataArrayIdType *c=0,*ci=0;
2928 DataArrayIdType::ExtractFromIndexedArraysSlice(start,end,step,_conn,_conn_indx,c,ci);
2929 MCAuto<DataArrayIdType> cSafe(c),ciSafe(ci);
2930 ret->setNodalConnectivity(c,ci);
2934 void MEDCoupling1DGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
2937 mcIdType sz(ToIdType(nodeIdsInUse.size()));
2938 for(const mcIdType *conn=_conn->begin();conn!=_conn->end();conn++)
2940 if(*conn>=0 && *conn<sz)
2941 nodeIdsInUse[*conn]=true;
2946 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeNodeIdsAlg : At pos #" << std::distance(_conn->begin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !";
2947 throw INTERP_KERNEL::Exception(oss.str().c_str());
2953 void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayIdType *revNodal, DataArrayIdType *revNodalIndx) const
2955 checkFullyDefined();
2956 mcIdType nbOfNodes=getNumberOfNodes();
2957 mcIdType *revNodalIndxPtr=(mcIdType *)malloc((nbOfNodes+1)*sizeof(mcIdType));
2958 revNodalIndx->useArray(revNodalIndxPtr,true,DeallocType::C_DEALLOC,nbOfNodes+1,1);
2959 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
2960 const mcIdType *conn=_conn->begin(),*conni=_conn_indx->begin();
2961 mcIdType nbOfCells=getNumberOfCells();
2962 mcIdType nbOfEltsInRevNodal=0;
2963 for(mcIdType eltId=0;eltId<nbOfCells;eltId++)
2965 mcIdType nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2966 if(nbOfNodesPerCell>=0)
2968 for(mcIdType j=0;j<nbOfNodesPerCell;j++)
2970 mcIdType nodeId=conn[conni[eltId]+j];
2971 if(nodeId==-1) continue;
2972 if(nodeId>=0 && nodeId<nbOfNodes)
2974 nbOfEltsInRevNodal++;
2975 revNodalIndxPtr[nodeId+1]++;
2979 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
2980 throw INTERP_KERNEL::Exception(oss.str().c_str());
2986 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << "nodal connectivity is invalid !";
2987 throw INTERP_KERNEL::Exception(oss.str().c_str());
2990 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<mcIdType>());
2991 conn=_conn->begin();
2992 mcIdType *revNodalPtr=(mcIdType *)malloc((nbOfEltsInRevNodal)*sizeof(mcIdType));
2993 revNodal->useArray(revNodalPtr,true,DeallocType::C_DEALLOC,nbOfEltsInRevNodal,1);
2994 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
2995 for(mcIdType eltId=0;eltId<nbOfCells;eltId++)
2997 mcIdType nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2998 for(mcIdType j=0;j<nbOfNodesPerCell;j++)
3000 mcIdType nodeId=conn[conni[eltId]+j];
3002 *std::find_if(revNodalPtr+revNodalIndxPtr[nodeId],revNodalPtr+revNodalIndxPtr[nodeId+1],std::bind(std::equal_to<mcIdType>(),std::placeholders::_1,-1))=eltId;
3007 void MEDCoupling1DGTUMesh::checkFullyDefined() const
3009 if(!((const DataArrayIdType *)_conn) || !((const DataArrayIdType *)_conn_indx) || !((const DataArrayDouble *)_coords))
3010 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined.");
3013 bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector<mcIdType>& tinyInfo) const
3015 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !");
3018 void MEDCoupling1DGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<mcIdType>& tinyInfo, std::vector<std::string>& littleStrings) const
3021 double time=getTime(it,order);
3022 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
3024 littleStrings.push_back(getName());
3025 littleStrings.push_back(getDescription());
3026 littleStrings.push_back(getTimeUnit());
3028 std::vector<std::string> littleStrings2,littleStrings3,littleStrings4;
3029 if((const DataArrayDouble *)_coords)
3030 _coords->getTinySerializationStrInformation(littleStrings2);
3031 if((const DataArrayIdType *)_conn)
3032 _conn->getTinySerializationStrInformation(littleStrings3);
3033 if((const DataArrayIdType *)_conn_indx)
3034 _conn_indx->getTinySerializationStrInformation(littleStrings4);
3035 mcIdType sz0(ToIdType(littleStrings2.size())),sz1(ToIdType(littleStrings3.size())),sz2(ToIdType(littleStrings4.size()));
3036 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
3037 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
3038 littleStrings.insert(littleStrings.end(),littleStrings4.begin(),littleStrings4.end());
3040 tinyInfo.push_back(getCellModelEnum());
3041 tinyInfo.push_back(it);
3042 tinyInfo.push_back(order);
3043 std::vector<mcIdType> tinyInfo2,tinyInfo3,tinyInfo4;
3044 if((const DataArrayDouble *)_coords)
3045 _coords->getTinySerializationIntInformation(tinyInfo2);
3046 if((const DataArrayIdType *)_conn)
3047 _conn->getTinySerializationIntInformation(tinyInfo3);
3048 if((const DataArrayIdType *)_conn_indx)
3049 _conn_indx->getTinySerializationIntInformation(tinyInfo4);
3050 mcIdType sz3(ToIdType(tinyInfo2.size())),sz4(ToIdType(tinyInfo3.size())),sz5(ToIdType(tinyInfo4.size()));
3051 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3); tinyInfo.push_back(sz4); tinyInfo.push_back(sz5);
3052 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
3053 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
3054 tinyInfo.insert(tinyInfo.end(),tinyInfo4.begin(),tinyInfo4.end());
3056 tinyInfoD.push_back(time);
3059 void MEDCoupling1DGTUMesh::resizeForUnserialization(const std::vector<mcIdType>& tinyInfo, DataArrayIdType *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
3061 std::vector<mcIdType> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+tinyInfo[6]);
3062 std::vector<mcIdType> tinyInfo1(tinyInfo.begin()+9+tinyInfo[6],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]);
3063 std::vector<mcIdType> tinyInfo12(tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]+tinyInfo[8]);
3064 MCAuto<DataArrayIdType> p1(DataArrayIdType::New()); p1->resizeForUnserialization(tinyInfo1);
3065 MCAuto<DataArrayIdType> p2(DataArrayIdType::New()); p2->resizeForUnserialization(tinyInfo12);
3066 std::vector<const DataArrayIdType *> v(2); v[0]=p1; v[1]=p2;
3067 p2=DataArrayIdType::Aggregate(v);
3068 a2->resizeForUnserialization(tinyInfo2);
3069 a1->alloc(p2->getNbOfElems(),1);
3072 void MEDCoupling1DGTUMesh::serialize(DataArrayIdType *&a1, DataArrayDouble *&a2) const
3075 if((const DataArrayIdType *)_conn)
3076 if(_conn->isAllocated())
3077 sz=_conn->getNbOfElems();
3078 if((const DataArrayIdType *)_conn_indx)
3079 if(_conn_indx->isAllocated())
3080 sz+=_conn_indx->getNbOfElems();
3081 a1=DataArrayIdType::New();
3083 mcIdType *work(a1->getPointer());
3084 if(sz!=0 && (const DataArrayIdType *)_conn)
3085 work=std::copy(_conn->begin(),_conn->end(),a1->getPointer());
3086 if(sz!=0 && (const DataArrayIdType *)_conn_indx)
3087 std::copy(_conn_indx->begin(),_conn_indx->end(),work);
3089 if((const DataArrayDouble *)_coords)
3090 if(_coords->isAllocated())
3091 sz=_coords->getNbOfElems();
3092 a2=DataArrayDouble::New();
3094 if(sz!=0 && (const DataArrayDouble *)_coords)
3095 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
3098 void MEDCoupling1DGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<mcIdType>& tinyInfo, const DataArrayIdType *a1, DataArrayDouble *a2,
3099 const std::vector<std::string>& littleStrings)
3101 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
3102 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
3103 setName(littleStrings[0]);
3104 setDescription(littleStrings[1]);
3105 setTimeUnit(littleStrings[2]);
3106 setTime(tinyInfoD[0],FromIdType<int>(tinyInfo[1]),FromIdType<int>(tinyInfo[2]));
3107 mcIdType sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]),sz4(tinyInfo[7]),sz5(tinyInfo[8]);
3109 _coords=DataArrayDouble::New();
3110 std::vector<mcIdType> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+sz3);
3111 _coords->resizeForUnserialization(tinyInfo2);
3112 std::copy(a2->begin(),a2->end(),_coords->getPointer());
3113 _conn=DataArrayIdType::New();
3114 std::vector<mcIdType> tinyInfo3(tinyInfo.begin()+9+sz3,tinyInfo.begin()+9+sz3+sz4);
3115 _conn->resizeForUnserialization(tinyInfo3);
3116 std::copy(a1->begin(),a1->begin()+_conn->getNbOfElems(),_conn->getPointer());
3117 _conn_indx=DataArrayIdType::New();
3118 std::vector<mcIdType> tinyInfo4(tinyInfo.begin()+9+sz3+sz4,tinyInfo.begin()+9+sz3+sz4+sz5);
3119 _conn_indx->resizeForUnserialization(tinyInfo4);
3120 std::copy(a1->begin()+_conn->getNbOfElems(),a1->end(),_conn_indx->getPointer());
3121 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
3122 _coords->finishUnserialization(tinyInfo2,littleStrings2);
3123 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
3124 _conn->finishUnserialization(tinyInfo3,littleStrings3);
3125 std::vector<std::string> littleStrings4(littleStrings.begin()+3+sz0+sz1,littleStrings.begin()+3+sz0+sz1+sz2);
3126 _conn_indx->finishUnserialization(tinyInfo4,littleStrings4);
3130 * Finds nodes not used in any cell and returns an array giving a new id to every node
3131 * by excluding the unused nodes, for which the array holds -1. The result array is
3132 * a mapping in "Old to New" mode.
3133 * \return DataArrayIdType * - a new instance of DataArrayIdType. Its length is \a
3134 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
3135 * if the node is unused or a new id else. The caller is to delete this
3136 * array using decrRef() as it is no more needed.
3137 * \throw If the coordinates array is not set.
3138 * \throw If the nodal connectivity of cells is not defined.
3139 * \throw If the nodal connectivity includes an invalid id.
3140 * \sa MEDCoupling1DGTUMesh::getNodeIdsInUse, areAllNodesFetched
3142 DataArrayIdType *MEDCoupling1DGTUMesh::computeFetchedNodeIds() const
3145 mcIdType nbNodes(getNumberOfNodes());
3146 std::vector<bool> fetchedNodes(nbNodes,false);
3147 computeNodeIdsAlg(fetchedNodes);
3148 mcIdType sz(ToIdType(std::count(fetchedNodes.begin(),fetchedNodes.end(),true)));
3149 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(sz,1);
3150 mcIdType *retPtr(ret->getPointer());
3151 for(mcIdType i=0;i<nbNodes;i++)
3158 * Finds nodes not used in any cell and returns an array giving a new id to every node
3159 * by excluding the unused nodes, for which the array holds -1. The result array is
3160 * a mapping in "Old to New" mode.
3161 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
3162 * \return DataArrayIdType * - a new instance of DataArrayIdType. Its length is \a
3163 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
3164 * if the node is unused or a new id else. The caller is to delete this
3165 * array using decrRef() as it is no more needed.
3166 * \throw If the coordinates array is not set.
3167 * \throw If the nodal connectivity of cells is not defined.
3168 * \throw If the nodal connectivity includes an invalid id.
3169 * \sa MEDCoupling1DGTUMesh::computeFetchedNodeIds, areAllNodesFetched
3171 DataArrayIdType *MEDCoupling1DGTUMesh::getNodeIdsInUse(mcIdType& nbrOfNodesInUse) const
3174 mcIdType nbOfNodes=getNumberOfNodes();
3175 mcIdType nbOfCells=getNumberOfCells();//checkConsistencyLight
3176 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
3177 ret->alloc(nbOfNodes,1);
3178 mcIdType *traducer=ret->getPointer();
3179 std::fill(traducer,traducer+nbOfNodes,-1);
3180 const mcIdType *conn=_conn->begin(),*conni(_conn_indx->begin());
3181 for(mcIdType i=0;i<nbOfCells;i++,conni++)
3183 mcIdType nbNodesPerCell=conni[1]-conni[0];
3184 for(mcIdType j=0;j<nbNodesPerCell;j++)
3186 mcIdType nodeId=conn[conni[0]+j];
3187 if(nodeId==-1) continue;
3188 if(nodeId>=0 && nodeId<nbOfNodes)
3192 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << nodeId << " not in [0," << nbOfNodes << ") !";
3193 throw INTERP_KERNEL::Exception(oss.str().c_str());
3197 nbrOfNodesInUse=ToIdType(std::count(traducer,traducer+nbOfNodes,1));
3198 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
3203 * This method renumbers only nodal connectivity in \a this. The renumbering is only an offset applied. So this method is a specialization of
3204 * \a renumberNodesInConn. \b WARNING, this method does not check that the resulting node ids in the nodal connectivity is in a valid range !
3206 * \param [in] offset - specifies the offset to be applied on each element of connectivity.
3208 * \sa renumberNodesInConn
3210 void MEDCoupling1DGTUMesh::renumberNodesWithOffsetInConn(mcIdType offset)
3212 getNumberOfCells();//only to check that all is well defined.
3214 mcIdType nbOfTuples(_conn->getNumberOfTuples());
3215 mcIdType *pt(_conn->getPointer());
3216 for(mcIdType i=0;i<nbOfTuples;i++,pt++)
3218 if(*pt==-1) continue;
3226 * Same than renumberNodesInConn(const mcIdType *) except that here the format of old-to-new traducer is using map instead
3227 * of array. This method is dedicated for renumbering from a big set of nodes the a tiny set of nodes which is the case during extraction
3230 void MEDCoupling1DGTUMesh::renumberNodesInConn(const INTERP_KERNEL::HashMap<mcIdType,mcIdType>& newNodeNumbersO2N)
3232 this->renumberNodesInConnT< INTERP_KERNEL::HashMap<mcIdType,mcIdType> >(newNodeNumbersO2N);
3236 * Same than renumberNodesInConn(const mcIdType *) except that here the format of old-to-new traducer is using map instead
3237 * of array. This method is dedicated for renumbering from a big set of nodes the a tiny set of nodes which is the case during extraction
3240 void MEDCoupling1DGTUMesh::renumberNodesInConn(const std::map<mcIdType,mcIdType>& newNodeNumbersO2N)
3242 this->renumberNodesInConnT< std::map<mcIdType,mcIdType> >(newNodeNumbersO2N);
3246 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
3247 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
3248 * This method is a generalization of shiftNodeNumbersInConn().
3249 * \warning This method performs no check of validity of new ids. **Use it with care !**
3250 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
3251 * this->getNumberOfNodes(), in "Old to New" mode.
3252 * See \ref numbering for more info on renumbering modes.
3253 * \throw If the nodal connectivity of cells is not defined.
3255 void MEDCoupling1DGTUMesh::renumberNodesInConn(const mcIdType *newNodeNumbersO2N)
3257 getNumberOfCells();//only to check that all is well defined.
3259 mcIdType nbElemsIn(getNumberOfNodes()),nbOfTuples(_conn->getNumberOfTuples());
3260 mcIdType *pt(_conn->getPointer());
3261 for(mcIdType i=0;i<nbOfTuples;i++,pt++)
3263 if(*pt==-1) continue;
3264 if(*pt>=0 && *pt<nbElemsIn)
3265 *pt=newNodeNumbersO2N[*pt];
3268 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
3269 throw INTERP_KERNEL::Exception(oss.str().c_str());
3277 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
3278 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
3279 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
3280 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
3282 * \param [in] begin input start of array of node ids.
3283 * \param [in] end input end of array of node ids.
3284 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
3285 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
3287 void MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const mcIdType *begin, const mcIdType *end, bool fullyIn, DataArrayIdType *&cellIdsKeptArr) const
3289 mcIdType nbOfCells=getNumberOfCells();
3290 MCAuto<DataArrayIdType> cellIdsKept=DataArrayIdType::New(); cellIdsKept->alloc(0,1);
3292 mcIdType sz=_conn->getMaxValue(tmp); sz=std::max(sz,ToIdType(0))+1;
3293 std::vector<bool> fastFinder(sz,false);
3294 for(const mcIdType *work=begin;work!=end;work++)
3295 if(*work>=0 && *work<sz)
3296 fastFinder[*work]=true;
3297 const mcIdType *conn=_conn->begin(),*conni=_conn_indx->begin();
3298 for(mcIdType i=0;i<nbOfCells;i++,conni++)
3300 int ref=0,nbOfHit=0;
3301 mcIdType nbNodesPerCell=conni[1]-conni[0];
3302 if(nbNodesPerCell>=0)
3304 for(mcIdType j=0;j<nbNodesPerCell;j++)
3306 mcIdType nodeId=conn[conni[0]+j];
3310 if(fastFinder[nodeId])
3317 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !";
3318 throw INTERP_KERNEL::Exception(oss.str().c_str());
3320 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
3321 cellIdsKept->pushBackSilent(i);
3323 cellIdsKeptArr=cellIdsKept.retn();
3326 void MEDCoupling1DGTUMesh::allocateCells(mcIdType nbOfCells)
3329 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !");
3330 _conn=DataArrayIdType::New();
3331 _conn->reserve(nbOfCells*3);
3332 _conn_indx=DataArrayIdType::New();
3333 _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0);
3338 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
3340 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
3341 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
3342 * \throw If the length of the input nodal connectivity array of the cell to add is not equal to number of nodes per cell relative to the unique geometric type
3343 * attached to \a this.
3344 * \throw If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
3346 void MEDCoupling1DGTUMesh::insertNextCell(const mcIdType *nodalConnOfCellBg, const mcIdType *nodalConnOfCellEnd)
3348 std::size_t sz(std::distance(nodalConnOfCellBg,nodalConnOfCellEnd));
3349 DataArrayIdType *c(_conn),*c2(_conn_indx);
3352 mcIdType pos=c2->back();
3353 if(pos==c->getNumberOfTuples())
3355 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
3356 c2->pushBackSilent(pos+ToIdType(sz));
3360 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !";
3361 throw INTERP_KERNEL::Exception(oss.str().c_str());
3365 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !");
3368 void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayIdType *nodalConn, DataArrayIdType *nodalConnIndex)
3371 nodalConn->incrRef();
3374 nodalConnIndex->incrRef();
3375 _conn_indx=nodalConnIndex;
3380 * \return DataArrayIdType * - the internal reference to the nodal connectivity. The caller is not responsible to deallocate it.
3382 DataArrayIdType *MEDCoupling1DGTUMesh::getNodalConnectivity() const
3384 const DataArrayIdType *ret(_conn);
3385 return const_cast<DataArrayIdType *>(ret);
3389 * \return DataArrayIdType * - the internal reference to the nodal connectivity index. The caller is not responsible to deallocate it.
3391 DataArrayIdType *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const
3393 const DataArrayIdType *ret(_conn_indx);
3394 return const_cast<DataArrayIdType *>(ret);
3398 * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here".
3399 * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity).
3400 * Geometrically the returned mesh is equal to \a this. So if \a this is already packed, the return value is a shallow copy of \a this.
3402 * Whatever the status of pack of \a this, the coordinates array of the returned newly created instance is the same than those in \a this.
3404 * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal
3405 * connectivity arrays are different (false)
3406 * \return a new object to be managed by the caller.
3408 * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked
3410 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const
3412 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3413 DataArrayIdType *nc=0,*nci=0;
3414 isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci);
3415 MCAuto<DataArrayIdType> ncs(nc),ncis(nci);
3416 ret->_conn=ncs; ret->_conn_indx=ncis;
3417 ret->setCoords(getCoords());
3422 * This method allows to compute, if needed, the packed nodal connectivity pair.
3423 * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges covered by nodal connectivity index array.
3424 * It is typically the case when nodalConnIndx starts with an id greater than 0, and finishes with id less than number of tuples in \c this->_conn.
3426 * If \a this looks packed (the front of nodal connectivity index equal to 0 and back of connectivity index equal to number of tuple of nodal connectivity array)
3427 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3429 * If nodal connectivity index points to a subpart of nodal connectivity index the packed pair of arrays will be computed (new objects) and returned and false
3432 * This method return 3 elements.
3433 * \param [out] nodalConn - a pointer that can be equal to \a this->_conn if true is returned (general case). Whatever the value of return parameter
3434 * this pointer can be seen as a new object, that is to managed by the caller.
3435 * \param [out] nodalConnIndx - a pointer that can be equal to \a this->_conn_indx if true is returned (general case). Whatever the value of return parameter
3436 * this pointer can be seen as a new object, that is to managed by the caller.
3437 * \return bool - an indication of the content of the 2 output parameters. If true, \a this looks packed (general case), if true, \a this is not packed then
3438 * output parameters are newly created objects.
3440 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkConsistencyLight test
3442 bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayIdType *&nodalConn, DataArrayIdType *&nodalConnIndx) const
3444 if(isPacked())//performs the checkConsistencyLight
3446 const DataArrayIdType *c0(_conn),*c1(_conn_indx);
3447 nodalConn=const_cast<DataArrayIdType *>(c0); nodalConnIndx=const_cast<DataArrayIdType *>(c1);
3448 nodalConn->incrRef(); nodalConnIndx->incrRef();
3451 mcIdType bg=_conn_indx->front(),end=_conn_indx->back();
3452 MCAuto<DataArrayIdType> nc(_conn->selectByTupleIdSafeSlice(bg,end,1));
3453 MCAuto<DataArrayIdType> nci(_conn_indx->deepCopy());
3454 nci->applyLin(1,-bg);
3455 nodalConn=nc.retn(); nodalConnIndx=nci.retn();
3460 * If \a this looks packed (the front of nodal connectivity index equal to 0 and back of connectivity index equal to number of tuple of nodal connectivity array)
3461 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3462 * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned.
3463 * \return bool - true if \a this looks packed, false is not.
3465 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkConsistencyLight test
3467 bool MEDCoupling1DGTUMesh::isPacked() const
3469 checkConsistencyLight();
3470 return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples();
3473 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2)
3475 std::vector<const MEDCoupling1DGTUMesh *> tmp(2);
3476 tmp[0]=const_cast<MEDCoupling1DGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1DGTUMesh *>(mesh2);
3477 return Merge1DGTUMeshes(tmp);
3480 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a)
3482 std::size_t sz=a.size();
3484 return Merge1DGTUMeshesLL(a);
3485 for(std::size_t ii=0;ii<sz;ii++)
3488 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::Merge1DGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
3489 throw INTERP_KERNEL::Exception(oss.str().c_str());
3491 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
3492 for(std::size_t ii=0;ii<sz;ii++)
3493 if(&(a[ii]->getCellModel())!=cm)
3494 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !");
3495 std::vector< MCAuto<MEDCoupling1DGTUMesh> > bb(sz);
3496 std::vector< const MEDCoupling1DGTUMesh * > aa(sz);
3497 std::size_t spaceDimUndef=-3, spaceDim=spaceDimUndef;
3498 for(std::size_t i=0;i<sz && spaceDim==spaceDimUndef;i++)
3500 const MEDCoupling1DGTUMesh *cur=a[i];
3501 const DataArrayDouble *coo=cur->getCoords();
3503 spaceDim=coo->getNumberOfComponents();
3505 if(spaceDim==spaceDimUndef)
3506 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !");
3507 for(std::size_t i=0;i<sz;i++)
3509 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
3512 return Merge1DGTUMeshesLL(aa);
3516 * \throw If presence of a null instance in the input vector \a a.
3517 * \throw If a is empty
3519 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a)
3522 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !");
3523 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3525 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !");
3526 std::vector< MCAuto<MEDCoupling1DGTUMesh> > objs(a.size());
3527 std::vector<const DataArrayIdType *> ncs(a.size()),ncis(a.size());
3528 (*it)->getNumberOfCells();//to check that all is OK
3529 const DataArrayDouble *coords=(*it)->getCoords();
3530 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3532 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3533 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3535 for(int i=1;it!=a.end();i++,it++)
3538 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !");
3539 if(cm!=&((*it)->getCellModel()))
3540 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3541 (*it)->getNumberOfCells();//to check that all is OK
3542 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3543 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3544 if(coords!=(*it)->getCoords())
3545 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !");
3547 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3548 ret->setCoords(coords);
3549 ret->_conn=DataArrayIdType::Aggregate(ncs);
3550 ret->_conn_indx=DataArrayIdType::AggregateIndexes(ncis);
3555 * Assume that all instances in \a a are non null. If null it leads to a crash. That's why this method is assigned to be low level (LL)
3557 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a)
3560 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : input array must be NON EMPTY !");
3561 std::vector< MCAuto<MEDCoupling1DGTUMesh> > objs(a.size());
3562 std::vector<const DataArrayIdType *> ncs(a.size()),ncis(a.size());
3563 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3564 std::vector<mcIdType> nbNodesPerElt(a.size());
3565 std::size_t nbOfCells=(*it)->getNumberOfCells();
3567 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3568 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3570 mcIdType prevNbOfNodes=(*it)->getNumberOfNodes();
3571 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3573 for(int i=1;it!=a.end();i++,it++)
3575 if(cm!=&((*it)->getCellModel()))
3576 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3577 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3578 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3579 nbOfCells+=(*it)->getNumberOfCells();
3580 nbNodesPerElt[i]=nbNodesPerElt[i-1]+prevNbOfNodes;
3581 prevNbOfNodes=(*it)->getNumberOfNodes();
3583 std::vector<const MEDCouplingPointSet *> aps(a.size());
3584 std::copy(a.begin(),a.end(),aps.begin());
3585 MCAuto<DataArrayDouble> pts=MergeNodesArray(aps);
3586 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3587 ret->setCoords(pts);
3588 ret->_conn=AggregateNodalConnAndShiftNodeIds(ncs,nbNodesPerElt);
3589 ret->_conn_indx=DataArrayIdType::AggregateIndexes(ncis);
3593 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(std::size_t spaceDim) const
3595 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3596 MCAuto<DataArrayIdType> tmp1,tmp2;
3597 const DataArrayIdType *nodalConn(_conn),*nodalConnI(_conn_indx);
3600 tmp1=DataArrayIdType::New(); tmp1->alloc(0,1);
3608 tmp2=DataArrayIdType::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
3612 ret->_conn_indx=tmp2;
3616 MCAuto<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
3617 ret->setCoords(coords);
3620 ret->setCoords(_coords);
3625 * This method aggregate the bbox of each cell and put it into bbox parameter.
3627 * \param [in] arcDetEps - a parameter specifying in case of 2D quadratic polygon cell the detection limit between linear and arc circle. (By default 1e-12)
3628 * For all other cases this input parameter is ignored.
3629 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
3631 * \throw If \a this is not fully set (coordinates and connectivity).
3632 * \throw If a cell in \a this has no valid nodeId.
3634 DataArrayDouble *MEDCoupling1DGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
3636 checkFullyDefined();
3637 mcIdType spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes());
3638 MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
3639 double *bbox(ret->getPointer());
3640 for(mcIdType i=0;i<nbOfCells*spaceDim;i++)
3642 bbox[2*i]=std::numeric_limits<double>::max();
3643 bbox[2*i+1]=-std::numeric_limits<double>::max();
3645 const double *coordsPtr(_coords->getConstPointer());
3646 const mcIdType *conn(_conn->getConstPointer()),*connI(_conn_indx->getConstPointer());
3647 for(mcIdType i=0;i<nbOfCells;i++)
3649 mcIdType offset=connI[i];
3650 mcIdType nbOfNodesForCell(connI[i+1]-offset),kk(0);
3651 for(mcIdType j=0;j<nbOfNodesForCell;j++)
3653 mcIdType nodeId=conn[offset+j];
3654 if(nodeId>=0 && nodeId<nbOfNodes)
3656 for(int k=0;k<spaceDim;k++)
3658 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
3659 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
3666 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
3667 throw INTERP_KERNEL::Exception(oss.str().c_str());
3674 * Returns the cell field giving for each cell in \a this its diameter. Diameter means the max length of all possible SEG2 in the cell.
3676 * \return a new instance of field containing the result. The returned instance has to be deallocated by the caller.
3678 MEDCouplingFieldDouble *MEDCoupling1DGTUMesh::computeDiameterField() const
3680 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::computeDiameterField : not implemented yet for dynamic types !");
3683 std::vector<mcIdType> MEDCoupling1DGTUMesh::BuildAPolygonFromParts(const std::vector< std::vector<mcIdType> >& parts)
3685 std::vector<mcIdType> ret;
3688 ret.insert(ret.end(),parts[0].begin(),parts[0].end());
3689 mcIdType ref(ret.back());
3690 std::size_t sz(parts.size()),nbh(1);
3691 std::vector<bool> b(sz,true); b[0]=false;
3695 for(;i<sz;i++) if(b[i] && parts[i].front()==ref) { ret.insert(ret.end(),parts[i].begin()+1,parts[i].end()); nbh++; break; }
3699 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::BuildAPolygonFromParts : the input vector is not a part of a single polygon !");
3701 if(ret.back()==ret.front())
3707 * This method invert orientation of all cells in \a this.
3708 * After calling this method the absolute value of measure of cells in \a this are the same than before calling.
3709 * This method only operates on the connectivity so coordinates are not touched at all.
3711 void MEDCoupling1DGTUMesh::invertOrientationOfAllCells()
3713 checkConsistencyOfConnectivity();
3714 INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::OrientationInverter> oi(INTERP_KERNEL::OrientationInverter::BuildInstanceFrom(getCellModelEnum()));
3715 mcIdType nbCells=getNumberOfCells();
3716 const mcIdType *connI(_conn_indx->begin());
3717 mcIdType *conn(_conn->getPointer());
3718 for(mcIdType i=0;i<nbCells;i++)
3719 oi->operate(conn+connI[i],conn+connI[i+1]);
3724 * This method performs an aggregation of \a nodalConns (as DataArrayIdType::Aggregate does) but in addition of that a shift is applied on the
3725 * values contained in \a nodalConns using corresponding offset specified in input \a offsetInNodeIdsPerElt.
3726 * But it also manage the values -1, that have a semantic in MEDCoupling1DGTUMesh class (separator for polyhedron).
3728 * \param [in] nodalConns - a list of nodal connectivity arrays same size than \a offsetInNodeIdsPerElt.
3729 * \param [in] offsetInNodeIdsPerElt - a list of offsets to apply.
3730 * \return DataArrayIdType * - A new object (to be managed by the caller) that is the result of the aggregation.
3731 * \throw If \a nodalConns or \a offsetInNodeIdsPerElt are empty.
3732 * \throw If \a nodalConns and \a offsetInNodeIdsPerElt have not the same size.
3733 * \throw If presence of null pointer in \a nodalConns.
3734 * \throw If presence of not allocated or array with not exactly one component in \a nodalConns.
3736 DataArrayIdType *MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds(const std::vector<const DataArrayIdType *>& nodalConns, const std::vector<mcIdType>& offsetInNodeIdsPerElt)
3738 std::size_t sz1(nodalConns.size()),sz2(offsetInNodeIdsPerElt.size());
3740 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : input vectors do not have the same size !");
3742 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : empty vectors in input !");
3743 mcIdType nbOfTuples=0;
3744 for(std::vector<const DataArrayIdType *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++)
3747 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of null pointer in input vector !");
3748 if(!(*it)->isAllocated())
3749 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of non allocated array in input vector !");
3750 if((*it)->getNumberOfComponents()!=1)
3751 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of array with not exactly one component !");
3752 nbOfTuples+=(*it)->getNumberOfTuples();
3754 MCAuto<DataArrayIdType> ret=DataArrayIdType::New(); ret->alloc(nbOfTuples,1);
3755 mcIdType *pt=ret->getPointer();
3757 for(std::vector<const DataArrayIdType *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++,i++)
3759 mcIdType curNbt=(*it)->getNumberOfTuples();
3760 const mcIdType *inPt=(*it)->begin();
3761 mcIdType offset=offsetInNodeIdsPerElt[i];
3762 for(mcIdType j=0;j<curNbt;j++,pt++)
3773 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m)
3776 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh is null !");
3777 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
3779 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh must have exactly one geometric type !");
3780 mcIdType geoType(ToIdType(*gts.begin()));
3781 MCAuto<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(m->getName(),*gts.begin()));
3782 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription());
3783 mcIdType nbCells=m->getNumberOfCells();
3784 MCAuto<DataArrayIdType> conn(DataArrayIdType::New()),connI(DataArrayIdType::New());
3785 conn->alloc(m->getNodalConnectivityArrayLen()-nbCells,1); connI->alloc(nbCells+1,1);
3786 mcIdType *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
3787 const mcIdType *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
3788 for(mcIdType i=0;i<nbCells;i++,ciin++,ci++)
3790 if(cin[ciin[0]]==geoType)
3792 if(ciin[1]-ciin[0]>=1)
3794 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
3795 ci[1]=ci[0]+ciin[1]-ciin[0]-1;
3799 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m) : something is wrong in the input mesh at cell #" << i << " ! The size of cell is not >=0 !";
3800 throw INTERP_KERNEL::Exception(oss.str().c_str());
3805 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m) : something is wrong in the input mesh at cell #" << i << " ! The geometric type is not those expected !";
3806 throw INTERP_KERNEL::Exception(oss.str().c_str());
3809 ret->setNodalConnectivity(conn,connI);