1 // Copyright (C) 2007-2020 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"
31 using namespace MEDCoupling;
33 const int MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[6]={0,1,2,4,3,5};
35 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh():_cm(0)
39 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):_cm(&cm)
44 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const MEDCoupling1GTUMesh& other, bool recDeepCpy):MEDCouplingPointSet(other,recDeepCpy),_cm(other._cm)
48 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
50 if(type==INTERP_KERNEL::NORM_ERROR)
51 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
52 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
54 return MEDCoupling1SGTUMesh::New(name,type);
56 return MEDCoupling1DGTUMesh::New(name,type);
59 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const MEDCouplingUMesh *m)
62 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh is null !");
63 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
65 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh must have exactly one geometric type !");
66 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*gts.begin());
68 return MEDCoupling1SGTUMesh::New(m);
70 return MEDCoupling1DGTUMesh::New(m);
73 const INTERP_KERNEL::CellModel& MEDCoupling1GTUMesh::getCellModel() const
78 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getCellModelEnum() const
80 return _cm->getEnum();
83 int MEDCoupling1GTUMesh::getMeshDimension() const
85 return (int)_cm->getDimension();
89 * This method returns a newly allocated array containing cell ids (ascendingly sorted) whose geometric type are equal to type.
90 * This method does not throw exception if geometric type \a type is not in \a this.
91 * This method throws an INTERP_KERNEL::Exception if meshdimension of \b this is not equal to those of \b type.
92 * The coordinates array is not considered here.
94 * \param [in] type the geometric type
95 * \return cell ids in this having geometric type \a type.
97 DataArrayIdType *MEDCoupling1GTUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
99 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
100 if(type==getCellModelEnum())
101 ret->alloc(getNumberOfCells(),1);
109 * Returns nb of cells having the geometric type \a type. No throw if no cells in \a this has the geometric type \a type.
111 mcIdType MEDCoupling1GTUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
113 return type==getCellModelEnum()?getNumberOfCells():0;
117 * Returns a type of a cell by its id.
118 * \param [in] cellId - the id of the cell of interest.
119 * \return INTERP_KERNEL::NormalizedCellType - enumeration item describing the cell type.
120 * \throw If \a cellId is invalid. Valid range is [0, \a this->getNumberOfCells() ).
122 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getTypeOfCell(mcIdType cellId) const
124 if(cellId<getNumberOfCells())
125 return getCellModelEnum();
126 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::getTypeOfCell : Requesting type of cell #" << cellId << " but it should be in [0," << getNumberOfCells() << ") !";
127 throw INTERP_KERNEL::Exception(oss.str().c_str());
131 * Returns a set of all cell types available in \a this mesh.
132 * \return std::set<INTERP_KERNEL::NormalizedCellType> - the set of cell types.
133 * \warning this method does not throw any exception even if \a this is not defined.
135 std::set<INTERP_KERNEL::NormalizedCellType> MEDCoupling1GTUMesh::getAllGeoTypes() const
137 std::set<INTERP_KERNEL::NormalizedCellType> ret;
138 ret.insert(getCellModelEnum());
143 * This method expects that \a this is sorted by types. If not an exception will be thrown.
144 * This method returns in the same format as code (see MEDCouplingUMesh::checkTypeConsistencyAndContig or MEDCouplingUMesh::splitProfilePerType) how
145 * \a this is composed in cell types.
146 * The returned array is of size 3*n where n is the number of different types present in \a this.
147 * For every k in [0,n] ret[3*k+2]==-1 because it has no sense here.
148 * This parameter is kept only for compatibility with other method listed above.
150 std::vector<mcIdType> MEDCoupling1GTUMesh::getDistributionOfTypes() const
152 std::vector<mcIdType> ret(3);
153 ret[0]=ToIdType(getCellModelEnum()); ret[1]=getNumberOfCells(); ret[2]=-1;
158 * 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.
159 * 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.
160 * This method has 1 input \a profile and 3 outputs \a code \a idsInPflPerType and \a idsPerType.
162 * \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.
163 * \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,
164 * \a idsInPflPerType[i] stores the tuple ids in \a profile that correspond to the geometric type code[3*i+0]
165 * \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.
166 * This vector can be empty in case of all geometric type cells are fully covered in ascending in the given input \a profile.
168 * \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.
170 * \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
173 * - Before \a this has 3 cells \a profile contains [0,1,2]
174 * - After \a code contains [NORM_...,nbCells,-1], \a idsInPflPerType [[0,1,2]] and \a idsPerType is empty <br>
177 * - Before \a this has 3 cells \a profile contains [1,2]
178 * - After \a code contains [NORM_...,nbCells,0], \a idsInPflPerType [[0,1]] and \a idsPerType is [[1,2]] <br>
181 void MEDCoupling1GTUMesh::splitProfilePerType(const DataArrayIdType *profile, std::vector<mcIdType>& code, std::vector<DataArrayIdType *>& idsInPflPerType, std::vector<DataArrayIdType *>& idsPerType, bool smartPflKiller) const
184 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile is NULL !");
185 if(profile->getNumberOfComponents()!=1)
186 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile should have exactly one component !");
187 mcIdType nbTuples=profile->getNumberOfTuples(),nbOfCells=getNumberOfCells();
188 code.resize(3); idsInPflPerType.resize(1);
189 code[0]=ToIdType(getCellModelEnum()); code[1]=nbTuples;
190 idsInPflPerType.resize(1);
191 if(smartPflKiller && profile->isIota(nbOfCells))
194 idsInPflPerType[0]=const_cast<DataArrayIdType *>(profile); idsInPflPerType[0]->incrRef();
199 profile->checkAllIdsInRange(0,nbOfCells);
200 idsPerType.resize(1);
201 idsPerType[0]=const_cast<DataArrayIdType *>(profile); idsPerType[0]->incrRef();
202 idsInPflPerType[0]=DataArrayIdType::Range(0,nbTuples,1);
206 * This method tries to minimize at most the number of deep copy.
207 * So if \a idsPerType is not empty it can be returned directly (without copy, but with ref count incremented) in return.
209 * \sa MEDCouplingUMesh::checkTypeConsistencyAndContig
211 DataArrayIdType *MEDCoupling1GTUMesh::checkTypeConsistencyAndContig(const std::vector<mcIdType>& code, const std::vector<const DataArrayIdType *>& idsPerType) const
213 mcIdType nbOfCells=getNumberOfCells();
215 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : invalid input code should be exactly of size 3 !");
216 if(code[0]!=ToIdType(getCellModelEnum()))
218 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() << ") !";
219 throw INTERP_KERNEL::Exception(oss.str().c_str());
223 if(code[1]==nbOfCells)
227 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : mismatch between the number of cells in this (" << nbOfCells << ") and the number of non profile (" << code[1] << ") !";
228 throw INTERP_KERNEL::Exception(oss.str().c_str());
232 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : single geo type mesh ! 0 or -1 is expected at pos #2 of input code !");
233 if(idsPerType.size()!=1)
234 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input code points to DataArrayIdType #0 whereas the size of idsPerType is not equal to 1 !");
235 const DataArrayIdType *pfl=idsPerType[0];
237 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : the input code points to a NULL DataArrayIdType at rank 0 !");
238 if(pfl->getNumberOfComponents()!=1)
239 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input profile should have exactly one component !");
240 pfl->checkAllIdsInRange(0,nbOfCells);
242 return const_cast<DataArrayIdType *>(pfl);
245 void MEDCoupling1GTUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const
247 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
248 m->writeVTKLL(ofs,cellData,pointData,byteData);
251 std::string MEDCoupling1GTUMesh::getVTKDataSetType() const
253 return std::string("UnstructuredGrid");
256 std::string MEDCoupling1GTUMesh::getVTKFileExtension() const
258 return std::string("vtu");
261 std::size_t MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren() const
263 return MEDCouplingPointSet::getHeapMemorySizeWithoutChildren();
266 bool MEDCoupling1GTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
268 if(!MEDCouplingPointSet::isEqualIfNotWhy(other,prec,reason))
271 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualIfNotWhy : input other pointer is null !");
272 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
275 reason="mesh given in input is not castable in MEDCouplingSGTUMesh !";
280 reason="mismatch in geometric type !";
286 bool MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
288 if(!MEDCouplingPointSet::isEqualWithoutConsideringStr(other,prec))
291 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
292 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
300 void MEDCoupling1GTUMesh::checkConsistencyLight() const
302 MEDCouplingPointSet::checkConsistencyLight();
305 DataArrayDouble *MEDCoupling1GTUMesh::computeCellCenterOfMass() const
307 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
308 MCAuto<DataArrayDouble> ret=m->computeCellCenterOfMass();
312 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureField(bool isAbs) const
314 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
315 MCAuto<MEDCouplingFieldDouble> ret=m->getMeasureField(isAbs);
320 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureFieldOnNode(bool isAbs) const
322 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
323 MCAuto<MEDCouplingFieldDouble> ret=m->getMeasureFieldOnNode(isAbs);
331 mcIdType MEDCoupling1GTUMesh::getCellContainingPoint(const double *pos, double eps) const
333 MCAuto<MEDCouplingUMesh> m(buildUnstructured());
334 return m->getCellContainingPoint(pos,eps);
340 void MEDCoupling1GTUMesh::getCellsContainingPoint(const double *pos, double eps, std::vector<mcIdType>& elts) const
342 MCAuto<MEDCouplingUMesh> m(buildUnstructured());
343 return m->getCellsContainingPoint(pos,eps,elts);
346 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::buildOrthogonalField() const
348 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
349 MCAuto<MEDCouplingFieldDouble> ret=m->buildOrthogonalField();
354 DataArrayIdType *MEDCoupling1GTUMesh::getCellsInBoundingBox(const double *bbox, double eps) const
356 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
357 return m->getCellsInBoundingBox(bbox,eps);
360 DataArrayIdType *MEDCoupling1GTUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps)
362 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
363 return m->getCellsInBoundingBox(bbox,eps);
366 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildFacePartOfMySelfNode(const mcIdType *start, const mcIdType *end, bool fullyIn) const
368 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
369 return m->buildFacePartOfMySelfNode(start,end,fullyIn);
372 DataArrayIdType *MEDCoupling1GTUMesh::findBoundaryNodes() const
374 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
375 return m->findBoundaryNodes();
378 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildBoundaryMesh(bool keepCoords) const
380 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
381 return m->buildBoundaryMesh(keepCoords);
384 void MEDCoupling1GTUMesh::findCommonCells(int compType, mcIdType startCellId, DataArrayIdType *& commonCellsArr, DataArrayIdType *& commonCellsIArr) const
386 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
387 m->findCommonCells(compType,startCellId,commonCellsArr,commonCellsIArr);
390 mcIdType MEDCoupling1GTUMesh::getNodalConnectivityLength() const
392 const DataArrayIdType *c1(getNodalConnectivity());
394 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : no connectivity set !");
395 if(c1->getNumberOfComponents()!=1)
396 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array set must have exactly one component !");
397 if(!c1->isAllocated())
398 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array must be allocated !");
399 return c1->getNumberOfTuples();
403 * This method aggregates all the meshes in \a parts to put them in a single unstructured mesh (those returned).
404 * The order of cells is the returned instance is those in the order of instances in \a parts.
406 * \param [in] parts - all not null parts of single geo type meshes to be aggreagated having the same mesh dimension and same coordinates.
407 * \return MEDCouplingUMesh * - new object to be dealt by the caller.
409 * \throw If one element is null in \a parts.
410 * \throw If not all the parts do not have the same mesh dimension.
411 * \throw If not all the parts do not share the same coordinates.
412 * \throw If not all the parts have their connectivity set properly.
413 * \throw If \a parts is empty.
415 MEDCouplingUMesh *MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh(const std::vector< const MEDCoupling1GTUMesh *>& parts)
418 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : input parts vector is empty !");
419 const MEDCoupling1GTUMesh *firstPart(parts[0]);
421 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : the first instance in input parts is null !");
422 const DataArrayDouble *coords(firstPart->getCoords());
423 int meshDim(firstPart->getMeshDimension());
424 MCAuto<MEDCouplingUMesh> ret(MEDCouplingUMesh::New(firstPart->getName(),meshDim)); ret->setDescription(firstPart->getDescription());
425 ret->setCoords(coords);
426 mcIdType nbOfCells(0),connSize(0);
427 for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
430 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of null pointer in input vector !");
431 if((*it)->getMeshDimension()!=meshDim)
432 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances in input vector must have same mesh dimension !");
433 if((*it)->getCoords()!=coords)
434 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances must share the same coordinates pointer !");
435 nbOfCells+=(*it)->getNumberOfCells();
436 connSize+=(*it)->getNodalConnectivityLength();
438 MCAuto<DataArrayIdType> conn(DataArrayIdType::New()),connI(DataArrayIdType::New());
439 connI->alloc(nbOfCells+1,1); conn->alloc(connSize+nbOfCells,1);
440 mcIdType *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
441 for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
443 mcIdType curNbCells=(*it)->getNumberOfCells();
444 mcIdType geoType(ToIdType((*it)->getCellModelEnum()));
445 const mcIdType *cinPtr((*it)->getNodalConnectivity()->begin());
446 const MEDCoupling1SGTUMesh *ps(dynamic_cast<const MEDCoupling1SGTUMesh *>(*it));
447 const MEDCoupling1DGTUMesh *pd(dynamic_cast<const MEDCoupling1DGTUMesh *>(*it));
450 mcIdType nNodesPerCell(ps->getNumberOfNodesPerCell());
451 for(int i=0;i<curNbCells;i++,ci++,cinPtr+=nNodesPerCell)
454 c=std::copy(cinPtr,cinPtr+nNodesPerCell,c);
455 ci[1]=ci[0]+nNodesPerCell+1;
460 const mcIdType *ciinPtr(pd->getNodalConnectivityIndex()->begin());
461 for(int i=0;i<curNbCells;i++,ci++,ciinPtr++)
464 c=std::copy(cinPtr+ciinPtr[0],cinPtr+ciinPtr[1],c);
465 ci[1]=ci[0]+ciinPtr[1]-ciinPtr[0]+1;
469 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of instance which type is not in [MEDCoupling1SGTUMesh,MEDCoupling1DGTUMesh] !");
471 ret->setConnectivity(conn,connI,true);
477 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const MEDCoupling1SGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
481 const DataArrayIdType *c(other._conn);
487 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
491 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh()
495 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New()
497 return new MEDCoupling1SGTUMesh;
500 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
502 if(type==INTERP_KERNEL::NORM_ERROR)
503 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
504 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
507 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New : the input geometric type " << cm.getRepr() << " is dynamic ! Only static types are allowed here !";
508 throw INTERP_KERNEL::Exception(oss.str().c_str());
510 return new MEDCoupling1SGTUMesh(name,cm);
513 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m)
516 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh is null !");
517 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
519 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh must have exactly one geometric type !");
520 mcIdType geoType(ToIdType(*gts.begin()));
521 MCAuto<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(m->getName(),*gts.begin()));
522 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription());
523 mcIdType nbCells=m->getNumberOfCells();
524 mcIdType nbOfNodesPerCell(ret->getNumberOfNodesPerCell());
525 MCAuto<DataArrayIdType> conn(DataArrayIdType::New()); conn->alloc(nbCells*nbOfNodesPerCell,1);
526 mcIdType *c(conn->getPointer());
527 const mcIdType *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
528 for(mcIdType i=0;i<nbCells;i++,ciin++)
530 if(cin[ciin[0]]==geoType)
532 if(ciin[1]-ciin[0]==nbOfNodesPerCell+1)
533 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
536 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 << ") !";
537 throw INTERP_KERNEL::Exception(oss.str().c_str());
542 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 !";
543 throw INTERP_KERNEL::Exception(oss.str().c_str());
546 ret->setNodalConnectivity(conn);
548 { ret->copyTinyInfoFrom(m); }
549 catch(INTERP_KERNEL::Exception&) { }
553 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::clone(bool recDeepCpy) const
555 return new MEDCoupling1SGTUMesh(*this,recDeepCpy);
559 * This method behaves mostly like MEDCoupling1SGTUMesh::deepCopy method, except that only nodal connectivity arrays are deeply copied.
560 * The coordinates are shared between \a this and the returned instance.
562 * \return MEDCoupling1SGTUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
563 * \sa MEDCoupling1SGTUMesh::deepCopy
565 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::deepCopyConnectivityOnly() const
567 checkConsistencyLight();
568 MCAuto<MEDCoupling1SGTUMesh> ret(clone(false));
569 MCAuto<DataArrayIdType> c(_conn->deepCopy());
570 ret->setNodalConnectivity(c);
574 void MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
577 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
578 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
580 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1SGTUMesh instance !");
581 setNodalConnectivity(otherC->getNodalConnectivity());
584 void MEDCoupling1SGTUMesh::updateTime() const
586 MEDCoupling1GTUMesh::updateTime();
587 const DataArrayIdType *c(_conn);
592 std::size_t MEDCoupling1SGTUMesh::getHeapMemorySizeWithoutChildren() const
594 return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren();
597 std::vector<const BigMemoryObject *> MEDCoupling1SGTUMesh::getDirectChildrenWithNull() const
599 std::vector<const BigMemoryObject *> ret(MEDCoupling1GTUMesh::getDirectChildrenWithNull());
600 ret.push_back((const DataArrayIdType *)_conn);
604 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::deepCopy() const
609 bool MEDCoupling1SGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
612 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualIfNotWhy : input other pointer is null !");
613 std::ostringstream oss; oss.precision(15);
614 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
617 reason="mesh given in input is not castable in MEDCoupling1SGTUMesh !";
620 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
622 const DataArrayIdType *c1(_conn),*c2(otherC->_conn);
627 reason="in connectivity of single static geometric type exactly one among this and other is null !";
630 if(!c1->isEqualIfNotWhy(*c2,reason))
632 reason.insert(0,"Nodal connectivity DataArrayIdType differ : ");
638 bool MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
641 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
642 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
645 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
647 const DataArrayIdType *c1(_conn),*c2(otherC->_conn);
652 if(!c1->isEqualWithoutConsideringStr(*c2))
657 void MEDCoupling1SGTUMesh::checkConsistencyOfConnectivity() const
659 const DataArrayIdType *c1(_conn);
662 if(c1->getNumberOfComponents()!=1)
663 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
664 if(c1->getInfoOnComponent(0)!="")
665 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
666 c1->checkAllocated();
669 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
672 void MEDCoupling1SGTUMesh::checkConsistencyLight() const
674 MEDCouplingPointSet::checkConsistencyLight();
675 checkConsistencyOfConnectivity();
678 void MEDCoupling1SGTUMesh::checkConsistency(double eps) const
680 checkConsistencyLight();
681 const DataArrayIdType *c1(_conn);
682 mcIdType nbOfTuples(c1->getNumberOfTuples());
683 mcIdType nbOfNodesPerCell=_cm->getNumberOfNodes();
684 if(nbOfTuples%nbOfNodesPerCell!=0)
686 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 !";
687 throw INTERP_KERNEL::Exception(oss.str().c_str());
689 mcIdType nbOfNodes=getNumberOfNodes();
690 mcIdType nbOfCells=nbOfTuples/nbOfNodesPerCell;
691 const mcIdType *w(c1->begin());
692 for(mcIdType i=0;i<nbOfCells;i++)
693 for(int j=0;j<nbOfNodesPerCell;j++,w++)
695 if(*w<0 || *w>=nbOfNodes)
697 std::ostringstream oss; oss << "At node #" << j << " of cell #" << i << ", is equal to " << *w << " must be in [0," << nbOfNodes << ") !";
698 throw INTERP_KERNEL::Exception(oss.str().c_str());
703 mcIdType MEDCoupling1SGTUMesh::getNumberOfCells() const
705 mcIdType nbOfTuples(getNodalConnectivityLength());
706 mcIdType nbOfNodesPerCell(getNumberOfNodesPerCell());
707 if(nbOfTuples%nbOfNodesPerCell!=0)
709 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 !";
710 throw INTERP_KERNEL::Exception(oss.str().c_str());
712 return nbOfTuples/nbOfNodesPerCell;
715 mcIdType MEDCoupling1SGTUMesh::getNumberOfNodesInCell(mcIdType cellId) const
717 return getNumberOfNodesPerCell();
720 mcIdType MEDCoupling1SGTUMesh::getNumberOfNodesPerCell() const
722 checkNonDynamicGeoType();
723 return _cm->getNumberOfNodes();
726 DataArrayIdType *MEDCoupling1SGTUMesh::computeNbOfNodesPerCell() const
728 checkNonDynamicGeoType();
729 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
730 ret->alloc(getNumberOfCells(),1);
731 ret->fillWithValue(_cm->getNumberOfNodes());
735 DataArrayIdType *MEDCoupling1SGTUMesh::computeNbOfFacesPerCell() const
737 checkNonDynamicGeoType();
738 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
739 ret->alloc(getNumberOfCells(),1);
740 ret->fillWithValue(ToIdType(_cm->getNumberOfSons()));
744 DataArrayIdType *MEDCoupling1SGTUMesh::computeEffectiveNbOfNodesPerCell() const
746 checkNonDynamicGeoType();
747 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
748 mcIdType nbCells=getNumberOfCells();
749 ret->alloc(nbCells,1);
750 mcIdType *retPtr(ret->getPointer());
751 mcIdType nbNodesPerCell(getNumberOfNodesPerCell());
752 const mcIdType *conn(_conn->begin());
753 for(mcIdType i=0;i<nbCells;i++,conn+=nbNodesPerCell,retPtr++)
755 std::set<mcIdType> s(conn,conn+nbNodesPerCell);
756 *retPtr=ToIdType(s.size());
761 void MEDCoupling1SGTUMesh::getNodeIdsOfCell(mcIdType cellId, std::vector<mcIdType>& conn) const
763 mcIdType sz=getNumberOfNodesPerCell();
765 if(cellId<getNumberOfCells())
766 std::copy(_conn->begin()+cellId*sz,_conn->begin()+(cellId+1)*sz,conn.begin());
769 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << getNumberOfCells() << ") !";
770 throw INTERP_KERNEL::Exception(oss.str().c_str());
774 void MEDCoupling1SGTUMesh::checkNonDynamicGeoType() const
777 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkNonDynamicGeoType : internal error ! the internal geo type is dynamic ! should be static !");
780 std::string MEDCoupling1SGTUMesh::simpleRepr() const
782 static const char msg0[]="No coordinates specified !";
783 std::ostringstream ret;
784 ret << "Single static geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
785 ret << "Description of mesh : \"" << getDescription() << "\"\n";
787 double tt=getTime(tmpp1,tmpp2);
788 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
789 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
790 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
793 const int spaceDim=getSpaceDimension();
794 ret << spaceDim << "\nInfo attached on space dimension : ";
795 for(int i=0;i<spaceDim;i++)
796 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
801 ret << "Number of nodes : ";
803 ret << getNumberOfNodes() << "\n";
806 ret << "Number of cells : ";
807 if((const DataArrayIdType *)_conn)
809 if(_conn->isAllocated())
811 if(_conn->getNumberOfComponents()==1)
812 ret << getNumberOfCells() << "\n";
814 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
817 ret << "Nodal connectivity array specified but not allocated !" << "\n";
820 ret << "No connectivity specified !" << "\n";
821 ret << "Cell type : " << _cm->getRepr() << "\n";
825 std::string MEDCoupling1SGTUMesh::advancedRepr() const
827 std::ostringstream ret;
829 ret << "\nCoordinates array : \n___________________\n\n";
831 _coords->reprWithoutNameStream(ret);
833 ret << "No array set !\n";
834 ret << "\n\nConnectivity array : \n____________________\n\n";
836 if((const DataArrayIdType *)_conn)
838 if(_conn->isAllocated())
840 if(_conn->getNumberOfComponents()==1)
842 mcIdType nbOfCells=getNumberOfCells();
843 mcIdType sz=getNumberOfNodesPerCell();
844 const mcIdType *connPtr=_conn->begin();
845 for(mcIdType i=0;i<nbOfCells;i++,connPtr+=sz)
847 ret << "Cell #" << i << " : ";
848 std::copy(connPtr,connPtr+sz,std::ostream_iterator<mcIdType>(ret," "));
853 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
856 ret << "Nodal connectivity array specified but not allocated !" << "\n";
859 ret << "No connectivity specified !" << "\n";
863 DataArrayDouble *MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell() const
865 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
866 int spaceDim=getSpaceDimension();
867 mcIdType nbOfCells=getNumberOfCells();//checkConsistencyLight()
868 mcIdType nbOfNodes=getNumberOfNodes();
869 ret->alloc(nbOfCells,spaceDim);
870 double *ptToFill=ret->getPointer();
871 const double *coor=_coords->begin();
872 const mcIdType *nodal=_conn->begin();
873 mcIdType sz=getNumberOfNodesPerCell();
874 double coeff=1./FromIdType<double>(sz);
875 for(mcIdType i=0;i<nbOfCells;i++,ptToFill+=spaceDim)
877 std::fill(ptToFill,ptToFill+spaceDim,0.);
878 for(mcIdType j=0;j<sz;j++,nodal++)
879 if(*nodal>=0 && *nodal<nbOfNodes)
880 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
883 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
884 throw INTERP_KERNEL::Exception(oss.str().c_str());
886 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),coeff));
891 void MEDCoupling1SGTUMesh::renumberCells(const mcIdType *old2NewBg, bool check)
893 mcIdType nbCells=getNumberOfCells();
894 MCAuto<DataArrayIdType> o2n=DataArrayIdType::New();
895 o2n->useArray(old2NewBg,false,DeallocType::C_DEALLOC,nbCells,1);
897 o2n=o2n->checkAndPreparePermutation();
899 const mcIdType *conn=_conn->begin();
900 MCAuto<DataArrayIdType> n2o=o2n->invertArrayO2N2N2O(nbCells);
901 const mcIdType *n2oPtr=n2o->begin();
902 MCAuto<DataArrayIdType> newConn=DataArrayIdType::New();
903 newConn->alloc(_conn->getNumberOfTuples(),1);
904 newConn->copyStringInfoFrom(*_conn);
905 mcIdType sz=getNumberOfNodesPerCell();
907 mcIdType *newC=newConn->getPointer();
908 for(mcIdType i=0;i<nbCells;i++,newC+=sz)
910 mcIdType pos=n2oPtr[i];
911 std::copy(conn+pos*sz,conn+(pos+1)*sz,newC);
917 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
918 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
919 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
920 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
922 * \param [in] begin input start of array of node ids.
923 * \param [in] end input end of array of node ids.
924 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
925 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
927 void MEDCoupling1SGTUMesh::fillCellIdsToKeepFromNodeIds(const mcIdType *begin, const mcIdType *end, bool fullyIn, DataArrayIdType *&cellIdsKeptArr) const
929 mcIdType nbOfCells=getNumberOfCells();
930 MCAuto<DataArrayIdType> cellIdsKept=DataArrayIdType::New(); cellIdsKept->alloc(0,1);
932 mcIdType sz=_conn->getMaxValue(tmp); sz=std::max(sz,ToIdType(0))+1;
933 std::vector<bool> fastFinder(sz,false);
934 for(const mcIdType *work=begin;work!=end;work++)
935 if(*work>=0 && *work<sz)
936 fastFinder[*work]=true;
937 const mcIdType *conn=_conn->begin();
938 mcIdType nbNodesPerCell=getNumberOfNodesPerCell();
939 for(mcIdType i=0;i<nbOfCells;i++,conn+=nbNodesPerCell)
942 for(mcIdType j=0;j<nbNodesPerCell;j++)
946 if(fastFinder[conn[j]])
949 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
950 cellIdsKept->pushBackSilent(i);
952 cellIdsKeptArr=cellIdsKept.retn();
955 MEDCouplingMesh *MEDCoupling1SGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
957 if(other->getType()!=SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED)
958 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single static geo type each other !");
959 const MEDCoupling1SGTUMesh *otherC=static_cast<const MEDCoupling1SGTUMesh *>(other);
960 return Merge1SGTUMeshes(this,otherC);
963 MEDCouplingUMesh *MEDCoupling1SGTUMesh::buildUnstructured() const
965 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
966 ret->setCoords(getCoords());
967 const mcIdType *nodalConn=_conn->begin();
968 mcIdType nbCells=getNumberOfCells();
969 mcIdType nbNodesPerCell=getNumberOfNodesPerCell();
970 mcIdType geoType=ToIdType(getCellModelEnum());
971 MCAuto<DataArrayIdType> c=DataArrayIdType::New(); c->alloc(nbCells*(nbNodesPerCell+1),1);
972 mcIdType *cPtr=c->getPointer();
973 for(mcIdType i=0;i<nbCells;i++,nodalConn+=nbNodesPerCell)
976 cPtr=std::copy(nodalConn,nodalConn+nbNodesPerCell,cPtr);
978 MCAuto<DataArrayIdType> cI=DataArrayIdType::Range(0,(nbCells+1)*(nbNodesPerCell+1),nbNodesPerCell+1);
979 ret->setConnectivity(c,cI,true);
981 { ret->copyTinyInfoFrom(this); }
982 catch(INTERP_KERNEL::Exception&) { }
986 DataArrayIdType *MEDCoupling1SGTUMesh::simplexize(int policy)
991 return simplexizePol0();
993 return simplexizePol1();
994 case INTERP_KERNEL::PLANAR_FACE_5:
995 return simplexizePlanarFace5();
996 case INTERP_KERNEL::PLANAR_FACE_6:
997 return simplexizePlanarFace6();
999 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)");
1005 struct MEDCouplingAccVisit
1007 MEDCouplingAccVisit():_new_nb_of_nodes(0) { }
1008 mcIdType operator()(mcIdType val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; }
1009 mcIdType _new_nb_of_nodes;
1015 * This method returns all node ids used in \b this. The data array returned has to be dealt by the caller.
1016 * The returned node ids are sortes ascendingly. This method is closed to MEDCoupling1SGTUMesh::getNodeIdsInUse except
1017 * the format of returned DataArrayIdType instance.
1019 * \return a newly allocated DataArrayIdType sorted ascendingly of fetched node ids.
1020 * \sa MEDCoupling1SGTUMesh::getNodeIdsInUse, areAllNodesFetched
1022 DataArrayIdType *MEDCoupling1SGTUMesh::computeFetchedNodeIds() const
1024 checkConsistencyOfConnectivity();
1025 mcIdType nbNodes(getNumberOfNodes());
1026 std::vector<bool> fetchedNodes(nbNodes,false);
1027 computeNodeIdsAlg(fetchedNodes);
1028 mcIdType sz(ToIdType(std::count(fetchedNodes.begin(),fetchedNodes.end(),true)));
1029 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(sz,1);
1030 mcIdType *retPtr(ret->getPointer());
1031 for(mcIdType i=0;i<nbNodes;i++)
1038 * Finds nodes not used in any cell and returns an array giving a new id to every node
1039 * by excluding the unused nodes, for which the array holds -1. The result array is
1040 * a mapping in "Old to New" mode.
1041 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
1042 * \return DataArrayIdType * - a new instance of DataArrayIdType. Its length is \a
1043 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
1044 * if the node is unused or a new id else. The caller is to delete this
1045 * array using decrRef() as it is no more needed.
1046 * \throw If the coordinates array is not set.
1047 * \throw If the nodal connectivity of cells is not defined.
1048 * \throw If the nodal connectivity includes an invalid id.
1049 * \sa MEDCoupling1SGTUMesh::computeFetchedNodeIds, areAllNodesFetched
1051 DataArrayIdType *MEDCoupling1SGTUMesh::getNodeIdsInUse(mcIdType& nbrOfNodesInUse) const
1054 mcIdType nbOfNodes=getNumberOfNodes();
1055 mcIdType nbOfCells=getNumberOfCells();
1056 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
1057 ret->alloc(nbOfNodes,1);
1058 mcIdType *traducer=ret->getPointer();
1059 std::fill(traducer,traducer+nbOfNodes,-1);
1060 const mcIdType *conn=_conn->begin();
1061 mcIdType nbNodesPerCell=getNumberOfNodesPerCell();
1062 for(mcIdType i=0;i<nbOfCells;i++)
1063 for(int j=0;j<nbNodesPerCell;j++,conn++)
1064 if(*conn>=0 && *conn<nbOfNodes)
1068 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << conn[j] << " not in [0," << nbOfNodes << ") !";
1069 throw INTERP_KERNEL::Exception(oss.str().c_str());
1071 nbrOfNodesInUse=ToIdType(std::count(traducer,traducer+nbOfNodes,1));
1072 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
1077 * This method renumbers only nodal connectivity in \a this. The renumbering is only an offset applied. So this method is a specialization of
1078 * \a renumberNodesInConn. \b WARNING, this method does not check that the resulting node ids in the nodal connectivity is in a valid range !
1080 * \param [in] offset - specifies the offset to be applied on each element of connectivity.
1082 * \sa renumberNodesInConn
1084 void MEDCoupling1SGTUMesh::renumberNodesWithOffsetInConn(mcIdType offset)
1086 getNumberOfCells();//only to check that all is well defined.
1087 _conn->applyLin(1,offset);
1092 * Same than renumberNodesInConn(const mcIdType *) except that here the format of old-to-new traducer is using map instead
1093 * 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
1096 void MEDCoupling1SGTUMesh::renumberNodesInConn(const INTERP_KERNEL::HashMap<mcIdType,mcIdType>& newNodeNumbersO2N)
1098 this->renumberNodesInConnT< INTERP_KERNEL::HashMap<mcIdType,mcIdType> >(newNodeNumbersO2N);
1102 * Same than renumberNodesInConn(const mcIdType *) except that here the format of old-to-new traducer is using map instead
1103 * 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
1106 void MEDCoupling1SGTUMesh::renumberNodesInConn(const std::map<mcIdType,mcIdType>& newNodeNumbersO2N)
1108 this->renumberNodesInConnT< std::map<mcIdType,mcIdType> >(newNodeNumbersO2N);
1112 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
1113 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
1114 * This method is a generalization of shiftNodeNumbersInConn().
1115 * \warning This method performs no check of validity of new ids. **Use it with care !**
1116 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
1117 * this->getNumberOfNodes(), in "Old to New" mode.
1118 * See \ref numbering for more info on renumbering modes.
1119 * \throw If the nodal connectivity of cells is not defined.
1121 void MEDCoupling1SGTUMesh::renumberNodesInConn(const mcIdType *newNodeNumbersO2N)
1123 getNumberOfCells();//only to check that all is well defined.
1124 _conn->transformWithIndArr(newNodeNumbersO2N,newNodeNumbersO2N+getNumberOfNodes());
1128 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2)
1130 std::vector<const MEDCoupling1SGTUMesh *> tmp(2);
1131 tmp[0]=const_cast<MEDCoupling1SGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1SGTUMesh *>(mesh2);
1132 return Merge1SGTUMeshes(tmp);
1135 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(std::vector<const MEDCoupling1SGTUMesh *>& a)
1137 std::size_t sz=a.size();
1139 return Merge1SGTUMeshesLL(a);
1140 for(std::size_t ii=0;ii<sz;ii++)
1143 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::Merge1SGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
1144 throw INTERP_KERNEL::Exception(oss.str().c_str());
1146 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
1147 for(std::size_t ii=0;ii<sz;ii++)
1148 if(&(a[ii]->getCellModel())!=cm)
1149 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : all items must have the same geo type !");
1150 std::vector< MCAuto<MEDCoupling1SGTUMesh> > bb(sz);
1151 std::vector< const MEDCoupling1SGTUMesh * > aa(sz);
1152 std::size_t spaceDimUndef=-3, spaceDim=spaceDimUndef;
1153 for(std::size_t i=0;i<sz && spaceDim==spaceDimUndef;i++)
1155 const MEDCoupling1SGTUMesh *cur=a[i];
1156 const DataArrayDouble *coo=cur->getCoords();
1158 spaceDim=coo->getNumberOfComponents();
1160 if(spaceDim==spaceDimUndef)
1161 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : no spaceDim specified ! unable to perform merge !");
1162 for(std::size_t i=0;i<sz;i++)
1164 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
1167 return Merge1SGTUMeshesLL(aa);
1171 * \throw If presence of a null instance in the input vector \a a.
1172 * \throw If a is empty
1174 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::vector<const MEDCoupling1SGTUMesh *>& a)
1177 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : input array must be NON EMPTY !");
1178 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1180 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : null instance in the first element of input vector !");
1181 std::vector<const DataArrayIdType *> ncs(a.size());
1182 (*it)->getNumberOfCells();//to check that all is OK
1183 const DataArrayDouble *coords=(*it)->getCoords();
1184 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1185 ncs[0]=(*it)->getNodalConnectivity();
1187 for(int i=1;it!=a.end();i++,it++)
1190 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : presence of a null instance in the input vector !");
1191 if(cm!=&((*it)->getCellModel()))
1192 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1193 (*it)->getNumberOfCells();//to check that all is OK
1194 ncs[i]=(*it)->getNodalConnectivity();
1195 if(coords!=(*it)->getCoords())
1196 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : not lying on same coords !");
1198 MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1199 ret->setCoords(coords);
1200 ret->_conn=DataArrayIdType::Aggregate(ncs);
1205 * 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)
1207 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector<const MEDCoupling1SGTUMesh *>& a)
1210 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : input array must be NON EMPTY !");
1211 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1212 mcIdType nbOfCells=(*it)->getNumberOfCells();
1213 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1214 mcIdType nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
1216 for(;it!=a.end();it++)
1218 if(cm!=&((*it)->getCellModel()))
1219 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1220 nbOfCells+=(*it)->getNumberOfCells();
1222 std::vector<const MEDCouplingPointSet *> aps(a.size());
1223 std::copy(a.begin(),a.end(),aps.begin());
1224 MCAuto<DataArrayDouble> pts=MergeNodesArray(aps);
1225 MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1226 ret->setCoords(pts);
1227 MCAuto<DataArrayIdType> c=DataArrayIdType::New();
1228 c->alloc(nbOfCells*nbNodesPerCell,1);
1229 mcIdType *cPtr=c->getPointer();
1231 for(it=a.begin();it!=a.end();it++)
1233 mcIdType curConnLgth=(*it)->getNodalConnectivityLength();
1234 const mcIdType *curC=(*it)->_conn->begin();
1235 cPtr=std::transform(curC,curC+curConnLgth,cPtr,std::bind2nd(std::plus<mcIdType>(),offset));
1236 offset+=(*it)->getNumberOfNodes();
1239 ret->setNodalConnectivity(c);
1243 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const mcIdType *begin, const mcIdType *end) const
1245 mcIdType ncell=getNumberOfCells();
1246 MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1247 ret->setCoords(_coords);
1248 std::size_t nbOfElemsRet=std::distance(begin,end);
1249 const mcIdType *inConn=_conn->getConstPointer();
1250 mcIdType sz=getNumberOfNodesPerCell();
1251 MCAuto<DataArrayIdType> connRet=DataArrayIdType::New(); connRet->alloc(nbOfElemsRet*sz,1);
1252 mcIdType *connPtr=connRet->getPointer();
1253 for(const mcIdType *work=begin;work!=end;work++,connPtr+=sz)
1255 if(*work>=0 && *work<ncell)
1256 std::copy(inConn+(work[0])*sz,inConn+(work[0]+1)*sz,connPtr);
1259 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !";
1260 throw INTERP_KERNEL::Exception(oss.str().c_str());
1264 ret->copyTinyInfoFrom(this);
1268 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoordsSlice(mcIdType start, mcIdType end, mcIdType step) const
1270 mcIdType ncell=getNumberOfCells();
1271 mcIdType nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoordsSlice : ");
1272 MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1273 ret->setCoords(_coords);
1274 const mcIdType *inConn=_conn->getConstPointer();
1275 mcIdType sz=getNumberOfNodesPerCell();
1276 MCAuto<DataArrayIdType> connRet=DataArrayIdType::New(); connRet->alloc(nbOfElemsRet*sz,1);
1277 mcIdType *connPtr=connRet->getPointer();
1278 mcIdType curId=start;
1279 for(mcIdType i=0;i<nbOfElemsRet;i++,connPtr+=sz,curId+=step)
1281 if(curId>=0 && curId<ncell)
1282 std::copy(inConn+curId*sz,inConn+(curId+1)*sz,connPtr);
1285 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoordsSlice : On pos #" << i << " input cell id =" << curId << " should be in [0," << ncell << ") !";
1286 throw INTERP_KERNEL::Exception(oss.str().c_str());
1290 ret->copyTinyInfoFrom(this);
1294 void MEDCoupling1SGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
1296 mcIdType sz(ToIdType(nodeIdsInUse.size()));
1297 for(const mcIdType *conn=_conn->begin();conn!=_conn->end();conn++)
1299 if(*conn>=0 && *conn<sz)
1300 nodeIdsInUse[*conn]=true;
1303 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeFetchedNodeIds : At pos #" << std::distance(_conn->begin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !";
1304 throw INTERP_KERNEL::Exception(oss.str().c_str());
1309 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(std::size_t spaceDim) const
1311 MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1312 MCAuto<DataArrayIdType> tmp1;
1313 const DataArrayIdType *nodalConn(_conn);
1316 tmp1=DataArrayIdType::New(); tmp1->alloc(0,1);
1323 MCAuto<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
1324 ret->setCoords(coords);
1327 ret->setCoords(_coords);
1331 DataArrayIdType *MEDCoupling1SGTUMesh::simplexizePol0()
1333 mcIdType nbOfCells=getNumberOfCells();
1334 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1335 return DataArrayIdType::Range(0,nbOfCells,1);
1336 MCAuto<DataArrayIdType> newConn=DataArrayIdType::New(); newConn->alloc(2*3*nbOfCells,1);
1337 MCAuto<DataArrayIdType> ret=DataArrayIdType::New(); ret->alloc(2*nbOfCells,1);
1338 const mcIdType *c(_conn->begin());
1339 mcIdType *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1340 for(mcIdType i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1342 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[2];
1343 newConnPtr[3]=c[0]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1344 retPtr[0]=i; retPtr[1]=i;
1347 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1352 DataArrayIdType *MEDCoupling1SGTUMesh::simplexizePol1()
1354 mcIdType nbOfCells=getNumberOfCells();
1355 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1356 return DataArrayIdType::Range(0,nbOfCells,1);
1357 MCAuto<DataArrayIdType> newConn=DataArrayIdType::New(); newConn->alloc(2*3*nbOfCells,1);
1358 MCAuto<DataArrayIdType> ret=DataArrayIdType::New(); ret->alloc(2*nbOfCells,1);
1359 const mcIdType *c(_conn->begin());
1360 mcIdType *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1361 for(mcIdType i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1363 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[3];
1364 newConnPtr[3]=c[1]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1365 retPtr[0]=i; retPtr[1]=i;
1368 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1373 DataArrayIdType *MEDCoupling1SGTUMesh::simplexizePlanarFace5()
1375 mcIdType nbOfCells=getNumberOfCells();
1376 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1377 return DataArrayIdType::Range(0,nbOfCells,1);
1378 MCAuto<DataArrayIdType> newConn=DataArrayIdType::New(); newConn->alloc(5*4*nbOfCells,1);
1379 MCAuto<DataArrayIdType> ret=DataArrayIdType::New(); ret->alloc(5*nbOfCells,1);
1380 const mcIdType *c(_conn->begin());
1381 mcIdType *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1382 for(mcIdType i=0;i<nbOfCells;i++,c+=8,newConnPtr+=20,retPtr+=5)
1384 for(int j=0;j<20;j++)
1385 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_5_WO[j]];
1386 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i;
1389 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1394 DataArrayIdType *MEDCoupling1SGTUMesh::simplexizePlanarFace6()
1396 mcIdType nbOfCells=getNumberOfCells();
1397 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1398 return DataArrayIdType::Range(0,nbOfCells,1);
1399 MCAuto<DataArrayIdType> newConn=DataArrayIdType::New(); newConn->alloc(6*4*nbOfCells,1);
1400 MCAuto<DataArrayIdType> ret=DataArrayIdType::New(); ret->alloc(6*nbOfCells,1);
1401 const mcIdType *c(_conn->begin());
1402 mcIdType *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1403 for(mcIdType i=0;i<nbOfCells;i++,c+=8,newConnPtr+=24,retPtr+=6)
1405 for(int j=0;j<24;j++)
1406 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_6_WO[j]];
1407 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i; retPtr[5]=i;
1410 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1415 void MEDCoupling1SGTUMesh::reprQuickOverview(std::ostream& stream) const
1417 stream << "MEDCoupling1SGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
1418 stream << " Mesh dimension : " << getMeshDimension() << ".";
1420 { stream << " No coordinates set !"; return ; }
1421 if(!_coords->isAllocated())
1422 { stream << " Coordinates set but not allocated !"; return ; }
1423 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
1424 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
1425 if(!(const DataArrayIdType *)_conn)
1426 { stream << std::endl << "Nodal connectivity NOT set !"; return ; }
1427 if(_conn->isAllocated())
1429 if(_conn->getNumberOfComponents()==1)
1430 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
1434 void MEDCoupling1SGTUMesh::checkFullyDefined() const
1436 if(!((const DataArrayIdType *)_conn) || !((const DataArrayDouble *)_coords))
1437 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFullyDefined : part of this is not fully defined.");
1441 * First step of unserialization process.
1443 bool MEDCoupling1SGTUMesh::isEmptyMesh(const std::vector<mcIdType>& tinyInfo) const
1445 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEmptyMesh : not implemented yet !");
1448 void MEDCoupling1SGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<mcIdType>& tinyInfo, std::vector<std::string>& littleStrings) const
1451 double time=getTime(it,order);
1452 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
1454 littleStrings.push_back(getName());
1455 littleStrings.push_back(getDescription());
1456 littleStrings.push_back(getTimeUnit());
1458 std::vector<std::string> littleStrings2,littleStrings3;
1459 if((const DataArrayDouble *)_coords)
1460 _coords->getTinySerializationStrInformation(littleStrings2);
1461 if((const DataArrayIdType *)_conn)
1462 _conn->getTinySerializationStrInformation(littleStrings3);
1463 mcIdType sz0(ToIdType(littleStrings2.size())),sz1(ToIdType(littleStrings3.size()));
1464 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
1465 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
1467 tinyInfo.push_back(getCellModelEnum());
1468 tinyInfo.push_back(it);
1469 tinyInfo.push_back(order);
1470 std::vector<mcIdType> tinyInfo2,tinyInfo3;
1471 if((const DataArrayDouble *)_coords)
1472 _coords->getTinySerializationIntInformation(tinyInfo2);
1473 if((const DataArrayIdType *)_conn)
1474 _conn->getTinySerializationIntInformation(tinyInfo3);
1475 mcIdType sz2(ToIdType(tinyInfo2.size())),sz3(ToIdType(tinyInfo3.size()));
1476 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3);
1477 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1478 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
1480 tinyInfoD.push_back(time);
1483 void MEDCoupling1SGTUMesh::resizeForUnserialization(const std::vector<mcIdType>& tinyInfo, DataArrayIdType *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
1485 std::vector<mcIdType> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+tinyInfo[5]);
1486 std::vector<mcIdType> tinyInfo1(tinyInfo.begin()+7+tinyInfo[5],tinyInfo.begin()+7+tinyInfo[5]+tinyInfo[6]);
1487 a1->resizeForUnserialization(tinyInfo1);
1488 a2->resizeForUnserialization(tinyInfo2);
1491 void MEDCoupling1SGTUMesh::serialize(DataArrayIdType *&a1, DataArrayDouble *&a2) const
1494 if((const DataArrayIdType *)_conn)
1495 if(_conn->isAllocated())
1496 sz=_conn->getNbOfElems();
1497 a1=DataArrayIdType::New();
1499 if(sz!=0 && (const DataArrayIdType *)_conn)
1500 std::copy(_conn->begin(),_conn->end(),a1->getPointer());
1502 if((const DataArrayDouble *)_coords)
1503 if(_coords->isAllocated())
1504 sz=_coords->getNbOfElems();
1505 a2=DataArrayDouble::New();
1507 if(sz!=0 && (const DataArrayDouble *)_coords)
1508 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
1511 void MEDCoupling1SGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<mcIdType>& tinyInfo, const DataArrayIdType *a1, DataArrayDouble *a2,
1512 const std::vector<std::string>& littleStrings)
1514 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
1515 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
1516 setName(littleStrings[0]);
1517 setDescription(littleStrings[1]);
1518 setTimeUnit(littleStrings[2]);
1519 setTime(tinyInfoD[0],FromIdType<int>(tinyInfo[1]),FromIdType<int>(tinyInfo[2]));
1520 mcIdType sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]);
1522 _coords=DataArrayDouble::New();
1523 std::vector<mcIdType> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+sz2);
1524 _coords->resizeForUnserialization(tinyInfo2);
1525 std::copy(a2->begin(),a2->end(),_coords->getPointer());
1526 _conn=DataArrayIdType::New();
1527 std::vector<mcIdType> tinyInfo3(tinyInfo.begin()+7+sz2,tinyInfo.begin()+7+sz2+sz3);
1528 _conn->resizeForUnserialization(tinyInfo3);
1529 std::copy(a1->begin(),a1->end(),_conn->getPointer());
1530 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
1531 _coords->finishUnserialization(tinyInfo2,littleStrings2);
1532 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
1533 _conn->finishUnserialization(tinyInfo3,littleStrings3);
1537 * Checks if \a this and \a other meshes are geometrically equivalent with high
1538 * probability, else an exception is thrown. The meshes are considered equivalent if
1539 * (1) meshes contain the same number of nodes and the same number of elements of the
1540 * same types (2) three cells of the two meshes (first, last and middle) are based
1541 * on coincident nodes (with a specified precision).
1542 * \param [in] other - the mesh to compare with.
1543 * \param [in] prec - the precision used to compare nodes of the two meshes.
1544 * \throw If the two meshes do not match.
1546 void MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
1548 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1549 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1551 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single static geometric type !");
1552 const DataArrayIdType *c1(_conn),*c2(otherC->_conn);
1556 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1557 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1558 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1559 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1560 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1561 if(c1->getHashCode()!=c2->getHashCode())
1562 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1565 MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
1568 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
1569 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1571 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
1572 std::vector<const MEDCoupling1SGTUMesh *> ms(2);
1575 return Merge1SGTUMeshesOnSameCoords(ms);
1578 void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayIdType *revNodal, DataArrayIdType *revNodalIndx) const
1580 checkFullyDefined();
1581 mcIdType nbOfNodes=getNumberOfNodes();
1582 mcIdType *revNodalIndxPtr=(mcIdType *)malloc((nbOfNodes+1)*sizeof(mcIdType));
1583 revNodalIndx->useArray(revNodalIndxPtr,true,DeallocType::C_DEALLOC,nbOfNodes+1,1);
1584 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
1585 const mcIdType *conn=_conn->begin();
1586 mcIdType nbOfCells=getNumberOfCells();
1587 mcIdType nbOfEltsInRevNodal=0;
1588 mcIdType nbOfNodesPerCell=getNumberOfNodesPerCell();
1589 for(mcIdType eltId=0;eltId<nbOfCells;eltId++)
1591 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1593 if(conn[0]>=0 && conn[0]<nbOfNodes)
1595 nbOfEltsInRevNodal++;
1596 revNodalIndxPtr[conn[0]+1]++;
1600 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
1601 throw INTERP_KERNEL::Exception(oss.str().c_str());
1605 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<mcIdType>());
1606 conn=_conn->begin();
1607 mcIdType *revNodalPtr=(mcIdType *)malloc(nbOfEltsInRevNodal*sizeof(mcIdType));
1608 revNodal->useArray(revNodalPtr,true,DeallocType::C_DEALLOC,nbOfEltsInRevNodal,1);
1609 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
1610 for(mcIdType eltId=0;eltId<nbOfCells;eltId++)
1612 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1614 *std::find_if(revNodalPtr+revNodalIndxPtr[*conn],revNodalPtr+revNodalIndxPtr[*conn+1],std::bind2nd(std::equal_to<mcIdType>(),-1))=eltId;
1620 * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null.
1622 void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayIdType *nodalConn)
1625 nodalConn->incrRef();
1631 * \return DataArrayIdType * - the internal reference to the nodal connectivity. The caller is not responsible to deallocate it.
1633 DataArrayIdType *MEDCoupling1SGTUMesh::getNodalConnectivity() const
1635 const DataArrayIdType *ret(_conn);
1636 return const_cast<DataArrayIdType *>(ret);
1640 * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted,
1641 * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter.
1642 * If a nodal connectivity previously existed before the call of this method, it will be reset.
1644 * \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain.
1646 void MEDCoupling1SGTUMesh::allocateCells(mcIdType nbOfCells)
1649 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !");
1650 _conn=DataArrayIdType::New();
1651 _conn->reserve(getNumberOfNodesPerCell()*nbOfCells);
1656 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
1658 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
1659 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
1660 * \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
1661 * attached to \a this.
1662 * \throw If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
1664 void MEDCoupling1SGTUMesh::insertNextCell(const mcIdType *nodalConnOfCellBg, const mcIdType *nodalConnOfCellEnd)
1666 mcIdType sz=ToIdType(std::distance(nodalConnOfCellBg,nodalConnOfCellEnd));
1667 mcIdType ref=getNumberOfNodesPerCell();
1670 DataArrayIdType *c(_conn);
1672 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
1674 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !");
1678 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this (";
1679 oss << ref << ") !";
1680 throw INTERP_KERNEL::Exception(oss.str().c_str());
1685 * This method builds the dual mesh of \a this and returns it.
1687 * \return MEDCoupling1SGTUMesh * - newly object created to be managed by the caller.
1688 * \throw If \a this is not a mesh containing only simplex cells.
1689 * \throw If \a this is not correctly allocated (coordinates and connectivities have to be correctly set !).
1690 * \throw If at least one node in \a this is orphan (without any simplex cell lying on it !)
1692 MEDCoupling1GTUMesh *MEDCoupling1SGTUMesh::computeDualMesh() const
1694 const INTERP_KERNEL::CellModel& cm(getCellModel());
1696 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : this mesh is not a simplex mesh ! Please invoke simplexize of tetrahedrize on this before calling this method !");
1697 switch(getMeshDimension())
1700 return computeDualMesh3D();
1702 return computeDualMesh2D();
1704 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : meshdimension must be in [2,3] !");
1709 * This method explode each NORM_HEXA8 cells in \a this into 6 NORM_QUAD4 cells and put the result into the MEDCoupling1SGTUMesh returned instance.
1711 * \return MEDCoupling1SGTUMesh * - a newly allocated instances (to be managed by the caller) storing the result of the explosion.
1712 * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
1713 * \throw If \a this is not properly allocated.
1715 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4() const
1717 const INTERP_KERNEL::CellModel& cm(getCellModel());
1718 if(cm.getEnum()!=INTERP_KERNEL::NORM_HEXA8)
1719 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4 : this method can be applied only on HEXA8 mesh !");
1720 mcIdType nbHexa8=getNumberOfCells();
1721 const mcIdType *inConnPtr(getNodalConnectivity()->begin());
1722 MCAuto<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(getName(),INTERP_KERNEL::NORM_QUAD4));
1723 MCAuto<DataArrayIdType> c(DataArrayIdType::New()); c->alloc(nbHexa8*6*4,1);
1724 mcIdType *cPtr(c->getPointer());
1725 for(mcIdType i=0;i<nbHexa8;i++,inConnPtr+=8)
1727 for(int j=0;j<6;j++,cPtr+=4)
1728 cm.fillSonCellNodalConnectivity(j,inConnPtr,cPtr);
1730 ret->setCoords(getCoords());
1731 ret->setNodalConnectivity(c);
1736 * This method starts from an unstructured mesh that hides in reality a cartesian mesh.
1737 * If it is not the case, an exception will be thrown.
1738 * This method returns three objects : The cartesian mesh geometrically equivalent to \a this (within a precision of \a eps) and a permutation of cells
1739 * and a permutation of nodes.
1741 * - this[cellPerm[i]]=ret[i]
1743 * \param [out] cellPerm the permutation array of size \c this->getNumberOfCells()
1744 * \param [out] nodePerm the permutation array of size \c this->getNumberOfNodes()
1745 * \return MEDCouplingCMesh * - a newly allocated mesh that is the result of the structurization of \a this.
1747 MEDCouplingCMesh *MEDCoupling1SGTUMesh::structurizeMe(DataArrayIdType *& cellPerm, DataArrayIdType *& nodePerm, double eps) const
1749 checkConsistencyLight();
1750 int spaceDim(getSpaceDimension()),meshDim(getMeshDimension()); mcIdType nbNodes(getNumberOfNodes());
1751 if(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim)!=getCellModelEnum())
1752 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::structurizeMe : the unique geo type in this is not compatible with the geometric type regarding mesh dimension !");
1753 MCAuto<MEDCouplingCMesh> cm(MEDCouplingCMesh::New());
1754 for(int i=0;i<spaceDim;i++)
1756 std::vector<std::size_t> tmp(1,i);
1757 MCAuto<DataArrayDouble> elt(static_cast<DataArrayDouble*>(getCoords()->keepSelectedComponents(tmp)));
1758 elt=elt->getDifferentValues(eps);
1760 cm->setCoordsAt(i,elt);
1762 if(nbNodes!=cm->getNumberOfNodes())
1763 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 ?");
1765 { cm->copyTinyInfoFrom(this); }
1766 catch(INTERP_KERNEL::Exception&) { }
1767 MCAuto<MEDCouplingUMesh> um(cm->buildUnstructured()),self(buildUnstructured());
1768 self->checkGeoEquivalWith(um,12,eps,cellPerm,nodePerm);
1774 bool UpdateHexa8Cell(int validAxis, mcIdType neighId, const mcIdType *validConnQuad4NeighSide, mcIdType *allFacesNodalConn, mcIdType *myNeighbours)
1776 static const int TAB[48]={
1784 static const int TAB2[6]={0,0,3,3,3,3};
1785 if(myNeighbours[validAxis]==neighId && allFacesNodalConn[4*validAxis+0]==validConnQuad4NeighSide[TAB2[validAxis]])
1787 mcIdType oldAxis(ToIdType(std::distance(myNeighbours,std::find(myNeighbours,myNeighbours+6,neighId))));
1788 std::size_t pos(std::distance(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,std::find(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS+6,oldAxis)));
1789 std::size_t pos0(pos/2),pos1(pos%2);
1790 int oldAxisOpp(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[2*pos0+(pos1+1)%2]);
1791 mcIdType oldConn[8],myConn2[8]={-1,-1,-1,-1,-1,-1,-1,-1},myConn[8],edgeConn[2],allFacesTmp[24],neighTmp[6];
1792 oldConn[0]=allFacesNodalConn[0]; oldConn[1]=allFacesNodalConn[1]; oldConn[2]=allFacesNodalConn[2]; oldConn[3]=allFacesNodalConn[3];
1793 oldConn[4]=allFacesNodalConn[4]; oldConn[5]=allFacesNodalConn[7]; oldConn[6]=allFacesNodalConn[6]; oldConn[7]=allFacesNodalConn[5];
1794 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_HEXA8));
1795 for(int i=0;i<4;i++)
1796 myConn2[i]=validConnQuad4NeighSide[(4-i+TAB2[validAxis])%4];
1797 for(int i=0;i<4;i++)
1799 mcIdType nodeId(myConn2[i]);//the node id for which the opposite one will be found
1801 INTERP_KERNEL::NormalizedCellType typeOfSon;
1802 for(int j=0;j<12 && !found;j++)
1804 cm.fillSonEdgesNodalConnectivity3D(j,oldConn,-1,edgeConn,typeOfSon);
1805 if(edgeConn[0]==nodeId || edgeConn[1]==nodeId)
1807 if(std::find(allFacesNodalConn+4*oldAxisOpp,allFacesNodalConn+4*oldAxisOpp+4,edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0])!=allFacesNodalConn+4*oldAxisOpp+4)
1809 myConn2[i+4]=edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0];
1815 throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error !");
1817 const int *myTab(TAB+8*validAxis);
1818 for(int i=0;i<8;i++)
1819 myConn[i]=myConn2[myTab[i]];
1820 for(int i=0;i<6;i++)
1822 cm.fillSonCellNodalConnectivity(i,myConn,allFacesTmp+4*i);
1823 std::set<mcIdType> s(allFacesTmp+4*i,allFacesTmp+4*i+4);
1825 for(int j=0;j<6 && !found;j++)
1827 std::set<mcIdType> s1(allFacesNodalConn+4*j,allFacesNodalConn+4*j+4);
1830 neighTmp[i]=myNeighbours[j];
1835 throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error #2 !");
1837 std::copy(allFacesTmp,allFacesTmp+24,allFacesNodalConn);
1838 std::copy(neighTmp,neighTmp+6,myNeighbours);
1845 * 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
1846 * homogeneous. If it succeeds the result of MEDCouplingUMesh::tetrahedrize will return a conform mesh.
1848 * \return DataArrayIdType * - a newly allocated array (to be managed by the caller) containing renumbered cell ids.
1850 * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
1851 * \throw If \a this is not properly allocated.
1852 * \sa MEDCouplingUMesh::tetrahedrize, MEDCouplingUMesh::simplexize.
1854 DataArrayIdType *MEDCoupling1SGTUMesh::sortHexa8EachOther()
1856 MCAuto<MEDCoupling1SGTUMesh> quads(explodeEachHexa8To6Quad4());//checks that only hexa8
1857 mcIdType nbHexa8=getNumberOfCells();
1858 mcIdType *cQuads(quads->getNodalConnectivity()->getPointer());
1859 MCAuto<DataArrayIdType> neighOfQuads(DataArrayIdType::New()); neighOfQuads->alloc(nbHexa8*6,1); neighOfQuads->fillWithValue(-1);
1860 mcIdType *ptNeigh(neighOfQuads->getPointer());
1861 {//neighOfQuads tells for each face of each Quad8 which cell (if!=-1) is connected to this face.
1862 MCAuto<MEDCouplingUMesh> quadsTmp(quads->buildUnstructured());
1863 MCAuto<DataArrayIdType> ccSafe,cciSafe;
1864 DataArrayIdType *cc(0),*cci(0);
1865 quadsTmp->findCommonCells(3,0,cc,cci);
1866 ccSafe=cc; cciSafe=cci;
1867 const mcIdType *ccPtr(ccSafe->begin());
1868 mcIdType nbOfPair=cci->getNumberOfTuples()-1;
1869 for(mcIdType i=0;i<nbOfPair;i++)
1870 { ptNeigh[ccPtr[2*i+0]]=ccPtr[2*i+1]/6; ptNeigh[ccPtr[2*i+1]]=ccPtr[2*i+0]/6; }
1872 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(0,1);
1873 std::vector<bool> fetched(nbHexa8,false);
1874 std::vector<bool>::iterator it(std::find(fetched.begin(),fetched.end(),false));
1875 while(it!=fetched.end())//it will turns as time as number of connected zones
1877 mcIdType cellId(ToIdType(std::distance(fetched.begin(),it)));//it is the seed of the connected zone.
1878 std::set<mcIdType> s; s.insert(cellId);//s contains already organized.
1881 std::set<mcIdType> sNext;
1882 for(std::set<mcIdType>::const_iterator it0=s.begin();it0!=s.end();it0++)
1885 mcIdType *myNeighb(ptNeigh+6*(*it0));
1886 for(int i=0;i<6;i++)
1888 if(myNeighb[i]!=-1 && !fetched[myNeighb[i]])
1890 std::size_t pos(std::distance(HEXA8_FACE_PAIRS,std::find(HEXA8_FACE_PAIRS,HEXA8_FACE_PAIRS+6,i)));
1891 std::size_t pos0(pos/2),pos1(pos%2);
1892 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]))
1893 ret->pushBackSilent(myNeighb[i]);
1894 fetched[myNeighb[i]]=true;
1895 sNext.insert(myNeighb[i]);
1901 it=std::find(fetched.begin(),fetched.end(),false);
1905 mcIdType *conn(getNodalConnectivity()->getPointer());
1906 for(const mcIdType *pt=ret->begin();pt!=ret->end();pt++)
1908 mcIdType cellId(*pt);
1909 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];
1910 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];
1917 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh3D() const
1919 static const int DUAL_TETRA_0[36]={
1920 4,1,0, 6,0,3, 7,3,1,
1921 4,0,1, 5,2,0, 8,1,2,
1922 6,3,0, 5,0,2, 9,2,3,
1925 static const int DUAL_TETRA_1[36]={
1926 8,4,10, 11,5,8, 10,7,11,
1927 9,4,8, 8,5,12, 12,6,9,
1928 10,4,9, 9,6,13, 13,7,10,
1929 12,5,11, 13,6,12, 11,7,13
1931 static const int FACEID_NOT_SH_NODE[4]={2,3,1,0};
1932 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TETRA4)
1933 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh3D : only TETRA4 supported !");
1934 checkFullyDefined();
1935 MCAuto<MEDCouplingUMesh> thisu(buildUnstructured());
1936 MCAuto<DataArrayIdType> revNodArr(DataArrayIdType::New()),revNodIArr(DataArrayIdType::New());
1937 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1938 const mcIdType *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1939 MCAuto<DataArrayIdType> d1Arr(DataArrayIdType::New()),di1Arr(DataArrayIdType::New()),rd1Arr(DataArrayIdType::New()),rdi1Arr(DataArrayIdType::New());
1940 MCAuto<MEDCouplingUMesh> edges(thisu->explode3DMeshTo1D(d1Arr,di1Arr,rd1Arr,rdi1Arr));
1941 const mcIdType *d1(d1Arr->begin());
1942 MCAuto<DataArrayIdType> d2Arr(DataArrayIdType::New()),di2Arr(DataArrayIdType::New()),rd2Arr(DataArrayIdType::New()),rdi2Arr(DataArrayIdType::New());
1943 MCAuto<MEDCouplingUMesh> faces(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
1944 const mcIdType *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
1945 MCAuto<DataArrayDouble> edgesBaryArr(edges->computeCellCenterOfMass()),facesBaryArr(faces->computeCellCenterOfMass()),baryArr(computeCellCenterOfMass());
1946 const mcIdType nbOfNodes(getNumberOfNodes());
1947 const mcIdType offset0=nbOfNodes+faces->getNumberOfCells();
1948 const mcIdType offset1=offset0+edges->getNumberOfCells();
1950 std::vector<const DataArrayDouble *> v(4); v[0]=getCoords(); v[1]=facesBaryArr; v[2]=edgesBaryArr; v[3]=baryArr;
1951 MCAuto<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0; facesBaryArr=0;
1952 std::string name("DualOf_"); name+=getName();
1953 MCAuto<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYHED)); ret->setCoords(zeArr);
1954 MCAuto<DataArrayIdType> cArr(DataArrayIdType::New()),ciArr(DataArrayIdType::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1955 for(mcIdType i=0;i<nbOfNodes;i++,revNodI++)
1957 mcIdType nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1958 if(nbOfCellsSharingNode==0)
1960 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh3D : Node #" << i << " is orphan !";
1961 throw INTERP_KERNEL::Exception(oss.str().c_str());
1963 for(int j=0;j<nbOfCellsSharingNode;j++)
1965 mcIdType curCellId(revNod[revNodI[0]+j]);
1966 const mcIdType *connOfCurCell(nodal+4*curCellId);
1967 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1968 if(j!=0) cArr->pushBackSilent(-1);
1971 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;
1972 tmp[2]=curCellId+offset1; tmp[3]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+2]]+nbOfNodes;
1974 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;
1975 tmp[7]=curCellId+offset1; tmp[8]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+5]]+nbOfNodes;
1977 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;
1978 tmp[12]=curCellId+offset1; tmp[13]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+8]]+nbOfNodes;
1979 cArr->insertAtTheEnd(tmp,tmp+14);
1981 for(int k=0;k<4;k++)
1983 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1985 const mcIdType *faceId(d2+4*curCellId+k);
1986 if(rdi2[*faceId+1]-rdi2[*faceId]==1)
1988 mcIdType tmp2[5]; tmp2[0]=-1; tmp2[1]=i;
1989 tmp2[2]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+0]-8]+offset0;
1990 tmp2[3]=d2[4*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+1]-4]+nbOfNodes;
1991 tmp2[4]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+2]-8]+offset0;
1992 cArr->insertAtTheEnd(tmp2,tmp2+5);
1998 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
2000 ret->setNodalConnectivity(cArr,ciArr);
2004 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh2D() const
2006 static const int DUAL_TRI_0[6]={0,2, 1,0, 2,1};
2007 static const int DUAL_TRI_1[6]={-3,+5, +3,-4, +4,-5};
2008 static const int FACEID_NOT_SH_NODE[3]={1,2,0};
2009 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TRI3)
2010 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh2D : only TRI3 supported !");
2011 checkFullyDefined();
2012 MCAuto<MEDCouplingUMesh> thisu(buildUnstructured());
2013 MCAuto<DataArrayIdType> revNodArr(DataArrayIdType::New()),revNodIArr(DataArrayIdType::New());
2014 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
2015 const mcIdType *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
2016 MCAuto<DataArrayIdType> d2Arr(DataArrayIdType::New()),di2Arr(DataArrayIdType::New()),rd2Arr(DataArrayIdType::New()),rdi2Arr(DataArrayIdType::New());
2017 MCAuto<MEDCouplingUMesh> edges(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
2018 const mcIdType *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
2019 MCAuto<DataArrayDouble> edgesBaryArr(edges->computeCellCenterOfMass()),baryArr(computeCellCenterOfMass());
2020 const mcIdType nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+edges->getNumberOfCells());
2022 std::vector<const DataArrayDouble *> v(3); v[0]=getCoords(); v[1]=edgesBaryArr; v[2]=baryArr;
2023 MCAuto<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0;
2024 std::string name("DualOf_"); name+=getName();
2025 MCAuto<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYGON)); ret->setCoords(zeArr);
2026 MCAuto<DataArrayIdType> cArr(DataArrayIdType::New()),ciArr(DataArrayIdType::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
2027 for(mcIdType i=0;i<nbOfNodes;i++,revNodI++)
2029 mcIdType nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
2030 if(nbOfCellsSharingNode==0)
2032 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh2D : Node #" << i << " is orphan !";
2033 throw INTERP_KERNEL::Exception(oss.str().c_str());
2035 std::vector< std::vector<mcIdType> > polyg;
2036 for(int j=0;j<nbOfCellsSharingNode;j++)
2038 mcIdType curCellId(revNod[revNodI[0]+j]);
2039 const mcIdType *connOfCurCell(nodal+3*curCellId);
2040 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
2041 std::vector<mcIdType> locV(3);
2042 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;
2043 polyg.push_back(locV);
2045 for(int k=0;k<3;k++)
2047 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
2049 const mcIdType *edgeId(d2+3*curCellId+k);
2050 if(rdi2[*edgeId+1]-rdi2[*edgeId]==1)
2052 std::vector<mcIdType> locV2(2);
2053 int zeLocEdgeIdRel(DUAL_TRI_1[2*nodePosInCurCell+kk]);
2054 if(zeLocEdgeIdRel>0)
2055 { locV2[0]=d2[3*curCellId+zeLocEdgeIdRel-3]+nbOfNodes; locV2[1]=i; }
2057 { locV2[0]=i; locV2[1]=d2[3*curCellId-zeLocEdgeIdRel-3]+nbOfNodes; }
2058 polyg.push_back(locV2);
2064 std::vector<mcIdType> zePolyg(MEDCoupling1DGTUMesh::BuildAPolygonFromParts(polyg));
2065 cArr->insertAtTheEnd(zePolyg.begin(),zePolyg.end());
2066 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
2068 ret->setNodalConnectivity(cArr,ciArr);
2073 * This method aggregate the bbox of each cell and put it into bbox
2075 * \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)
2076 * For all other cases this input parameter is ignored.
2077 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
2079 * \throw If \a this is not fully set (coordinates and connectivity).
2080 * \throw If a cell in \a this has no valid nodeId.
2082 DataArrayDouble *MEDCoupling1SGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
2084 mcIdType spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()),nbOfNodesPerCell(getNumberOfNodesPerCell());
2085 MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
2086 double *bbox(ret->getPointer());
2087 for(mcIdType i=0;i<nbOfCells*spaceDim;i++)
2089 bbox[2*i]=std::numeric_limits<double>::max();
2090 bbox[2*i+1]=-std::numeric_limits<double>::max();
2092 const double *coordsPtr(_coords->getConstPointer());
2093 const mcIdType *conn(_conn->getConstPointer());
2094 for(mcIdType i=0;i<nbOfCells;i++)
2097 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
2099 mcIdType nodeId(*conn);
2100 if(nodeId>=0 && nodeId<nbOfNodes)
2102 for(int k=0;k<spaceDim;k++)
2104 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
2105 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
2112 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
2113 throw INTERP_KERNEL::Exception(oss.str().c_str());
2120 * 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.
2122 * \return a new instance of field containing the result. The returned instance has to be deallocated by the caller.
2124 MEDCouplingFieldDouble *MEDCoupling1SGTUMesh::computeDiameterField() const
2126 checkFullyDefined();
2127 MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME));
2128 mcIdType nbCells=getNumberOfCells();
2129 MCAuto<DataArrayDouble> arr(DataArrayDouble::New());
2130 arr->alloc(nbCells,1);
2131 INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::DiameterCalculator> dc(_cm->buildInstanceOfDiameterCalulator(getSpaceDimension()));
2132 dc->computeFor1SGTUMeshFrmt(nbCells,_conn->begin(),getCoords()->begin(),arr->getPointer());
2135 ret->setName("Diameter");
2140 * This method invert orientation of all cells in \a this.
2141 * After calling this method the absolute value of measure of cells in \a this are the same than before calling.
2142 * This method only operates on the connectivity so coordinates are not touched at all.
2144 void MEDCoupling1SGTUMesh::invertOrientationOfAllCells()
2146 checkConsistencyOfConnectivity();
2147 INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::OrientationInverter> oi(INTERP_KERNEL::OrientationInverter::BuildInstanceFrom(getCellModelEnum()));
2148 mcIdType nbOfNodesPerCell=ToIdType(_cm->getNumberOfNodes()),nbCells=getNumberOfCells();
2149 mcIdType *conn(_conn->getPointer());
2150 for(mcIdType i=0;i<nbCells;i++)
2151 oi->operate(conn+i*nbOfNodesPerCell,conn+(i+1)*nbOfNodesPerCell);
2157 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New()
2159 return new MEDCoupling1DGTUMesh;
2162 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
2164 if(type==INTERP_KERNEL::NORM_ERROR)
2165 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
2166 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
2169 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !";
2170 throw INTERP_KERNEL::Exception(oss.str().c_str());
2172 return new MEDCoupling1DGTUMesh(name,cm);
2175 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh()
2179 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
2183 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn_indx(other._conn_indx),_conn(other._conn)
2187 const DataArrayIdType *c(other._conn);
2189 _conn=c->deepCopy();
2192 _conn_indx=c->deepCopy();
2196 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const
2198 return new MEDCoupling1DGTUMesh(*this,recDeepCpy);
2202 * This method behaves mostly like MEDCoupling1DGTUMesh::deepCopy method, except that only nodal connectivity arrays are deeply copied.
2203 * The coordinates are shared between \a this and the returned instance.
2205 * \return MEDCoupling1DGTUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
2206 * \sa MEDCoupling1DGTUMesh::deepCopy
2208 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::deepCopyConnectivityOnly() const
2210 checkConsistencyLight();
2211 MCAuto<MEDCoupling1DGTUMesh> ret(clone(false));
2212 MCAuto<DataArrayIdType> c(_conn->deepCopy()),ci(_conn_indx->deepCopy());
2213 ret->setNodalConnectivity(c,ci);
2217 void MEDCoupling1DGTUMesh::updateTime() const
2219 MEDCoupling1GTUMesh::updateTime();
2220 const DataArrayIdType *c(_conn);
2228 std::size_t MEDCoupling1DGTUMesh::getHeapMemorySizeWithoutChildren() const
2230 return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren();
2233 std::vector<const BigMemoryObject *> MEDCoupling1DGTUMesh::getDirectChildrenWithNull() const
2235 std::vector<const BigMemoryObject *> ret(MEDCoupling1GTUMesh::getDirectChildrenWithNull());
2236 ret.push_back((const DataArrayIdType *)_conn);
2237 ret.push_back((const DataArrayIdType *)_conn_indx);
2241 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::deepCopy() const
2246 bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
2249 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !");
2250 std::ostringstream oss; oss.precision(15);
2251 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2254 reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !";
2257 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
2259 const DataArrayIdType *c1(_conn),*c2(otherC->_conn);
2264 reason="in connectivity of single dynamic geometric type exactly one among this and other is null !";
2267 if(!c1->isEqualIfNotWhy(*c2,reason))
2269 reason.insert(0,"Nodal connectivity DataArrayIdType differs : ");
2272 c1=_conn_indx; c2=otherC->_conn_indx;
2277 reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !";
2280 if(!c1->isEqualIfNotWhy(*c2,reason))
2282 reason.insert(0,"Nodal connectivity index DataArrayIdType differs : ");
2288 bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
2291 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
2292 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2295 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
2297 const DataArrayIdType *c1(_conn),*c2(otherC->_conn);
2302 if(!c1->isEqualWithoutConsideringStr(*c2))
2308 * Checks if \a this and \a other meshes are geometrically equivalent with high
2309 * probability, else an exception is thrown. The meshes are considered equivalent if
2310 * (1) meshes contain the same number of nodes and the same number of elements of the
2311 * same types (2) three cells of the two meshes (first, last and middle) are based
2312 * on coincident nodes (with a specified precision).
2313 * \param [in] other - the mesh to compare with.
2314 * \param [in] prec - the precision used to compare nodes of the two meshes.
2315 * \throw If the two meshes do not match.
2317 void MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
2319 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
2320 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2322 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single dynamic geometric type !");
2323 const DataArrayIdType *c1(_conn),*c2(otherC->_conn);
2327 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
2328 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2329 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
2330 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2331 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
2332 if(c1->getHashCode()!=c2->getHashCode())
2333 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs");
2335 c1=_conn_indx; c2=otherC->_conn_indx;
2339 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !");
2340 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2341 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !");
2342 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2343 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !");
2344 if(c1->getHashCode()!=c2->getHashCode())
2345 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs");
2349 void MEDCoupling1DGTUMesh::checkConsistencyOfConnectivity() const
2351 const DataArrayIdType *c1(_conn);
2354 if(c1->getNumberOfComponents()!=1)
2355 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
2356 if(c1->getInfoOnComponent(0)!="")
2357 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
2358 c1->checkAllocated();
2361 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
2363 mcIdType sz2(_conn->getNumberOfTuples());
2367 if(c1->getNumberOfComponents()!=1)
2368 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
2369 c1->checkAllocated();
2370 if(c1->getNumberOfTuples()<1)
2371 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !");
2372 if(c1->getInfoOnComponent(0)!="")
2373 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
2374 mcIdType f=c1->front(),ll=c1->back();
2375 if(f<0 || (sz2>0 && f>=sz2))
2377 std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !";
2378 throw INTERP_KERNEL::Exception(oss.str().c_str());
2382 std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !";
2383 throw INTERP_KERNEL::Exception(oss.str().c_str());
2387 std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !";
2388 throw INTERP_KERNEL::Exception(oss.str().c_str());
2392 throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !");
2393 mcIdType szOfC1Exp=_conn_indx->back();
2396 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() << " !";
2397 throw INTERP_KERNEL::Exception(oss.str().c_str());
2402 * 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.
2403 * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one.
2404 * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array.
2406 void MEDCoupling1DGTUMesh::checkConsistencyLight() const
2408 MEDCouplingPointSet::checkConsistencyLight();
2409 checkConsistencyOfConnectivity();
2412 void MEDCoupling1DGTUMesh::checkConsistency(double eps) const
2414 checkConsistencyLight();
2415 const DataArrayIdType *c1(_conn),*c2(_conn_indx);
2416 if(!c2->isMonotonic(true))
2417 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkConsistency : the nodal connectivity index is expected to be increasing monotinic !");
2419 mcIdType nbOfTuples(c1->getNumberOfTuples());
2420 mcIdType nbOfNodes=getNumberOfNodes();
2421 const mcIdType *w(c1->begin());
2422 for(mcIdType i=0;i<nbOfTuples;i++,w++)
2424 if(*w==-1) continue;
2425 if(*w<0 || *w>=nbOfNodes)
2427 std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !";
2428 throw INTERP_KERNEL::Exception(oss.str().c_str());
2433 mcIdType MEDCoupling1DGTUMesh::getNumberOfCells() const
2435 checkConsistencyOfConnectivity();//do not remove
2436 return _conn_indx->getNumberOfTuples()-1;
2440 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2441 * For each cell in \b this the number of nodes constituting cell is computed.
2442 * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned.
2443 * So for pohyhedrons some nodes can be counted several times in the returned result.
2445 * \return a newly allocated array
2447 DataArrayIdType *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const
2449 checkConsistencyLight();
2450 _conn_indx->checkMonotonic(true);
2451 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2452 return _conn_indx->deltaShiftIndex();
2454 mcIdType nbOfCells=_conn_indx->getNumberOfTuples()-1;
2455 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
2456 ret->alloc(nbOfCells,1);
2457 mcIdType *retPtr=ret->getPointer();
2458 const mcIdType *ci=_conn_indx->begin(),*c=_conn->begin();
2459 for(mcIdType i=0;i<nbOfCells;i++,retPtr++,ci++)
2460 *retPtr=int(ci[1]-ci[0]-ToIdType(std::count(c+ci[0],c+ci[1],-1)));
2465 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2466 * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed.
2468 * \return a newly allocated array
2470 DataArrayIdType *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const
2472 checkConsistencyLight();
2473 _conn_indx->checkMonotonic(true);
2474 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG)
2475 return _conn_indx->deltaShiftIndex();
2476 if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG)
2478 MCAuto<DataArrayIdType> ret=_conn_indx->deltaShiftIndex();
2479 ret->applyDivideBy(2);
2483 mcIdType nbOfCells=_conn_indx->getNumberOfTuples()-1;
2484 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
2485 ret->alloc(nbOfCells,1);
2486 mcIdType *retPtr=ret->getPointer();
2487 const mcIdType *ci=_conn_indx->begin(),*c=_conn->begin();
2488 for(mcIdType i=0;i<nbOfCells;i++,retPtr++,ci++)
2489 *retPtr=ToIdType(std::count(c+ci[0],c+ci[1],-1))+1;
2494 * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell,
2495 * will be counted only once here whereas it will be counted several times in MEDCoupling1DGTUMesh::computeNbOfNodesPerCell method.
2497 * \return DataArrayIdType * - new object to be deallocated by the caller.
2498 * \sa MEDCoupling1DGTUMesh::computeNbOfNodesPerCell
2500 DataArrayIdType *MEDCoupling1DGTUMesh::computeEffectiveNbOfNodesPerCell() const
2502 checkConsistencyLight();
2503 _conn_indx->checkMonotonic(true);
2504 mcIdType nbOfCells=_conn_indx->getNumberOfTuples()-1;
2505 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
2506 ret->alloc(nbOfCells,1);
2507 mcIdType *retPtr(ret->getPointer());
2508 const mcIdType *ci(_conn_indx->begin()),*c(_conn->begin());
2509 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2511 for(mcIdType i=0;i<nbOfCells;i++,retPtr++,ci++)
2513 std::set<mcIdType> s(c+ci[0],c+ci[1]);
2514 *retPtr=ToIdType(s.size());
2519 for(mcIdType i=0;i<nbOfCells;i++,retPtr++,ci++)
2521 std::set<mcIdType> s(c+ci[0],c+ci[1]); s.erase(-1);
2522 *retPtr=ToIdType(s.size());
2528 void MEDCoupling1DGTUMesh::getNodeIdsOfCell(mcIdType cellId, std::vector<mcIdType>& conn) const
2530 mcIdType nbOfCells(getNumberOfCells());//performs checks
2531 if(cellId<nbOfCells)
2533 mcIdType strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2534 mcIdType nbOfNodes=stp-strt;
2536 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !");
2537 conn.resize(nbOfNodes);
2538 std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin());
2542 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2543 throw INTERP_KERNEL::Exception(oss.str().c_str());
2547 mcIdType MEDCoupling1DGTUMesh::getNumberOfNodesInCell(mcIdType cellId) const
2549 mcIdType nbOfCells=getNumberOfCells();//performs checks
2550 if(cellId>=0 && cellId<nbOfCells)
2552 const mcIdType *conn(_conn->begin());
2553 mcIdType strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2554 return stp-strt-ToIdType(std::count(conn+strt,conn+stp,-1));
2558 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNumberOfNodesInCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2559 throw INTERP_KERNEL::Exception(oss.str().c_str());
2563 std::string MEDCoupling1DGTUMesh::simpleRepr() const
2565 static const char msg0[]="No coordinates specified !";
2566 std::ostringstream ret;
2567 ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
2568 ret << "Description of mesh : \"" << getDescription() << "\"\n";
2570 double tt=getTime(tmpp1,tmpp2);
2571 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
2572 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
2573 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
2576 const int spaceDim=getSpaceDimension();
2577 ret << spaceDim << "\nInfo attached on space dimension : ";
2578 for(int i=0;i<spaceDim;i++)
2579 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
2583 ret << msg0 << "\n";
2584 ret << "Number of nodes : ";
2586 ret << getNumberOfNodes() << "\n";
2588 ret << msg0 << "\n";
2589 ret << "Number of cells : ";
2591 try { checkConsistencyLight(); } catch(INTERP_KERNEL::Exception& /* e */)
2593 ret << "Nodal connectivity arrays are not set or badly set !\n";
2597 ret << getNumberOfCells() << "\n";
2598 ret << "Cell type : " << _cm->getRepr() << "\n";
2602 std::string MEDCoupling1DGTUMesh::advancedRepr() const
2604 std::ostringstream ret;
2605 ret << simpleRepr();
2606 ret << "\nCoordinates array : \n___________________\n\n";
2608 _coords->reprWithoutNameStream(ret);
2610 ret << "No array set !\n";
2611 ret << "\n\nNodal Connectivity : \n____________________\n\n";
2614 try { checkConsistency(); } catch(INTERP_KERNEL::Exception& /* e */)
2616 ret << "Nodal connectivity arrays are not set or badly set !\n";
2621 mcIdType nbOfCells=getNumberOfCells();
2622 const mcIdType *ci=_conn_indx->begin(),*c=_conn->begin();
2623 for(mcIdType i=0;i<nbOfCells;i++,ci++)
2625 ret << "Cell #" << i << " : ";
2626 std::copy(c+ci[0],c+ci[1],std::ostream_iterator<int>(ret," "));
2632 DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const
2634 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2635 int spaceDim=getSpaceDimension();
2636 mcIdType nbOfCells=getNumberOfCells();//checkConsistencyLight()
2637 mcIdType nbOfNodes=getNumberOfNodes();
2638 ret->alloc(nbOfCells,spaceDim);
2639 double *ptToFill=ret->getPointer();
2640 const double *coor=_coords->begin();
2641 const mcIdType *nodal=_conn->begin(),*nodali=_conn_indx->begin();
2643 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2645 for(mcIdType i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2647 std::fill(ptToFill,ptToFill+spaceDim,0.);
2648 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2650 for(mcIdType j=nodali[0];j<nodali[1];j++,nodal++)
2652 if(*nodal>=0 && *nodal<nbOfNodes)
2653 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2656 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2657 throw INTERP_KERNEL::Exception(oss.str().c_str());
2659 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./double(nodali[1]-nodali[0])));
2664 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !";
2665 throw INTERP_KERNEL::Exception(oss.str().c_str());
2671 for(mcIdType i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2673 std::fill(ptToFill,ptToFill+spaceDim,0.);
2674 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2677 for(mcIdType j=nodali[0];j<nodali[1];j++,nodal++)
2679 if(*nodal==-1) continue;
2680 if(*nodal>=0 && *nodal<nbOfNodes)
2682 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2687 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2688 throw INTERP_KERNEL::Exception(oss.str().c_str());
2692 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./nbOfNod));
2695 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !";
2696 throw INTERP_KERNEL::Exception(oss.str().c_str());
2701 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : at cell #" << i << " the nodal index array is invalid !";
2702 throw INTERP_KERNEL::Exception(oss.str().c_str());
2709 void MEDCoupling1DGTUMesh::renumberCells(const mcIdType *old2NewBg, bool check)
2711 mcIdType nbCells=getNumberOfCells();
2712 MCAuto<DataArrayIdType> o2n=DataArrayIdType::New();
2713 o2n->useArray(old2NewBg,false,DeallocType::C_DEALLOC,nbCells,1);
2715 o2n=o2n->checkAndPreparePermutation();
2717 const mcIdType *o2nPtr=o2n->getPointer();
2718 const mcIdType *conn=_conn->begin(),*conni=_conn_indx->begin();
2719 MCAuto<DataArrayIdType> newConn=DataArrayIdType::New();
2720 MCAuto<DataArrayIdType> newConnI=DataArrayIdType::New();
2721 newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1);
2722 newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx);
2724 mcIdType *newC=newConn->getPointer(),*newCI=newConnI->getPointer();
2725 for(mcIdType i=0;i<nbCells;i++)
2727 mcIdType newPos=o2nPtr[i];
2728 mcIdType sz=conni[i+1]-conni[i];
2733 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !";
2734 throw INTERP_KERNEL::Exception(oss.str().c_str());
2737 newConnI->computeOffsetsFull(); newCI=newConnI->getPointer();
2739 for(mcIdType i=0;i<nbCells;i++,conni++)
2741 mcIdType newp=o2nPtr[i];
2742 std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]);
2745 _conn_indx=newConnI;
2748 MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
2750 if(other->getType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED)
2751 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !");
2752 const MEDCoupling1DGTUMesh *otherC=static_cast<const MEDCoupling1DGTUMesh *>(other);
2753 return Merge1DGTUMeshes(this,otherC);
2756 MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const
2758 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
2759 ret->setCoords(getCoords());
2760 const mcIdType *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin();
2761 mcIdType nbCells=getNumberOfCells();//checkConsistencyLight
2762 mcIdType geoType=ToIdType(getCellModelEnum());
2763 MCAuto<DataArrayIdType> c=DataArrayIdType::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1);
2764 MCAuto<DataArrayIdType> cI=DataArrayIdType::New(); cI->alloc(nbCells+1);
2765 mcIdType *cPtr=c->getPointer(),*ciPtr=cI->getPointer();
2767 for(mcIdType i=0;i<nbCells;i++,ciPtr++)
2769 mcIdType sz=nodalConnI[i+1]-nodalConnI[i];
2773 cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr);
2774 ciPtr[1]=ciPtr[0]+sz+1;
2778 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !";
2779 throw INTERP_KERNEL::Exception(oss.str().c_str());
2782 ret->setConnectivity(c,cI,true);
2784 { ret->copyTinyInfoFrom(this); }
2785 catch(INTERP_KERNEL::Exception&) { }
2790 * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes
2792 DataArrayIdType *MEDCoupling1DGTUMesh::simplexize(int policy)
2794 mcIdType nbOfCells=getNumberOfCells();
2795 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
2796 ret->alloc(nbOfCells,1);
2801 void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const
2803 stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
2804 stream << " Mesh dimension : " << getMeshDimension() << ".";
2806 { stream << " No coordinates set !"; return ; }
2807 if(!_coords->isAllocated())
2808 { stream << " Coordinates set but not allocated !"; return ; }
2809 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
2810 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
2812 try { checkConsistencyLight(); } catch(INTERP_KERNEL::Exception& /* e */)
2814 stream << std::endl << "Nodal connectivity NOT set properly !\n";
2818 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
2821 void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
2824 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
2825 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2827 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !");
2828 setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex());
2831 MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
2834 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
2835 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2837 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
2838 std::vector<const MEDCoupling1DGTUMesh *> ms(2);
2841 return Merge1DGTUMeshesOnSameCoords(ms);
2844 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const mcIdType *begin, const mcIdType *end) const
2846 checkConsistencyLight();
2847 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2848 ret->setCoords(_coords);
2849 DataArrayIdType *c=0,*ci=0;
2850 DataArrayIdType::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci);
2851 MCAuto<DataArrayIdType> cSafe(c),ciSafe(ci);
2852 ret->setNodalConnectivity(c,ci);
2856 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoordsSlice(mcIdType start, mcIdType end, mcIdType step) const
2858 checkConsistencyLight();
2859 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2860 ret->setCoords(_coords);
2861 DataArrayIdType *c=0,*ci=0;
2862 DataArrayIdType::ExtractFromIndexedArraysSlice(start,end,step,_conn,_conn_indx,c,ci);
2863 MCAuto<DataArrayIdType> cSafe(c),ciSafe(ci);
2864 ret->setNodalConnectivity(c,ci);
2868 void MEDCoupling1DGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
2871 mcIdType sz(ToIdType(nodeIdsInUse.size()));
2872 for(const mcIdType *conn=_conn->begin();conn!=_conn->end();conn++)
2874 if(*conn>=0 && *conn<sz)
2875 nodeIdsInUse[*conn]=true;
2880 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeNodeIdsAlg : At pos #" << std::distance(_conn->begin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !";
2881 throw INTERP_KERNEL::Exception(oss.str().c_str());
2887 void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayIdType *revNodal, DataArrayIdType *revNodalIndx) const
2889 checkFullyDefined();
2890 mcIdType nbOfNodes=getNumberOfNodes();
2891 mcIdType *revNodalIndxPtr=(mcIdType *)malloc((nbOfNodes+1)*sizeof(mcIdType));
2892 revNodalIndx->useArray(revNodalIndxPtr,true,DeallocType::C_DEALLOC,nbOfNodes+1,1);
2893 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
2894 const mcIdType *conn=_conn->begin(),*conni=_conn_indx->begin();
2895 mcIdType nbOfCells=getNumberOfCells();
2896 mcIdType nbOfEltsInRevNodal=0;
2897 for(mcIdType eltId=0;eltId<nbOfCells;eltId++)
2899 mcIdType nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2900 if(nbOfNodesPerCell>=0)
2902 for(mcIdType j=0;j<nbOfNodesPerCell;j++)
2904 mcIdType nodeId=conn[conni[eltId]+j];
2905 if(nodeId==-1) continue;
2906 if(nodeId>=0 && nodeId<nbOfNodes)
2908 nbOfEltsInRevNodal++;
2909 revNodalIndxPtr[nodeId+1]++;
2913 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
2914 throw INTERP_KERNEL::Exception(oss.str().c_str());
2920 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << "nodal connectivity is invalid !";
2921 throw INTERP_KERNEL::Exception(oss.str().c_str());
2924 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<mcIdType>());
2925 conn=_conn->begin();
2926 mcIdType *revNodalPtr=(mcIdType *)malloc((nbOfEltsInRevNodal)*sizeof(mcIdType));
2927 revNodal->useArray(revNodalPtr,true,DeallocType::C_DEALLOC,nbOfEltsInRevNodal,1);
2928 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
2929 for(mcIdType eltId=0;eltId<nbOfCells;eltId++)
2931 mcIdType nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2932 for(mcIdType j=0;j<nbOfNodesPerCell;j++)
2934 mcIdType nodeId=conn[conni[eltId]+j];
2936 *std::find_if(revNodalPtr+revNodalIndxPtr[nodeId],revNodalPtr+revNodalIndxPtr[nodeId+1],std::bind2nd(std::equal_to<mcIdType>(),-1))=eltId;
2941 void MEDCoupling1DGTUMesh::checkFullyDefined() const
2943 if(!((const DataArrayIdType *)_conn) || !((const DataArrayIdType *)_conn_indx) || !((const DataArrayDouble *)_coords))
2944 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined.");
2947 bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector<mcIdType>& tinyInfo) const
2949 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !");
2952 void MEDCoupling1DGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<mcIdType>& tinyInfo, std::vector<std::string>& littleStrings) const
2955 double time=getTime(it,order);
2956 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
2958 littleStrings.push_back(getName());
2959 littleStrings.push_back(getDescription());
2960 littleStrings.push_back(getTimeUnit());
2962 std::vector<std::string> littleStrings2,littleStrings3,littleStrings4;
2963 if((const DataArrayDouble *)_coords)
2964 _coords->getTinySerializationStrInformation(littleStrings2);
2965 if((const DataArrayIdType *)_conn)
2966 _conn->getTinySerializationStrInformation(littleStrings3);
2967 if((const DataArrayIdType *)_conn_indx)
2968 _conn_indx->getTinySerializationStrInformation(littleStrings4);
2969 mcIdType sz0(ToIdType(littleStrings2.size())),sz1(ToIdType(littleStrings3.size())),sz2(ToIdType(littleStrings4.size()));
2970 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
2971 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
2972 littleStrings.insert(littleStrings.end(),littleStrings4.begin(),littleStrings4.end());
2974 tinyInfo.push_back(getCellModelEnum());
2975 tinyInfo.push_back(it);
2976 tinyInfo.push_back(order);
2977 std::vector<mcIdType> tinyInfo2,tinyInfo3,tinyInfo4;
2978 if((const DataArrayDouble *)_coords)
2979 _coords->getTinySerializationIntInformation(tinyInfo2);
2980 if((const DataArrayIdType *)_conn)
2981 _conn->getTinySerializationIntInformation(tinyInfo3);
2982 if((const DataArrayIdType *)_conn_indx)
2983 _conn_indx->getTinySerializationIntInformation(tinyInfo4);
2984 mcIdType sz3(ToIdType(tinyInfo2.size())),sz4(ToIdType(tinyInfo3.size())),sz5(ToIdType(tinyInfo4.size()));
2985 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3); tinyInfo.push_back(sz4); tinyInfo.push_back(sz5);
2986 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
2987 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
2988 tinyInfo.insert(tinyInfo.end(),tinyInfo4.begin(),tinyInfo4.end());
2990 tinyInfoD.push_back(time);
2993 void MEDCoupling1DGTUMesh::resizeForUnserialization(const std::vector<mcIdType>& tinyInfo, DataArrayIdType *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
2995 std::vector<mcIdType> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+tinyInfo[6]);
2996 std::vector<mcIdType> tinyInfo1(tinyInfo.begin()+9+tinyInfo[6],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]);
2997 std::vector<mcIdType> tinyInfo12(tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]+tinyInfo[8]);
2998 MCAuto<DataArrayIdType> p1(DataArrayIdType::New()); p1->resizeForUnserialization(tinyInfo1);
2999 MCAuto<DataArrayIdType> p2(DataArrayIdType::New()); p2->resizeForUnserialization(tinyInfo12);
3000 std::vector<const DataArrayIdType *> v(2); v[0]=p1; v[1]=p2;
3001 p2=DataArrayIdType::Aggregate(v);
3002 a2->resizeForUnserialization(tinyInfo2);
3003 a1->alloc(p2->getNbOfElems(),1);
3006 void MEDCoupling1DGTUMesh::serialize(DataArrayIdType *&a1, DataArrayDouble *&a2) const
3009 if((const DataArrayIdType *)_conn)
3010 if(_conn->isAllocated())
3011 sz=_conn->getNbOfElems();
3012 if((const DataArrayIdType *)_conn_indx)
3013 if(_conn_indx->isAllocated())
3014 sz+=_conn_indx->getNbOfElems();
3015 a1=DataArrayIdType::New();
3017 mcIdType *work(a1->getPointer());
3018 if(sz!=0 && (const DataArrayIdType *)_conn)
3019 work=std::copy(_conn->begin(),_conn->end(),a1->getPointer());
3020 if(sz!=0 && (const DataArrayIdType *)_conn_indx)
3021 std::copy(_conn_indx->begin(),_conn_indx->end(),work);
3023 if((const DataArrayDouble *)_coords)
3024 if(_coords->isAllocated())
3025 sz=_coords->getNbOfElems();
3026 a2=DataArrayDouble::New();
3028 if(sz!=0 && (const DataArrayDouble *)_coords)
3029 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
3032 void MEDCoupling1DGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<mcIdType>& tinyInfo, const DataArrayIdType *a1, DataArrayDouble *a2,
3033 const std::vector<std::string>& littleStrings)
3035 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
3036 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
3037 setName(littleStrings[0]);
3038 setDescription(littleStrings[1]);
3039 setTimeUnit(littleStrings[2]);
3040 setTime(tinyInfoD[0],FromIdType<int>(tinyInfo[1]),FromIdType<int>(tinyInfo[2]));
3041 mcIdType sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]),sz4(tinyInfo[7]),sz5(tinyInfo[8]);
3043 _coords=DataArrayDouble::New();
3044 std::vector<mcIdType> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+sz3);
3045 _coords->resizeForUnserialization(tinyInfo2);
3046 std::copy(a2->begin(),a2->end(),_coords->getPointer());
3047 _conn=DataArrayIdType::New();
3048 std::vector<mcIdType> tinyInfo3(tinyInfo.begin()+9+sz3,tinyInfo.begin()+9+sz3+sz4);
3049 _conn->resizeForUnserialization(tinyInfo3);
3050 std::copy(a1->begin(),a1->begin()+_conn->getNbOfElems(),_conn->getPointer());
3051 _conn_indx=DataArrayIdType::New();
3052 std::vector<mcIdType> tinyInfo4(tinyInfo.begin()+9+sz3+sz4,tinyInfo.begin()+9+sz3+sz4+sz5);
3053 _conn_indx->resizeForUnserialization(tinyInfo4);
3054 std::copy(a1->begin()+_conn->getNbOfElems(),a1->end(),_conn_indx->getPointer());
3055 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
3056 _coords->finishUnserialization(tinyInfo2,littleStrings2);
3057 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
3058 _conn->finishUnserialization(tinyInfo3,littleStrings3);
3059 std::vector<std::string> littleStrings4(littleStrings.begin()+3+sz0+sz1,littleStrings.begin()+3+sz0+sz1+sz2);
3060 _conn_indx->finishUnserialization(tinyInfo4,littleStrings4);
3064 * Finds nodes not used in any cell and returns an array giving a new id to every node
3065 * by excluding the unused nodes, for which the array holds -1. The result array is
3066 * a mapping in "Old to New" mode.
3067 * \return DataArrayIdType * - a new instance of DataArrayIdType. Its length is \a
3068 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
3069 * if the node is unused or a new id else. The caller is to delete this
3070 * array using decrRef() as it is no more needed.
3071 * \throw If the coordinates array is not set.
3072 * \throw If the nodal connectivity of cells is not defined.
3073 * \throw If the nodal connectivity includes an invalid id.
3074 * \sa MEDCoupling1DGTUMesh::getNodeIdsInUse, areAllNodesFetched
3076 DataArrayIdType *MEDCoupling1DGTUMesh::computeFetchedNodeIds() const
3079 mcIdType nbNodes(getNumberOfNodes());
3080 std::vector<bool> fetchedNodes(nbNodes,false);
3081 computeNodeIdsAlg(fetchedNodes);
3082 mcIdType sz(ToIdType(std::count(fetchedNodes.begin(),fetchedNodes.end(),true)));
3083 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(sz,1);
3084 mcIdType *retPtr(ret->getPointer());
3085 for(mcIdType i=0;i<nbNodes;i++)
3092 * Finds nodes not used in any cell and returns an array giving a new id to every node
3093 * by excluding the unused nodes, for which the array holds -1. The result array is
3094 * a mapping in "Old to New" mode.
3095 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
3096 * \return DataArrayIdType * - a new instance of DataArrayIdType. Its length is \a
3097 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
3098 * if the node is unused or a new id else. The caller is to delete this
3099 * array using decrRef() as it is no more needed.
3100 * \throw If the coordinates array is not set.
3101 * \throw If the nodal connectivity of cells is not defined.
3102 * \throw If the nodal connectivity includes an invalid id.
3103 * \sa MEDCoupling1DGTUMesh::computeFetchedNodeIds, areAllNodesFetched
3105 DataArrayIdType *MEDCoupling1DGTUMesh::getNodeIdsInUse(mcIdType& nbrOfNodesInUse) const
3108 mcIdType nbOfNodes=getNumberOfNodes();
3109 mcIdType nbOfCells=getNumberOfCells();//checkConsistencyLight
3110 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
3111 ret->alloc(nbOfNodes,1);
3112 mcIdType *traducer=ret->getPointer();
3113 std::fill(traducer,traducer+nbOfNodes,-1);
3114 const mcIdType *conn=_conn->begin(),*conni(_conn_indx->begin());
3115 for(mcIdType i=0;i<nbOfCells;i++,conni++)
3117 mcIdType nbNodesPerCell=conni[1]-conni[0];
3118 for(mcIdType j=0;j<nbNodesPerCell;j++)
3120 mcIdType nodeId=conn[conni[0]+j];
3121 if(nodeId==-1) continue;
3122 if(nodeId>=0 && nodeId<nbOfNodes)
3126 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << nodeId << " not in [0," << nbOfNodes << ") !";
3127 throw INTERP_KERNEL::Exception(oss.str().c_str());
3131 nbrOfNodesInUse=ToIdType(std::count(traducer,traducer+nbOfNodes,1));
3132 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
3137 * This method renumbers only nodal connectivity in \a this. The renumbering is only an offset applied. So this method is a specialization of
3138 * \a renumberNodesInConn. \b WARNING, this method does not check that the resulting node ids in the nodal connectivity is in a valid range !
3140 * \param [in] offset - specifies the offset to be applied on each element of connectivity.
3142 * \sa renumberNodesInConn
3144 void MEDCoupling1DGTUMesh::renumberNodesWithOffsetInConn(mcIdType offset)
3146 getNumberOfCells();//only to check that all is well defined.
3148 mcIdType nbOfTuples(_conn->getNumberOfTuples());
3149 mcIdType *pt(_conn->getPointer());
3150 for(mcIdType i=0;i<nbOfTuples;i++,pt++)
3152 if(*pt==-1) continue;
3160 * Same than renumberNodesInConn(const mcIdType *) except that here the format of old-to-new traducer is using map instead
3161 * 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
3164 void MEDCoupling1DGTUMesh::renumberNodesInConn(const INTERP_KERNEL::HashMap<mcIdType,mcIdType>& newNodeNumbersO2N)
3166 this->renumberNodesInConnT< INTERP_KERNEL::HashMap<mcIdType,mcIdType> >(newNodeNumbersO2N);
3170 * Same than renumberNodesInConn(const mcIdType *) except that here the format of old-to-new traducer is using map instead
3171 * 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
3174 void MEDCoupling1DGTUMesh::renumberNodesInConn(const std::map<mcIdType,mcIdType>& newNodeNumbersO2N)
3176 this->renumberNodesInConnT< std::map<mcIdType,mcIdType> >(newNodeNumbersO2N);
3180 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
3181 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
3182 * This method is a generalization of shiftNodeNumbersInConn().
3183 * \warning This method performs no check of validity of new ids. **Use it with care !**
3184 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
3185 * this->getNumberOfNodes(), in "Old to New" mode.
3186 * See \ref numbering for more info on renumbering modes.
3187 * \throw If the nodal connectivity of cells is not defined.
3189 void MEDCoupling1DGTUMesh::renumberNodesInConn(const mcIdType *newNodeNumbersO2N)
3191 getNumberOfCells();//only to check that all is well defined.
3193 mcIdType nbElemsIn(getNumberOfNodes()),nbOfTuples(_conn->getNumberOfTuples());
3194 mcIdType *pt(_conn->getPointer());
3195 for(mcIdType i=0;i<nbOfTuples;i++,pt++)
3197 if(*pt==-1) continue;
3198 if(*pt>=0 && *pt<nbElemsIn)
3199 *pt=newNodeNumbersO2N[*pt];
3202 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
3203 throw INTERP_KERNEL::Exception(oss.str().c_str());
3211 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
3212 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
3213 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
3214 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
3216 * \param [in] begin input start of array of node ids.
3217 * \param [in] end input end of array of node ids.
3218 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
3219 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
3221 void MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const mcIdType *begin, const mcIdType *end, bool fullyIn, DataArrayIdType *&cellIdsKeptArr) const
3223 mcIdType nbOfCells=getNumberOfCells();
3224 MCAuto<DataArrayIdType> cellIdsKept=DataArrayIdType::New(); cellIdsKept->alloc(0,1);
3226 mcIdType sz=_conn->getMaxValue(tmp); sz=std::max(sz,ToIdType(0))+1;
3227 std::vector<bool> fastFinder(sz,false);
3228 for(const mcIdType *work=begin;work!=end;work++)
3229 if(*work>=0 && *work<sz)
3230 fastFinder[*work]=true;
3231 const mcIdType *conn=_conn->begin(),*conni=_conn_indx->begin();
3232 for(mcIdType i=0;i<nbOfCells;i++,conni++)
3234 int ref=0,nbOfHit=0;
3235 mcIdType nbNodesPerCell=conni[1]-conni[0];
3236 if(nbNodesPerCell>=0)
3238 for(mcIdType j=0;j<nbNodesPerCell;j++)
3240 mcIdType nodeId=conn[conni[0]+j];
3244 if(fastFinder[nodeId])
3251 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !";
3252 throw INTERP_KERNEL::Exception(oss.str().c_str());
3254 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
3255 cellIdsKept->pushBackSilent(i);
3257 cellIdsKeptArr=cellIdsKept.retn();
3260 void MEDCoupling1DGTUMesh::allocateCells(mcIdType nbOfCells)
3263 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !");
3264 _conn=DataArrayIdType::New();
3265 _conn->reserve(nbOfCells*3);
3266 _conn_indx=DataArrayIdType::New();
3267 _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0);
3272 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
3274 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
3275 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
3276 * \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
3277 * attached to \a this.
3278 * \throw If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
3280 void MEDCoupling1DGTUMesh::insertNextCell(const mcIdType *nodalConnOfCellBg, const mcIdType *nodalConnOfCellEnd)
3282 std::size_t sz(std::distance(nodalConnOfCellBg,nodalConnOfCellEnd));
3283 DataArrayIdType *c(_conn),*c2(_conn_indx);
3286 mcIdType pos=c2->back();
3287 if(pos==c->getNumberOfTuples())
3289 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
3290 c2->pushBackSilent(pos+ToIdType(sz));
3294 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !";
3295 throw INTERP_KERNEL::Exception(oss.str().c_str());
3299 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !");
3302 void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayIdType *nodalConn, DataArrayIdType *nodalConnIndex)
3305 nodalConn->incrRef();
3308 nodalConnIndex->incrRef();
3309 _conn_indx=nodalConnIndex;
3314 * \return DataArrayIdType * - the internal reference to the nodal connectivity. The caller is not responsible to deallocate it.
3316 DataArrayIdType *MEDCoupling1DGTUMesh::getNodalConnectivity() const
3318 const DataArrayIdType *ret(_conn);
3319 return const_cast<DataArrayIdType *>(ret);
3323 * \return DataArrayIdType * - the internal reference to the nodal connectivity index. The caller is not responsible to deallocate it.
3325 DataArrayIdType *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const
3327 const DataArrayIdType *ret(_conn_indx);
3328 return const_cast<DataArrayIdType *>(ret);
3332 * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here".
3333 * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity).
3334 * 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.
3336 * 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.
3338 * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal
3339 * connectivity arrays are different (false)
3340 * \return a new object to be managed by the caller.
3342 * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked
3344 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const
3346 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3347 DataArrayIdType *nc=0,*nci=0;
3348 isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci);
3349 MCAuto<DataArrayIdType> ncs(nc),ncis(nci);
3350 ret->_conn=ncs; ret->_conn_indx=ncis;
3351 ret->setCoords(getCoords());
3356 * This method allows to compute, if needed, the packed nodal connectivity pair.
3357 * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges covered by nodal connectivity index array.
3358 * 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.
3360 * 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)
3361 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3363 * 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
3366 * This method return 3 elements.
3367 * \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
3368 * this pointer can be seen as a new object, that is to managed by the caller.
3369 * \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
3370 * this pointer can be seen as a new object, that is to managed by the caller.
3371 * \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
3372 * output parameters are newly created objects.
3374 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkConsistencyLight test
3376 bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayIdType *&nodalConn, DataArrayIdType *&nodalConnIndx) const
3378 if(isPacked())//performs the checkConsistencyLight
3380 const DataArrayIdType *c0(_conn),*c1(_conn_indx);
3381 nodalConn=const_cast<DataArrayIdType *>(c0); nodalConnIndx=const_cast<DataArrayIdType *>(c1);
3382 nodalConn->incrRef(); nodalConnIndx->incrRef();
3385 mcIdType bg=_conn_indx->front(),end=_conn_indx->back();
3386 MCAuto<DataArrayIdType> nc(_conn->selectByTupleIdSafeSlice(bg,end,1));
3387 MCAuto<DataArrayIdType> nci(_conn_indx->deepCopy());
3388 nci->applyLin(1,-bg);
3389 nodalConn=nc.retn(); nodalConnIndx=nci.retn();
3394 * 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)
3395 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3396 * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned.
3397 * \return bool - true if \a this looks packed, false is not.
3399 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkConsistencyLight test
3401 bool MEDCoupling1DGTUMesh::isPacked() const
3403 checkConsistencyLight();
3404 return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples();
3407 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2)
3409 std::vector<const MEDCoupling1DGTUMesh *> tmp(2);
3410 tmp[0]=const_cast<MEDCoupling1DGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1DGTUMesh *>(mesh2);
3411 return Merge1DGTUMeshes(tmp);
3414 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a)
3416 std::size_t sz=a.size();
3418 return Merge1DGTUMeshesLL(a);
3419 for(std::size_t ii=0;ii<sz;ii++)
3422 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::Merge1DGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
3423 throw INTERP_KERNEL::Exception(oss.str().c_str());
3425 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
3426 for(std::size_t ii=0;ii<sz;ii++)
3427 if(&(a[ii]->getCellModel())!=cm)
3428 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !");
3429 std::vector< MCAuto<MEDCoupling1DGTUMesh> > bb(sz);
3430 std::vector< const MEDCoupling1DGTUMesh * > aa(sz);
3431 std::size_t spaceDimUndef=-3, spaceDim=spaceDimUndef;
3432 for(std::size_t i=0;i<sz && spaceDim==spaceDimUndef;i++)
3434 const MEDCoupling1DGTUMesh *cur=a[i];
3435 const DataArrayDouble *coo=cur->getCoords();
3437 spaceDim=coo->getNumberOfComponents();
3439 if(spaceDim==spaceDimUndef)
3440 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !");
3441 for(std::size_t i=0;i<sz;i++)
3443 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
3446 return Merge1DGTUMeshesLL(aa);
3450 * \throw If presence of a null instance in the input vector \a a.
3451 * \throw If a is empty
3453 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a)
3456 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !");
3457 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3459 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !");
3460 std::vector< MCAuto<MEDCoupling1DGTUMesh> > objs(a.size());
3461 std::vector<const DataArrayIdType *> ncs(a.size()),ncis(a.size());
3462 (*it)->getNumberOfCells();//to check that all is OK
3463 const DataArrayDouble *coords=(*it)->getCoords();
3464 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3466 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3467 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3469 for(int i=1;it!=a.end();i++,it++)
3472 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !");
3473 if(cm!=&((*it)->getCellModel()))
3474 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3475 (*it)->getNumberOfCells();//to check that all is OK
3476 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3477 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3478 if(coords!=(*it)->getCoords())
3479 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !");
3481 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3482 ret->setCoords(coords);
3483 ret->_conn=DataArrayIdType::Aggregate(ncs);
3484 ret->_conn_indx=DataArrayIdType::AggregateIndexes(ncis);
3489 * 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)
3491 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a)
3494 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : input array must be NON EMPTY !");
3495 std::vector< MCAuto<MEDCoupling1DGTUMesh> > objs(a.size());
3496 std::vector<const DataArrayIdType *> ncs(a.size()),ncis(a.size());
3497 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3498 std::vector<mcIdType> nbNodesPerElt(a.size());
3499 std::size_t nbOfCells=(*it)->getNumberOfCells();
3501 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3502 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3504 mcIdType prevNbOfNodes=(*it)->getNumberOfNodes();
3505 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3507 for(int i=1;it!=a.end();i++,it++)
3509 if(cm!=&((*it)->getCellModel()))
3510 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3511 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3512 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3513 nbOfCells+=(*it)->getNumberOfCells();
3514 nbNodesPerElt[i]=nbNodesPerElt[i-1]+prevNbOfNodes;
3515 prevNbOfNodes=(*it)->getNumberOfNodes();
3517 std::vector<const MEDCouplingPointSet *> aps(a.size());
3518 std::copy(a.begin(),a.end(),aps.begin());
3519 MCAuto<DataArrayDouble> pts=MergeNodesArray(aps);
3520 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3521 ret->setCoords(pts);
3522 ret->_conn=AggregateNodalConnAndShiftNodeIds(ncs,nbNodesPerElt);
3523 ret->_conn_indx=DataArrayIdType::AggregateIndexes(ncis);
3527 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(std::size_t spaceDim) const
3529 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3530 MCAuto<DataArrayIdType> tmp1,tmp2;
3531 const DataArrayIdType *nodalConn(_conn),*nodalConnI(_conn_indx);
3534 tmp1=DataArrayIdType::New(); tmp1->alloc(0,1);
3542 tmp2=DataArrayIdType::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
3546 ret->_conn_indx=tmp2;
3550 MCAuto<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
3551 ret->setCoords(coords);
3554 ret->setCoords(_coords);
3559 * This method aggregate the bbox of each cell and put it into bbox parameter.
3561 * \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)
3562 * For all other cases this input parameter is ignored.
3563 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
3565 * \throw If \a this is not fully set (coordinates and connectivity).
3566 * \throw If a cell in \a this has no valid nodeId.
3568 DataArrayDouble *MEDCoupling1DGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
3570 checkFullyDefined();
3571 mcIdType spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes());
3572 MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
3573 double *bbox(ret->getPointer());
3574 for(mcIdType i=0;i<nbOfCells*spaceDim;i++)
3576 bbox[2*i]=std::numeric_limits<double>::max();
3577 bbox[2*i+1]=-std::numeric_limits<double>::max();
3579 const double *coordsPtr(_coords->getConstPointer());
3580 const mcIdType *conn(_conn->getConstPointer()),*connI(_conn_indx->getConstPointer());
3581 for(mcIdType i=0;i<nbOfCells;i++)
3583 mcIdType offset=connI[i];
3584 mcIdType nbOfNodesForCell(connI[i+1]-offset),kk(0);
3585 for(mcIdType j=0;j<nbOfNodesForCell;j++)
3587 mcIdType nodeId=conn[offset+j];
3588 if(nodeId>=0 && nodeId<nbOfNodes)
3590 for(int k=0;k<spaceDim;k++)
3592 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
3593 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
3600 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
3601 throw INTERP_KERNEL::Exception(oss.str().c_str());
3608 * 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.
3610 * \return a new instance of field containing the result. The returned instance has to be deallocated by the caller.
3612 MEDCouplingFieldDouble *MEDCoupling1DGTUMesh::computeDiameterField() const
3614 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::computeDiameterField : not implemented yet for dynamic types !");
3617 std::vector<mcIdType> MEDCoupling1DGTUMesh::BuildAPolygonFromParts(const std::vector< std::vector<mcIdType> >& parts)
3619 std::vector<mcIdType> ret;
3622 ret.insert(ret.end(),parts[0].begin(),parts[0].end());
3623 mcIdType ref(ret.back());
3624 std::size_t sz(parts.size()),nbh(1);
3625 std::vector<bool> b(sz,true); b[0]=false;
3629 for(;i<sz;i++) if(b[i] && parts[i].front()==ref) { ret.insert(ret.end(),parts[i].begin()+1,parts[i].end()); nbh++; break; }
3633 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::BuildAPolygonFromParts : the input vector is not a part of a single polygon !");
3635 if(ret.back()==ret.front())
3641 * This method invert orientation of all cells in \a this.
3642 * After calling this method the absolute value of measure of cells in \a this are the same than before calling.
3643 * This method only operates on the connectivity so coordinates are not touched at all.
3645 void MEDCoupling1DGTUMesh::invertOrientationOfAllCells()
3647 checkConsistencyOfConnectivity();
3648 INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::OrientationInverter> oi(INTERP_KERNEL::OrientationInverter::BuildInstanceFrom(getCellModelEnum()));
3649 mcIdType nbCells=getNumberOfCells();
3650 const mcIdType *connI(_conn_indx->begin());
3651 mcIdType *conn(_conn->getPointer());
3652 for(mcIdType i=0;i<nbCells;i++)
3653 oi->operate(conn+connI[i],conn+connI[i+1]);
3658 * This method performs an aggregation of \a nodalConns (as DataArrayIdType::Aggregate does) but in addition of that a shift is applied on the
3659 * values contained in \a nodalConns using corresponding offset specified in input \a offsetInNodeIdsPerElt.
3660 * But it also manage the values -1, that have a semantic in MEDCoupling1DGTUMesh class (separator for polyhedron).
3662 * \param [in] nodalConns - a list of nodal connectivity arrays same size than \a offsetInNodeIdsPerElt.
3663 * \param [in] offsetInNodeIdsPerElt - a list of offsets to apply.
3664 * \return DataArrayIdType * - A new object (to be managed by the caller) that is the result of the aggregation.
3665 * \throw If \a nodalConns or \a offsetInNodeIdsPerElt are empty.
3666 * \throw If \a nodalConns and \a offsetInNodeIdsPerElt have not the same size.
3667 * \throw If presence of null pointer in \a nodalConns.
3668 * \throw If presence of not allocated or array with not exactly one component in \a nodalConns.
3670 DataArrayIdType *MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds(const std::vector<const DataArrayIdType *>& nodalConns, const std::vector<mcIdType>& offsetInNodeIdsPerElt)
3672 std::size_t sz1(nodalConns.size()),sz2(offsetInNodeIdsPerElt.size());
3674 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : input vectors do not have the same size !");
3676 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : empty vectors in input !");
3677 mcIdType nbOfTuples=0;
3678 for(std::vector<const DataArrayIdType *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++)
3681 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of null pointer in input vector !");
3682 if(!(*it)->isAllocated())
3683 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of non allocated array in input vector !");
3684 if((*it)->getNumberOfComponents()!=1)
3685 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of array with not exactly one component !");
3686 nbOfTuples+=(*it)->getNumberOfTuples();
3688 MCAuto<DataArrayIdType> ret=DataArrayIdType::New(); ret->alloc(nbOfTuples,1);
3689 mcIdType *pt=ret->getPointer();
3691 for(std::vector<const DataArrayIdType *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++,i++)
3693 mcIdType curNbt=(*it)->getNumberOfTuples();
3694 const mcIdType *inPt=(*it)->begin();
3695 mcIdType offset=offsetInNodeIdsPerElt[i];
3696 for(mcIdType j=0;j<curNbt;j++,pt++)
3707 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m)
3710 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh is null !");
3711 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
3713 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh must have exactly one geometric type !");
3714 mcIdType geoType(ToIdType(*gts.begin()));
3715 MCAuto<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(m->getName(),*gts.begin()));
3716 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription());
3717 mcIdType nbCells=m->getNumberOfCells();
3718 MCAuto<DataArrayIdType> conn(DataArrayIdType::New()),connI(DataArrayIdType::New());
3719 conn->alloc(m->getNodalConnectivityArrayLen()-nbCells,1); connI->alloc(nbCells+1,1);
3720 mcIdType *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
3721 const mcIdType *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
3722 for(mcIdType i=0;i<nbCells;i++,ciin++,ci++)
3724 if(cin[ciin[0]]==geoType)
3726 if(ciin[1]-ciin[0]>=1)
3728 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
3729 ci[1]=ci[0]+ciin[1]-ciin[0]-1;
3733 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 !";
3734 throw INTERP_KERNEL::Exception(oss.str().c_str());
3739 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 !";
3740 throw INTERP_KERNEL::Exception(oss.str().c_str());
3743 ret->setNodalConnectivity(conn,connI);