1 // Copyright (C) 2007-2019 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))
2305 c1=_conn_indx; c2=otherC->_conn_indx;
2310 if(!c1->isEqualWithoutConsideringStr(*c2))
2316 * Checks if \a this and \a other meshes are geometrically equivalent with high
2317 * probability, else an exception is thrown. The meshes are considered equivalent if
2318 * (1) meshes contain the same number of nodes and the same number of elements of the
2319 * same types (2) three cells of the two meshes (first, last and middle) are based
2320 * on coincident nodes (with a specified precision).
2321 * \param [in] other - the mesh to compare with.
2322 * \param [in] prec - the precision used to compare nodes of the two meshes.
2323 * \throw If the two meshes do not match.
2325 void MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
2327 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
2328 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2330 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single dynamic geometric type !");
2331 const DataArrayIdType *c1(_conn),*c2(otherC->_conn);
2335 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
2336 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2337 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
2338 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2339 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
2340 if(c1->getHashCode()!=c2->getHashCode())
2341 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs");
2343 c1=_conn_indx; c2=otherC->_conn_indx;
2347 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !");
2348 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2349 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !");
2350 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2351 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !");
2352 if(c1->getHashCode()!=c2->getHashCode())
2353 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs");
2357 void MEDCoupling1DGTUMesh::checkConsistencyOfConnectivity() const
2359 const DataArrayIdType *c1(_conn);
2362 if(c1->getNumberOfComponents()!=1)
2363 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
2364 if(c1->getInfoOnComponent(0)!="")
2365 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
2366 c1->checkAllocated();
2369 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
2371 mcIdType sz2(_conn->getNumberOfTuples());
2375 if(c1->getNumberOfComponents()!=1)
2376 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
2377 c1->checkAllocated();
2378 if(c1->getNumberOfTuples()<1)
2379 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !");
2380 if(c1->getInfoOnComponent(0)!="")
2381 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
2382 mcIdType f=c1->front(),ll=c1->back();
2383 if(f<0 || (sz2>0 && f>=sz2))
2385 std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !";
2386 throw INTERP_KERNEL::Exception(oss.str().c_str());
2390 std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !";
2391 throw INTERP_KERNEL::Exception(oss.str().c_str());
2395 std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !";
2396 throw INTERP_KERNEL::Exception(oss.str().c_str());
2400 throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !");
2401 mcIdType szOfC1Exp=_conn_indx->back();
2404 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() << " !";
2405 throw INTERP_KERNEL::Exception(oss.str().c_str());
2410 * 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.
2411 * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one.
2412 * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array.
2414 void MEDCoupling1DGTUMesh::checkConsistencyLight() const
2416 MEDCouplingPointSet::checkConsistencyLight();
2417 checkConsistencyOfConnectivity();
2420 void MEDCoupling1DGTUMesh::checkConsistency(double eps) const
2422 checkConsistencyLight();
2423 const DataArrayIdType *c1(_conn),*c2(_conn_indx);
2424 if(!c2->isMonotonic(true))
2425 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkConsistency : the nodal connectivity index is expected to be increasing monotinic !");
2427 mcIdType nbOfTuples(c1->getNumberOfTuples());
2428 mcIdType nbOfNodes=getNumberOfNodes();
2429 const mcIdType *w(c1->begin());
2430 for(mcIdType i=0;i<nbOfTuples;i++,w++)
2432 if(*w==-1) continue;
2433 if(*w<0 || *w>=nbOfNodes)
2435 std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !";
2436 throw INTERP_KERNEL::Exception(oss.str().c_str());
2441 mcIdType MEDCoupling1DGTUMesh::getNumberOfCells() const
2443 checkConsistencyOfConnectivity();//do not remove
2444 return _conn_indx->getNumberOfTuples()-1;
2448 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2449 * For each cell in \b this the number of nodes constituting cell is computed.
2450 * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned.
2451 * So for pohyhedrons some nodes can be counted several times in the returned result.
2453 * \return a newly allocated array
2455 DataArrayIdType *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const
2457 checkConsistencyLight();
2458 _conn_indx->checkMonotonic(true);
2459 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2460 return _conn_indx->deltaShiftIndex();
2462 mcIdType nbOfCells=_conn_indx->getNumberOfTuples()-1;
2463 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
2464 ret->alloc(nbOfCells,1);
2465 mcIdType *retPtr=ret->getPointer();
2466 const mcIdType *ci=_conn_indx->begin(),*c=_conn->begin();
2467 for(mcIdType i=0;i<nbOfCells;i++,retPtr++,ci++)
2468 *retPtr=int(ci[1]-ci[0]-ToIdType(std::count(c+ci[0],c+ci[1],-1)));
2473 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2474 * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed.
2476 * \return a newly allocated array
2478 DataArrayIdType *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const
2480 checkConsistencyLight();
2481 _conn_indx->checkMonotonic(true);
2482 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG)
2483 return _conn_indx->deltaShiftIndex();
2484 if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG)
2486 MCAuto<DataArrayIdType> ret=_conn_indx->deltaShiftIndex();
2487 ret->applyDivideBy(2);
2491 mcIdType nbOfCells=_conn_indx->getNumberOfTuples()-1;
2492 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
2493 ret->alloc(nbOfCells,1);
2494 mcIdType *retPtr=ret->getPointer();
2495 const mcIdType *ci=_conn_indx->begin(),*c=_conn->begin();
2496 for(mcIdType i=0;i<nbOfCells;i++,retPtr++,ci++)
2497 *retPtr=ToIdType(std::count(c+ci[0],c+ci[1],-1))+1;
2502 * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell,
2503 * will be counted only once here whereas it will be counted several times in MEDCoupling1DGTUMesh::computeNbOfNodesPerCell method.
2505 * \return DataArrayIdType * - new object to be deallocated by the caller.
2506 * \sa MEDCoupling1DGTUMesh::computeNbOfNodesPerCell
2508 DataArrayIdType *MEDCoupling1DGTUMesh::computeEffectiveNbOfNodesPerCell() const
2510 checkConsistencyLight();
2511 _conn_indx->checkMonotonic(true);
2512 mcIdType nbOfCells=_conn_indx->getNumberOfTuples()-1;
2513 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
2514 ret->alloc(nbOfCells,1);
2515 mcIdType *retPtr(ret->getPointer());
2516 const mcIdType *ci(_conn_indx->begin()),*c(_conn->begin());
2517 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2519 for(mcIdType i=0;i<nbOfCells;i++,retPtr++,ci++)
2521 std::set<mcIdType> s(c+ci[0],c+ci[1]);
2522 *retPtr=ToIdType(s.size());
2527 for(mcIdType i=0;i<nbOfCells;i++,retPtr++,ci++)
2529 std::set<mcIdType> s(c+ci[0],c+ci[1]); s.erase(-1);
2530 *retPtr=ToIdType(s.size());
2536 void MEDCoupling1DGTUMesh::getNodeIdsOfCell(mcIdType cellId, std::vector<mcIdType>& conn) const
2538 mcIdType nbOfCells(getNumberOfCells());//performs checks
2539 if(cellId<nbOfCells)
2541 mcIdType strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2542 mcIdType nbOfNodes=stp-strt;
2544 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !");
2545 conn.resize(nbOfNodes);
2546 std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin());
2550 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2551 throw INTERP_KERNEL::Exception(oss.str().c_str());
2555 mcIdType MEDCoupling1DGTUMesh::getNumberOfNodesInCell(mcIdType cellId) const
2557 mcIdType nbOfCells=getNumberOfCells();//performs checks
2558 if(cellId>=0 && cellId<nbOfCells)
2560 const mcIdType *conn(_conn->begin());
2561 mcIdType strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2562 return stp-strt-ToIdType(std::count(conn+strt,conn+stp,-1));
2566 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNumberOfNodesInCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2567 throw INTERP_KERNEL::Exception(oss.str().c_str());
2571 std::string MEDCoupling1DGTUMesh::simpleRepr() const
2573 static const char msg0[]="No coordinates specified !";
2574 std::ostringstream ret;
2575 ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
2576 ret << "Description of mesh : \"" << getDescription() << "\"\n";
2578 double tt=getTime(tmpp1,tmpp2);
2579 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
2580 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
2581 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
2584 const int spaceDim=getSpaceDimension();
2585 ret << spaceDim << "\nInfo attached on space dimension : ";
2586 for(int i=0;i<spaceDim;i++)
2587 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
2591 ret << msg0 << "\n";
2592 ret << "Number of nodes : ";
2594 ret << getNumberOfNodes() << "\n";
2596 ret << msg0 << "\n";
2597 ret << "Number of cells : ";
2599 try { checkConsistencyLight(); } catch(INTERP_KERNEL::Exception& /* e */)
2601 ret << "Nodal connectivity arrays are not set or badly set !\n";
2605 ret << getNumberOfCells() << "\n";
2606 ret << "Cell type : " << _cm->getRepr() << "\n";
2610 std::string MEDCoupling1DGTUMesh::advancedRepr() const
2612 std::ostringstream ret;
2613 ret << simpleRepr();
2614 ret << "\nCoordinates array : \n___________________\n\n";
2616 _coords->reprWithoutNameStream(ret);
2618 ret << "No array set !\n";
2619 ret << "\n\nNodal Connectivity : \n____________________\n\n";
2622 try { checkConsistency(); } catch(INTERP_KERNEL::Exception& /* e */)
2624 ret << "Nodal connectivity arrays are not set or badly set !\n";
2629 mcIdType nbOfCells=getNumberOfCells();
2630 const mcIdType *ci=_conn_indx->begin(),*c=_conn->begin();
2631 for(mcIdType i=0;i<nbOfCells;i++,ci++)
2633 ret << "Cell #" << i << " : ";
2634 std::copy(c+ci[0],c+ci[1],std::ostream_iterator<int>(ret," "));
2640 DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const
2642 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2643 int spaceDim=getSpaceDimension();
2644 mcIdType nbOfCells=getNumberOfCells();//checkConsistencyLight()
2645 mcIdType nbOfNodes=getNumberOfNodes();
2646 ret->alloc(nbOfCells,spaceDim);
2647 double *ptToFill=ret->getPointer();
2648 const double *coor=_coords->begin();
2649 const mcIdType *nodal=_conn->begin(),*nodali=_conn_indx->begin();
2651 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2653 for(mcIdType i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2655 std::fill(ptToFill,ptToFill+spaceDim,0.);
2656 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2658 for(mcIdType j=nodali[0];j<nodali[1];j++,nodal++)
2660 if(*nodal>=0 && *nodal<nbOfNodes)
2661 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2664 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2665 throw INTERP_KERNEL::Exception(oss.str().c_str());
2667 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./double(nodali[1]-nodali[0])));
2672 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !";
2673 throw INTERP_KERNEL::Exception(oss.str().c_str());
2679 for(mcIdType i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2681 std::fill(ptToFill,ptToFill+spaceDim,0.);
2682 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2685 for(mcIdType j=nodali[0];j<nodali[1];j++,nodal++)
2687 if(*nodal==-1) continue;
2688 if(*nodal>=0 && *nodal<nbOfNodes)
2690 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2695 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2696 throw INTERP_KERNEL::Exception(oss.str().c_str());
2700 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./nbOfNod));
2703 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !";
2704 throw INTERP_KERNEL::Exception(oss.str().c_str());
2709 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : at cell #" << i << " the nodal index array is invalid !";
2710 throw INTERP_KERNEL::Exception(oss.str().c_str());
2717 void MEDCoupling1DGTUMesh::renumberCells(const mcIdType *old2NewBg, bool check)
2719 mcIdType nbCells=getNumberOfCells();
2720 MCAuto<DataArrayIdType> o2n=DataArrayIdType::New();
2721 o2n->useArray(old2NewBg,false,DeallocType::C_DEALLOC,nbCells,1);
2723 o2n=o2n->checkAndPreparePermutation();
2725 const mcIdType *o2nPtr=o2n->getPointer();
2726 const mcIdType *conn=_conn->begin(),*conni=_conn_indx->begin();
2727 MCAuto<DataArrayIdType> newConn=DataArrayIdType::New();
2728 MCAuto<DataArrayIdType> newConnI=DataArrayIdType::New();
2729 newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1);
2730 newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx);
2732 mcIdType *newC=newConn->getPointer(),*newCI=newConnI->getPointer();
2733 for(mcIdType i=0;i<nbCells;i++)
2735 mcIdType newPos=o2nPtr[i];
2736 mcIdType sz=conni[i+1]-conni[i];
2741 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !";
2742 throw INTERP_KERNEL::Exception(oss.str().c_str());
2745 newConnI->computeOffsetsFull(); newCI=newConnI->getPointer();
2747 for(mcIdType i=0;i<nbCells;i++,conni++)
2749 mcIdType newp=o2nPtr[i];
2750 std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]);
2753 _conn_indx=newConnI;
2756 MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
2758 if(other->getType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED)
2759 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !");
2760 const MEDCoupling1DGTUMesh *otherC=static_cast<const MEDCoupling1DGTUMesh *>(other);
2761 return Merge1DGTUMeshes(this,otherC);
2764 MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const
2766 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
2767 ret->setCoords(getCoords());
2768 const mcIdType *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin();
2769 mcIdType nbCells=getNumberOfCells();//checkConsistencyLight
2770 mcIdType geoType=ToIdType(getCellModelEnum());
2771 MCAuto<DataArrayIdType> c=DataArrayIdType::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1);
2772 MCAuto<DataArrayIdType> cI=DataArrayIdType::New(); cI->alloc(nbCells+1);
2773 mcIdType *cPtr=c->getPointer(),*ciPtr=cI->getPointer();
2775 for(mcIdType i=0;i<nbCells;i++,ciPtr++)
2777 mcIdType sz=nodalConnI[i+1]-nodalConnI[i];
2781 cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr);
2782 ciPtr[1]=ciPtr[0]+sz+1;
2786 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !";
2787 throw INTERP_KERNEL::Exception(oss.str().c_str());
2790 ret->setConnectivity(c,cI,true);
2792 { ret->copyTinyInfoFrom(this); }
2793 catch(INTERP_KERNEL::Exception&) { }
2798 * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes
2800 DataArrayIdType *MEDCoupling1DGTUMesh::simplexize(int policy)
2802 mcIdType nbOfCells=getNumberOfCells();
2803 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
2804 ret->alloc(nbOfCells,1);
2809 void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const
2811 stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
2812 stream << " Mesh dimension : " << getMeshDimension() << ".";
2814 { stream << " No coordinates set !"; return ; }
2815 if(!_coords->isAllocated())
2816 { stream << " Coordinates set but not allocated !"; return ; }
2817 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
2818 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
2820 try { checkConsistencyLight(); } catch(INTERP_KERNEL::Exception& /* e */)
2822 stream << std::endl << "Nodal connectivity NOT set properly !\n";
2826 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
2829 void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
2832 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
2833 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2835 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !");
2836 setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex());
2839 MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
2842 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
2843 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2845 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
2846 std::vector<const MEDCoupling1DGTUMesh *> ms(2);
2849 return Merge1DGTUMeshesOnSameCoords(ms);
2852 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const mcIdType *begin, const mcIdType *end) const
2854 checkConsistencyLight();
2855 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2856 ret->setCoords(_coords);
2857 DataArrayIdType *c=0,*ci=0;
2858 DataArrayIdType::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci);
2859 MCAuto<DataArrayIdType> cSafe(c),ciSafe(ci);
2860 ret->setNodalConnectivity(c,ci);
2864 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoordsSlice(mcIdType start, mcIdType end, mcIdType step) const
2866 checkConsistencyLight();
2867 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2868 ret->setCoords(_coords);
2869 DataArrayIdType *c=0,*ci=0;
2870 DataArrayIdType::ExtractFromIndexedArraysSlice(start,end,step,_conn,_conn_indx,c,ci);
2871 MCAuto<DataArrayIdType> cSafe(c),ciSafe(ci);
2872 ret->setNodalConnectivity(c,ci);
2876 void MEDCoupling1DGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
2879 mcIdType sz(ToIdType(nodeIdsInUse.size()));
2880 for(const mcIdType *conn=_conn->begin();conn!=_conn->end();conn++)
2882 if(*conn>=0 && *conn<sz)
2883 nodeIdsInUse[*conn]=true;
2888 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeNodeIdsAlg : At pos #" << std::distance(_conn->begin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !";
2889 throw INTERP_KERNEL::Exception(oss.str().c_str());
2895 void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayIdType *revNodal, DataArrayIdType *revNodalIndx) const
2897 checkFullyDefined();
2898 mcIdType nbOfNodes=getNumberOfNodes();
2899 mcIdType *revNodalIndxPtr=(mcIdType *)malloc((nbOfNodes+1)*sizeof(mcIdType));
2900 revNodalIndx->useArray(revNodalIndxPtr,true,DeallocType::C_DEALLOC,nbOfNodes+1,1);
2901 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
2902 const mcIdType *conn=_conn->begin(),*conni=_conn_indx->begin();
2903 mcIdType nbOfCells=getNumberOfCells();
2904 mcIdType nbOfEltsInRevNodal=0;
2905 for(mcIdType eltId=0;eltId<nbOfCells;eltId++)
2907 mcIdType nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2908 if(nbOfNodesPerCell>=0)
2910 for(mcIdType j=0;j<nbOfNodesPerCell;j++)
2912 mcIdType nodeId=conn[conni[eltId]+j];
2913 if(nodeId==-1) continue;
2914 if(nodeId>=0 && nodeId<nbOfNodes)
2916 nbOfEltsInRevNodal++;
2917 revNodalIndxPtr[nodeId+1]++;
2921 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
2922 throw INTERP_KERNEL::Exception(oss.str().c_str());
2928 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << "nodal connectivity is invalid !";
2929 throw INTERP_KERNEL::Exception(oss.str().c_str());
2932 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<mcIdType>());
2933 conn=_conn->begin();
2934 mcIdType *revNodalPtr=(mcIdType *)malloc((nbOfEltsInRevNodal)*sizeof(mcIdType));
2935 revNodal->useArray(revNodalPtr,true,DeallocType::C_DEALLOC,nbOfEltsInRevNodal,1);
2936 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
2937 for(mcIdType eltId=0;eltId<nbOfCells;eltId++)
2939 mcIdType nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2940 for(mcIdType j=0;j<nbOfNodesPerCell;j++)
2942 mcIdType nodeId=conn[conni[eltId]+j];
2944 *std::find_if(revNodalPtr+revNodalIndxPtr[nodeId],revNodalPtr+revNodalIndxPtr[nodeId+1],std::bind2nd(std::equal_to<mcIdType>(),-1))=eltId;
2949 void MEDCoupling1DGTUMesh::checkFullyDefined() const
2951 if(!((const DataArrayIdType *)_conn) || !((const DataArrayIdType *)_conn_indx) || !((const DataArrayDouble *)_coords))
2952 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined.");
2955 bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector<mcIdType>& tinyInfo) const
2957 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !");
2960 void MEDCoupling1DGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<mcIdType>& tinyInfo, std::vector<std::string>& littleStrings) const
2963 double time=getTime(it,order);
2964 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
2966 littleStrings.push_back(getName());
2967 littleStrings.push_back(getDescription());
2968 littleStrings.push_back(getTimeUnit());
2970 std::vector<std::string> littleStrings2,littleStrings3,littleStrings4;
2971 if((const DataArrayDouble *)_coords)
2972 _coords->getTinySerializationStrInformation(littleStrings2);
2973 if((const DataArrayIdType *)_conn)
2974 _conn->getTinySerializationStrInformation(littleStrings3);
2975 if((const DataArrayIdType *)_conn_indx)
2976 _conn_indx->getTinySerializationStrInformation(littleStrings4);
2977 mcIdType sz0(ToIdType(littleStrings2.size())),sz1(ToIdType(littleStrings3.size())),sz2(ToIdType(littleStrings4.size()));
2978 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
2979 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
2980 littleStrings.insert(littleStrings.end(),littleStrings4.begin(),littleStrings4.end());
2982 tinyInfo.push_back(getCellModelEnum());
2983 tinyInfo.push_back(it);
2984 tinyInfo.push_back(order);
2985 std::vector<mcIdType> tinyInfo2,tinyInfo3,tinyInfo4;
2986 if((const DataArrayDouble *)_coords)
2987 _coords->getTinySerializationIntInformation(tinyInfo2);
2988 if((const DataArrayIdType *)_conn)
2989 _conn->getTinySerializationIntInformation(tinyInfo3);
2990 if((const DataArrayIdType *)_conn_indx)
2991 _conn_indx->getTinySerializationIntInformation(tinyInfo4);
2992 mcIdType sz3(ToIdType(tinyInfo2.size())),sz4(ToIdType(tinyInfo3.size())),sz5(ToIdType(tinyInfo4.size()));
2993 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3); tinyInfo.push_back(sz4); tinyInfo.push_back(sz5);
2994 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
2995 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
2996 tinyInfo.insert(tinyInfo.end(),tinyInfo4.begin(),tinyInfo4.end());
2998 tinyInfoD.push_back(time);
3001 void MEDCoupling1DGTUMesh::resizeForUnserialization(const std::vector<mcIdType>& tinyInfo, DataArrayIdType *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
3003 std::vector<mcIdType> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+tinyInfo[6]);
3004 std::vector<mcIdType> tinyInfo1(tinyInfo.begin()+9+tinyInfo[6],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]);
3005 std::vector<mcIdType> tinyInfo12(tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]+tinyInfo[8]);
3006 MCAuto<DataArrayIdType> p1(DataArrayIdType::New()); p1->resizeForUnserialization(tinyInfo1);
3007 MCAuto<DataArrayIdType> p2(DataArrayIdType::New()); p2->resizeForUnserialization(tinyInfo12);
3008 std::vector<const DataArrayIdType *> v(2); v[0]=p1; v[1]=p2;
3009 p2=DataArrayIdType::Aggregate(v);
3010 a2->resizeForUnserialization(tinyInfo2);
3011 a1->alloc(p2->getNbOfElems(),1);
3014 void MEDCoupling1DGTUMesh::serialize(DataArrayIdType *&a1, DataArrayDouble *&a2) const
3017 if((const DataArrayIdType *)_conn)
3018 if(_conn->isAllocated())
3019 sz=_conn->getNbOfElems();
3020 if((const DataArrayIdType *)_conn_indx)
3021 if(_conn_indx->isAllocated())
3022 sz+=_conn_indx->getNbOfElems();
3023 a1=DataArrayIdType::New();
3025 mcIdType *work(a1->getPointer());
3026 if(sz!=0 && (const DataArrayIdType *)_conn)
3027 work=std::copy(_conn->begin(),_conn->end(),a1->getPointer());
3028 if(sz!=0 && (const DataArrayIdType *)_conn_indx)
3029 std::copy(_conn_indx->begin(),_conn_indx->end(),work);
3031 if((const DataArrayDouble *)_coords)
3032 if(_coords->isAllocated())
3033 sz=_coords->getNbOfElems();
3034 a2=DataArrayDouble::New();
3036 if(sz!=0 && (const DataArrayDouble *)_coords)
3037 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
3040 void MEDCoupling1DGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<mcIdType>& tinyInfo, const DataArrayIdType *a1, DataArrayDouble *a2,
3041 const std::vector<std::string>& littleStrings)
3043 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
3044 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
3045 setName(littleStrings[0]);
3046 setDescription(littleStrings[1]);
3047 setTimeUnit(littleStrings[2]);
3048 setTime(tinyInfoD[0],FromIdType<int>(tinyInfo[1]),FromIdType<int>(tinyInfo[2]));
3049 mcIdType sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]),sz4(tinyInfo[7]),sz5(tinyInfo[8]);
3051 _coords=DataArrayDouble::New();
3052 std::vector<mcIdType> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+sz3);
3053 _coords->resizeForUnserialization(tinyInfo2);
3054 std::copy(a2->begin(),a2->end(),_coords->getPointer());
3055 _conn=DataArrayIdType::New();
3056 std::vector<mcIdType> tinyInfo3(tinyInfo.begin()+9+sz3,tinyInfo.begin()+9+sz3+sz4);
3057 _conn->resizeForUnserialization(tinyInfo3);
3058 std::copy(a1->begin(),a1->begin()+_conn->getNbOfElems(),_conn->getPointer());
3059 _conn_indx=DataArrayIdType::New();
3060 std::vector<mcIdType> tinyInfo4(tinyInfo.begin()+9+sz3+sz4,tinyInfo.begin()+9+sz3+sz4+sz5);
3061 _conn_indx->resizeForUnserialization(tinyInfo4);
3062 std::copy(a1->begin()+_conn->getNbOfElems(),a1->end(),_conn_indx->getPointer());
3063 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
3064 _coords->finishUnserialization(tinyInfo2,littleStrings2);
3065 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
3066 _conn->finishUnserialization(tinyInfo3,littleStrings3);
3067 std::vector<std::string> littleStrings4(littleStrings.begin()+3+sz0+sz1,littleStrings.begin()+3+sz0+sz1+sz2);
3068 _conn_indx->finishUnserialization(tinyInfo4,littleStrings4);
3072 * Finds nodes not used in any cell and returns an array giving a new id to every node
3073 * by excluding the unused nodes, for which the array holds -1. The result array is
3074 * a mapping in "Old to New" mode.
3075 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
3076 * \return DataArrayIdType * - a new instance of DataArrayIdType. Its length is \a
3077 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
3078 * if the node is unused or a new id else. The caller is to delete this
3079 * array using decrRef() as it is no more needed.
3080 * \throw If the coordinates array is not set.
3081 * \throw If the nodal connectivity of cells is not defined.
3082 * \throw If the nodal connectivity includes an invalid id.
3083 * \sa MEDCoupling1DGTUMesh::getNodeIdsInUse, areAllNodesFetched
3085 DataArrayIdType *MEDCoupling1DGTUMesh::computeFetchedNodeIds() const
3088 mcIdType nbNodes(getNumberOfNodes());
3089 std::vector<bool> fetchedNodes(nbNodes,false);
3090 computeNodeIdsAlg(fetchedNodes);
3091 mcIdType sz(ToIdType(std::count(fetchedNodes.begin(),fetchedNodes.end(),true)));
3092 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(sz,1);
3093 mcIdType *retPtr(ret->getPointer());
3094 for(mcIdType i=0;i<nbNodes;i++)
3101 * Finds nodes not used in any cell and returns an array giving a new id to every node
3102 * by excluding the unused nodes, for which the array holds -1. The result array is
3103 * a mapping in "Old to New" mode.
3104 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
3105 * \return DataArrayIdType * - a new instance of DataArrayIdType. Its length is \a
3106 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
3107 * if the node is unused or a new id else. The caller is to delete this
3108 * array using decrRef() as it is no more needed.
3109 * \throw If the coordinates array is not set.
3110 * \throw If the nodal connectivity of cells is not defined.
3111 * \throw If the nodal connectivity includes an invalid id.
3112 * \sa MEDCoupling1DGTUMesh::computeFetchedNodeIds, areAllNodesFetched
3114 DataArrayIdType *MEDCoupling1DGTUMesh::getNodeIdsInUse(mcIdType& nbrOfNodesInUse) const
3117 mcIdType nbOfNodes=getNumberOfNodes();
3118 mcIdType nbOfCells=getNumberOfCells();//checkConsistencyLight
3119 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
3120 ret->alloc(nbOfNodes,1);
3121 mcIdType *traducer=ret->getPointer();
3122 std::fill(traducer,traducer+nbOfNodes,-1);
3123 const mcIdType *conn=_conn->begin(),*conni(_conn_indx->begin());
3124 for(mcIdType i=0;i<nbOfCells;i++,conni++)
3126 mcIdType nbNodesPerCell=conni[1]-conni[0];
3127 for(mcIdType j=0;j<nbNodesPerCell;j++)
3129 mcIdType nodeId=conn[conni[0]+j];
3130 if(nodeId==-1) continue;
3131 if(nodeId>=0 && nodeId<nbOfNodes)
3135 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << nodeId << " not in [0," << nbOfNodes << ") !";
3136 throw INTERP_KERNEL::Exception(oss.str().c_str());
3140 nbrOfNodesInUse=ToIdType(std::count(traducer,traducer+nbOfNodes,1));
3141 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
3146 * This method renumbers only nodal connectivity in \a this. The renumbering is only an offset applied. So this method is a specialization of
3147 * \a renumberNodesInConn. \b WARNING, this method does not check that the resulting node ids in the nodal connectivity is in a valid range !
3149 * \param [in] offset - specifies the offset to be applied on each element of connectivity.
3151 * \sa renumberNodesInConn
3153 void MEDCoupling1DGTUMesh::renumberNodesWithOffsetInConn(mcIdType offset)
3155 getNumberOfCells();//only to check that all is well defined.
3157 mcIdType nbOfTuples(_conn->getNumberOfTuples());
3158 mcIdType *pt(_conn->getPointer());
3159 for(mcIdType i=0;i<nbOfTuples;i++,pt++)
3161 if(*pt==-1) continue;
3169 * Same than renumberNodesInConn(const mcIdType *) except that here the format of old-to-new traducer is using map instead
3170 * 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
3173 void MEDCoupling1DGTUMesh::renumberNodesInConn(const INTERP_KERNEL::HashMap<mcIdType,mcIdType>& newNodeNumbersO2N)
3175 this->renumberNodesInConnT< INTERP_KERNEL::HashMap<mcIdType,mcIdType> >(newNodeNumbersO2N);
3179 * Same than renumberNodesInConn(const mcIdType *) except that here the format of old-to-new traducer is using map instead
3180 * 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
3183 void MEDCoupling1DGTUMesh::renumberNodesInConn(const std::map<mcIdType,mcIdType>& newNodeNumbersO2N)
3185 this->renumberNodesInConnT< std::map<mcIdType,mcIdType> >(newNodeNumbersO2N);
3189 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
3190 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
3191 * This method is a generalization of shiftNodeNumbersInConn().
3192 * \warning This method performs no check of validity of new ids. **Use it with care !**
3193 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
3194 * this->getNumberOfNodes(), in "Old to New" mode.
3195 * See \ref numbering for more info on renumbering modes.
3196 * \throw If the nodal connectivity of cells is not defined.
3198 void MEDCoupling1DGTUMesh::renumberNodesInConn(const mcIdType *newNodeNumbersO2N)
3200 getNumberOfCells();//only to check that all is well defined.
3202 mcIdType nbElemsIn(getNumberOfNodes()),nbOfTuples(_conn->getNumberOfTuples());
3203 mcIdType *pt(_conn->getPointer());
3204 for(mcIdType i=0;i<nbOfTuples;i++,pt++)
3206 if(*pt==-1) continue;
3207 if(*pt>=0 && *pt<nbElemsIn)
3208 *pt=newNodeNumbersO2N[*pt];
3211 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
3212 throw INTERP_KERNEL::Exception(oss.str().c_str());
3220 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
3221 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
3222 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
3223 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
3225 * \param [in] begin input start of array of node ids.
3226 * \param [in] end input end of array of node ids.
3227 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
3228 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
3230 void MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const mcIdType *begin, const mcIdType *end, bool fullyIn, DataArrayIdType *&cellIdsKeptArr) const
3232 mcIdType nbOfCells=getNumberOfCells();
3233 MCAuto<DataArrayIdType> cellIdsKept=DataArrayIdType::New(); cellIdsKept->alloc(0,1);
3235 mcIdType sz=_conn->getMaxValue(tmp); sz=std::max(sz,ToIdType(0))+1;
3236 std::vector<bool> fastFinder(sz,false);
3237 for(const mcIdType *work=begin;work!=end;work++)
3238 if(*work>=0 && *work<sz)
3239 fastFinder[*work]=true;
3240 const mcIdType *conn=_conn->begin(),*conni=_conn_indx->begin();
3241 for(mcIdType i=0;i<nbOfCells;i++,conni++)
3243 int ref=0,nbOfHit=0;
3244 mcIdType nbNodesPerCell=conni[1]-conni[0];
3245 if(nbNodesPerCell>=0)
3247 for(mcIdType j=0;j<nbNodesPerCell;j++)
3249 mcIdType nodeId=conn[conni[0]+j];
3253 if(fastFinder[nodeId])
3260 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !";
3261 throw INTERP_KERNEL::Exception(oss.str().c_str());
3263 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
3264 cellIdsKept->pushBackSilent(i);
3266 cellIdsKeptArr=cellIdsKept.retn();
3269 void MEDCoupling1DGTUMesh::allocateCells(mcIdType nbOfCells)
3272 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !");
3273 _conn=DataArrayIdType::New();
3274 _conn->reserve(nbOfCells*3);
3275 _conn_indx=DataArrayIdType::New();
3276 _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0);
3281 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
3283 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
3284 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
3285 * \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
3286 * attached to \a this.
3287 * \throw If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
3289 void MEDCoupling1DGTUMesh::insertNextCell(const mcIdType *nodalConnOfCellBg, const mcIdType *nodalConnOfCellEnd)
3291 std::size_t sz(std::distance(nodalConnOfCellBg,nodalConnOfCellEnd));
3292 DataArrayIdType *c(_conn),*c2(_conn_indx);
3295 mcIdType pos=c2->back();
3296 if(pos==c->getNumberOfTuples())
3298 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
3299 c2->pushBackSilent(pos+ToIdType(sz));
3303 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !";
3304 throw INTERP_KERNEL::Exception(oss.str().c_str());
3308 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !");
3311 void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayIdType *nodalConn, DataArrayIdType *nodalConnIndex)
3314 nodalConn->incrRef();
3317 nodalConnIndex->incrRef();
3318 _conn_indx=nodalConnIndex;
3323 * \return DataArrayIdType * - the internal reference to the nodal connectivity. The caller is not responsible to deallocate it.
3325 DataArrayIdType *MEDCoupling1DGTUMesh::getNodalConnectivity() const
3327 const DataArrayIdType *ret(_conn);
3328 return const_cast<DataArrayIdType *>(ret);
3332 * \return DataArrayIdType * - the internal reference to the nodal connectivity index. The caller is not responsible to deallocate it.
3334 DataArrayIdType *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const
3336 const DataArrayIdType *ret(_conn_indx);
3337 return const_cast<DataArrayIdType *>(ret);
3341 * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here".
3342 * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity).
3343 * 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.
3345 * 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.
3347 * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal
3348 * connectivity arrays are different (false)
3349 * \return a new object to be managed by the caller.
3351 * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked
3353 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const
3355 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3356 DataArrayIdType *nc=0,*nci=0;
3357 isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci);
3358 MCAuto<DataArrayIdType> ncs(nc),ncis(nci);
3359 ret->_conn=ncs; ret->_conn_indx=ncis;
3360 ret->setCoords(getCoords());
3365 * This method allows to compute, if needed, the packed nodal connectivity pair.
3366 * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges covered by nodal connectivity index array.
3367 * 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.
3369 * 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)
3370 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3372 * 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
3375 * This method return 3 elements.
3376 * \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
3377 * this pointer can be seen as a new object, that is to managed by the caller.
3378 * \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
3379 * this pointer can be seen as a new object, that is to managed by the caller.
3380 * \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
3381 * output parameters are newly created objects.
3383 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkConsistencyLight test
3385 bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayIdType *&nodalConn, DataArrayIdType *&nodalConnIndx) const
3387 if(isPacked())//performs the checkConsistencyLight
3389 const DataArrayIdType *c0(_conn),*c1(_conn_indx);
3390 nodalConn=const_cast<DataArrayIdType *>(c0); nodalConnIndx=const_cast<DataArrayIdType *>(c1);
3391 nodalConn->incrRef(); nodalConnIndx->incrRef();
3394 mcIdType bg=_conn_indx->front(),end=_conn_indx->back();
3395 MCAuto<DataArrayIdType> nc(_conn->selectByTupleIdSafeSlice(bg,end,1));
3396 MCAuto<DataArrayIdType> nci(_conn_indx->deepCopy());
3397 nci->applyLin(1,-bg);
3398 nodalConn=nc.retn(); nodalConnIndx=nci.retn();
3403 * 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)
3404 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3405 * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned.
3406 * \return bool - true if \a this looks packed, false is not.
3408 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkConsistencyLight test
3410 bool MEDCoupling1DGTUMesh::isPacked() const
3412 checkConsistencyLight();
3413 return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples();
3416 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2)
3418 std::vector<const MEDCoupling1DGTUMesh *> tmp(2);
3419 tmp[0]=const_cast<MEDCoupling1DGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1DGTUMesh *>(mesh2);
3420 return Merge1DGTUMeshes(tmp);
3423 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a)
3425 std::size_t sz=a.size();
3427 return Merge1DGTUMeshesLL(a);
3428 for(std::size_t ii=0;ii<sz;ii++)
3431 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::Merge1DGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
3432 throw INTERP_KERNEL::Exception(oss.str().c_str());
3434 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
3435 for(std::size_t ii=0;ii<sz;ii++)
3436 if(&(a[ii]->getCellModel())!=cm)
3437 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !");
3438 std::vector< MCAuto<MEDCoupling1DGTUMesh> > bb(sz);
3439 std::vector< const MEDCoupling1DGTUMesh * > aa(sz);
3440 std::size_t spaceDimUndef=-3, spaceDim=spaceDimUndef;
3441 for(std::size_t i=0;i<sz && spaceDim==spaceDimUndef;i++)
3443 const MEDCoupling1DGTUMesh *cur=a[i];
3444 const DataArrayDouble *coo=cur->getCoords();
3446 spaceDim=coo->getNumberOfComponents();
3448 if(spaceDim==spaceDimUndef)
3449 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !");
3450 for(std::size_t i=0;i<sz;i++)
3452 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
3455 return Merge1DGTUMeshesLL(aa);
3459 * \throw If presence of a null instance in the input vector \a a.
3460 * \throw If a is empty
3462 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a)
3465 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !");
3466 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3468 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !");
3469 std::vector< MCAuto<MEDCoupling1DGTUMesh> > objs(a.size());
3470 std::vector<const DataArrayIdType *> ncs(a.size()),ncis(a.size());
3471 (*it)->getNumberOfCells();//to check that all is OK
3472 const DataArrayDouble *coords=(*it)->getCoords();
3473 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3475 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3476 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3478 for(int i=1;it!=a.end();i++,it++)
3481 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !");
3482 if(cm!=&((*it)->getCellModel()))
3483 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3484 (*it)->getNumberOfCells();//to check that all is OK
3485 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3486 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3487 if(coords!=(*it)->getCoords())
3488 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !");
3490 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3491 ret->setCoords(coords);
3492 ret->_conn=DataArrayIdType::Aggregate(ncs);
3493 ret->_conn_indx=DataArrayIdType::AggregateIndexes(ncis);
3498 * 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)
3500 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a)
3503 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : input array must be NON EMPTY !");
3504 std::vector< MCAuto<MEDCoupling1DGTUMesh> > objs(a.size());
3505 std::vector<const DataArrayIdType *> ncs(a.size()),ncis(a.size());
3506 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3507 std::vector<mcIdType> nbNodesPerElt(a.size());
3508 std::size_t nbOfCells=(*it)->getNumberOfCells();
3510 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3511 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3513 mcIdType prevNbOfNodes=(*it)->getNumberOfNodes();
3514 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3516 for(int i=1;it!=a.end();i++,it++)
3518 if(cm!=&((*it)->getCellModel()))
3519 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3520 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3521 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3522 nbOfCells+=(*it)->getNumberOfCells();
3523 nbNodesPerElt[i]=nbNodesPerElt[i-1]+prevNbOfNodes;
3524 prevNbOfNodes=(*it)->getNumberOfNodes();
3526 std::vector<const MEDCouplingPointSet *> aps(a.size());
3527 std::copy(a.begin(),a.end(),aps.begin());
3528 MCAuto<DataArrayDouble> pts=MergeNodesArray(aps);
3529 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3530 ret->setCoords(pts);
3531 ret->_conn=AggregateNodalConnAndShiftNodeIds(ncs,nbNodesPerElt);
3532 ret->_conn_indx=DataArrayIdType::AggregateIndexes(ncis);
3536 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(std::size_t spaceDim) const
3538 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3539 MCAuto<DataArrayIdType> tmp1,tmp2;
3540 const DataArrayIdType *nodalConn(_conn),*nodalConnI(_conn_indx);
3543 tmp1=DataArrayIdType::New(); tmp1->alloc(0,1);
3551 tmp2=DataArrayIdType::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
3555 ret->_conn_indx=tmp2;
3559 MCAuto<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
3560 ret->setCoords(coords);
3563 ret->setCoords(_coords);
3568 * This method aggregate the bbox of each cell and put it into bbox parameter.
3570 * \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)
3571 * For all other cases this input parameter is ignored.
3572 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
3574 * \throw If \a this is not fully set (coordinates and connectivity).
3575 * \throw If a cell in \a this has no valid nodeId.
3577 DataArrayDouble *MEDCoupling1DGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
3579 checkFullyDefined();
3580 mcIdType spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes());
3581 MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
3582 double *bbox(ret->getPointer());
3583 for(mcIdType i=0;i<nbOfCells*spaceDim;i++)
3585 bbox[2*i]=std::numeric_limits<double>::max();
3586 bbox[2*i+1]=-std::numeric_limits<double>::max();
3588 const double *coordsPtr(_coords->getConstPointer());
3589 const mcIdType *conn(_conn->getConstPointer()),*connI(_conn_indx->getConstPointer());
3590 for(mcIdType i=0;i<nbOfCells;i++)
3592 mcIdType offset=connI[i];
3593 mcIdType nbOfNodesForCell(connI[i+1]-offset),kk(0);
3594 for(mcIdType j=0;j<nbOfNodesForCell;j++)
3596 mcIdType nodeId=conn[offset+j];
3597 if(nodeId>=0 && nodeId<nbOfNodes)
3599 for(int k=0;k<spaceDim;k++)
3601 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
3602 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
3609 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
3610 throw INTERP_KERNEL::Exception(oss.str().c_str());
3617 * 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.
3619 * \return a new instance of field containing the result. The returned instance has to be deallocated by the caller.
3621 MEDCouplingFieldDouble *MEDCoupling1DGTUMesh::computeDiameterField() const
3623 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::computeDiameterField : not implemented yet for dynamic types !");
3626 std::vector<mcIdType> MEDCoupling1DGTUMesh::BuildAPolygonFromParts(const std::vector< std::vector<mcIdType> >& parts)
3628 std::vector<mcIdType> ret;
3631 ret.insert(ret.end(),parts[0].begin(),parts[0].end());
3632 mcIdType ref(ret.back());
3633 std::size_t sz(parts.size()),nbh(1);
3634 std::vector<bool> b(sz,true); b[0]=false;
3638 for(;i<sz;i++) if(b[i] && parts[i].front()==ref) { ret.insert(ret.end(),parts[i].begin()+1,parts[i].end()); nbh++; break; }
3642 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::BuildAPolygonFromParts : the input vector is not a part of a single polygon !");
3644 if(ret.back()==ret.front())
3650 * This method invert orientation of all cells in \a this.
3651 * After calling this method the absolute value of measure of cells in \a this are the same than before calling.
3652 * This method only operates on the connectivity so coordinates are not touched at all.
3654 void MEDCoupling1DGTUMesh::invertOrientationOfAllCells()
3656 checkConsistencyOfConnectivity();
3657 INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::OrientationInverter> oi(INTERP_KERNEL::OrientationInverter::BuildInstanceFrom(getCellModelEnum()));
3658 mcIdType nbCells=getNumberOfCells();
3659 const mcIdType *connI(_conn_indx->begin());
3660 mcIdType *conn(_conn->getPointer());
3661 for(mcIdType i=0;i<nbCells;i++)
3662 oi->operate(conn+connI[i],conn+connI[i+1]);
3667 * This method performs an aggregation of \a nodalConns (as DataArrayIdType::Aggregate does) but in addition of that a shift is applied on the
3668 * values contained in \a nodalConns using corresponding offset specified in input \a offsetInNodeIdsPerElt.
3669 * But it also manage the values -1, that have a semantic in MEDCoupling1DGTUMesh class (separator for polyhedron).
3671 * \param [in] nodalConns - a list of nodal connectivity arrays same size than \a offsetInNodeIdsPerElt.
3672 * \param [in] offsetInNodeIdsPerElt - a list of offsets to apply.
3673 * \return DataArrayIdType * - A new object (to be managed by the caller) that is the result of the aggregation.
3674 * \throw If \a nodalConns or \a offsetInNodeIdsPerElt are empty.
3675 * \throw If \a nodalConns and \a offsetInNodeIdsPerElt have not the same size.
3676 * \throw If presence of null pointer in \a nodalConns.
3677 * \throw If presence of not allocated or array with not exactly one component in \a nodalConns.
3679 DataArrayIdType *MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds(const std::vector<const DataArrayIdType *>& nodalConns, const std::vector<mcIdType>& offsetInNodeIdsPerElt)
3681 std::size_t sz1(nodalConns.size()),sz2(offsetInNodeIdsPerElt.size());
3683 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : input vectors do not have the same size !");
3685 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : empty vectors in input !");
3686 mcIdType nbOfTuples=0;
3687 for(std::vector<const DataArrayIdType *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++)
3690 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of null pointer in input vector !");
3691 if(!(*it)->isAllocated())
3692 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of non allocated array in input vector !");
3693 if((*it)->getNumberOfComponents()!=1)
3694 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of array with not exactly one component !");
3695 nbOfTuples+=(*it)->getNumberOfTuples();
3697 MCAuto<DataArrayIdType> ret=DataArrayIdType::New(); ret->alloc(nbOfTuples,1);
3698 mcIdType *pt=ret->getPointer();
3700 for(std::vector<const DataArrayIdType *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++,i++)
3702 mcIdType curNbt=(*it)->getNumberOfTuples();
3703 const mcIdType *inPt=(*it)->begin();
3704 mcIdType offset=offsetInNodeIdsPerElt[i];
3705 for(mcIdType j=0;j<curNbt;j++,pt++)
3716 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m)
3719 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh is null !");
3720 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
3722 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh must have exactly one geometric type !");
3723 mcIdType geoType(ToIdType(*gts.begin()));
3724 MCAuto<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(m->getName(),*gts.begin()));
3725 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription());
3726 mcIdType nbCells=m->getNumberOfCells();
3727 MCAuto<DataArrayIdType> conn(DataArrayIdType::New()),connI(DataArrayIdType::New());
3728 conn->alloc(m->getNodalConnectivityArrayLen()-nbCells,1); connI->alloc(nbCells+1,1);
3729 mcIdType *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
3730 const mcIdType *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
3731 for(mcIdType i=0;i<nbCells;i++,ciin++,ci++)
3733 if(cin[ciin[0]]==geoType)
3735 if(ciin[1]-ciin[0]>=1)
3737 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
3738 ci[1]=ci[0]+ciin[1]-ciin[0]-1;
3742 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 !";
3743 throw INTERP_KERNEL::Exception(oss.str().c_str());
3748 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 !";
3749 throw INTERP_KERNEL::Exception(oss.str().c_str());
3752 ret->setNodalConnectivity(conn,connI);