1 // Copyright (C) 2007-2021 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;
786 ret << "No geometric type specified" << std::endl;
789 ret << "Single static geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
790 ret << "Description of mesh : \"" << getDescription() << "\"\n";
792 double tt=getTime(tmpp1,tmpp2);
793 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
794 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
795 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
798 const int spaceDim=getSpaceDimension();
799 ret << spaceDim << "\nInfo attached on space dimension : ";
800 for(int i=0;i<spaceDim;i++)
801 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
806 ret << "Number of nodes : ";
808 ret << getNumberOfNodes() << "\n";
811 ret << "Number of cells : ";
812 if((const DataArrayIdType *)_conn)
814 if(_conn->isAllocated())
816 if(_conn->getNumberOfComponents()==1)
817 ret << getNumberOfCells() << "\n";
819 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
822 ret << "Nodal connectivity array specified but not allocated !" << "\n";
825 ret << "No connectivity specified !" << "\n";
826 ret << "Cell type : " << _cm->getRepr() << "\n";
830 std::string MEDCoupling1SGTUMesh::advancedRepr() const
832 std::ostringstream ret;
834 ret << "\nCoordinates array : \n___________________\n\n";
836 _coords->reprWithoutNameStream(ret);
838 ret << "No array set !\n";
839 ret << "\n\nConnectivity array : \n____________________\n\n";
841 if((const DataArrayIdType *)_conn)
843 if(_conn->isAllocated())
845 if(_conn->getNumberOfComponents()==1)
847 mcIdType nbOfCells=getNumberOfCells();
848 mcIdType sz=getNumberOfNodesPerCell();
849 const mcIdType *connPtr=_conn->begin();
850 for(mcIdType i=0;i<nbOfCells;i++,connPtr+=sz)
852 ret << "Cell #" << i << " : ";
853 std::copy(connPtr,connPtr+sz,std::ostream_iterator<mcIdType>(ret," "));
858 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
861 ret << "Nodal connectivity array specified but not allocated !" << "\n";
864 ret << "No connectivity specified !" << "\n";
868 DataArrayDouble *MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell() const
870 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
871 int spaceDim=getSpaceDimension();
872 mcIdType nbOfCells=getNumberOfCells();//checkConsistencyLight()
873 mcIdType nbOfNodes=getNumberOfNodes();
874 ret->alloc(nbOfCells,spaceDim);
875 double *ptToFill=ret->getPointer();
876 const double *coor=_coords->begin();
877 const mcIdType *nodal=_conn->begin();
878 mcIdType sz=getNumberOfNodesPerCell();
879 double coeff=1./FromIdType<double>(sz);
880 for(mcIdType i=0;i<nbOfCells;i++,ptToFill+=spaceDim)
882 std::fill(ptToFill,ptToFill+spaceDim,0.);
883 for(mcIdType j=0;j<sz;j++,nodal++)
884 if(*nodal>=0 && *nodal<nbOfNodes)
885 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
888 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
889 throw INTERP_KERNEL::Exception(oss.str().c_str());
891 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind(std::multiplies<double>(),std::placeholders::_1,coeff));
896 void MEDCoupling1SGTUMesh::renumberCells(const mcIdType *old2NewBg, bool check)
898 mcIdType nbCells=getNumberOfCells();
899 MCAuto<DataArrayIdType> o2n=DataArrayIdType::New();
900 o2n->useArray(old2NewBg,false,DeallocType::C_DEALLOC,nbCells,1);
902 o2n=o2n->checkAndPreparePermutation();
904 const mcIdType *conn=_conn->begin();
905 MCAuto<DataArrayIdType> n2o=o2n->invertArrayO2N2N2O(nbCells);
906 const mcIdType *n2oPtr=n2o->begin();
907 MCAuto<DataArrayIdType> newConn=DataArrayIdType::New();
908 newConn->alloc(_conn->getNumberOfTuples(),1);
909 newConn->copyStringInfoFrom(*_conn);
910 mcIdType sz=getNumberOfNodesPerCell();
912 mcIdType *newC=newConn->getPointer();
913 for(mcIdType i=0;i<nbCells;i++,newC+=sz)
915 mcIdType pos=n2oPtr[i];
916 std::copy(conn+pos*sz,conn+(pos+1)*sz,newC);
922 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
923 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
924 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
925 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
927 * \param [in] begin input start of array of node ids.
928 * \param [in] end input end of array of node ids.
929 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
930 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
932 void MEDCoupling1SGTUMesh::fillCellIdsToKeepFromNodeIds(const mcIdType *begin, const mcIdType *end, bool fullyIn, DataArrayIdType *&cellIdsKeptArr) const
934 mcIdType nbOfCells=getNumberOfCells();
935 MCAuto<DataArrayIdType> cellIdsKept=DataArrayIdType::New(); cellIdsKept->alloc(0,1);
937 mcIdType sz=_conn->getMaxValue(tmp); sz=std::max(sz,ToIdType(0))+1;
938 std::vector<bool> fastFinder(sz,false);
939 for(const mcIdType *work=begin;work!=end;work++)
940 if(*work>=0 && *work<sz)
941 fastFinder[*work]=true;
942 const mcIdType *conn=_conn->begin();
943 mcIdType nbNodesPerCell=getNumberOfNodesPerCell();
944 for(mcIdType i=0;i<nbOfCells;i++,conn+=nbNodesPerCell)
947 for(mcIdType j=0;j<nbNodesPerCell;j++)
951 if(fastFinder[conn[j]])
954 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
955 cellIdsKept->pushBackSilent(i);
957 cellIdsKeptArr=cellIdsKept.retn();
960 MEDCouplingMesh *MEDCoupling1SGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
962 if(other->getType()!=SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED)
963 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single static geo type each other !");
964 const MEDCoupling1SGTUMesh *otherC=static_cast<const MEDCoupling1SGTUMesh *>(other);
965 return Merge1SGTUMeshes(this,otherC);
968 MEDCouplingUMesh *MEDCoupling1SGTUMesh::buildUnstructured() const
970 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
971 ret->setCoords(getCoords());
972 const mcIdType *nodalConn=_conn->begin();
973 mcIdType nbCells=getNumberOfCells();
974 mcIdType nbNodesPerCell=getNumberOfNodesPerCell();
975 mcIdType geoType=ToIdType(getCellModelEnum());
976 MCAuto<DataArrayIdType> c=DataArrayIdType::New(); c->alloc(nbCells*(nbNodesPerCell+1),1);
977 mcIdType *cPtr=c->getPointer();
978 for(mcIdType i=0;i<nbCells;i++,nodalConn+=nbNodesPerCell)
981 cPtr=std::copy(nodalConn,nodalConn+nbNodesPerCell,cPtr);
983 MCAuto<DataArrayIdType> cI=DataArrayIdType::Range(0,(nbCells+1)*(nbNodesPerCell+1),nbNodesPerCell+1);
984 ret->setConnectivity(c,cI,true);
986 { ret->copyTinyInfoFrom(this); }
987 catch(INTERP_KERNEL::Exception&) { }
991 DataArrayIdType *MEDCoupling1SGTUMesh::simplexize(int policy)
996 return simplexizePol0();
998 return simplexizePol1();
999 case INTERP_KERNEL::PLANAR_FACE_5:
1000 return simplexizePlanarFace5();
1001 case INTERP_KERNEL::PLANAR_FACE_6:
1002 return simplexizePlanarFace6();
1004 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)");
1010 struct MEDCouplingAccVisit
1012 MEDCouplingAccVisit():_new_nb_of_nodes(0) { }
1013 mcIdType operator()(mcIdType val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; }
1014 mcIdType _new_nb_of_nodes;
1020 * This method returns all node ids used in \b this. The data array returned has to be dealt by the caller.
1021 * The returned node ids are sortes ascendingly. This method is closed to MEDCoupling1SGTUMesh::getNodeIdsInUse except
1022 * the format of returned DataArrayIdType instance.
1024 * \return a newly allocated DataArrayIdType sorted ascendingly of fetched node ids.
1025 * \sa MEDCoupling1SGTUMesh::getNodeIdsInUse, areAllNodesFetched
1027 DataArrayIdType *MEDCoupling1SGTUMesh::computeFetchedNodeIds() const
1029 checkConsistencyOfConnectivity();
1030 mcIdType nbNodes(getNumberOfNodes());
1031 std::vector<bool> fetchedNodes(nbNodes,false);
1032 computeNodeIdsAlg(fetchedNodes);
1033 mcIdType sz(ToIdType(std::count(fetchedNodes.begin(),fetchedNodes.end(),true)));
1034 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(sz,1);
1035 mcIdType *retPtr(ret->getPointer());
1036 for(mcIdType i=0;i<nbNodes;i++)
1043 * Finds nodes not used in any cell and returns an array giving a new id to every node
1044 * by excluding the unused nodes, for which the array holds -1. The result array is
1045 * a mapping in "Old to New" mode.
1046 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
1047 * \return DataArrayIdType * - a new instance of DataArrayIdType. Its length is \a
1048 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
1049 * if the node is unused or a new id else. The caller is to delete this
1050 * array using decrRef() as it is no more needed.
1051 * \throw If the coordinates array is not set.
1052 * \throw If the nodal connectivity of cells is not defined.
1053 * \throw If the nodal connectivity includes an invalid id.
1054 * \sa MEDCoupling1SGTUMesh::computeFetchedNodeIds, areAllNodesFetched
1056 DataArrayIdType *MEDCoupling1SGTUMesh::getNodeIdsInUse(mcIdType& nbrOfNodesInUse) const
1059 mcIdType nbOfNodes=getNumberOfNodes();
1060 mcIdType nbOfCells=getNumberOfCells();
1061 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
1062 ret->alloc(nbOfNodes,1);
1063 mcIdType *traducer=ret->getPointer();
1064 std::fill(traducer,traducer+nbOfNodes,-1);
1065 const mcIdType *conn=_conn->begin();
1066 mcIdType nbNodesPerCell=getNumberOfNodesPerCell();
1067 for(mcIdType i=0;i<nbOfCells;i++)
1068 for(int j=0;j<nbNodesPerCell;j++,conn++)
1069 if(*conn>=0 && *conn<nbOfNodes)
1073 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << conn[j] << " not in [0," << nbOfNodes << ") !";
1074 throw INTERP_KERNEL::Exception(oss.str().c_str());
1076 nbrOfNodesInUse=ToIdType(std::count(traducer,traducer+nbOfNodes,1));
1077 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
1082 * This method renumbers only nodal connectivity in \a this. The renumbering is only an offset applied. So this method is a specialization of
1083 * \a renumberNodesInConn. \b WARNING, this method does not check that the resulting node ids in the nodal connectivity is in a valid range !
1085 * \param [in] offset - specifies the offset to be applied on each element of connectivity.
1087 * \sa renumberNodesInConn
1089 void MEDCoupling1SGTUMesh::renumberNodesWithOffsetInConn(mcIdType offset)
1091 getNumberOfCells();//only to check that all is well defined.
1092 _conn->applyLin(1,offset);
1097 * Same than renumberNodesInConn(const mcIdType *) except that here the format of old-to-new traducer is using map instead
1098 * 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
1101 void MEDCoupling1SGTUMesh::renumberNodesInConn(const INTERP_KERNEL::HashMap<mcIdType,mcIdType>& newNodeNumbersO2N)
1103 this->renumberNodesInConnT< INTERP_KERNEL::HashMap<mcIdType,mcIdType> >(newNodeNumbersO2N);
1107 * Same than renumberNodesInConn(const mcIdType *) except that here the format of old-to-new traducer is using map instead
1108 * 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
1111 void MEDCoupling1SGTUMesh::renumberNodesInConn(const std::map<mcIdType,mcIdType>& newNodeNumbersO2N)
1113 this->renumberNodesInConnT< std::map<mcIdType,mcIdType> >(newNodeNumbersO2N);
1117 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
1118 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
1119 * This method is a generalization of shiftNodeNumbersInConn().
1120 * \warning This method performs no check of validity of new ids. **Use it with care !**
1121 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
1122 * this->getNumberOfNodes(), in "Old to New" mode.
1123 * See \ref numbering for more info on renumbering modes.
1124 * \throw If the nodal connectivity of cells is not defined.
1126 void MEDCoupling1SGTUMesh::renumberNodesInConn(const mcIdType *newNodeNumbersO2N)
1128 getNumberOfCells();//only to check that all is well defined.
1129 _conn->transformWithIndArr(newNodeNumbersO2N,newNodeNumbersO2N+getNumberOfNodes());
1133 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2)
1135 std::vector<const MEDCoupling1SGTUMesh *> tmp(2);
1136 tmp[0]=const_cast<MEDCoupling1SGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1SGTUMesh *>(mesh2);
1137 return Merge1SGTUMeshes(tmp);
1140 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(std::vector<const MEDCoupling1SGTUMesh *>& a)
1142 std::size_t sz=a.size();
1144 return Merge1SGTUMeshesLL(a);
1145 for(std::size_t ii=0;ii<sz;ii++)
1148 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::Merge1SGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
1149 throw INTERP_KERNEL::Exception(oss.str().c_str());
1151 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
1152 for(std::size_t ii=0;ii<sz;ii++)
1153 if(&(a[ii]->getCellModel())!=cm)
1154 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : all items must have the same geo type !");
1155 std::vector< MCAuto<MEDCoupling1SGTUMesh> > bb(sz);
1156 std::vector< const MEDCoupling1SGTUMesh * > aa(sz);
1157 std::size_t spaceDimUndef=-3, spaceDim=spaceDimUndef;
1158 for(std::size_t i=0;i<sz && spaceDim==spaceDimUndef;i++)
1160 const MEDCoupling1SGTUMesh *cur=a[i];
1161 const DataArrayDouble *coo=cur->getCoords();
1163 spaceDim=coo->getNumberOfComponents();
1165 if(spaceDim==spaceDimUndef)
1166 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : no spaceDim specified ! unable to perform merge !");
1167 for(std::size_t i=0;i<sz;i++)
1169 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
1172 return Merge1SGTUMeshesLL(aa);
1176 * \throw If presence of a null instance in the input vector \a a.
1177 * \throw If a is empty
1179 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::vector<const MEDCoupling1SGTUMesh *>& a)
1182 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : input array must be NON EMPTY !");
1183 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1185 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : null instance in the first element of input vector !");
1186 std::vector<const DataArrayIdType *> ncs(a.size());
1187 (*it)->getNumberOfCells();//to check that all is OK
1188 const DataArrayDouble *coords=(*it)->getCoords();
1189 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1190 ncs[0]=(*it)->getNodalConnectivity();
1192 for(int i=1;it!=a.end();i++,it++)
1195 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : presence of a null instance in the input vector !");
1196 if(cm!=&((*it)->getCellModel()))
1197 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1198 (*it)->getNumberOfCells();//to check that all is OK
1199 ncs[i]=(*it)->getNodalConnectivity();
1200 if(coords!=(*it)->getCoords())
1201 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : not lying on same coords !");
1203 MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1204 ret->setCoords(coords);
1205 ret->_conn=DataArrayIdType::Aggregate(ncs);
1210 * 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)
1212 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector<const MEDCoupling1SGTUMesh *>& a)
1215 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : input array must be NON EMPTY !");
1216 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1217 mcIdType nbOfCells=(*it)->getNumberOfCells();
1218 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1219 mcIdType nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
1221 for(;it!=a.end();it++)
1223 if(cm!=&((*it)->getCellModel()))
1224 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1225 nbOfCells+=(*it)->getNumberOfCells();
1227 std::vector<const MEDCouplingPointSet *> aps(a.size());
1228 std::copy(a.begin(),a.end(),aps.begin());
1229 MCAuto<DataArrayDouble> pts=MergeNodesArray(aps);
1230 MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1231 ret->setCoords(pts);
1232 MCAuto<DataArrayIdType> c=DataArrayIdType::New();
1233 c->alloc(nbOfCells*nbNodesPerCell,1);
1234 mcIdType *cPtr=c->getPointer();
1236 for(it=a.begin();it!=a.end();it++)
1238 mcIdType curConnLgth=(*it)->getNodalConnectivityLength();
1239 const mcIdType *curC=(*it)->_conn->begin();
1240 cPtr=std::transform(curC,curC+curConnLgth,cPtr,std::bind(std::plus<mcIdType>(),std::placeholders::_1,offset));
1241 offset+=(*it)->getNumberOfNodes();
1244 ret->setNodalConnectivity(c);
1248 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const mcIdType *begin, const mcIdType *end) const
1250 mcIdType ncell=getNumberOfCells();
1251 MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1252 ret->setCoords(_coords);
1253 std::size_t nbOfElemsRet=std::distance(begin,end);
1254 const mcIdType *inConn=_conn->getConstPointer();
1255 mcIdType sz=getNumberOfNodesPerCell();
1256 MCAuto<DataArrayIdType> connRet=DataArrayIdType::New(); connRet->alloc(nbOfElemsRet*sz,1);
1257 mcIdType *connPtr=connRet->getPointer();
1258 for(const mcIdType *work=begin;work!=end;work++,connPtr+=sz)
1260 if(*work>=0 && *work<ncell)
1261 std::copy(inConn+(work[0])*sz,inConn+(work[0]+1)*sz,connPtr);
1264 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !";
1265 throw INTERP_KERNEL::Exception(oss.str().c_str());
1269 ret->copyTinyInfoFrom(this);
1273 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoordsSlice(mcIdType start, mcIdType end, mcIdType step) const
1275 mcIdType ncell=getNumberOfCells();
1276 mcIdType nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoordsSlice : ");
1277 MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1278 ret->setCoords(_coords);
1279 const mcIdType *inConn=_conn->getConstPointer();
1280 mcIdType sz=getNumberOfNodesPerCell();
1281 MCAuto<DataArrayIdType> connRet=DataArrayIdType::New(); connRet->alloc(nbOfElemsRet*sz,1);
1282 mcIdType *connPtr=connRet->getPointer();
1283 mcIdType curId=start;
1284 for(mcIdType i=0;i<nbOfElemsRet;i++,connPtr+=sz,curId+=step)
1286 if(curId>=0 && curId<ncell)
1287 std::copy(inConn+curId*sz,inConn+(curId+1)*sz,connPtr);
1290 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoordsSlice : On pos #" << i << " input cell id =" << curId << " should be in [0," << ncell << ") !";
1291 throw INTERP_KERNEL::Exception(oss.str().c_str());
1295 ret->copyTinyInfoFrom(this);
1299 void MEDCoupling1SGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
1301 mcIdType sz(ToIdType(nodeIdsInUse.size()));
1302 for(const mcIdType *conn=_conn->begin();conn!=_conn->end();conn++)
1304 if(*conn>=0 && *conn<sz)
1305 nodeIdsInUse[*conn]=true;
1308 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeFetchedNodeIds : At pos #" << std::distance(_conn->begin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !";
1309 throw INTERP_KERNEL::Exception(oss.str().c_str());
1314 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(std::size_t spaceDim) const
1316 MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1317 MCAuto<DataArrayIdType> tmp1;
1318 const DataArrayIdType *nodalConn(_conn);
1321 tmp1=DataArrayIdType::New(); tmp1->alloc(0,1);
1328 MCAuto<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
1329 ret->setCoords(coords);
1332 ret->setCoords(_coords);
1336 DataArrayIdType *MEDCoupling1SGTUMesh::simplexizePol0()
1338 mcIdType nbOfCells=getNumberOfCells();
1339 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1340 return DataArrayIdType::Range(0,nbOfCells,1);
1341 MCAuto<DataArrayIdType> newConn=DataArrayIdType::New(); newConn->alloc(2*3*nbOfCells,1);
1342 MCAuto<DataArrayIdType> ret=DataArrayIdType::New(); ret->alloc(2*nbOfCells,1);
1343 const mcIdType *c(_conn->begin());
1344 mcIdType *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1345 for(mcIdType i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1347 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[2];
1348 newConnPtr[3]=c[0]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1349 retPtr[0]=i; retPtr[1]=i;
1352 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1357 DataArrayIdType *MEDCoupling1SGTUMesh::simplexizePol1()
1359 mcIdType nbOfCells=getNumberOfCells();
1360 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1361 return DataArrayIdType::Range(0,nbOfCells,1);
1362 MCAuto<DataArrayIdType> newConn=DataArrayIdType::New(); newConn->alloc(2*3*nbOfCells,1);
1363 MCAuto<DataArrayIdType> ret=DataArrayIdType::New(); ret->alloc(2*nbOfCells,1);
1364 const mcIdType *c(_conn->begin());
1365 mcIdType *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1366 for(mcIdType i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1368 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[3];
1369 newConnPtr[3]=c[1]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1370 retPtr[0]=i; retPtr[1]=i;
1373 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1378 DataArrayIdType *MEDCoupling1SGTUMesh::simplexizePlanarFace5()
1380 mcIdType nbOfCells=getNumberOfCells();
1381 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1382 return DataArrayIdType::Range(0,nbOfCells,1);
1383 MCAuto<DataArrayIdType> newConn=DataArrayIdType::New(); newConn->alloc(5*4*nbOfCells,1);
1384 MCAuto<DataArrayIdType> ret=DataArrayIdType::New(); ret->alloc(5*nbOfCells,1);
1385 const mcIdType *c(_conn->begin());
1386 mcIdType *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1387 for(mcIdType i=0;i<nbOfCells;i++,c+=8,newConnPtr+=20,retPtr+=5)
1389 for(int j=0;j<20;j++)
1390 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_5_WO[j]];
1391 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i;
1394 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1399 DataArrayIdType *MEDCoupling1SGTUMesh::simplexizePlanarFace6()
1401 mcIdType nbOfCells=getNumberOfCells();
1402 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1403 return DataArrayIdType::Range(0,nbOfCells,1);
1404 MCAuto<DataArrayIdType> newConn=DataArrayIdType::New(); newConn->alloc(6*4*nbOfCells,1);
1405 MCAuto<DataArrayIdType> ret=DataArrayIdType::New(); ret->alloc(6*nbOfCells,1);
1406 const mcIdType *c(_conn->begin());
1407 mcIdType *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1408 for(mcIdType i=0;i<nbOfCells;i++,c+=8,newConnPtr+=24,retPtr+=6)
1410 for(int j=0;j<24;j++)
1411 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_6_WO[j]];
1412 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i; retPtr[5]=i;
1415 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1420 void MEDCoupling1SGTUMesh::reprQuickOverview(std::ostream& stream) const
1422 stream << "MEDCoupling1SGTUMesh C++ instance at " << this << ". Type=";
1425 stream << "Not set";
1428 stream << _cm->getRepr() << ". Name : \"" << getName() << "\".";
1429 stream << " Mesh dimension : " << getMeshDimension() << ".";
1431 { stream << " No coordinates set !"; return ; }
1432 if(!_coords->isAllocated())
1433 { stream << " Coordinates set but not allocated !"; return ; }
1434 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
1435 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
1436 if(!(const DataArrayIdType *)_conn)
1437 { stream << std::endl << "Nodal connectivity NOT set !"; return ; }
1438 if(_conn->isAllocated())
1440 if(_conn->getNumberOfComponents()==1)
1441 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
1445 void MEDCoupling1SGTUMesh::checkFullyDefined() const
1447 if(!((const DataArrayIdType *)_conn) || !((const DataArrayDouble *)_coords))
1448 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFullyDefined : part of this is not fully defined.");
1452 * First step of unserialization process.
1454 bool MEDCoupling1SGTUMesh::isEmptyMesh(const std::vector<mcIdType>& tinyInfo) const
1456 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEmptyMesh : not implemented yet !");
1459 void MEDCoupling1SGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<mcIdType>& tinyInfo, std::vector<std::string>& littleStrings) const
1462 double time=getTime(it,order);
1463 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
1465 littleStrings.push_back(getName());
1466 littleStrings.push_back(getDescription());
1467 littleStrings.push_back(getTimeUnit());
1469 std::vector<std::string> littleStrings2,littleStrings3;
1470 if((const DataArrayDouble *)_coords)
1471 _coords->getTinySerializationStrInformation(littleStrings2);
1472 if((const DataArrayIdType *)_conn)
1473 _conn->getTinySerializationStrInformation(littleStrings3);
1474 mcIdType sz0(ToIdType(littleStrings2.size())),sz1(ToIdType(littleStrings3.size()));
1475 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
1476 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
1478 tinyInfo.push_back(getCellModelEnum());
1479 tinyInfo.push_back(it);
1480 tinyInfo.push_back(order);
1481 std::vector<mcIdType> tinyInfo2,tinyInfo3;
1482 if((const DataArrayDouble *)_coords)
1483 _coords->getTinySerializationIntInformation(tinyInfo2);
1484 if((const DataArrayIdType *)_conn)
1485 _conn->getTinySerializationIntInformation(tinyInfo3);
1486 mcIdType sz2(ToIdType(tinyInfo2.size())),sz3(ToIdType(tinyInfo3.size()));
1487 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3);
1488 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1489 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
1491 tinyInfoD.push_back(time);
1494 void MEDCoupling1SGTUMesh::resizeForUnserialization(const std::vector<mcIdType>& tinyInfo, DataArrayIdType *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
1496 std::vector<mcIdType> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+tinyInfo[5]);
1497 std::vector<mcIdType> tinyInfo1(tinyInfo.begin()+7+tinyInfo[5],tinyInfo.begin()+7+tinyInfo[5]+tinyInfo[6]);
1498 a1->resizeForUnserialization(tinyInfo1);
1499 a2->resizeForUnserialization(tinyInfo2);
1502 void MEDCoupling1SGTUMesh::serialize(DataArrayIdType *&a1, DataArrayDouble *&a2) const
1505 if((const DataArrayIdType *)_conn)
1506 if(_conn->isAllocated())
1507 sz=_conn->getNbOfElems();
1508 a1=DataArrayIdType::New();
1510 if(sz!=0 && (const DataArrayIdType *)_conn)
1511 std::copy(_conn->begin(),_conn->end(),a1->getPointer());
1513 if((const DataArrayDouble *)_coords)
1514 if(_coords->isAllocated())
1515 sz=_coords->getNbOfElems();
1516 a2=DataArrayDouble::New();
1518 if(sz!=0 && (const DataArrayDouble *)_coords)
1519 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
1522 void MEDCoupling1SGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<mcIdType>& tinyInfo, const DataArrayIdType *a1, DataArrayDouble *a2,
1523 const std::vector<std::string>& littleStrings)
1525 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
1526 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
1527 setName(littleStrings[0]);
1528 setDescription(littleStrings[1]);
1529 setTimeUnit(littleStrings[2]);
1530 setTime(tinyInfoD[0],FromIdType<int>(tinyInfo[1]),FromIdType<int>(tinyInfo[2]));
1531 mcIdType sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]);
1533 _coords=DataArrayDouble::New();
1534 std::vector<mcIdType> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+sz2);
1535 _coords->resizeForUnserialization(tinyInfo2);
1536 std::copy(a2->begin(),a2->end(),_coords->getPointer());
1537 _conn=DataArrayIdType::New();
1538 std::vector<mcIdType> tinyInfo3(tinyInfo.begin()+7+sz2,tinyInfo.begin()+7+sz2+sz3);
1539 _conn->resizeForUnserialization(tinyInfo3);
1540 std::copy(a1->begin(),a1->end(),_conn->getPointer());
1541 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
1542 _coords->finishUnserialization(tinyInfo2,littleStrings2);
1543 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
1544 _conn->finishUnserialization(tinyInfo3,littleStrings3);
1548 * Checks if \a this and \a other meshes are geometrically equivalent with high
1549 * probability, else an exception is thrown. The meshes are considered equivalent if
1550 * (1) meshes contain the same number of nodes and the same number of elements of the
1551 * same types (2) three cells of the two meshes (first, last and middle) are based
1552 * on coincident nodes (with a specified precision).
1553 * \param [in] other - the mesh to compare with.
1554 * \param [in] prec - the precision used to compare nodes of the two meshes.
1555 * \throw If the two meshes do not match.
1557 void MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
1559 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1560 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1562 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single static geometric type !");
1563 const DataArrayIdType *c1(_conn),*c2(otherC->_conn);
1567 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1568 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1569 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1570 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1571 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1572 if(c1->getHashCode()!=c2->getHashCode())
1573 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1576 MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
1579 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
1580 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1582 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
1583 std::vector<const MEDCoupling1SGTUMesh *> ms(2);
1586 return Merge1SGTUMeshesOnSameCoords(ms);
1589 void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayIdType *revNodal, DataArrayIdType *revNodalIndx) const
1591 checkFullyDefined();
1592 mcIdType nbOfNodes=getNumberOfNodes();
1593 mcIdType *revNodalIndxPtr=(mcIdType *)malloc((nbOfNodes+1)*sizeof(mcIdType));
1594 revNodalIndx->useArray(revNodalIndxPtr,true,DeallocType::C_DEALLOC,nbOfNodes+1,1);
1595 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
1596 const mcIdType *conn=_conn->begin();
1597 mcIdType nbOfCells=getNumberOfCells();
1598 mcIdType nbOfEltsInRevNodal=0;
1599 mcIdType nbOfNodesPerCell=getNumberOfNodesPerCell();
1600 for(mcIdType eltId=0;eltId<nbOfCells;eltId++)
1602 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1604 if(conn[0]>=0 && conn[0]<nbOfNodes)
1606 nbOfEltsInRevNodal++;
1607 revNodalIndxPtr[conn[0]+1]++;
1611 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
1612 throw INTERP_KERNEL::Exception(oss.str().c_str());
1616 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<mcIdType>());
1617 conn=_conn->begin();
1618 mcIdType *revNodalPtr=(mcIdType *)malloc(nbOfEltsInRevNodal*sizeof(mcIdType));
1619 revNodal->useArray(revNodalPtr,true,DeallocType::C_DEALLOC,nbOfEltsInRevNodal,1);
1620 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
1621 for(mcIdType eltId=0;eltId<nbOfCells;eltId++)
1623 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1625 *std::find_if(revNodalPtr+revNodalIndxPtr[*conn],revNodalPtr+revNodalIndxPtr[*conn+1],std::bind(std::equal_to<mcIdType>(),std::placeholders::_1,-1))=eltId;
1631 * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null.
1633 void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayIdType *nodalConn)
1636 nodalConn->incrRef();
1642 * \return DataArrayIdType * - the internal reference to the nodal connectivity. The caller is not responsible to deallocate it.
1644 DataArrayIdType *MEDCoupling1SGTUMesh::getNodalConnectivity() const
1646 const DataArrayIdType *ret(_conn);
1647 return const_cast<DataArrayIdType *>(ret);
1651 * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted,
1652 * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter.
1653 * If a nodal connectivity previously existed before the call of this method, it will be reset.
1655 * \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain.
1657 void MEDCoupling1SGTUMesh::allocateCells(mcIdType nbOfCells)
1660 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !");
1661 _conn=DataArrayIdType::New();
1662 _conn->reserve(getNumberOfNodesPerCell()*nbOfCells);
1667 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
1669 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
1670 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
1671 * \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
1672 * attached to \a this.
1673 * \throw If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
1675 void MEDCoupling1SGTUMesh::insertNextCell(const mcIdType *nodalConnOfCellBg, const mcIdType *nodalConnOfCellEnd)
1677 mcIdType sz=ToIdType(std::distance(nodalConnOfCellBg,nodalConnOfCellEnd));
1678 mcIdType ref=getNumberOfNodesPerCell();
1681 DataArrayIdType *c(_conn);
1683 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
1685 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !");
1689 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this (";
1690 oss << ref << ") !";
1691 throw INTERP_KERNEL::Exception(oss.str().c_str());
1696 * This method builds the dual mesh of \a this and returns it.
1698 * \return MEDCoupling1SGTUMesh * - newly object created to be managed by the caller.
1699 * \throw If \a this is not a mesh containing only simplex cells.
1700 * \throw If \a this is not correctly allocated (coordinates and connectivities have to be correctly set !).
1701 * \throw If at least one node in \a this is orphan (without any simplex cell lying on it !)
1703 MEDCoupling1GTUMesh *MEDCoupling1SGTUMesh::computeDualMesh() const
1705 const INTERP_KERNEL::CellModel& cm(getCellModel());
1707 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : this mesh is not a simplex mesh ! Please invoke simplexize of tetrahedrize on this before calling this method !");
1708 switch(getMeshDimension())
1711 return computeDualMesh3D();
1713 return computeDualMesh2D();
1715 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : meshdimension must be in [2,3] !");
1720 * This method explode each NORM_HEXA8 cells in \a this into 6 NORM_QUAD4 cells and put the result into the MEDCoupling1SGTUMesh returned instance.
1722 * \return MEDCoupling1SGTUMesh * - a newly allocated instances (to be managed by the caller) storing the result of the explosion.
1723 * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
1724 * \throw If \a this is not properly allocated.
1726 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4() const
1728 const INTERP_KERNEL::CellModel& cm(getCellModel());
1729 if(cm.getEnum()!=INTERP_KERNEL::NORM_HEXA8)
1730 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4 : this method can be applied only on HEXA8 mesh !");
1731 mcIdType nbHexa8=getNumberOfCells();
1732 const mcIdType *inConnPtr(getNodalConnectivity()->begin());
1733 MCAuto<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(getName(),INTERP_KERNEL::NORM_QUAD4));
1734 MCAuto<DataArrayIdType> c(DataArrayIdType::New()); c->alloc(nbHexa8*6*4,1);
1735 mcIdType *cPtr(c->getPointer());
1736 for(mcIdType i=0;i<nbHexa8;i++,inConnPtr+=8)
1738 for(int j=0;j<6;j++,cPtr+=4)
1739 cm.fillSonCellNodalConnectivity(j,inConnPtr,cPtr);
1741 ret->setCoords(getCoords());
1742 ret->setNodalConnectivity(c);
1747 * This method starts from an unstructured mesh that hides in reality a cartesian mesh.
1748 * If it is not the case, an exception will be thrown.
1749 * This method returns three objects : The cartesian mesh geometrically equivalent to \a this (within a precision of \a eps) and a permutation of cells
1750 * and a permutation of nodes.
1752 * - this[cellPerm[i]]=ret[i]
1754 * \param [out] cellPerm the permutation array of size \c this->getNumberOfCells()
1755 * \param [out] nodePerm the permutation array of size \c this->getNumberOfNodes()
1756 * \return MEDCouplingCMesh * - a newly allocated mesh that is the result of the structurization of \a this.
1758 MEDCouplingCMesh *MEDCoupling1SGTUMesh::structurizeMe(DataArrayIdType *& cellPerm, DataArrayIdType *& nodePerm, double eps) const
1760 checkConsistencyLight();
1761 int spaceDim(getSpaceDimension()),meshDim(getMeshDimension()); mcIdType nbNodes(getNumberOfNodes());
1762 if(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim)!=getCellModelEnum())
1763 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::structurizeMe : the unique geo type in this is not compatible with the geometric type regarding mesh dimension !");
1764 MCAuto<MEDCouplingCMesh> cm(MEDCouplingCMesh::New());
1765 for(int i=0;i<spaceDim;i++)
1767 std::vector<std::size_t> tmp(1,i);
1768 MCAuto<DataArrayDouble> elt(static_cast<DataArrayDouble*>(getCoords()->keepSelectedComponents(tmp)));
1769 elt=elt->getDifferentValues(eps);
1771 cm->setCoordsAt(i,elt);
1773 if(nbNodes!=cm->getNumberOfNodes())
1774 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 ?");
1776 { cm->copyTinyInfoFrom(this); }
1777 catch(INTERP_KERNEL::Exception&) { }
1778 MCAuto<MEDCouplingUMesh> um(cm->buildUnstructured()),self(buildUnstructured());
1779 self->checkGeoEquivalWith(um,12,eps,cellPerm,nodePerm);
1785 bool UpdateHexa8Cell(int validAxis, mcIdType neighId, const mcIdType *validConnQuad4NeighSide, mcIdType *allFacesNodalConn, mcIdType *myNeighbours)
1787 static const int TAB[48]={
1795 static const int TAB2[6]={0,0,3,3,3,3};
1796 if(myNeighbours[validAxis]==neighId && allFacesNodalConn[4*validAxis+0]==validConnQuad4NeighSide[TAB2[validAxis]])
1798 mcIdType oldAxis(ToIdType(std::distance(myNeighbours,std::find(myNeighbours,myNeighbours+6,neighId))));
1799 std::size_t pos(std::distance(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,std::find(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS+6,oldAxis)));
1800 std::size_t pos0(pos/2),pos1(pos%2);
1801 int oldAxisOpp(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[2*pos0+(pos1+1)%2]);
1802 mcIdType oldConn[8],myConn2[8]={-1,-1,-1,-1,-1,-1,-1,-1},myConn[8],edgeConn[2],allFacesTmp[24],neighTmp[6];
1803 oldConn[0]=allFacesNodalConn[0]; oldConn[1]=allFacesNodalConn[1]; oldConn[2]=allFacesNodalConn[2]; oldConn[3]=allFacesNodalConn[3];
1804 oldConn[4]=allFacesNodalConn[4]; oldConn[5]=allFacesNodalConn[7]; oldConn[6]=allFacesNodalConn[6]; oldConn[7]=allFacesNodalConn[5];
1805 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_HEXA8));
1806 for(int i=0;i<4;i++)
1807 myConn2[i]=validConnQuad4NeighSide[(4-i+TAB2[validAxis])%4];
1808 for(int i=0;i<4;i++)
1810 mcIdType nodeId(myConn2[i]);//the node id for which the opposite one will be found
1812 INTERP_KERNEL::NormalizedCellType typeOfSon;
1813 for(int j=0;j<12 && !found;j++)
1815 cm.fillSonEdgesNodalConnectivity3D(j,oldConn,-1,edgeConn,typeOfSon);
1816 if(edgeConn[0]==nodeId || edgeConn[1]==nodeId)
1818 if(std::find(allFacesNodalConn+4*oldAxisOpp,allFacesNodalConn+4*oldAxisOpp+4,edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0])!=allFacesNodalConn+4*oldAxisOpp+4)
1820 myConn2[i+4]=edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0];
1826 throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error !");
1828 const int *myTab(TAB+8*validAxis);
1829 for(int i=0;i<8;i++)
1830 myConn[i]=myConn2[myTab[i]];
1831 for(int i=0;i<6;i++)
1833 cm.fillSonCellNodalConnectivity(i,myConn,allFacesTmp+4*i);
1834 std::set<mcIdType> s(allFacesTmp+4*i,allFacesTmp+4*i+4);
1836 for(int j=0;j<6 && !found;j++)
1838 std::set<mcIdType> s1(allFacesNodalConn+4*j,allFacesNodalConn+4*j+4);
1841 neighTmp[i]=myNeighbours[j];
1846 throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error #2 !");
1848 std::copy(allFacesTmp,allFacesTmp+24,allFacesNodalConn);
1849 std::copy(neighTmp,neighTmp+6,myNeighbours);
1856 * 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
1857 * homogeneous. If it succeeds the result of MEDCouplingUMesh::tetrahedrize will return a conform mesh.
1859 * \return DataArrayIdType * - a newly allocated array (to be managed by the caller) containing renumbered cell ids.
1861 * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
1862 * \throw If \a this is not properly allocated.
1863 * \sa MEDCouplingUMesh::tetrahedrize, MEDCouplingUMesh::simplexize.
1865 DataArrayIdType *MEDCoupling1SGTUMesh::sortHexa8EachOther()
1867 MCAuto<MEDCoupling1SGTUMesh> quads(explodeEachHexa8To6Quad4());//checks that only hexa8
1868 mcIdType nbHexa8=getNumberOfCells();
1869 mcIdType *cQuads(quads->getNodalConnectivity()->getPointer());
1870 MCAuto<DataArrayIdType> neighOfQuads(DataArrayIdType::New()); neighOfQuads->alloc(nbHexa8*6,1); neighOfQuads->fillWithValue(-1);
1871 mcIdType *ptNeigh(neighOfQuads->getPointer());
1872 {//neighOfQuads tells for each face of each Quad8 which cell (if!=-1) is connected to this face.
1873 MCAuto<MEDCouplingUMesh> quadsTmp(quads->buildUnstructured());
1874 MCAuto<DataArrayIdType> ccSafe,cciSafe;
1875 DataArrayIdType *cc(0),*cci(0);
1876 quadsTmp->findCommonCells(3,0,cc,cci);
1877 ccSafe=cc; cciSafe=cci;
1878 const mcIdType *ccPtr(ccSafe->begin());
1879 mcIdType nbOfPair=cci->getNumberOfTuples()-1;
1880 for(mcIdType i=0;i<nbOfPair;i++)
1881 { ptNeigh[ccPtr[2*i+0]]=ccPtr[2*i+1]/6; ptNeigh[ccPtr[2*i+1]]=ccPtr[2*i+0]/6; }
1883 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(0,1);
1884 std::vector<bool> fetched(nbHexa8,false);
1885 std::vector<bool>::iterator it(std::find(fetched.begin(),fetched.end(),false));
1886 while(it!=fetched.end())//it will turns as time as number of connected zones
1888 mcIdType cellId(ToIdType(std::distance(fetched.begin(),it)));//it is the seed of the connected zone.
1889 std::set<mcIdType> s; s.insert(cellId);//s contains already organized.
1892 std::set<mcIdType> sNext;
1893 for(std::set<mcIdType>::const_iterator it0=s.begin();it0!=s.end();it0++)
1896 mcIdType *myNeighb(ptNeigh+6*(*it0));
1897 for(int i=0;i<6;i++)
1899 if(myNeighb[i]!=-1 && !fetched[myNeighb[i]])
1901 std::size_t pos(std::distance(HEXA8_FACE_PAIRS,std::find(HEXA8_FACE_PAIRS,HEXA8_FACE_PAIRS+6,i)));
1902 std::size_t pos0(pos/2),pos1(pos%2);
1903 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]))
1904 ret->pushBackSilent(myNeighb[i]);
1905 fetched[myNeighb[i]]=true;
1906 sNext.insert(myNeighb[i]);
1912 it=std::find(fetched.begin(),fetched.end(),false);
1916 mcIdType *conn(getNodalConnectivity()->getPointer());
1917 for(const mcIdType *pt=ret->begin();pt!=ret->end();pt++)
1919 mcIdType cellId(*pt);
1920 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];
1921 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];
1928 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh3D() const
1930 static const int DUAL_TETRA_0[36]={
1931 4,1,0, 6,0,3, 7,3,1,
1932 4,0,1, 5,2,0, 8,1,2,
1933 6,3,0, 5,0,2, 9,2,3,
1936 static const int DUAL_TETRA_1[36]={
1937 8,4,10, 11,5,8, 10,7,11,
1938 9,4,8, 8,5,12, 12,6,9,
1939 10,4,9, 9,6,13, 13,7,10,
1940 12,5,11, 13,6,12, 11,7,13
1942 static const int FACEID_NOT_SH_NODE[4]={2,3,1,0};
1943 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TETRA4)
1944 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh3D : only TETRA4 supported !");
1945 checkFullyDefined();
1946 MCAuto<MEDCouplingUMesh> thisu(buildUnstructured());
1947 MCAuto<DataArrayIdType> revNodArr(DataArrayIdType::New()),revNodIArr(DataArrayIdType::New());
1948 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1949 const mcIdType *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1950 MCAuto<DataArrayIdType> d1Arr(DataArrayIdType::New()),di1Arr(DataArrayIdType::New()),rd1Arr(DataArrayIdType::New()),rdi1Arr(DataArrayIdType::New());
1951 MCAuto<MEDCouplingUMesh> edges(thisu->explode3DMeshTo1D(d1Arr,di1Arr,rd1Arr,rdi1Arr));
1952 const mcIdType *d1(d1Arr->begin());
1953 MCAuto<DataArrayIdType> d2Arr(DataArrayIdType::New()),di2Arr(DataArrayIdType::New()),rd2Arr(DataArrayIdType::New()),rdi2Arr(DataArrayIdType::New());
1954 MCAuto<MEDCouplingUMesh> faces(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
1955 const mcIdType *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
1956 MCAuto<DataArrayDouble> edgesBaryArr(edges->computeCellCenterOfMass()),facesBaryArr(faces->computeCellCenterOfMass()),baryArr(computeCellCenterOfMass());
1957 const mcIdType nbOfNodes(getNumberOfNodes());
1958 const mcIdType offset0=nbOfNodes+faces->getNumberOfCells();
1959 const mcIdType offset1=offset0+edges->getNumberOfCells();
1961 std::vector<const DataArrayDouble *> v(4); v[0]=getCoords(); v[1]=facesBaryArr; v[2]=edgesBaryArr; v[3]=baryArr;
1962 MCAuto<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0; facesBaryArr=0;
1963 std::string name("DualOf_"); name+=getName();
1964 MCAuto<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYHED)); ret->setCoords(zeArr);
1965 MCAuto<DataArrayIdType> cArr(DataArrayIdType::New()),ciArr(DataArrayIdType::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1966 for(mcIdType i=0;i<nbOfNodes;i++,revNodI++)
1968 mcIdType nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1969 if(nbOfCellsSharingNode==0)
1971 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh3D : Node #" << i << " is orphan !";
1972 throw INTERP_KERNEL::Exception(oss.str().c_str());
1974 for(int j=0;j<nbOfCellsSharingNode;j++)
1976 mcIdType curCellId(revNod[revNodI[0]+j]);
1977 const mcIdType *connOfCurCell(nodal+4*curCellId);
1978 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1979 if(j!=0) cArr->pushBackSilent(-1);
1982 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;
1983 tmp[2]=curCellId+offset1; tmp[3]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+2]]+nbOfNodes;
1985 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;
1986 tmp[7]=curCellId+offset1; tmp[8]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+5]]+nbOfNodes;
1988 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;
1989 tmp[12]=curCellId+offset1; tmp[13]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+8]]+nbOfNodes;
1990 cArr->insertAtTheEnd(tmp,tmp+14);
1992 for(int k=0;k<4;k++)
1994 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1996 const mcIdType *faceId(d2+4*curCellId+k);
1997 if(rdi2[*faceId+1]-rdi2[*faceId]==1)
1999 mcIdType tmp2[5]; tmp2[0]=-1; tmp2[1]=i;
2000 tmp2[2]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+0]-8]+offset0;
2001 tmp2[3]=d2[4*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+1]-4]+nbOfNodes;
2002 tmp2[4]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+2]-8]+offset0;
2003 cArr->insertAtTheEnd(tmp2,tmp2+5);
2009 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
2011 ret->setNodalConnectivity(cArr,ciArr);
2015 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh2D() const
2017 static const int DUAL_TRI_0[6]={0,2, 1,0, 2,1};
2018 static const int DUAL_TRI_1[6]={-3,+5, +3,-4, +4,-5};
2019 static const int FACEID_NOT_SH_NODE[3]={1,2,0};
2020 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TRI3)
2021 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh2D : only TRI3 supported !");
2022 checkFullyDefined();
2023 MCAuto<MEDCouplingUMesh> thisu(buildUnstructured());
2024 MCAuto<DataArrayIdType> revNodArr(DataArrayIdType::New()),revNodIArr(DataArrayIdType::New());
2025 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
2026 const mcIdType *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
2027 MCAuto<DataArrayIdType> d2Arr(DataArrayIdType::New()),di2Arr(DataArrayIdType::New()),rd2Arr(DataArrayIdType::New()),rdi2Arr(DataArrayIdType::New());
2028 MCAuto<MEDCouplingUMesh> edges(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
2029 const mcIdType *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
2030 MCAuto<DataArrayDouble> edgesBaryArr(edges->computeCellCenterOfMass()),baryArr(computeCellCenterOfMass());
2031 const mcIdType nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+edges->getNumberOfCells());
2033 std::vector<const DataArrayDouble *> v(3); v[0]=getCoords(); v[1]=edgesBaryArr; v[2]=baryArr;
2034 MCAuto<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0;
2035 std::string name("DualOf_"); name+=getName();
2036 MCAuto<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYGON)); ret->setCoords(zeArr);
2037 MCAuto<DataArrayIdType> cArr(DataArrayIdType::New()),ciArr(DataArrayIdType::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
2038 for(mcIdType i=0;i<nbOfNodes;i++,revNodI++)
2040 mcIdType nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
2041 if(nbOfCellsSharingNode==0)
2043 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh2D : Node #" << i << " is orphan !";
2044 throw INTERP_KERNEL::Exception(oss.str().c_str());
2046 std::vector< std::vector<mcIdType> > polyg;
2047 for(int j=0;j<nbOfCellsSharingNode;j++)
2049 mcIdType curCellId(revNod[revNodI[0]+j]);
2050 const mcIdType *connOfCurCell(nodal+3*curCellId);
2051 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
2052 std::vector<mcIdType> locV(3);
2053 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;
2054 polyg.push_back(locV);
2056 for(int k=0;k<3;k++)
2058 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
2060 const mcIdType *edgeId(d2+3*curCellId+k);
2061 if(rdi2[*edgeId+1]-rdi2[*edgeId]==1)
2063 std::vector<mcIdType> locV2(2);
2064 int zeLocEdgeIdRel(DUAL_TRI_1[2*nodePosInCurCell+kk]);
2065 if(zeLocEdgeIdRel>0)
2066 { locV2[0]=d2[3*curCellId+zeLocEdgeIdRel-3]+nbOfNodes; locV2[1]=i; }
2068 { locV2[0]=i; locV2[1]=d2[3*curCellId-zeLocEdgeIdRel-3]+nbOfNodes; }
2069 polyg.push_back(locV2);
2075 std::vector<mcIdType> zePolyg(MEDCoupling1DGTUMesh::BuildAPolygonFromParts(polyg));
2076 cArr->insertAtTheEnd(zePolyg.begin(),zePolyg.end());
2077 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
2079 ret->setNodalConnectivity(cArr,ciArr);
2084 * This method aggregate the bbox of each cell and put it into bbox
2086 * \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)
2087 * For all other cases this input parameter is ignored.
2088 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
2090 * \throw If \a this is not fully set (coordinates and connectivity).
2091 * \throw If a cell in \a this has no valid nodeId.
2093 DataArrayDouble *MEDCoupling1SGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
2095 mcIdType spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()),nbOfNodesPerCell(getNumberOfNodesPerCell());
2096 MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
2097 double *bbox(ret->getPointer());
2098 for(mcIdType i=0;i<nbOfCells*spaceDim;i++)
2100 bbox[2*i]=std::numeric_limits<double>::max();
2101 bbox[2*i+1]=-std::numeric_limits<double>::max();
2103 const double *coordsPtr(_coords->getConstPointer());
2104 const mcIdType *conn(_conn->getConstPointer());
2105 for(mcIdType i=0;i<nbOfCells;i++)
2108 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
2110 mcIdType nodeId(*conn);
2111 if(nodeId>=0 && nodeId<nbOfNodes)
2113 for(int k=0;k<spaceDim;k++)
2115 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
2116 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
2123 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
2124 throw INTERP_KERNEL::Exception(oss.str().c_str());
2131 * 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.
2133 * \return a new instance of field containing the result. The returned instance has to be deallocated by the caller.
2135 MEDCouplingFieldDouble *MEDCoupling1SGTUMesh::computeDiameterField() const
2137 checkFullyDefined();
2138 MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME));
2139 mcIdType nbCells=getNumberOfCells();
2140 MCAuto<DataArrayDouble> arr(DataArrayDouble::New());
2141 arr->alloc(nbCells,1);
2142 INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::DiameterCalculator> dc(_cm->buildInstanceOfDiameterCalulator(getSpaceDimension()));
2143 dc->computeFor1SGTUMeshFrmt(nbCells,_conn->begin(),getCoords()->begin(),arr->getPointer());
2146 ret->setName("Diameter");
2151 * This method invert orientation of all cells in \a this.
2152 * After calling this method the absolute value of measure of cells in \a this are the same than before calling.
2153 * This method only operates on the connectivity so coordinates are not touched at all.
2155 void MEDCoupling1SGTUMesh::invertOrientationOfAllCells()
2157 checkConsistencyOfConnectivity();
2158 INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::OrientationInverter> oi(INTERP_KERNEL::OrientationInverter::BuildInstanceFrom(getCellModelEnum()));
2159 mcIdType nbOfNodesPerCell=ToIdType(_cm->getNumberOfNodes()),nbCells=getNumberOfCells();
2160 mcIdType *conn(_conn->getPointer());
2161 for(mcIdType i=0;i<nbCells;i++)
2162 oi->operate(conn+i*nbOfNodesPerCell,conn+(i+1)*nbOfNodesPerCell);
2168 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New()
2170 return new MEDCoupling1DGTUMesh;
2173 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
2175 if(type==INTERP_KERNEL::NORM_ERROR)
2176 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
2177 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
2180 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !";
2181 throw INTERP_KERNEL::Exception(oss.str().c_str());
2183 return new MEDCoupling1DGTUMesh(name,cm);
2186 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh()
2190 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
2194 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn_indx(other._conn_indx),_conn(other._conn)
2198 const DataArrayIdType *c(other._conn);
2200 _conn=c->deepCopy();
2203 _conn_indx=c->deepCopy();
2207 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const
2209 return new MEDCoupling1DGTUMesh(*this,recDeepCpy);
2213 * This method behaves mostly like MEDCoupling1DGTUMesh::deepCopy method, except that only nodal connectivity arrays are deeply copied.
2214 * The coordinates are shared between \a this and the returned instance.
2216 * \return MEDCoupling1DGTUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
2217 * \sa MEDCoupling1DGTUMesh::deepCopy
2219 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::deepCopyConnectivityOnly() const
2221 checkConsistencyLight();
2222 MCAuto<MEDCoupling1DGTUMesh> ret(clone(false));
2223 MCAuto<DataArrayIdType> c(_conn->deepCopy()),ci(_conn_indx->deepCopy());
2224 ret->setNodalConnectivity(c,ci);
2228 void MEDCoupling1DGTUMesh::updateTime() const
2230 MEDCoupling1GTUMesh::updateTime();
2231 const DataArrayIdType *c(_conn);
2239 std::size_t MEDCoupling1DGTUMesh::getHeapMemorySizeWithoutChildren() const
2241 return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren();
2244 std::vector<const BigMemoryObject *> MEDCoupling1DGTUMesh::getDirectChildrenWithNull() const
2246 std::vector<const BigMemoryObject *> ret(MEDCoupling1GTUMesh::getDirectChildrenWithNull());
2247 ret.push_back((const DataArrayIdType *)_conn);
2248 ret.push_back((const DataArrayIdType *)_conn_indx);
2252 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::deepCopy() const
2257 bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
2260 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !");
2261 std::ostringstream oss; oss.precision(15);
2262 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2265 reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !";
2268 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
2270 const DataArrayIdType *c1(_conn),*c2(otherC->_conn);
2275 reason="in connectivity of single dynamic geometric type exactly one among this and other is null !";
2278 if(!c1->isEqualIfNotWhy(*c2,reason))
2280 reason.insert(0,"Nodal connectivity DataArrayIdType differs : ");
2283 c1=_conn_indx; c2=otherC->_conn_indx;
2288 reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !";
2291 if(!c1->isEqualIfNotWhy(*c2,reason))
2293 reason.insert(0,"Nodal connectivity index DataArrayIdType differs : ");
2299 bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
2302 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
2303 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2306 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
2308 const DataArrayIdType *c1(_conn),*c2(otherC->_conn);
2313 if(!c1->isEqualWithoutConsideringStr(*c2))
2319 * Checks if \a this and \a other meshes are geometrically equivalent with high
2320 * probability, else an exception is thrown. The meshes are considered equivalent if
2321 * (1) meshes contain the same number of nodes and the same number of elements of the
2322 * same types (2) three cells of the two meshes (first, last and middle) are based
2323 * on coincident nodes (with a specified precision).
2324 * \param [in] other - the mesh to compare with.
2325 * \param [in] prec - the precision used to compare nodes of the two meshes.
2326 * \throw If the two meshes do not match.
2328 void MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
2330 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
2331 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2333 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single dynamic geometric type !");
2334 const DataArrayIdType *c1(_conn),*c2(otherC->_conn);
2338 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
2339 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2340 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
2341 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2342 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
2343 if(c1->getHashCode()!=c2->getHashCode())
2344 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs");
2346 c1=_conn_indx; c2=otherC->_conn_indx;
2350 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !");
2351 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2352 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !");
2353 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2354 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !");
2355 if(c1->getHashCode()!=c2->getHashCode())
2356 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs");
2360 void MEDCoupling1DGTUMesh::checkConsistencyOfConnectivity() const
2362 const DataArrayIdType *c1(_conn);
2365 if(c1->getNumberOfComponents()!=1)
2366 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
2367 if(c1->getInfoOnComponent(0)!="")
2368 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
2369 c1->checkAllocated();
2372 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
2374 mcIdType sz2(_conn->getNumberOfTuples());
2378 if(c1->getNumberOfComponents()!=1)
2379 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
2380 c1->checkAllocated();
2381 if(c1->getNumberOfTuples()<1)
2382 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !");
2383 if(c1->getInfoOnComponent(0)!="")
2384 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
2385 mcIdType f=c1->front(),ll=c1->back();
2386 if(f<0 || (sz2>0 && f>=sz2))
2388 std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !";
2389 throw INTERP_KERNEL::Exception(oss.str().c_str());
2393 std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !";
2394 throw INTERP_KERNEL::Exception(oss.str().c_str());
2398 std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !";
2399 throw INTERP_KERNEL::Exception(oss.str().c_str());
2403 throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !");
2404 mcIdType szOfC1Exp=_conn_indx->back();
2407 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() << " !";
2408 throw INTERP_KERNEL::Exception(oss.str().c_str());
2413 * 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.
2414 * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one.
2415 * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array.
2417 void MEDCoupling1DGTUMesh::checkConsistencyLight() const
2419 MEDCouplingPointSet::checkConsistencyLight();
2420 checkConsistencyOfConnectivity();
2423 void MEDCoupling1DGTUMesh::checkConsistency(double eps) const
2425 checkConsistencyLight();
2426 const DataArrayIdType *c1(_conn),*c2(_conn_indx);
2427 if(!c2->isMonotonic(true))
2428 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkConsistency : the nodal connectivity index is expected to be increasing monotinic !");
2430 mcIdType nbOfTuples(c1->getNumberOfTuples());
2431 mcIdType nbOfNodes=getNumberOfNodes();
2432 const mcIdType *w(c1->begin());
2433 for(mcIdType i=0;i<nbOfTuples;i++,w++)
2435 if(*w==-1) continue;
2436 if(*w<0 || *w>=nbOfNodes)
2438 std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !";
2439 throw INTERP_KERNEL::Exception(oss.str().c_str());
2444 mcIdType MEDCoupling1DGTUMesh::getNumberOfCells() const
2446 checkConsistencyOfConnectivity();//do not remove
2447 return _conn_indx->getNumberOfTuples()-1;
2451 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2452 * For each cell in \b this the number of nodes constituting cell is computed.
2453 * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned.
2454 * So for pohyhedrons some nodes can be counted several times in the returned result.
2456 * \return a newly allocated array
2458 DataArrayIdType *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const
2460 checkConsistencyLight();
2461 _conn_indx->checkMonotonic(true);
2462 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2463 return _conn_indx->deltaShiftIndex();
2465 mcIdType nbOfCells=_conn_indx->getNumberOfTuples()-1;
2466 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
2467 ret->alloc(nbOfCells,1);
2468 mcIdType *retPtr=ret->getPointer();
2469 const mcIdType *ci=_conn_indx->begin(),*c=_conn->begin();
2470 for(mcIdType i=0;i<nbOfCells;i++,retPtr++,ci++)
2471 *retPtr=int(ci[1]-ci[0]-ToIdType(std::count(c+ci[0],c+ci[1],-1)));
2476 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2477 * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed.
2479 * \return a newly allocated array
2481 DataArrayIdType *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const
2483 checkConsistencyLight();
2484 _conn_indx->checkMonotonic(true);
2485 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG)
2486 return _conn_indx->deltaShiftIndex();
2487 if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG)
2489 MCAuto<DataArrayIdType> ret=_conn_indx->deltaShiftIndex();
2490 ret->applyDivideBy(2);
2494 mcIdType nbOfCells=_conn_indx->getNumberOfTuples()-1;
2495 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
2496 ret->alloc(nbOfCells,1);
2497 mcIdType *retPtr=ret->getPointer();
2498 const mcIdType *ci=_conn_indx->begin(),*c=_conn->begin();
2499 for(mcIdType i=0;i<nbOfCells;i++,retPtr++,ci++)
2500 *retPtr=ToIdType(std::count(c+ci[0],c+ci[1],-1))+1;
2505 * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell,
2506 * will be counted only once here whereas it will be counted several times in MEDCoupling1DGTUMesh::computeNbOfNodesPerCell method.
2508 * \return DataArrayIdType * - new object to be deallocated by the caller.
2509 * \sa MEDCoupling1DGTUMesh::computeNbOfNodesPerCell
2511 DataArrayIdType *MEDCoupling1DGTUMesh::computeEffectiveNbOfNodesPerCell() const
2513 checkConsistencyLight();
2514 _conn_indx->checkMonotonic(true);
2515 mcIdType nbOfCells=_conn_indx->getNumberOfTuples()-1;
2516 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
2517 ret->alloc(nbOfCells,1);
2518 mcIdType *retPtr(ret->getPointer());
2519 const mcIdType *ci(_conn_indx->begin()),*c(_conn->begin());
2520 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2522 for(mcIdType i=0;i<nbOfCells;i++,retPtr++,ci++)
2524 std::set<mcIdType> s(c+ci[0],c+ci[1]);
2525 *retPtr=ToIdType(s.size());
2530 for(mcIdType i=0;i<nbOfCells;i++,retPtr++,ci++)
2532 std::set<mcIdType> s(c+ci[0],c+ci[1]); s.erase(-1);
2533 *retPtr=ToIdType(s.size());
2539 void MEDCoupling1DGTUMesh::getNodeIdsOfCell(mcIdType cellId, std::vector<mcIdType>& conn) const
2541 mcIdType nbOfCells(getNumberOfCells());//performs checks
2542 if(cellId<nbOfCells)
2544 mcIdType strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2545 mcIdType nbOfNodes=stp-strt;
2547 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !");
2548 conn.resize(nbOfNodes);
2549 std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin());
2553 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2554 throw INTERP_KERNEL::Exception(oss.str().c_str());
2558 mcIdType MEDCoupling1DGTUMesh::getNumberOfNodesInCell(mcIdType cellId) const
2560 mcIdType nbOfCells=getNumberOfCells();//performs checks
2561 if(cellId>=0 && cellId<nbOfCells)
2563 const mcIdType *conn(_conn->begin());
2564 mcIdType strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2565 return stp-strt-ToIdType(std::count(conn+strt,conn+stp,-1));
2569 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNumberOfNodesInCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2570 throw INTERP_KERNEL::Exception(oss.str().c_str());
2574 std::string MEDCoupling1DGTUMesh::simpleRepr() const
2576 static const char msg0[]="No coordinates specified !";
2578 return std::string("Cell type not specified");
2579 std::ostringstream ret;
2580 ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
2581 ret << "Description of mesh : \"" << getDescription() << "\"\n";
2583 double tt=getTime(tmpp1,tmpp2);
2584 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
2585 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
2586 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
2589 const int spaceDim=getSpaceDimension();
2590 ret << spaceDim << "\nInfo attached on space dimension : ";
2591 for(int i=0;i<spaceDim;i++)
2592 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
2596 ret << msg0 << "\n";
2597 ret << "Number of nodes : ";
2599 ret << getNumberOfNodes() << "\n";
2601 ret << msg0 << "\n";
2602 ret << "Number of cells : ";
2604 try { checkConsistencyLight(); } catch(INTERP_KERNEL::Exception& /* e */)
2606 ret << "Nodal connectivity arrays are not set or badly set !\n";
2610 ret << getNumberOfCells() << "\n";
2611 ret << "Cell type : " << _cm->getRepr() << "\n";
2615 std::string MEDCoupling1DGTUMesh::advancedRepr() const
2617 std::ostringstream ret;
2618 ret << simpleRepr();
2619 ret << "\nCoordinates array : \n___________________\n\n";
2621 _coords->reprWithoutNameStream(ret);
2623 ret << "No array set !\n";
2624 ret << "\n\nNodal Connectivity : \n____________________\n\n";
2627 try { checkConsistency(); } catch(INTERP_KERNEL::Exception& /* e */)
2629 ret << "Nodal connectivity arrays are not set or badly set !\n";
2634 mcIdType nbOfCells=getNumberOfCells();
2635 const mcIdType *ci=_conn_indx->begin(),*c=_conn->begin();
2636 for(mcIdType i=0;i<nbOfCells;i++,ci++)
2638 ret << "Cell #" << i << " : ";
2639 std::copy(c+ci[0],c+ci[1],std::ostream_iterator<int>(ret," "));
2645 DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const
2647 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2648 int spaceDim=getSpaceDimension();
2649 mcIdType nbOfCells=getNumberOfCells();//checkConsistencyLight()
2650 mcIdType nbOfNodes=getNumberOfNodes();
2651 ret->alloc(nbOfCells,spaceDim);
2652 double *ptToFill=ret->getPointer();
2653 const double *coor=_coords->begin();
2654 const mcIdType *nodal=_conn->begin(),*nodali=_conn_indx->begin();
2656 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2658 for(mcIdType i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2660 std::fill(ptToFill,ptToFill+spaceDim,0.);
2661 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2663 for(mcIdType j=nodali[0];j<nodali[1];j++,nodal++)
2665 if(*nodal>=0 && *nodal<nbOfNodes)
2666 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2669 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2670 throw INTERP_KERNEL::Exception(oss.str().c_str());
2672 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind(std::multiplies<double>(),std::placeholders::_1,1./double(nodali[1]-nodali[0])));
2677 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !";
2678 throw INTERP_KERNEL::Exception(oss.str().c_str());
2684 for(mcIdType i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2686 std::fill(ptToFill,ptToFill+spaceDim,0.);
2687 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2690 for(mcIdType j=nodali[0];j<nodali[1];j++,nodal++)
2692 if(*nodal==-1) continue;
2693 if(*nodal>=0 && *nodal<nbOfNodes)
2695 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2700 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2701 throw INTERP_KERNEL::Exception(oss.str().c_str());
2705 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind(std::multiplies<double>(),std::placeholders::_1,1./nbOfNod));
2708 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !";
2709 throw INTERP_KERNEL::Exception(oss.str().c_str());
2714 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : at cell #" << i << " the nodal index array is invalid !";
2715 throw INTERP_KERNEL::Exception(oss.str().c_str());
2722 void MEDCoupling1DGTUMesh::renumberCells(const mcIdType *old2NewBg, bool check)
2724 mcIdType nbCells=getNumberOfCells();
2725 MCAuto<DataArrayIdType> o2n=DataArrayIdType::New();
2726 o2n->useArray(old2NewBg,false,DeallocType::C_DEALLOC,nbCells,1);
2728 o2n=o2n->checkAndPreparePermutation();
2730 const mcIdType *o2nPtr=o2n->getPointer();
2731 const mcIdType *conn=_conn->begin(),*conni=_conn_indx->begin();
2732 MCAuto<DataArrayIdType> newConn=DataArrayIdType::New();
2733 MCAuto<DataArrayIdType> newConnI=DataArrayIdType::New();
2734 newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1);
2735 newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx);
2737 mcIdType *newC=newConn->getPointer(),*newCI=newConnI->getPointer();
2738 for(mcIdType i=0;i<nbCells;i++)
2740 mcIdType newPos=o2nPtr[i];
2741 mcIdType sz=conni[i+1]-conni[i];
2746 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !";
2747 throw INTERP_KERNEL::Exception(oss.str().c_str());
2750 newConnI->computeOffsetsFull(); newCI=newConnI->getPointer();
2752 for(mcIdType i=0;i<nbCells;i++,conni++)
2754 mcIdType newp=o2nPtr[i];
2755 std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]);
2758 _conn_indx=newConnI;
2761 MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
2763 if(other->getType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED)
2764 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !");
2765 const MEDCoupling1DGTUMesh *otherC=static_cast<const MEDCoupling1DGTUMesh *>(other);
2766 return Merge1DGTUMeshes(this,otherC);
2769 MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const
2771 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
2772 ret->setCoords(getCoords());
2773 const mcIdType *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin();
2774 mcIdType nbCells=getNumberOfCells();//checkConsistencyLight
2775 mcIdType geoType=ToIdType(getCellModelEnum());
2776 MCAuto<DataArrayIdType> c=DataArrayIdType::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1);
2777 MCAuto<DataArrayIdType> cI=DataArrayIdType::New(); cI->alloc(nbCells+1);
2778 mcIdType *cPtr=c->getPointer(),*ciPtr=cI->getPointer();
2780 for(mcIdType i=0;i<nbCells;i++,ciPtr++)
2782 mcIdType sz=nodalConnI[i+1]-nodalConnI[i];
2786 cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr);
2787 ciPtr[1]=ciPtr[0]+sz+1;
2791 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !";
2792 throw INTERP_KERNEL::Exception(oss.str().c_str());
2795 ret->setConnectivity(c,cI,true);
2797 { ret->copyTinyInfoFrom(this); }
2798 catch(INTERP_KERNEL::Exception&) { }
2803 * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes
2805 DataArrayIdType *MEDCoupling1DGTUMesh::simplexize(int policy)
2807 mcIdType nbOfCells=getNumberOfCells();
2808 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
2809 ret->alloc(nbOfCells,1);
2814 void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const
2816 stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=";
2819 stream << "Not defined";
2822 stream << _cm->getRepr() << ". Name : \"" << getName() << "\".";
2823 stream << " Mesh dimension : " << getMeshDimension() << ".";
2825 { stream << " No coordinates set !"; return ; }
2826 if(!_coords->isAllocated())
2827 { stream << " Coordinates set but not allocated !"; return ; }
2828 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
2829 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
2831 try { checkConsistencyLight(); } catch(INTERP_KERNEL::Exception& /* e */)
2833 stream << std::endl << "Nodal connectivity NOT set properly !\n";
2837 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
2840 void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
2843 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
2844 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2846 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !");
2847 setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex());
2850 MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
2853 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
2854 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2856 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
2857 std::vector<const MEDCoupling1DGTUMesh *> ms(2);
2860 return Merge1DGTUMeshesOnSameCoords(ms);
2863 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const mcIdType *begin, const mcIdType *end) const
2865 checkConsistencyLight();
2866 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2867 ret->setCoords(_coords);
2868 DataArrayIdType *c=0,*ci=0;
2869 DataArrayIdType::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci);
2870 MCAuto<DataArrayIdType> cSafe(c),ciSafe(ci);
2871 ret->setNodalConnectivity(c,ci);
2875 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoordsSlice(mcIdType start, mcIdType end, mcIdType step) const
2877 checkConsistencyLight();
2878 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2879 ret->setCoords(_coords);
2880 DataArrayIdType *c=0,*ci=0;
2881 DataArrayIdType::ExtractFromIndexedArraysSlice(start,end,step,_conn,_conn_indx,c,ci);
2882 MCAuto<DataArrayIdType> cSafe(c),ciSafe(ci);
2883 ret->setNodalConnectivity(c,ci);
2887 void MEDCoupling1DGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
2890 mcIdType sz(ToIdType(nodeIdsInUse.size()));
2891 for(const mcIdType *conn=_conn->begin();conn!=_conn->end();conn++)
2893 if(*conn>=0 && *conn<sz)
2894 nodeIdsInUse[*conn]=true;
2899 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeNodeIdsAlg : At pos #" << std::distance(_conn->begin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !";
2900 throw INTERP_KERNEL::Exception(oss.str().c_str());
2906 void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayIdType *revNodal, DataArrayIdType *revNodalIndx) const
2908 checkFullyDefined();
2909 mcIdType nbOfNodes=getNumberOfNodes();
2910 mcIdType *revNodalIndxPtr=(mcIdType *)malloc((nbOfNodes+1)*sizeof(mcIdType));
2911 revNodalIndx->useArray(revNodalIndxPtr,true,DeallocType::C_DEALLOC,nbOfNodes+1,1);
2912 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
2913 const mcIdType *conn=_conn->begin(),*conni=_conn_indx->begin();
2914 mcIdType nbOfCells=getNumberOfCells();
2915 mcIdType nbOfEltsInRevNodal=0;
2916 for(mcIdType eltId=0;eltId<nbOfCells;eltId++)
2918 mcIdType nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2919 if(nbOfNodesPerCell>=0)
2921 for(mcIdType j=0;j<nbOfNodesPerCell;j++)
2923 mcIdType nodeId=conn[conni[eltId]+j];
2924 if(nodeId==-1) continue;
2925 if(nodeId>=0 && nodeId<nbOfNodes)
2927 nbOfEltsInRevNodal++;
2928 revNodalIndxPtr[nodeId+1]++;
2932 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
2933 throw INTERP_KERNEL::Exception(oss.str().c_str());
2939 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << "nodal connectivity is invalid !";
2940 throw INTERP_KERNEL::Exception(oss.str().c_str());
2943 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<mcIdType>());
2944 conn=_conn->begin();
2945 mcIdType *revNodalPtr=(mcIdType *)malloc((nbOfEltsInRevNodal)*sizeof(mcIdType));
2946 revNodal->useArray(revNodalPtr,true,DeallocType::C_DEALLOC,nbOfEltsInRevNodal,1);
2947 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
2948 for(mcIdType eltId=0;eltId<nbOfCells;eltId++)
2950 mcIdType nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2951 for(mcIdType j=0;j<nbOfNodesPerCell;j++)
2953 mcIdType nodeId=conn[conni[eltId]+j];
2955 *std::find_if(revNodalPtr+revNodalIndxPtr[nodeId],revNodalPtr+revNodalIndxPtr[nodeId+1],std::bind(std::equal_to<mcIdType>(),std::placeholders::_1,-1))=eltId;
2960 void MEDCoupling1DGTUMesh::checkFullyDefined() const
2962 if(!((const DataArrayIdType *)_conn) || !((const DataArrayIdType *)_conn_indx) || !((const DataArrayDouble *)_coords))
2963 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined.");
2966 bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector<mcIdType>& tinyInfo) const
2968 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !");
2971 void MEDCoupling1DGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<mcIdType>& tinyInfo, std::vector<std::string>& littleStrings) const
2974 double time=getTime(it,order);
2975 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
2977 littleStrings.push_back(getName());
2978 littleStrings.push_back(getDescription());
2979 littleStrings.push_back(getTimeUnit());
2981 std::vector<std::string> littleStrings2,littleStrings3,littleStrings4;
2982 if((const DataArrayDouble *)_coords)
2983 _coords->getTinySerializationStrInformation(littleStrings2);
2984 if((const DataArrayIdType *)_conn)
2985 _conn->getTinySerializationStrInformation(littleStrings3);
2986 if((const DataArrayIdType *)_conn_indx)
2987 _conn_indx->getTinySerializationStrInformation(littleStrings4);
2988 mcIdType sz0(ToIdType(littleStrings2.size())),sz1(ToIdType(littleStrings3.size())),sz2(ToIdType(littleStrings4.size()));
2989 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
2990 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
2991 littleStrings.insert(littleStrings.end(),littleStrings4.begin(),littleStrings4.end());
2993 tinyInfo.push_back(getCellModelEnum());
2994 tinyInfo.push_back(it);
2995 tinyInfo.push_back(order);
2996 std::vector<mcIdType> tinyInfo2,tinyInfo3,tinyInfo4;
2997 if((const DataArrayDouble *)_coords)
2998 _coords->getTinySerializationIntInformation(tinyInfo2);
2999 if((const DataArrayIdType *)_conn)
3000 _conn->getTinySerializationIntInformation(tinyInfo3);
3001 if((const DataArrayIdType *)_conn_indx)
3002 _conn_indx->getTinySerializationIntInformation(tinyInfo4);
3003 mcIdType sz3(ToIdType(tinyInfo2.size())),sz4(ToIdType(tinyInfo3.size())),sz5(ToIdType(tinyInfo4.size()));
3004 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3); tinyInfo.push_back(sz4); tinyInfo.push_back(sz5);
3005 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
3006 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
3007 tinyInfo.insert(tinyInfo.end(),tinyInfo4.begin(),tinyInfo4.end());
3009 tinyInfoD.push_back(time);
3012 void MEDCoupling1DGTUMesh::resizeForUnserialization(const std::vector<mcIdType>& tinyInfo, DataArrayIdType *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
3014 std::vector<mcIdType> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+tinyInfo[6]);
3015 std::vector<mcIdType> tinyInfo1(tinyInfo.begin()+9+tinyInfo[6],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]);
3016 std::vector<mcIdType> tinyInfo12(tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]+tinyInfo[8]);
3017 MCAuto<DataArrayIdType> p1(DataArrayIdType::New()); p1->resizeForUnserialization(tinyInfo1);
3018 MCAuto<DataArrayIdType> p2(DataArrayIdType::New()); p2->resizeForUnserialization(tinyInfo12);
3019 std::vector<const DataArrayIdType *> v(2); v[0]=p1; v[1]=p2;
3020 p2=DataArrayIdType::Aggregate(v);
3021 a2->resizeForUnserialization(tinyInfo2);
3022 a1->alloc(p2->getNbOfElems(),1);
3025 void MEDCoupling1DGTUMesh::serialize(DataArrayIdType *&a1, DataArrayDouble *&a2) const
3028 if((const DataArrayIdType *)_conn)
3029 if(_conn->isAllocated())
3030 sz=_conn->getNbOfElems();
3031 if((const DataArrayIdType *)_conn_indx)
3032 if(_conn_indx->isAllocated())
3033 sz+=_conn_indx->getNbOfElems();
3034 a1=DataArrayIdType::New();
3036 mcIdType *work(a1->getPointer());
3037 if(sz!=0 && (const DataArrayIdType *)_conn)
3038 work=std::copy(_conn->begin(),_conn->end(),a1->getPointer());
3039 if(sz!=0 && (const DataArrayIdType *)_conn_indx)
3040 std::copy(_conn_indx->begin(),_conn_indx->end(),work);
3042 if((const DataArrayDouble *)_coords)
3043 if(_coords->isAllocated())
3044 sz=_coords->getNbOfElems();
3045 a2=DataArrayDouble::New();
3047 if(sz!=0 && (const DataArrayDouble *)_coords)
3048 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
3051 void MEDCoupling1DGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<mcIdType>& tinyInfo, const DataArrayIdType *a1, DataArrayDouble *a2,
3052 const std::vector<std::string>& littleStrings)
3054 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
3055 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
3056 setName(littleStrings[0]);
3057 setDescription(littleStrings[1]);
3058 setTimeUnit(littleStrings[2]);
3059 setTime(tinyInfoD[0],FromIdType<int>(tinyInfo[1]),FromIdType<int>(tinyInfo[2]));
3060 mcIdType sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]),sz4(tinyInfo[7]),sz5(tinyInfo[8]);
3062 _coords=DataArrayDouble::New();
3063 std::vector<mcIdType> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+sz3);
3064 _coords->resizeForUnserialization(tinyInfo2);
3065 std::copy(a2->begin(),a2->end(),_coords->getPointer());
3066 _conn=DataArrayIdType::New();
3067 std::vector<mcIdType> tinyInfo3(tinyInfo.begin()+9+sz3,tinyInfo.begin()+9+sz3+sz4);
3068 _conn->resizeForUnserialization(tinyInfo3);
3069 std::copy(a1->begin(),a1->begin()+_conn->getNbOfElems(),_conn->getPointer());
3070 _conn_indx=DataArrayIdType::New();
3071 std::vector<mcIdType> tinyInfo4(tinyInfo.begin()+9+sz3+sz4,tinyInfo.begin()+9+sz3+sz4+sz5);
3072 _conn_indx->resizeForUnserialization(tinyInfo4);
3073 std::copy(a1->begin()+_conn->getNbOfElems(),a1->end(),_conn_indx->getPointer());
3074 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
3075 _coords->finishUnserialization(tinyInfo2,littleStrings2);
3076 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
3077 _conn->finishUnserialization(tinyInfo3,littleStrings3);
3078 std::vector<std::string> littleStrings4(littleStrings.begin()+3+sz0+sz1,littleStrings.begin()+3+sz0+sz1+sz2);
3079 _conn_indx->finishUnserialization(tinyInfo4,littleStrings4);
3083 * Finds nodes not used in any cell and returns an array giving a new id to every node
3084 * by excluding the unused nodes, for which the array holds -1. The result array is
3085 * a mapping in "Old to New" mode.
3086 * \return DataArrayIdType * - a new instance of DataArrayIdType. Its length is \a
3087 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
3088 * if the node is unused or a new id else. The caller is to delete this
3089 * array using decrRef() as it is no more needed.
3090 * \throw If the coordinates array is not set.
3091 * \throw If the nodal connectivity of cells is not defined.
3092 * \throw If the nodal connectivity includes an invalid id.
3093 * \sa MEDCoupling1DGTUMesh::getNodeIdsInUse, areAllNodesFetched
3095 DataArrayIdType *MEDCoupling1DGTUMesh::computeFetchedNodeIds() const
3098 mcIdType nbNodes(getNumberOfNodes());
3099 std::vector<bool> fetchedNodes(nbNodes,false);
3100 computeNodeIdsAlg(fetchedNodes);
3101 mcIdType sz(ToIdType(std::count(fetchedNodes.begin(),fetchedNodes.end(),true)));
3102 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(sz,1);
3103 mcIdType *retPtr(ret->getPointer());
3104 for(mcIdType i=0;i<nbNodes;i++)
3111 * Finds nodes not used in any cell and returns an array giving a new id to every node
3112 * by excluding the unused nodes, for which the array holds -1. The result array is
3113 * a mapping in "Old to New" mode.
3114 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
3115 * \return DataArrayIdType * - a new instance of DataArrayIdType. Its length is \a
3116 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
3117 * if the node is unused or a new id else. The caller is to delete this
3118 * array using decrRef() as it is no more needed.
3119 * \throw If the coordinates array is not set.
3120 * \throw If the nodal connectivity of cells is not defined.
3121 * \throw If the nodal connectivity includes an invalid id.
3122 * \sa MEDCoupling1DGTUMesh::computeFetchedNodeIds, areAllNodesFetched
3124 DataArrayIdType *MEDCoupling1DGTUMesh::getNodeIdsInUse(mcIdType& nbrOfNodesInUse) const
3127 mcIdType nbOfNodes=getNumberOfNodes();
3128 mcIdType nbOfCells=getNumberOfCells();//checkConsistencyLight
3129 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
3130 ret->alloc(nbOfNodes,1);
3131 mcIdType *traducer=ret->getPointer();
3132 std::fill(traducer,traducer+nbOfNodes,-1);
3133 const mcIdType *conn=_conn->begin(),*conni(_conn_indx->begin());
3134 for(mcIdType i=0;i<nbOfCells;i++,conni++)
3136 mcIdType nbNodesPerCell=conni[1]-conni[0];
3137 for(mcIdType j=0;j<nbNodesPerCell;j++)
3139 mcIdType nodeId=conn[conni[0]+j];
3140 if(nodeId==-1) continue;
3141 if(nodeId>=0 && nodeId<nbOfNodes)
3145 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << nodeId << " not in [0," << nbOfNodes << ") !";
3146 throw INTERP_KERNEL::Exception(oss.str().c_str());
3150 nbrOfNodesInUse=ToIdType(std::count(traducer,traducer+nbOfNodes,1));
3151 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
3156 * This method renumbers only nodal connectivity in \a this. The renumbering is only an offset applied. So this method is a specialization of
3157 * \a renumberNodesInConn. \b WARNING, this method does not check that the resulting node ids in the nodal connectivity is in a valid range !
3159 * \param [in] offset - specifies the offset to be applied on each element of connectivity.
3161 * \sa renumberNodesInConn
3163 void MEDCoupling1DGTUMesh::renumberNodesWithOffsetInConn(mcIdType offset)
3165 getNumberOfCells();//only to check that all is well defined.
3167 mcIdType nbOfTuples(_conn->getNumberOfTuples());
3168 mcIdType *pt(_conn->getPointer());
3169 for(mcIdType i=0;i<nbOfTuples;i++,pt++)
3171 if(*pt==-1) continue;
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 INTERP_KERNEL::HashMap<mcIdType,mcIdType>& newNodeNumbersO2N)
3185 this->renumberNodesInConnT< INTERP_KERNEL::HashMap<mcIdType,mcIdType> >(newNodeNumbersO2N);
3189 * Same than renumberNodesInConn(const mcIdType *) except that here the format of old-to-new traducer is using map instead
3190 * 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
3193 void MEDCoupling1DGTUMesh::renumberNodesInConn(const std::map<mcIdType,mcIdType>& newNodeNumbersO2N)
3195 this->renumberNodesInConnT< std::map<mcIdType,mcIdType> >(newNodeNumbersO2N);
3199 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
3200 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
3201 * This method is a generalization of shiftNodeNumbersInConn().
3202 * \warning This method performs no check of validity of new ids. **Use it with care !**
3203 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
3204 * this->getNumberOfNodes(), in "Old to New" mode.
3205 * See \ref numbering for more info on renumbering modes.
3206 * \throw If the nodal connectivity of cells is not defined.
3208 void MEDCoupling1DGTUMesh::renumberNodesInConn(const mcIdType *newNodeNumbersO2N)
3210 getNumberOfCells();//only to check that all is well defined.
3212 mcIdType nbElemsIn(getNumberOfNodes()),nbOfTuples(_conn->getNumberOfTuples());
3213 mcIdType *pt(_conn->getPointer());
3214 for(mcIdType i=0;i<nbOfTuples;i++,pt++)
3216 if(*pt==-1) continue;
3217 if(*pt>=0 && *pt<nbElemsIn)
3218 *pt=newNodeNumbersO2N[*pt];
3221 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
3222 throw INTERP_KERNEL::Exception(oss.str().c_str());
3230 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
3231 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
3232 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
3233 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
3235 * \param [in] begin input start of array of node ids.
3236 * \param [in] end input end of array of node ids.
3237 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
3238 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
3240 void MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const mcIdType *begin, const mcIdType *end, bool fullyIn, DataArrayIdType *&cellIdsKeptArr) const
3242 mcIdType nbOfCells=getNumberOfCells();
3243 MCAuto<DataArrayIdType> cellIdsKept=DataArrayIdType::New(); cellIdsKept->alloc(0,1);
3245 mcIdType sz=_conn->getMaxValue(tmp); sz=std::max(sz,ToIdType(0))+1;
3246 std::vector<bool> fastFinder(sz,false);
3247 for(const mcIdType *work=begin;work!=end;work++)
3248 if(*work>=0 && *work<sz)
3249 fastFinder[*work]=true;
3250 const mcIdType *conn=_conn->begin(),*conni=_conn_indx->begin();
3251 for(mcIdType i=0;i<nbOfCells;i++,conni++)
3253 int ref=0,nbOfHit=0;
3254 mcIdType nbNodesPerCell=conni[1]-conni[0];
3255 if(nbNodesPerCell>=0)
3257 for(mcIdType j=0;j<nbNodesPerCell;j++)
3259 mcIdType nodeId=conn[conni[0]+j];
3263 if(fastFinder[nodeId])
3270 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !";
3271 throw INTERP_KERNEL::Exception(oss.str().c_str());
3273 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
3274 cellIdsKept->pushBackSilent(i);
3276 cellIdsKeptArr=cellIdsKept.retn();
3279 void MEDCoupling1DGTUMesh::allocateCells(mcIdType nbOfCells)
3282 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !");
3283 _conn=DataArrayIdType::New();
3284 _conn->reserve(nbOfCells*3);
3285 _conn_indx=DataArrayIdType::New();
3286 _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0);
3291 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
3293 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
3294 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
3295 * \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
3296 * attached to \a this.
3297 * \throw If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
3299 void MEDCoupling1DGTUMesh::insertNextCell(const mcIdType *nodalConnOfCellBg, const mcIdType *nodalConnOfCellEnd)
3301 std::size_t sz(std::distance(nodalConnOfCellBg,nodalConnOfCellEnd));
3302 DataArrayIdType *c(_conn),*c2(_conn_indx);
3305 mcIdType pos=c2->back();
3306 if(pos==c->getNumberOfTuples())
3308 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
3309 c2->pushBackSilent(pos+ToIdType(sz));
3313 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !";
3314 throw INTERP_KERNEL::Exception(oss.str().c_str());
3318 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !");
3321 void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayIdType *nodalConn, DataArrayIdType *nodalConnIndex)
3324 nodalConn->incrRef();
3327 nodalConnIndex->incrRef();
3328 _conn_indx=nodalConnIndex;
3333 * \return DataArrayIdType * - the internal reference to the nodal connectivity. The caller is not responsible to deallocate it.
3335 DataArrayIdType *MEDCoupling1DGTUMesh::getNodalConnectivity() const
3337 const DataArrayIdType *ret(_conn);
3338 return const_cast<DataArrayIdType *>(ret);
3342 * \return DataArrayIdType * - the internal reference to the nodal connectivity index. The caller is not responsible to deallocate it.
3344 DataArrayIdType *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const
3346 const DataArrayIdType *ret(_conn_indx);
3347 return const_cast<DataArrayIdType *>(ret);
3351 * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here".
3352 * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity).
3353 * 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.
3355 * 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.
3357 * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal
3358 * connectivity arrays are different (false)
3359 * \return a new object to be managed by the caller.
3361 * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked
3363 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const
3365 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3366 DataArrayIdType *nc=0,*nci=0;
3367 isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci);
3368 MCAuto<DataArrayIdType> ncs(nc),ncis(nci);
3369 ret->_conn=ncs; ret->_conn_indx=ncis;
3370 ret->setCoords(getCoords());
3375 * This method allows to compute, if needed, the packed nodal connectivity pair.
3376 * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges covered by nodal connectivity index array.
3377 * 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.
3379 * 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)
3380 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3382 * 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
3385 * This method return 3 elements.
3386 * \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
3387 * this pointer can be seen as a new object, that is to managed by the caller.
3388 * \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
3389 * this pointer can be seen as a new object, that is to managed by the caller.
3390 * \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
3391 * output parameters are newly created objects.
3393 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkConsistencyLight test
3395 bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayIdType *&nodalConn, DataArrayIdType *&nodalConnIndx) const
3397 if(isPacked())//performs the checkConsistencyLight
3399 const DataArrayIdType *c0(_conn),*c1(_conn_indx);
3400 nodalConn=const_cast<DataArrayIdType *>(c0); nodalConnIndx=const_cast<DataArrayIdType *>(c1);
3401 nodalConn->incrRef(); nodalConnIndx->incrRef();
3404 mcIdType bg=_conn_indx->front(),end=_conn_indx->back();
3405 MCAuto<DataArrayIdType> nc(_conn->selectByTupleIdSafeSlice(bg,end,1));
3406 MCAuto<DataArrayIdType> nci(_conn_indx->deepCopy());
3407 nci->applyLin(1,-bg);
3408 nodalConn=nc.retn(); nodalConnIndx=nci.retn();
3413 * 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)
3414 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3415 * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned.
3416 * \return bool - true if \a this looks packed, false is not.
3418 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkConsistencyLight test
3420 bool MEDCoupling1DGTUMesh::isPacked() const
3422 checkConsistencyLight();
3423 return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples();
3426 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2)
3428 std::vector<const MEDCoupling1DGTUMesh *> tmp(2);
3429 tmp[0]=const_cast<MEDCoupling1DGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1DGTUMesh *>(mesh2);
3430 return Merge1DGTUMeshes(tmp);
3433 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a)
3435 std::size_t sz=a.size();
3437 return Merge1DGTUMeshesLL(a);
3438 for(std::size_t ii=0;ii<sz;ii++)
3441 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::Merge1DGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
3442 throw INTERP_KERNEL::Exception(oss.str().c_str());
3444 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
3445 for(std::size_t ii=0;ii<sz;ii++)
3446 if(&(a[ii]->getCellModel())!=cm)
3447 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !");
3448 std::vector< MCAuto<MEDCoupling1DGTUMesh> > bb(sz);
3449 std::vector< const MEDCoupling1DGTUMesh * > aa(sz);
3450 std::size_t spaceDimUndef=-3, spaceDim=spaceDimUndef;
3451 for(std::size_t i=0;i<sz && spaceDim==spaceDimUndef;i++)
3453 const MEDCoupling1DGTUMesh *cur=a[i];
3454 const DataArrayDouble *coo=cur->getCoords();
3456 spaceDim=coo->getNumberOfComponents();
3458 if(spaceDim==spaceDimUndef)
3459 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !");
3460 for(std::size_t i=0;i<sz;i++)
3462 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
3465 return Merge1DGTUMeshesLL(aa);
3469 * \throw If presence of a null instance in the input vector \a a.
3470 * \throw If a is empty
3472 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a)
3475 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !");
3476 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3478 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !");
3479 std::vector< MCAuto<MEDCoupling1DGTUMesh> > objs(a.size());
3480 std::vector<const DataArrayIdType *> ncs(a.size()),ncis(a.size());
3481 (*it)->getNumberOfCells();//to check that all is OK
3482 const DataArrayDouble *coords=(*it)->getCoords();
3483 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3485 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3486 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3488 for(int i=1;it!=a.end();i++,it++)
3491 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !");
3492 if(cm!=&((*it)->getCellModel()))
3493 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3494 (*it)->getNumberOfCells();//to check that all is OK
3495 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3496 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3497 if(coords!=(*it)->getCoords())
3498 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !");
3500 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3501 ret->setCoords(coords);
3502 ret->_conn=DataArrayIdType::Aggregate(ncs);
3503 ret->_conn_indx=DataArrayIdType::AggregateIndexes(ncis);
3508 * 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)
3510 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a)
3513 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : input array must be NON EMPTY !");
3514 std::vector< MCAuto<MEDCoupling1DGTUMesh> > objs(a.size());
3515 std::vector<const DataArrayIdType *> ncs(a.size()),ncis(a.size());
3516 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3517 std::vector<mcIdType> nbNodesPerElt(a.size());
3518 std::size_t nbOfCells=(*it)->getNumberOfCells();
3520 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3521 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3523 mcIdType prevNbOfNodes=(*it)->getNumberOfNodes();
3524 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3526 for(int i=1;it!=a.end();i++,it++)
3528 if(cm!=&((*it)->getCellModel()))
3529 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3530 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3531 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3532 nbOfCells+=(*it)->getNumberOfCells();
3533 nbNodesPerElt[i]=nbNodesPerElt[i-1]+prevNbOfNodes;
3534 prevNbOfNodes=(*it)->getNumberOfNodes();
3536 std::vector<const MEDCouplingPointSet *> aps(a.size());
3537 std::copy(a.begin(),a.end(),aps.begin());
3538 MCAuto<DataArrayDouble> pts=MergeNodesArray(aps);
3539 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3540 ret->setCoords(pts);
3541 ret->_conn=AggregateNodalConnAndShiftNodeIds(ncs,nbNodesPerElt);
3542 ret->_conn_indx=DataArrayIdType::AggregateIndexes(ncis);
3546 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(std::size_t spaceDim) const
3548 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3549 MCAuto<DataArrayIdType> tmp1,tmp2;
3550 const DataArrayIdType *nodalConn(_conn),*nodalConnI(_conn_indx);
3553 tmp1=DataArrayIdType::New(); tmp1->alloc(0,1);
3561 tmp2=DataArrayIdType::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
3565 ret->_conn_indx=tmp2;
3569 MCAuto<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
3570 ret->setCoords(coords);
3573 ret->setCoords(_coords);
3578 * This method aggregate the bbox of each cell and put it into bbox parameter.
3580 * \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)
3581 * For all other cases this input parameter is ignored.
3582 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
3584 * \throw If \a this is not fully set (coordinates and connectivity).
3585 * \throw If a cell in \a this has no valid nodeId.
3587 DataArrayDouble *MEDCoupling1DGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
3589 checkFullyDefined();
3590 mcIdType spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes());
3591 MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
3592 double *bbox(ret->getPointer());
3593 for(mcIdType i=0;i<nbOfCells*spaceDim;i++)
3595 bbox[2*i]=std::numeric_limits<double>::max();
3596 bbox[2*i+1]=-std::numeric_limits<double>::max();
3598 const double *coordsPtr(_coords->getConstPointer());
3599 const mcIdType *conn(_conn->getConstPointer()),*connI(_conn_indx->getConstPointer());
3600 for(mcIdType i=0;i<nbOfCells;i++)
3602 mcIdType offset=connI[i];
3603 mcIdType nbOfNodesForCell(connI[i+1]-offset),kk(0);
3604 for(mcIdType j=0;j<nbOfNodesForCell;j++)
3606 mcIdType nodeId=conn[offset+j];
3607 if(nodeId>=0 && nodeId<nbOfNodes)
3609 for(int k=0;k<spaceDim;k++)
3611 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
3612 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
3619 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
3620 throw INTERP_KERNEL::Exception(oss.str().c_str());
3627 * 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.
3629 * \return a new instance of field containing the result. The returned instance has to be deallocated by the caller.
3631 MEDCouplingFieldDouble *MEDCoupling1DGTUMesh::computeDiameterField() const
3633 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::computeDiameterField : not implemented yet for dynamic types !");
3636 std::vector<mcIdType> MEDCoupling1DGTUMesh::BuildAPolygonFromParts(const std::vector< std::vector<mcIdType> >& parts)
3638 std::vector<mcIdType> ret;
3641 ret.insert(ret.end(),parts[0].begin(),parts[0].end());
3642 mcIdType ref(ret.back());
3643 std::size_t sz(parts.size()),nbh(1);
3644 std::vector<bool> b(sz,true); b[0]=false;
3648 for(;i<sz;i++) if(b[i] && parts[i].front()==ref) { ret.insert(ret.end(),parts[i].begin()+1,parts[i].end()); nbh++; break; }
3652 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::BuildAPolygonFromParts : the input vector is not a part of a single polygon !");
3654 if(ret.back()==ret.front())
3660 * This method invert orientation of all cells in \a this.
3661 * After calling this method the absolute value of measure of cells in \a this are the same than before calling.
3662 * This method only operates on the connectivity so coordinates are not touched at all.
3664 void MEDCoupling1DGTUMesh::invertOrientationOfAllCells()
3666 checkConsistencyOfConnectivity();
3667 INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::OrientationInverter> oi(INTERP_KERNEL::OrientationInverter::BuildInstanceFrom(getCellModelEnum()));
3668 mcIdType nbCells=getNumberOfCells();
3669 const mcIdType *connI(_conn_indx->begin());
3670 mcIdType *conn(_conn->getPointer());
3671 for(mcIdType i=0;i<nbCells;i++)
3672 oi->operate(conn+connI[i],conn+connI[i+1]);
3677 * This method performs an aggregation of \a nodalConns (as DataArrayIdType::Aggregate does) but in addition of that a shift is applied on the
3678 * values contained in \a nodalConns using corresponding offset specified in input \a offsetInNodeIdsPerElt.
3679 * But it also manage the values -1, that have a semantic in MEDCoupling1DGTUMesh class (separator for polyhedron).
3681 * \param [in] nodalConns - a list of nodal connectivity arrays same size than \a offsetInNodeIdsPerElt.
3682 * \param [in] offsetInNodeIdsPerElt - a list of offsets to apply.
3683 * \return DataArrayIdType * - A new object (to be managed by the caller) that is the result of the aggregation.
3684 * \throw If \a nodalConns or \a offsetInNodeIdsPerElt are empty.
3685 * \throw If \a nodalConns and \a offsetInNodeIdsPerElt have not the same size.
3686 * \throw If presence of null pointer in \a nodalConns.
3687 * \throw If presence of not allocated or array with not exactly one component in \a nodalConns.
3689 DataArrayIdType *MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds(const std::vector<const DataArrayIdType *>& nodalConns, const std::vector<mcIdType>& offsetInNodeIdsPerElt)
3691 std::size_t sz1(nodalConns.size()),sz2(offsetInNodeIdsPerElt.size());
3693 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : input vectors do not have the same size !");
3695 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : empty vectors in input !");
3696 mcIdType nbOfTuples=0;
3697 for(std::vector<const DataArrayIdType *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++)
3700 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of null pointer in input vector !");
3701 if(!(*it)->isAllocated())
3702 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of non allocated array in input vector !");
3703 if((*it)->getNumberOfComponents()!=1)
3704 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of array with not exactly one component !");
3705 nbOfTuples+=(*it)->getNumberOfTuples();
3707 MCAuto<DataArrayIdType> ret=DataArrayIdType::New(); ret->alloc(nbOfTuples,1);
3708 mcIdType *pt=ret->getPointer();
3710 for(std::vector<const DataArrayIdType *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++,i++)
3712 mcIdType curNbt=(*it)->getNumberOfTuples();
3713 const mcIdType *inPt=(*it)->begin();
3714 mcIdType offset=offsetInNodeIdsPerElt[i];
3715 for(mcIdType j=0;j<curNbt;j++,pt++)
3726 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m)
3729 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh is null !");
3730 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
3732 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh must have exactly one geometric type !");
3733 mcIdType geoType(ToIdType(*gts.begin()));
3734 MCAuto<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(m->getName(),*gts.begin()));
3735 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription());
3736 mcIdType nbCells=m->getNumberOfCells();
3737 MCAuto<DataArrayIdType> conn(DataArrayIdType::New()),connI(DataArrayIdType::New());
3738 conn->alloc(m->getNodalConnectivityArrayLen()-nbCells,1); connI->alloc(nbCells+1,1);
3739 mcIdType *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
3740 const mcIdType *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
3741 for(mcIdType i=0;i<nbCells;i++,ciin++,ci++)
3743 if(cin[ciin[0]]==geoType)
3745 if(ciin[1]-ciin[0]>=1)
3747 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
3748 ci[1]=ci[0]+ciin[1]-ciin[0]-1;
3752 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 !";
3753 throw INTERP_KERNEL::Exception(oss.str().c_str());
3758 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 !";
3759 throw INTERP_KERNEL::Exception(oss.str().c_str());
3762 ret->setNodalConnectivity(conn,connI);