1 // Copyright (C) 2007-2016 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 (CEA/DEN)
21 #include "MEDCoupling1GTUMesh.hxx"
22 #include "MEDCouplingUMesh.hxx"
23 #include "MEDCouplingFieldDouble.hxx"
24 #include "MEDCouplingCMesh.hxx"
26 #include "SplitterTetra.hxx"
27 #include "DiameterCalculator.hxx"
28 #include "InterpKernelAutoPtr.hxx"
30 using namespace MEDCoupling;
32 const int MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[6]={0,1,2,4,3,5};
34 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh():_cm(0)
38 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):_cm(&cm)
43 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const MEDCoupling1GTUMesh& other, bool recDeepCpy):MEDCouplingPointSet(other,recDeepCpy),_cm(other._cm)
47 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
49 if(type==INTERP_KERNEL::NORM_ERROR)
50 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
51 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
53 return MEDCoupling1SGTUMesh::New(name,type);
55 return MEDCoupling1DGTUMesh::New(name,type);
58 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const MEDCouplingUMesh *m)
61 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh is null !");
62 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
64 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh must have exactly one geometric type !");
65 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*gts.begin());
67 return MEDCoupling1SGTUMesh::New(m);
69 return MEDCoupling1DGTUMesh::New(m);
72 const INTERP_KERNEL::CellModel& MEDCoupling1GTUMesh::getCellModel() const
77 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getCellModelEnum() const
79 return _cm->getEnum();
82 int MEDCoupling1GTUMesh::getMeshDimension() const
84 return (int)_cm->getDimension();
88 * This method returns a newly allocated array containing cell ids (ascendingly sorted) whose geometric type are equal to type.
89 * This method does not throw exception if geometric type \a type is not in \a this.
90 * This method throws an INTERP_KERNEL::Exception if meshdimension of \b this is not equal to those of \b type.
91 * The coordinates array is not considered here.
93 * \param [in] type the geometric type
94 * \return cell ids in this having geometric type \a type.
96 DataArrayInt *MEDCoupling1GTUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
98 MCAuto<DataArrayInt> ret=DataArrayInt::New();
99 if(type==getCellModelEnum())
100 ret->alloc(getNumberOfCells(),1);
108 * Returns nb of cells having the geometric type \a type. No throw if no cells in \a this has the geometric type \a type.
110 int MEDCoupling1GTUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
112 return type==getCellModelEnum()?getNumberOfCells():0;
116 * Returns a type of a cell by its id.
117 * \param [in] cellId - the id of the cell of interest.
118 * \return INTERP_KERNEL::NormalizedCellType - enumeration item describing the cell type.
119 * \throw If \a cellId is invalid. Valid range is [0, \a this->getNumberOfCells() ).
121 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getTypeOfCell(int cellId) const
123 if(cellId>=0 && cellId<getNumberOfCells())
124 return getCellModelEnum();
125 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::getTypeOfCell : Requesting type of cell #" << cellId << " but it should be in [0," << getNumberOfCells() << ") !";
126 throw INTERP_KERNEL::Exception(oss.str().c_str());
130 * Returns a set of all cell types available in \a this mesh.
131 * \return std::set<INTERP_KERNEL::NormalizedCellType> - the set of cell types.
132 * \warning this method does not throw any exception even if \a this is not defined.
134 std::set<INTERP_KERNEL::NormalizedCellType> MEDCoupling1GTUMesh::getAllGeoTypes() const
136 std::set<INTERP_KERNEL::NormalizedCellType> ret;
137 ret.insert(getCellModelEnum());
142 * This method expects that \a this is sorted by types. If not an exception will be thrown.
143 * This method returns in the same format as code (see MEDCouplingUMesh::checkTypeConsistencyAndContig or MEDCouplingUMesh::splitProfilePerType) how
144 * \a this is composed in cell types.
145 * The returned array is of size 3*n where n is the number of different types present in \a this.
146 * For every k in [0,n] ret[3*k+2]==-1 because it has no sense here.
147 * This parameter is kept only for compatibility with other methode listed above.
149 std::vector<int> MEDCoupling1GTUMesh::getDistributionOfTypes() const
151 std::vector<int> ret(3);
152 ret[0]=(int)getCellModelEnum(); ret[1]=getNumberOfCells(); ret[2]=-1;
157 * 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.
158 * 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.
159 * This method has 1 input \a profile and 3 outputs \a code \a idsInPflPerType and \a idsPerType.
161 * \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.
162 * \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,
163 * \a idsInPflPerType[i] stores the tuple ids in \a profile that correspond to the geometric type code[3*i+0]
164 * \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.
165 * This vector can be empty in case of all geometric type cells are fully covered in ascending in the given input \a profile.
167 * \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.
169 * \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
172 * - Before \a this has 3 cells \a profile contains [0,1,2]
173 * - After \a code contains [NORM_...,nbCells,-1], \a idsInPflPerType [[0,1,2]] and \a idsPerType is empty <br>
176 * - Before \a this has 3 cells \a profile contains [1,2]
177 * - After \a code contains [NORM_...,nbCells,0], \a idsInPflPerType [[0,1]] and \a idsPerType is [[1,2]] <br>
180 void MEDCoupling1GTUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const
183 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile is NULL !");
184 if(profile->getNumberOfComponents()!=1)
185 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile should have exactly one component !");
186 int nbTuples(profile->getNumberOfTuples()),nbOfCells(getNumberOfCells());
187 code.resize(3); idsInPflPerType.resize(1);
188 code[0]=(int)getCellModelEnum(); code[1]=nbTuples;
189 idsInPflPerType.resize(1);
190 if(profile->isIota(nbOfCells))
193 idsInPflPerType[0]=const_cast<DataArrayInt *>(profile); idsInPflPerType[0]->incrRef();
198 profile->checkAllIdsInRange(0,nbOfCells);
199 idsPerType.resize(1);
200 idsPerType[0]=const_cast<DataArrayInt *>(profile); idsPerType[0]->incrRef();
201 idsInPflPerType[0]=DataArrayInt::Range(0,nbTuples,1);
205 * This method tries to minimize at most the number of deep copy.
206 * So if \a idsPerType is not empty it can be returned directly (without copy, but with ref count incremented) in return.
208 * \sa MEDCouplingUMesh::checkTypeConsistencyAndContig
210 DataArrayInt *MEDCoupling1GTUMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const
212 int nbOfCells=getNumberOfCells();
214 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : invalid input code should be exactly of size 3 !");
215 if(code[0]!=(int)getCellModelEnum())
217 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() << ") !";
218 throw INTERP_KERNEL::Exception(oss.str().c_str());
222 if(code[1]==nbOfCells)
226 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : mismatch between the number of cells in this (" << nbOfCells << ") and the number of non profile (" << code[1] << ") !";
227 throw INTERP_KERNEL::Exception(oss.str().c_str());
231 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : single geo type mesh ! 0 or -1 is expected at pos #2 of input code !");
232 if(idsPerType.size()!=1)
233 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input code points to DataArrayInt #0 whereas the size of idsPerType is not equal to 1 !");
234 const DataArrayInt *pfl=idsPerType[0];
236 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : the input code points to a NULL DataArrayInt at rank 0 !");
237 if(pfl->getNumberOfComponents()!=1)
238 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input profile should have exactly one component !");
239 pfl->checkAllIdsInRange(0,nbOfCells);
241 return const_cast<DataArrayInt *>(pfl);
244 void MEDCoupling1GTUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const
246 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
247 m->writeVTKLL(ofs,cellData,pointData,byteData);
250 std::string MEDCoupling1GTUMesh::getVTKDataSetType() const
252 return std::string("UnstructuredGrid");
255 std::string MEDCoupling1GTUMesh::getVTKFileExtension() const
257 return std::string("vtu");
260 std::size_t MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren() const
262 return MEDCouplingPointSet::getHeapMemorySizeWithoutChildren();
265 bool MEDCoupling1GTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
267 if(!MEDCouplingPointSet::isEqualIfNotWhy(other,prec,reason))
270 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualIfNotWhy : input other pointer is null !");
271 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
274 reason="mesh given in input is not castable in MEDCouplingSGTUMesh !";
279 reason="mismatch in geometric type !";
285 bool MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
287 if(!MEDCouplingPointSet::isEqualWithoutConsideringStr(other,prec))
290 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
291 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
299 void MEDCoupling1GTUMesh::checkConsistencyLight() const
301 MEDCouplingPointSet::checkConsistencyLight();
304 DataArrayDouble *MEDCoupling1GTUMesh::computeCellCenterOfMass() const
306 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
307 MCAuto<DataArrayDouble> ret=m->computeCellCenterOfMass();
311 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureField(bool isAbs) const
313 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
314 MCAuto<MEDCouplingFieldDouble> ret=m->getMeasureField(isAbs);
319 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureFieldOnNode(bool isAbs) const
321 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
322 MCAuto<MEDCouplingFieldDouble> ret=m->getMeasureFieldOnNode(isAbs);
330 int MEDCoupling1GTUMesh::getCellContainingPoint(const double *pos, double eps) const
332 MCAuto<MEDCouplingUMesh> m(buildUnstructured());
333 return m->getCellContainingPoint(pos,eps);
339 void MEDCoupling1GTUMesh::getCellsContainingPoint(const double *pos, double eps, std::vector<int>& elts) const
341 MCAuto<MEDCouplingUMesh> m(buildUnstructured());
342 return m->getCellsContainingPoint(pos,eps,elts);
345 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::buildOrthogonalField() const
347 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
348 MCAuto<MEDCouplingFieldDouble> ret=m->buildOrthogonalField();
353 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const double *bbox, double eps) const
355 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
356 return m->getCellsInBoundingBox(bbox,eps);
359 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps)
361 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
362 return m->getCellsInBoundingBox(bbox,eps);
365 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const
367 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
368 return m->buildFacePartOfMySelfNode(start,end,fullyIn);
371 DataArrayInt *MEDCoupling1GTUMesh::findBoundaryNodes() const
373 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
374 return m->findBoundaryNodes();
377 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildBoundaryMesh(bool keepCoords) const
379 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
380 return m->buildBoundaryMesh(keepCoords);
383 void MEDCoupling1GTUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const
385 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
386 m->findCommonCells(compType,startCellId,commonCellsArr,commonCellsIArr);
389 int MEDCoupling1GTUMesh::getNodalConnectivityLength() const
391 const DataArrayInt *c1(getNodalConnectivity());
393 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : no connectivity set !");
394 if(c1->getNumberOfComponents()!=1)
395 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array set must have exactly one component !");
396 if(!c1->isAllocated())
397 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array must be allocated !");
398 return c1->getNumberOfTuples();
402 * This method aggregates all the meshes in \a parts to put them in a single unstructured mesh (those returned).
403 * The order of cells is the returned instance is those in the order of instances in \a parts.
405 * \param [in] parts - all not null parts of single geo type meshes to be aggreagated having the same mesh dimension and same coordinates.
406 * \return MEDCouplingUMesh * - new object to be dealt by the caller.
408 * \throw If one element is null in \a parts.
409 * \throw If not all the parts do not have the same mesh dimension.
410 * \throw If not all the parts do not share the same coordinates.
411 * \throw If not all the parts have their connectivity set properly.
412 * \throw If \a parts is empty.
414 MEDCouplingUMesh *MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh(const std::vector< const MEDCoupling1GTUMesh *>& parts)
417 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : input parts vector is empty !");
418 const MEDCoupling1GTUMesh *firstPart(parts[0]);
420 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : the first instance in input parts is null !");
421 const DataArrayDouble *coords(firstPart->getCoords());
422 int meshDim(firstPart->getMeshDimension());
423 MCAuto<MEDCouplingUMesh> ret(MEDCouplingUMesh::New(firstPart->getName(),meshDim)); ret->setDescription(firstPart->getDescription());
424 ret->setCoords(coords);
425 int nbOfCells(0),connSize(0);
426 for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
429 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of null pointer in input vector !");
430 if((*it)->getMeshDimension()!=meshDim)
431 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances in input vector must have same mesh dimension !");
432 if((*it)->getCoords()!=coords)
433 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances must share the same coordinates pointer !");
434 nbOfCells+=(*it)->getNumberOfCells();
435 connSize+=(*it)->getNodalConnectivityLength();
437 MCAuto<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
438 connI->alloc(nbOfCells+1,1); conn->alloc(connSize+nbOfCells,1);
439 int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
440 for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
442 int curNbCells((*it)->getNumberOfCells());
443 int geoType((int)(*it)->getCellModelEnum());
444 const int *cinPtr((*it)->getNodalConnectivity()->begin());
445 const MEDCoupling1SGTUMesh *ps(dynamic_cast<const MEDCoupling1SGTUMesh *>(*it));
446 const MEDCoupling1DGTUMesh *pd(dynamic_cast<const MEDCoupling1DGTUMesh *>(*it));
449 int nNodesPerCell(ps->getNumberOfNodesPerCell());
450 for(int i=0;i<curNbCells;i++,ci++,cinPtr+=nNodesPerCell)
453 c=std::copy(cinPtr,cinPtr+nNodesPerCell,c);
454 ci[1]=ci[0]+nNodesPerCell+1;
459 const int *ciinPtr(pd->getNodalConnectivityIndex()->begin());
460 for(int i=0;i<curNbCells;i++,ci++,ciinPtr++)
463 c=std::copy(cinPtr+ciinPtr[0],cinPtr+ciinPtr[1],c);
464 ci[1]=ci[0]+ciinPtr[1]-ciinPtr[0]+1;
468 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of instance which type is not in [MEDCoupling1SGTUMesh,MEDCoupling1DGTUMesh] !");
470 ret->setConnectivity(conn,connI,true);
476 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const MEDCoupling1SGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
480 const DataArrayInt *c(other._conn);
486 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
490 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh()
494 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New()
496 return new MEDCoupling1SGTUMesh;
499 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
501 if(type==INTERP_KERNEL::NORM_ERROR)
502 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
503 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
506 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New : the input geometric type " << cm.getRepr() << " is dynamic ! Only static types are allowed here !";
507 throw INTERP_KERNEL::Exception(oss.str().c_str());
509 return new MEDCoupling1SGTUMesh(name,cm);
512 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m)
515 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh is null !");
516 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
518 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh must have exactly one geometric type !");
519 int geoType((int)*gts.begin());
520 MCAuto<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(m->getName(),*gts.begin()));
521 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription());
522 int nbCells(m->getNumberOfCells());
523 int nbOfNodesPerCell(ret->getNumberOfNodesPerCell());
524 MCAuto<DataArrayInt> conn(DataArrayInt::New()); conn->alloc(nbCells*nbOfNodesPerCell,1);
525 int *c(conn->getPointer());
526 const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
527 for(int i=0;i<nbCells;i++,ciin++)
529 if(cin[ciin[0]]==geoType)
531 if(ciin[1]-ciin[0]==nbOfNodesPerCell+1)
532 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
535 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 << ") !";
536 throw INTERP_KERNEL::Exception(oss.str().c_str());
541 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 !";
542 throw INTERP_KERNEL::Exception(oss.str().c_str());
545 ret->setNodalConnectivity(conn);
547 { ret->copyTinyInfoFrom(m); }
548 catch(INTERP_KERNEL::Exception&) { }
552 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::clone(bool recDeepCpy) const
554 return new MEDCoupling1SGTUMesh(*this,recDeepCpy);
558 * This method behaves mostly like MEDCoupling1SGTUMesh::deepCopy method, except that only nodal connectivity arrays are deeply copied.
559 * The coordinates are shared between \a this and the returned instance.
561 * \return MEDCoupling1SGTUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
562 * \sa MEDCoupling1SGTUMesh::deepCopy
564 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::deepCopyConnectivityOnly() const
566 checkConsistencyLight();
567 MCAuto<MEDCoupling1SGTUMesh> ret(clone(false));
568 MCAuto<DataArrayInt> c(_conn->deepCopy());
569 ret->setNodalConnectivity(c);
573 void MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
576 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
577 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
579 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1SGTUMesh instance !");
580 setNodalConnectivity(otherC->getNodalConnectivity());
583 void MEDCoupling1SGTUMesh::updateTime() const
585 MEDCoupling1GTUMesh::updateTime();
586 const DataArrayInt *c(_conn);
591 std::size_t MEDCoupling1SGTUMesh::getHeapMemorySizeWithoutChildren() const
593 return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren();
596 std::vector<const BigMemoryObject *> MEDCoupling1SGTUMesh::getDirectChildrenWithNull() const
598 std::vector<const BigMemoryObject *> ret(MEDCoupling1GTUMesh::getDirectChildrenWithNull());
599 ret.push_back((const DataArrayInt *)_conn);
603 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::deepCopy() const
608 bool MEDCoupling1SGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
611 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualIfNotWhy : input other pointer is null !");
612 std::ostringstream oss; oss.precision(15);
613 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
616 reason="mesh given in input is not castable in MEDCoupling1SGTUMesh !";
619 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
621 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
626 reason="in connectivity of single static geometric type exactly one among this and other is null !";
629 if(!c1->isEqualIfNotWhy(*c2,reason))
631 reason.insert(0,"Nodal connectivity DataArrayInt differ : ");
637 bool MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
640 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
641 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
644 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
646 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
651 if(!c1->isEqualWithoutConsideringStr(*c2))
656 void MEDCoupling1SGTUMesh::checkConsistencyOfConnectivity() const
658 const DataArrayInt *c1(_conn);
661 if(c1->getNumberOfComponents()!=1)
662 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
663 if(c1->getInfoOnComponent(0)!="")
664 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
665 c1->checkAllocated();
668 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
671 void MEDCoupling1SGTUMesh::checkConsistencyLight() const
673 MEDCouplingPointSet::checkConsistencyLight();
674 checkConsistencyOfConnectivity();
677 void MEDCoupling1SGTUMesh::checkConsistency(double eps) const
679 checkConsistencyLight();
680 const DataArrayInt *c1(_conn);
681 int nbOfTuples=c1->getNumberOfTuples();
682 int nbOfNodesPerCell=(int)_cm->getNumberOfNodes();
683 if(nbOfTuples%nbOfNodesPerCell!=0)
685 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 !";
686 throw INTERP_KERNEL::Exception(oss.str().c_str());
688 int nbOfNodes=getNumberOfNodes();
689 int nbOfCells=nbOfTuples/nbOfNodesPerCell;
690 const int *w(c1->begin());
691 for(int i=0;i<nbOfCells;i++)
692 for(int j=0;j<nbOfNodesPerCell;j++,w++)
694 if(*w<0 || *w>=nbOfNodes)
696 std::ostringstream oss; oss << "At node #" << j << " of cell #" << i << ", is equal to " << *w << " must be in [0," << nbOfNodes << ") !";
697 throw INTERP_KERNEL::Exception(oss.str().c_str());
702 int MEDCoupling1SGTUMesh::getNumberOfCells() const
704 int nbOfTuples=getNodalConnectivityLength();
705 int nbOfNodesPerCell=getNumberOfNodesPerCell();
706 if(nbOfTuples%nbOfNodesPerCell!=0)
708 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 !";
709 throw INTERP_KERNEL::Exception(oss.str().c_str());
711 return nbOfTuples/nbOfNodesPerCell;
714 int MEDCoupling1SGTUMesh::getNumberOfNodesInCell(int cellId) const
716 return getNumberOfNodesPerCell();
719 int MEDCoupling1SGTUMesh::getNumberOfNodesPerCell() const
721 checkNonDynamicGeoType();
722 return (int)_cm->getNumberOfNodes();
725 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfNodesPerCell() const
727 checkNonDynamicGeoType();
728 MCAuto<DataArrayInt> ret=DataArrayInt::New();
729 ret->alloc(getNumberOfCells(),1);
730 ret->fillWithValue((int)_cm->getNumberOfNodes());
734 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfFacesPerCell() const
736 checkNonDynamicGeoType();
737 MCAuto<DataArrayInt> ret=DataArrayInt::New();
738 ret->alloc(getNumberOfCells(),1);
739 ret->fillWithValue((int)_cm->getNumberOfSons());
743 DataArrayInt *MEDCoupling1SGTUMesh::computeEffectiveNbOfNodesPerCell() const
745 checkNonDynamicGeoType();
746 MCAuto<DataArrayInt> ret=DataArrayInt::New();
747 int nbCells(getNumberOfCells());
748 ret->alloc(nbCells,1);
749 int *retPtr(ret->getPointer());
750 int nbNodesPerCell(getNumberOfNodesPerCell());
751 const int *conn(_conn->begin());
752 for(int i=0;i<nbCells;i++,conn+=nbNodesPerCell,retPtr++)
754 std::set<int> s(conn,conn+nbNodesPerCell);
755 *retPtr=(int)s.size();
760 void MEDCoupling1SGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
762 int sz=getNumberOfNodesPerCell();
764 if(cellId>=0 && cellId<getNumberOfCells())
765 std::copy(_conn->begin()+cellId*sz,_conn->begin()+(cellId+1)*sz,conn.begin());
768 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << getNumberOfCells() << ") !";
769 throw INTERP_KERNEL::Exception(oss.str().c_str());
773 void MEDCoupling1SGTUMesh::checkNonDynamicGeoType() const
776 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkNonDynamicGeoType : internal error ! the internal geo type is dynamic ! should be static !");
779 std::string MEDCoupling1SGTUMesh::simpleRepr() const
781 static const char msg0[]="No coordinates specified !";
782 std::ostringstream ret;
783 ret << "Single static geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
784 ret << "Description of mesh : \"" << getDescription() << "\"\n";
786 double tt=getTime(tmpp1,tmpp2);
787 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
788 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
789 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
792 const int spaceDim=getSpaceDimension();
793 ret << spaceDim << "\nInfo attached on space dimension : ";
794 for(int i=0;i<spaceDim;i++)
795 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
800 ret << "Number of nodes : ";
802 ret << getNumberOfNodes() << "\n";
805 ret << "Number of cells : ";
806 if((const DataArrayInt *)_conn)
808 if(_conn->isAllocated())
810 if(_conn->getNumberOfComponents()==1)
811 ret << getNumberOfCells() << "\n";
813 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
816 ret << "Nodal connectivity array specified but not allocated !" << "\n";
819 ret << "No connectivity specified !" << "\n";
820 ret << "Cell type : " << _cm->getRepr() << "\n";
824 std::string MEDCoupling1SGTUMesh::advancedRepr() const
826 std::ostringstream ret;
828 ret << "\nCoordinates array : \n___________________\n\n";
830 _coords->reprWithoutNameStream(ret);
832 ret << "No array set !\n";
833 ret << "\n\nConnectivity array : \n____________________\n\n";
835 if((const DataArrayInt *)_conn)
837 if(_conn->isAllocated())
839 if(_conn->getNumberOfComponents()==1)
841 int nbOfCells=getNumberOfCells();
842 int sz=getNumberOfNodesPerCell();
843 const int *connPtr=_conn->begin();
844 for(int i=0;i<nbOfCells;i++,connPtr+=sz)
846 ret << "Cell #" << i << " : ";
847 std::copy(connPtr,connPtr+sz,std::ostream_iterator<int>(ret," "));
852 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
855 ret << "Nodal connectivity array specified but not allocated !" << "\n";
858 ret << "No connectivity specified !" << "\n";
862 DataArrayDouble *MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell() const
864 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
865 int spaceDim=getSpaceDimension();
866 int nbOfCells=getNumberOfCells();//checkConsistencyLight()
867 int nbOfNodes=getNumberOfNodes();
868 ret->alloc(nbOfCells,spaceDim);
869 double *ptToFill=ret->getPointer();
870 const double *coor=_coords->begin();
871 const int *nodal=_conn->begin();
872 int sz=getNumberOfNodesPerCell();
873 double coeff=1./(double)sz;
874 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim)
876 std::fill(ptToFill,ptToFill+spaceDim,0.);
877 for(int j=0;j<sz;j++,nodal++)
878 if(*nodal>=0 && *nodal<nbOfNodes)
879 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
882 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
883 throw INTERP_KERNEL::Exception(oss.str().c_str());
885 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),coeff));
890 void MEDCoupling1SGTUMesh::renumberCells(const int *old2NewBg, bool check)
892 int nbCells=getNumberOfCells();
893 MCAuto<DataArrayInt> o2n=DataArrayInt::New();
894 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
896 o2n=o2n->checkAndPreparePermutation();
898 const int *conn=_conn->begin();
899 MCAuto<DataArrayInt> n2o=o2n->invertArrayO2N2N2O(nbCells);
900 const int *n2oPtr=n2o->begin();
901 MCAuto<DataArrayInt> newConn=DataArrayInt::New();
902 newConn->alloc(_conn->getNumberOfTuples(),1);
903 newConn->copyStringInfoFrom(*_conn);
904 int sz=getNumberOfNodesPerCell();
906 int *newC=newConn->getPointer();
907 for(int i=0;i<nbCells;i++,newC+=sz)
910 std::copy(conn+pos*sz,conn+(pos+1)*sz,newC);
916 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
917 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
918 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
919 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
921 * \param [in] begin input start of array of node ids.
922 * \param [in] end input end of array of node ids.
923 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
924 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
926 void MEDCoupling1SGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
928 int nbOfCells=getNumberOfCells();
929 MCAuto<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
931 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
932 std::vector<bool> fastFinder(sz,false);
933 for(const int *work=begin;work!=end;work++)
934 if(*work>=0 && *work<sz)
935 fastFinder[*work]=true;
936 const int *conn=_conn->begin();
937 int nbNodesPerCell=getNumberOfNodesPerCell();
938 for(int i=0;i<nbOfCells;i++,conn+=nbNodesPerCell)
941 for(int j=0;j<nbNodesPerCell;j++)
945 if(fastFinder[conn[j]])
948 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
949 cellIdsKept->pushBackSilent(i);
951 cellIdsKeptArr=cellIdsKept.retn();
954 MEDCouplingMesh *MEDCoupling1SGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
956 if(other->getType()!=SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED)
957 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single static geo type each other !");
958 const MEDCoupling1SGTUMesh *otherC=static_cast<const MEDCoupling1SGTUMesh *>(other);
959 return Merge1SGTUMeshes(this,otherC);
962 MEDCouplingUMesh *MEDCoupling1SGTUMesh::buildUnstructured() const
964 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
965 ret->setCoords(getCoords());
966 const int *nodalConn=_conn->begin();
967 int nbCells=getNumberOfCells();
968 int nbNodesPerCell=getNumberOfNodesPerCell();
969 int geoType=(int)getCellModelEnum();
970 MCAuto<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells*(nbNodesPerCell+1),1);
971 int *cPtr=c->getPointer();
972 for(int i=0;i<nbCells;i++,nodalConn+=nbNodesPerCell)
975 cPtr=std::copy(nodalConn,nodalConn+nbNodesPerCell,cPtr);
977 MCAuto<DataArrayInt> cI=DataArrayInt::Range(0,(nbCells+1)*(nbNodesPerCell+1),nbNodesPerCell+1);
978 ret->setConnectivity(c,cI,true);
980 { ret->copyTinyInfoFrom(this); }
981 catch(INTERP_KERNEL::Exception&) { }
985 DataArrayInt *MEDCoupling1SGTUMesh::simplexize(int policy)
990 return simplexizePol0();
992 return simplexizePol1();
993 case (int) INTERP_KERNEL::PLANAR_FACE_5:
994 return simplexizePlanarFace5();
995 case (int) INTERP_KERNEL::PLANAR_FACE_6:
996 return simplexizePlanarFace6();
998 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)");
1004 struct MEDCouplingAccVisit
1006 MEDCouplingAccVisit():_new_nb_of_nodes(0) { }
1007 int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; }
1008 int _new_nb_of_nodes;
1014 * This method returns all node ids used in \b this. The data array returned has to be dealt by the caller.
1015 * The returned node ids are sortes ascendingly. This method is closed to MEDCoupling1SGTUMesh::getNodeIdsInUse except
1016 * the format of returned DataArrayInt instance.
1018 * \return a newly allocated DataArrayInt sorted ascendingly of fetched node ids.
1019 * \sa MEDCoupling1SGTUMesh::getNodeIdsInUse, areAllNodesFetched
1021 DataArrayInt *MEDCoupling1SGTUMesh::computeFetchedNodeIds() const
1023 checkConsistencyOfConnectivity();
1024 int nbNodes(getNumberOfNodes());
1025 std::vector<bool> fetchedNodes(nbNodes,false);
1026 computeNodeIdsAlg(fetchedNodes);
1027 int sz((int)std::count(fetchedNodes.begin(),fetchedNodes.end(),true));
1028 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
1029 int *retPtr(ret->getPointer());
1030 for(int i=0;i<nbNodes;i++)
1037 * Finds nodes not used in any cell and returns an array giving a new id to every node
1038 * by excluding the unused nodes, for which the array holds -1. The result array is
1039 * a mapping in "Old to New" mode.
1040 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
1041 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
1042 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
1043 * if the node is unused or a new id else. The caller is to delete this
1044 * array using decrRef() as it is no more needed.
1045 * \throw If the coordinates array is not set.
1046 * \throw If the nodal connectivity of cells is not defined.
1047 * \throw If the nodal connectivity includes an invalid id.
1048 * \sa MEDCoupling1SGTUMesh::computeFetchedNodeIds, areAllNodesFetched
1050 DataArrayInt *MEDCoupling1SGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
1053 int nbOfNodes=getNumberOfNodes();
1054 int nbOfCells=getNumberOfCells();
1055 MCAuto<DataArrayInt> ret(DataArrayInt::New());
1056 ret->alloc(nbOfNodes,1);
1057 int *traducer=ret->getPointer();
1058 std::fill(traducer,traducer+nbOfNodes,-1);
1059 const int *conn=_conn->begin();
1060 int nbNodesPerCell=getNumberOfNodesPerCell();
1061 for(int i=0;i<nbOfCells;i++)
1062 for(int j=0;j<nbNodesPerCell;j++,conn++)
1063 if(*conn>=0 && *conn<nbOfNodes)
1067 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << conn[j] << " not in [0," << nbOfNodes << ") !";
1068 throw INTERP_KERNEL::Exception(oss.str().c_str());
1070 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
1071 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
1076 * This method renumbers only nodal connectivity in \a this. The renumbering is only an offset applied. So this method is a specialization of
1077 * \a renumberNodesInConn. \b WARNING, this method does not check that the resulting node ids in the nodal connectivity is in a valid range !
1079 * \param [in] offset - specifies the offset to be applied on each element of connectivity.
1081 * \sa renumberNodesInConn
1083 void MEDCoupling1SGTUMesh::renumberNodesWithOffsetInConn(int offset)
1085 getNumberOfCells();//only to check that all is well defined.
1086 _conn->applyLin(1,offset);
1091 * Same than renumberNodesInConn(const int *) except that here the format of old-to-new traducer is using map instead
1092 * 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
1095 void MEDCoupling1SGTUMesh::renumberNodesInConn(const INTERP_KERNEL::HashMap<int,int>& newNodeNumbersO2N)
1097 getNumberOfCells();//only to check that all is well defined.
1098 int *begPtr(_conn->getPointer());
1099 int nbElt(_conn->getNumberOfTuples());
1100 int *endPtr(begPtr+nbElt);
1101 for(int *it=begPtr;it!=endPtr;it++)
1103 INTERP_KERNEL::HashMap<int,int>::const_iterator it2(newNodeNumbersO2N.find(*it));
1104 if(it2!=newNodeNumbersO2N.end())
1110 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::renumberNodesInConn : At pos #" << std::distance(begPtr,it) << " of nodal connectivity value is " << *it << ". Not in map !";
1111 throw INTERP_KERNEL::Exception(oss.str().c_str());
1118 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
1119 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
1120 * This method is a generalization of shiftNodeNumbersInConn().
1121 * \warning This method performs no check of validity of new ids. **Use it with care !**
1122 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
1123 * this->getNumberOfNodes(), in "Old to New" mode.
1124 * See \ref numbering for more info on renumbering modes.
1125 * \throw If the nodal connectivity of cells is not defined.
1127 void MEDCoupling1SGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
1129 getNumberOfCells();//only to check that all is well defined.
1130 _conn->transformWithIndArr(newNodeNumbersO2N,newNodeNumbersO2N+getNumberOfNodes());
1134 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2)
1136 std::vector<const MEDCoupling1SGTUMesh *> tmp(2);
1137 tmp[0]=const_cast<MEDCoupling1SGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1SGTUMesh *>(mesh2);
1138 return Merge1SGTUMeshes(tmp);
1141 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(std::vector<const MEDCoupling1SGTUMesh *>& a)
1143 std::size_t sz=a.size();
1145 return Merge1SGTUMeshesLL(a);
1146 for(std::size_t ii=0;ii<sz;ii++)
1149 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::Merge1SGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
1150 throw INTERP_KERNEL::Exception(oss.str().c_str());
1152 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
1153 for(std::size_t ii=0;ii<sz;ii++)
1154 if(&(a[ii]->getCellModel())!=cm)
1155 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : all items must have the same geo type !");
1156 std::vector< MCAuto<MEDCoupling1SGTUMesh> > bb(sz);
1157 std::vector< const MEDCoupling1SGTUMesh * > aa(sz);
1159 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
1161 const MEDCoupling1SGTUMesh *cur=a[i];
1162 const DataArrayDouble *coo=cur->getCoords();
1164 spaceDim=coo->getNumberOfComponents();
1167 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : no spaceDim specified ! unable to perform merge !");
1168 for(std::size_t i=0;i<sz;i++)
1170 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
1173 return Merge1SGTUMeshesLL(aa);
1177 * \throw If presence of a null instance in the input vector \a a.
1178 * \throw If a is empty
1180 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::vector<const MEDCoupling1SGTUMesh *>& a)
1183 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : input array must be NON EMPTY !");
1184 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1186 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : null instance in the first element of input vector !");
1187 std::vector<const DataArrayInt *> ncs(a.size());
1188 (*it)->getNumberOfCells();//to check that all is OK
1189 const DataArrayDouble *coords=(*it)->getCoords();
1190 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1191 ncs[0]=(*it)->getNodalConnectivity();
1193 for(int i=1;it!=a.end();i++,it++)
1196 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : presence of a null instance in the input vector !");
1197 if(cm!=&((*it)->getCellModel()))
1198 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1199 (*it)->getNumberOfCells();//to check that all is OK
1200 ncs[i]=(*it)->getNodalConnectivity();
1201 if(coords!=(*it)->getCoords())
1202 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : not lying on same coords !");
1204 MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1205 ret->setCoords(coords);
1206 ret->_conn=DataArrayInt::Aggregate(ncs);
1211 * Assume that all instances in \a a are non null. If null it leads to a crash. That's why this method is assigned to be low level (LL)
1213 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector<const MEDCoupling1SGTUMesh *>& a)
1216 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : input array must be NON EMPTY !");
1217 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1218 int nbOfCells=(*it)->getNumberOfCells();
1219 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1220 int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
1222 for(;it!=a.end();it++)
1224 if(cm!=&((*it)->getCellModel()))
1225 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1226 nbOfCells+=(*it)->getNumberOfCells();
1228 std::vector<const MEDCouplingPointSet *> aps(a.size());
1229 std::copy(a.begin(),a.end(),aps.begin());
1230 MCAuto<DataArrayDouble> pts=MergeNodesArray(aps);
1231 MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1232 ret->setCoords(pts);
1233 MCAuto<DataArrayInt> c=DataArrayInt::New();
1234 c->alloc(nbOfCells*nbNodesPerCell,1);
1235 int *cPtr=c->getPointer();
1237 for(it=a.begin();it!=a.end();it++)
1239 int curConnLgth=(*it)->getNodalConnectivityLength();
1240 const int *curC=(*it)->_conn->begin();
1241 cPtr=std::transform(curC,curC+curConnLgth,cPtr,std::bind2nd(std::plus<int>(),offset));
1242 offset+=(*it)->getNumberOfNodes();
1245 ret->setNodalConnectivity(c);
1249 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
1251 int ncell=getNumberOfCells();
1252 MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1253 ret->setCoords(_coords);
1254 std::size_t nbOfElemsRet=std::distance(begin,end);
1255 const int *inConn=_conn->getConstPointer();
1256 int sz=getNumberOfNodesPerCell();
1257 MCAuto<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1258 int *connPtr=connRet->getPointer();
1259 for(const int *work=begin;work!=end;work++,connPtr+=sz)
1261 if(*work>=0 && *work<ncell)
1262 std::copy(inConn+(work[0])*sz,inConn+(work[0]+1)*sz,connPtr);
1265 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !";
1266 throw INTERP_KERNEL::Exception(oss.str().c_str());
1270 ret->copyTinyInfoFrom(this);
1274 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoordsSlice(int start, int end, int step) const
1276 int ncell=getNumberOfCells();
1277 int nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoordsSlice : ");
1278 MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1279 ret->setCoords(_coords);
1280 const int *inConn=_conn->getConstPointer();
1281 int sz=getNumberOfNodesPerCell();
1282 MCAuto<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1283 int *connPtr=connRet->getPointer();
1285 for(int i=0;i<nbOfElemsRet;i++,connPtr+=sz,curId+=step)
1287 if(curId>=0 && curId<ncell)
1288 std::copy(inConn+curId*sz,inConn+(curId+1)*sz,connPtr);
1291 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoordsSlice : On pos #" << i << " input cell id =" << curId << " should be in [0," << ncell << ") !";
1292 throw INTERP_KERNEL::Exception(oss.str().c_str());
1296 ret->copyTinyInfoFrom(this);
1300 void MEDCoupling1SGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
1302 int sz((int)nodeIdsInUse.size());
1303 for(const int *conn=_conn->begin();conn!=_conn->end();conn++)
1305 if(*conn>=0 && *conn<sz)
1306 nodeIdsInUse[*conn]=true;
1309 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeFetchedNodeIds : At pos #" << std::distance(_conn->begin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !";
1310 throw INTERP_KERNEL::Exception(oss.str().c_str());
1315 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(int spaceDim) const
1317 MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1318 MCAuto<DataArrayInt> tmp1;
1319 const DataArrayInt *nodalConn(_conn);
1322 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
1329 MCAuto<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
1330 ret->setCoords(coords);
1333 ret->setCoords(_coords);
1337 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol0()
1339 int nbOfCells=getNumberOfCells();
1340 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1341 return DataArrayInt::Range(0,nbOfCells,1);
1342 MCAuto<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1343 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1344 const int *c(_conn->begin());
1345 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1346 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1348 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[2];
1349 newConnPtr[3]=c[0]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1350 retPtr[0]=i; retPtr[1]=i;
1353 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1358 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol1()
1360 int nbOfCells=getNumberOfCells();
1361 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1362 return DataArrayInt::Range(0,nbOfCells,1);
1363 MCAuto<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1364 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1365 const int *c(_conn->begin());
1366 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1367 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1369 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[3];
1370 newConnPtr[3]=c[1]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1371 retPtr[0]=i; retPtr[1]=i;
1374 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1379 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace5()
1381 int nbOfCells=getNumberOfCells();
1382 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1383 return DataArrayInt::Range(0,nbOfCells,1);
1384 MCAuto<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(5*4*nbOfCells,1);
1385 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(5*nbOfCells,1);
1386 const int *c(_conn->begin());
1387 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1388 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=20,retPtr+=5)
1390 for(int j=0;j<20;j++)
1391 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_5_WO[j]];
1392 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i;
1395 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1400 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace6()
1402 int nbOfCells=getNumberOfCells();
1403 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1404 return DataArrayInt::Range(0,nbOfCells,1);
1405 MCAuto<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(6*4*nbOfCells,1);
1406 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(6*nbOfCells,1);
1407 const int *c(_conn->begin());
1408 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1409 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=24,retPtr+=6)
1411 for(int j=0;j<24;j++)
1412 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_6_WO[j]];
1413 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i; retPtr[5]=i;
1416 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1421 void MEDCoupling1SGTUMesh::reprQuickOverview(std::ostream& stream) const
1423 stream << "MEDCoupling1SGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
1424 stream << " Mesh dimension : " << getMeshDimension() << ".";
1426 { stream << " No coordinates set !"; return ; }
1427 if(!_coords->isAllocated())
1428 { stream << " Coordinates set but not allocated !"; return ; }
1429 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
1430 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
1431 if(!(const DataArrayInt *)_conn)
1432 { stream << std::endl << "Nodal connectivity NOT set !"; return ; }
1433 if(_conn->isAllocated())
1435 if(_conn->getNumberOfComponents()==1)
1436 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
1440 void MEDCoupling1SGTUMesh::checkFullyDefined() const
1442 if(!((const DataArrayInt *)_conn) || !((const DataArrayDouble *)_coords))
1443 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFullyDefined : part of this is not fully defined.");
1447 * First step of unserialization process.
1449 bool MEDCoupling1SGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
1451 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEmptyMesh : not implemented yet !");
1454 void MEDCoupling1SGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
1457 double time=getTime(it,order);
1458 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
1460 littleStrings.push_back(getName());
1461 littleStrings.push_back(getDescription());
1462 littleStrings.push_back(getTimeUnit());
1464 std::vector<std::string> littleStrings2,littleStrings3;
1465 if((const DataArrayDouble *)_coords)
1466 _coords->getTinySerializationStrInformation(littleStrings2);
1467 if((const DataArrayInt *)_conn)
1468 _conn->getTinySerializationStrInformation(littleStrings3);
1469 int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size());
1470 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
1471 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
1473 tinyInfo.push_back(getCellModelEnum());
1474 tinyInfo.push_back(it);
1475 tinyInfo.push_back(order);
1476 std::vector<int> tinyInfo2,tinyInfo3;
1477 if((const DataArrayDouble *)_coords)
1478 _coords->getTinySerializationIntInformation(tinyInfo2);
1479 if((const DataArrayInt *)_conn)
1480 _conn->getTinySerializationIntInformation(tinyInfo3);
1481 int sz2((int)tinyInfo2.size()),sz3((int)tinyInfo3.size());
1482 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3);
1483 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1484 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
1486 tinyInfoD.push_back(time);
1489 void MEDCoupling1SGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
1491 std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+tinyInfo[5]);
1492 std::vector<int> tinyInfo1(tinyInfo.begin()+7+tinyInfo[5],tinyInfo.begin()+7+tinyInfo[5]+tinyInfo[6]);
1493 a1->resizeForUnserialization(tinyInfo1);
1494 a2->resizeForUnserialization(tinyInfo2);
1497 void MEDCoupling1SGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
1500 if((const DataArrayInt *)_conn)
1501 if(_conn->isAllocated())
1502 sz=_conn->getNbOfElems();
1503 a1=DataArrayInt::New();
1505 if(sz!=0 && (const DataArrayInt *)_conn)
1506 std::copy(_conn->begin(),_conn->end(),a1->getPointer());
1508 if((const DataArrayDouble *)_coords)
1509 if(_coords->isAllocated())
1510 sz=_coords->getNbOfElems();
1511 a2=DataArrayDouble::New();
1513 if(sz!=0 && (const DataArrayDouble *)_coords)
1514 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
1517 void MEDCoupling1SGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
1518 const std::vector<std::string>& littleStrings)
1520 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
1521 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
1522 setName(littleStrings[0]);
1523 setDescription(littleStrings[1]);
1524 setTimeUnit(littleStrings[2]);
1525 setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
1526 int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]);
1528 _coords=DataArrayDouble::New();
1529 std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+sz2);
1530 _coords->resizeForUnserialization(tinyInfo2);
1531 std::copy(a2->begin(),a2->end(),_coords->getPointer());
1532 _conn=DataArrayInt::New();
1533 std::vector<int> tinyInfo3(tinyInfo.begin()+7+sz2,tinyInfo.begin()+7+sz2+sz3);
1534 _conn->resizeForUnserialization(tinyInfo3);
1535 std::copy(a1->begin(),a1->end(),_conn->getPointer());
1536 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
1537 _coords->finishUnserialization(tinyInfo2,littleStrings2);
1538 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
1539 _conn->finishUnserialization(tinyInfo3,littleStrings3);
1543 * Checks if \a this and \a other meshes are geometrically equivalent with high
1544 * probability, else an exception is thrown. The meshes are considered equivalent if
1545 * (1) meshes contain the same number of nodes and the same number of elements of the
1546 * same types (2) three cells of the two meshes (first, last and middle) are based
1547 * on coincident nodes (with a specified precision).
1548 * \param [in] other - the mesh to compare with.
1549 * \param [in] prec - the precision used to compare nodes of the two meshes.
1550 * \throw If the two meshes do not match.
1552 void MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
1554 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1555 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1557 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single static geometric type !");
1558 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1562 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1563 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1564 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1565 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1566 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1567 if(c1->getHashCode()!=c2->getHashCode())
1568 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1571 MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
1574 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
1575 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1577 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
1578 std::vector<const MEDCoupling1SGTUMesh *> ms(2);
1581 return Merge1SGTUMeshesOnSameCoords(ms);
1584 void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const
1586 checkFullyDefined();
1587 int nbOfNodes=getNumberOfNodes();
1588 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
1589 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
1590 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
1591 const int *conn=_conn->begin();
1592 int nbOfCells=getNumberOfCells();
1593 int nbOfEltsInRevNodal=0;
1594 int nbOfNodesPerCell=getNumberOfNodesPerCell();
1595 for(int eltId=0;eltId<nbOfCells;eltId++)
1597 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1599 if(conn[0]>=0 && conn[0]<nbOfNodes)
1601 nbOfEltsInRevNodal++;
1602 revNodalIndxPtr[conn[0]+1]++;
1606 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
1607 throw INTERP_KERNEL::Exception(oss.str().c_str());
1611 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
1612 conn=_conn->begin();
1613 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
1614 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
1615 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
1616 for(int eltId=0;eltId<nbOfCells;eltId++)
1618 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1620 *std::find_if(revNodalPtr+revNodalIndxPtr[*conn],revNodalPtr+revNodalIndxPtr[*conn+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
1626 * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null.
1628 void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn)
1631 nodalConn->incrRef();
1637 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
1639 DataArrayInt *MEDCoupling1SGTUMesh::getNodalConnectivity() const
1641 const DataArrayInt *ret(_conn);
1642 return const_cast<DataArrayInt *>(ret);
1646 * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted,
1647 * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter.
1648 * If a nodal connectivity previouly existed before the call of this method, it will be reset.
1650 * \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain.
1652 void MEDCoupling1SGTUMesh::allocateCells(int nbOfCells)
1655 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !");
1656 _conn=DataArrayInt::New();
1657 _conn->reserve(getNumberOfNodesPerCell()*nbOfCells);
1662 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
1664 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
1665 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
1666 * \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
1667 * attached to \a this.
1668 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
1670 void MEDCoupling1SGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd)
1672 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
1673 int ref=getNumberOfNodesPerCell();
1676 DataArrayInt *c(_conn);
1678 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
1680 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !");
1684 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this (";
1685 oss << ref << ") !";
1686 throw INTERP_KERNEL::Exception(oss.str().c_str());
1691 * This method builds the dual mesh of \a this and returns it.
1693 * \return MEDCoupling1SGTUMesh * - newly object created to be managed by the caller.
1694 * \throw If \a this is not a mesh containing only simplex cells.
1695 * \throw If \a this is not correctly allocated (coordinates and connectivities have to be correctly set !).
1696 * \throw If at least one node in \a this is orphan (without any simplex cell lying on it !)
1698 MEDCoupling1GTUMesh *MEDCoupling1SGTUMesh::computeDualMesh() const
1700 const INTERP_KERNEL::CellModel& cm(getCellModel());
1702 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : this mesh is not a simplex mesh ! Please invoke simplexize of tetrahedrize on this before calling this method !");
1703 switch(getMeshDimension())
1706 return computeDualMesh3D();
1708 return computeDualMesh2D();
1710 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : meshdimension must be in [2,3] !");
1715 * This method explode each NORM_HEXA8 cells in \a this into 6 NORM_QUAD4 cells and put the result into the MEDCoupling1SGTUMesh returned instance.
1717 * \return MEDCoupling1SGTUMesh * - a newly allocated instances (to be managed by the caller) storing the result of the explosion.
1718 * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
1719 * \throw If \a this is not properly allocated.
1721 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4() const
1723 const INTERP_KERNEL::CellModel& cm(getCellModel());
1724 if(cm.getEnum()!=INTERP_KERNEL::NORM_HEXA8)
1725 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4 : this method can be applied only on HEXA8 mesh !");
1726 int nbHexa8(getNumberOfCells());
1727 const int *inConnPtr(getNodalConnectivity()->begin());
1728 MCAuto<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(getName(),INTERP_KERNEL::NORM_QUAD4));
1729 MCAuto<DataArrayInt> c(DataArrayInt::New()); c->alloc(nbHexa8*6*4,1);
1730 int *cPtr(c->getPointer());
1731 for(int i=0;i<nbHexa8;i++,inConnPtr+=8)
1733 for(int j=0;j<6;j++,cPtr+=4)
1734 cm.fillSonCellNodalConnectivity(j,inConnPtr,cPtr);
1736 ret->setCoords(getCoords());
1737 ret->setNodalConnectivity(c);
1742 * This method starts from an unstructured mesh that hides in reality a cartesian mesh.
1743 * If it is not the case, an exception will be thrown.
1744 * This method returns three objects : The cartesian mesh geometrically equivalent to \a this (within a precision of \a eps) and a permutation of cells
1745 * and a permutation of nodes.
1747 * - this[cellPerm[i]]=ret[i]
1749 * \param [out] cellPerm the permutation array of size \c this->getNumberOfCells()
1750 * \param [out] nodePerm the permutation array of size \c this->getNumberOfNodes()
1751 * \return MEDCouplingCMesh * - a newly allocated mesh that is the result of the structurization of \a this.
1753 MEDCouplingCMesh *MEDCoupling1SGTUMesh::structurizeMe(DataArrayInt *& cellPerm, DataArrayInt *& nodePerm, double eps) const
1755 checkConsistencyLight();
1756 int spaceDim(getSpaceDimension()),meshDim(getMeshDimension()),nbNodes(getNumberOfNodes());
1757 if(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim)!=getCellModelEnum())
1758 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::structurizeMe : the unique geo type in this is not compatible with the geometric type regarding mesh dimension !");
1759 MCAuto<MEDCouplingCMesh> cm(MEDCouplingCMesh::New());
1760 for(int i=0;i<spaceDim;i++)
1762 std::vector<int> tmp(1,i);
1763 MCAuto<DataArrayDouble> elt(static_cast<DataArrayDouble*>(getCoords()->keepSelectedComponents(tmp)));
1764 elt=elt->getDifferentValues(eps);
1766 cm->setCoordsAt(i,elt);
1768 if(nbNodes!=cm->getNumberOfNodes())
1769 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 ?");
1771 { cm->copyTinyInfoFrom(this); }
1772 catch(INTERP_KERNEL::Exception&) { }
1773 MCAuto<MEDCouplingUMesh> um(cm->buildUnstructured()),self(buildUnstructured());
1774 self->checkGeoEquivalWith(um,12,eps,cellPerm,nodePerm);
1780 bool UpdateHexa8Cell(int validAxis, int neighId, const int *validConnQuad4NeighSide, int *allFacesNodalConn, int *myNeighbours)
1782 static const int TAB[48]={
1790 static const int TAB2[6]={0,0,3,3,3,3};
1791 if(myNeighbours[validAxis]==neighId && allFacesNodalConn[4*validAxis+0]==validConnQuad4NeighSide[TAB2[validAxis]])
1793 int oldAxis((int)std::distance(myNeighbours,std::find(myNeighbours,myNeighbours+6,neighId)));
1794 std::size_t pos(std::distance(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,std::find(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS+6,oldAxis)));
1795 std::size_t pos0(pos/2),pos1(pos%2);
1796 int oldAxisOpp(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[2*pos0+(pos1+1)%2]);
1797 int oldConn[8],myConn2[8]={-1,-1,-1,-1,-1,-1,-1,-1},myConn[8],edgeConn[2],allFacesTmp[24],neighTmp[6];
1798 oldConn[0]=allFacesNodalConn[0]; oldConn[1]=allFacesNodalConn[1]; oldConn[2]=allFacesNodalConn[2]; oldConn[3]=allFacesNodalConn[3];
1799 oldConn[4]=allFacesNodalConn[4]; oldConn[5]=allFacesNodalConn[7]; oldConn[6]=allFacesNodalConn[6]; oldConn[7]=allFacesNodalConn[5];
1800 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_HEXA8));
1801 for(int i=0;i<4;i++)
1802 myConn2[i]=validConnQuad4NeighSide[(4-i+TAB2[validAxis])%4];
1803 for(int i=0;i<4;i++)
1805 int nodeId(myConn2[i]);//the node id for which the opposite one will be found
1807 INTERP_KERNEL::NormalizedCellType typeOfSon;
1808 for(int j=0;j<12 && !found;j++)
1810 cm.fillSonEdgesNodalConnectivity3D(j,oldConn,-1,edgeConn,typeOfSon);
1811 if(edgeConn[0]==nodeId || edgeConn[1]==nodeId)
1813 if(std::find(allFacesNodalConn+4*oldAxisOpp,allFacesNodalConn+4*oldAxisOpp+4,edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0])!=allFacesNodalConn+4*oldAxisOpp+4)
1815 myConn2[i+4]=edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0];
1821 throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error !");
1823 const int *myTab(TAB+8*validAxis);
1824 for(int i=0;i<8;i++)
1825 myConn[i]=myConn2[myTab[i]];
1826 for(int i=0;i<6;i++)
1828 cm.fillSonCellNodalConnectivity(i,myConn,allFacesTmp+4*i);
1829 std::set<int> s(allFacesTmp+4*i,allFacesTmp+4*i+4);
1831 for(int j=0;j<6 && !found;j++)
1833 std::set<int> s1(allFacesNodalConn+4*j,allFacesNodalConn+4*j+4);
1836 neighTmp[i]=myNeighbours[j];
1841 throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error #2 !");
1843 std::copy(allFacesTmp,allFacesTmp+24,allFacesNodalConn);
1844 std::copy(neighTmp,neighTmp+6,myNeighbours);
1851 * 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
1852 * homogeneous. If it succeeds the result of MEDCouplingUMesh::tetrahedrize will return a conform mesh.
1854 * \return DataArrayInt * - a newly allocated array (to be managed by the caller) containing renumbered cell ids.
1856 * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
1857 * \throw If \a this is not properly allocated.
1858 * \sa MEDCouplingUMesh::tetrahedrize, MEDCouplingUMesh::simplexize.
1860 DataArrayInt *MEDCoupling1SGTUMesh::sortHexa8EachOther()
1862 MCAuto<MEDCoupling1SGTUMesh> quads(explodeEachHexa8To6Quad4());//checks that only hexa8
1863 int nbHexa8(getNumberOfCells()),*cQuads(quads->getNodalConnectivity()->getPointer());
1864 MCAuto<DataArrayInt> neighOfQuads(DataArrayInt::New()); neighOfQuads->alloc(nbHexa8*6,1); neighOfQuads->fillWithValue(-1);
1865 int *ptNeigh(neighOfQuads->getPointer());
1866 {//neighOfQuads tells for each face of each Quad8 which cell (if!=-1) is connected to this face.
1867 MCAuto<MEDCouplingUMesh> quadsTmp(quads->buildUnstructured());
1868 MCAuto<DataArrayInt> ccSafe,cciSafe;
1869 DataArrayInt *cc(0),*cci(0);
1870 quadsTmp->findCommonCells(3,0,cc,cci);
1871 ccSafe=cc; cciSafe=cci;
1872 const int *ccPtr(ccSafe->begin()),nbOfPair(cci->getNumberOfTuples()-1);
1873 for(int i=0;i<nbOfPair;i++)
1874 { ptNeigh[ccPtr[2*i+0]]=ccPtr[2*i+1]/6; ptNeigh[ccPtr[2*i+1]]=ccPtr[2*i+0]/6; }
1876 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
1877 std::vector<bool> fetched(nbHexa8,false);
1878 std::vector<bool>::iterator it(std::find(fetched.begin(),fetched.end(),false));
1879 while(it!=fetched.end())//it will turns as time as number of connected zones
1881 int cellId((int)std::distance(fetched.begin(),it));//it is the seed of the connected zone.
1882 std::set<int> s; s.insert(cellId);//s contains already organized.
1885 std::set<int> sNext;
1886 for(std::set<int>::const_iterator it0=s.begin();it0!=s.end();it0++)
1889 int *myNeighb(ptNeigh+6*(*it0));
1890 for(int i=0;i<6;i++)
1892 if(myNeighb[i]!=-1 && !fetched[myNeighb[i]])
1894 std::size_t pos(std::distance(HEXA8_FACE_PAIRS,std::find(HEXA8_FACE_PAIRS,HEXA8_FACE_PAIRS+6,i)));
1895 std::size_t pos0(pos/2),pos1(pos%2);
1896 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]))
1897 ret->pushBackSilent(myNeighb[i]);
1898 fetched[myNeighb[i]]=true;
1899 sNext.insert(myNeighb[i]);
1905 it=std::find(fetched.begin(),fetched.end(),false);
1909 int *conn(getNodalConnectivity()->getPointer());
1910 for(const int *pt=ret->begin();pt!=ret->end();pt++)
1913 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];
1914 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];
1921 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh3D() const
1923 static const int DUAL_TETRA_0[36]={
1924 4,1,0, 6,0,3, 7,3,1,
1925 4,0,1, 5,2,0, 8,1,2,
1926 6,3,0, 5,0,2, 9,2,3,
1929 static const int DUAL_TETRA_1[36]={
1930 8,4,10, 11,5,8, 10,7,11,
1931 9,4,8, 8,5,12, 12,6,9,
1932 10,4,9, 9,6,13, 13,7,10,
1933 12,5,11, 13,6,12, 11,7,13
1935 static const int FACEID_NOT_SH_NODE[4]={2,3,1,0};
1936 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TETRA4)
1937 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh3D : only TETRA4 supported !");
1938 checkFullyDefined();
1939 MCAuto<MEDCouplingUMesh> thisu(buildUnstructured());
1940 MCAuto<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1941 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1942 const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1943 MCAuto<DataArrayInt> d1Arr(DataArrayInt::New()),di1Arr(DataArrayInt::New()),rd1Arr(DataArrayInt::New()),rdi1Arr(DataArrayInt::New());
1944 MCAuto<MEDCouplingUMesh> edges(thisu->explode3DMeshTo1D(d1Arr,di1Arr,rd1Arr,rdi1Arr));
1945 const int *d1(d1Arr->begin());
1946 MCAuto<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1947 MCAuto<MEDCouplingUMesh> faces(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
1948 const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
1949 MCAuto<DataArrayDouble> edgesBaryArr(edges->computeCellCenterOfMass()),facesBaryArr(faces->computeCellCenterOfMass()),baryArr(computeCellCenterOfMass());
1950 const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+faces->getNumberOfCells()),offset1(offset0+edges->getNumberOfCells());
1952 std::vector<const DataArrayDouble *> v(4); v[0]=getCoords(); v[1]=facesBaryArr; v[2]=edgesBaryArr; v[3]=baryArr;
1953 MCAuto<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0; facesBaryArr=0;
1954 std::string name("DualOf_"); name+=getName();
1955 MCAuto<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYHED)); ret->setCoords(zeArr);
1956 MCAuto<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1957 for(int i=0;i<nbOfNodes;i++,revNodI++)
1959 int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1960 if(nbOfCellsSharingNode==0)
1962 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh3D : Node #" << i << " is orphan !";
1963 throw INTERP_KERNEL::Exception(oss.str().c_str());
1965 for(int j=0;j<nbOfCellsSharingNode;j++)
1967 int curCellId(revNod[revNodI[0]+j]);
1968 const int *connOfCurCell(nodal+4*curCellId);
1969 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1970 if(j!=0) cArr->pushBackSilent(-1);
1973 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;
1974 tmp[2]=curCellId+offset1; tmp[3]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+2]]+nbOfNodes;
1976 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;
1977 tmp[7]=curCellId+offset1; tmp[8]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+5]]+nbOfNodes;
1979 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;
1980 tmp[12]=curCellId+offset1; tmp[13]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+8]]+nbOfNodes;
1981 cArr->insertAtTheEnd(tmp,tmp+14);
1983 for(int k=0;k<4;k++)
1985 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1987 const int *faceId(d2+4*curCellId+k);
1988 if(rdi2[*faceId+1]-rdi2[*faceId]==1)
1990 int tmp2[5]; tmp2[0]=-1; tmp2[1]=i;
1991 tmp2[2]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+0]-8]+offset0;
1992 tmp2[3]=d2[4*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+1]-4]+nbOfNodes;
1993 tmp2[4]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+2]-8]+offset0;
1994 cArr->insertAtTheEnd(tmp2,tmp2+5);
2000 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
2002 ret->setNodalConnectivity(cArr,ciArr);
2006 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh2D() const
2008 static const int DUAL_TRI_0[6]={0,2, 1,0, 2,1};
2009 static const int DUAL_TRI_1[6]={-3,+5, +3,-4, +4,-5};
2010 static const int FACEID_NOT_SH_NODE[3]={1,2,0};
2011 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TRI3)
2012 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh2D : only TRI3 supported !");
2013 checkFullyDefined();
2014 MCAuto<MEDCouplingUMesh> thisu(buildUnstructured());
2015 MCAuto<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
2016 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
2017 const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
2018 MCAuto<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
2019 MCAuto<MEDCouplingUMesh> edges(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
2020 const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
2021 MCAuto<DataArrayDouble> edgesBaryArr(edges->computeCellCenterOfMass()),baryArr(computeCellCenterOfMass());
2022 const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+edges->getNumberOfCells());
2024 std::vector<const DataArrayDouble *> v(3); v[0]=getCoords(); v[1]=edgesBaryArr; v[2]=baryArr;
2025 MCAuto<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0;
2026 std::string name("DualOf_"); name+=getName();
2027 MCAuto<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYGON)); ret->setCoords(zeArr);
2028 MCAuto<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
2029 for(int i=0;i<nbOfNodes;i++,revNodI++)
2031 int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
2032 if(nbOfCellsSharingNode==0)
2034 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh2D : Node #" << i << " is orphan !";
2035 throw INTERP_KERNEL::Exception(oss.str().c_str());
2037 std::vector< std::vector<int> > polyg;
2038 for(int j=0;j<nbOfCellsSharingNode;j++)
2040 int curCellId(revNod[revNodI[0]+j]);
2041 const int *connOfCurCell(nodal+3*curCellId);
2042 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
2043 std::vector<int> locV(3);
2044 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;
2045 polyg.push_back(locV);
2047 for(int k=0;k<3;k++)
2049 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
2051 const int *edgeId(d2+3*curCellId+k);
2052 if(rdi2[*edgeId+1]-rdi2[*edgeId]==1)
2054 std::vector<int> locV2(2);
2055 int zeLocEdgeIdRel(DUAL_TRI_1[2*nodePosInCurCell+kk]);
2056 if(zeLocEdgeIdRel>0)
2057 { locV2[0]=d2[3*curCellId+zeLocEdgeIdRel-3]+nbOfNodes; locV2[1]=i; }
2059 { locV2[0]=i; locV2[1]=d2[3*curCellId-zeLocEdgeIdRel-3]+nbOfNodes; }
2060 polyg.push_back(locV2);
2066 std::vector<int> zePolyg(MEDCoupling1DGTUMesh::BuildAPolygonFromParts(polyg));
2067 cArr->insertAtTheEnd(zePolyg.begin(),zePolyg.end());
2068 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
2070 ret->setNodalConnectivity(cArr,ciArr);
2075 * This method aggregate the bbox of each cell and put it into bbox
2077 * \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)
2078 * For all other cases this input parameter is ignored.
2079 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
2081 * \throw If \a this is not fully set (coordinates and connectivity).
2082 * \throw If a cell in \a this has no valid nodeId.
2084 DataArrayDouble *MEDCoupling1SGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
2086 int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()),nbOfNodesPerCell(getNumberOfNodesPerCell());
2087 MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
2088 double *bbox(ret->getPointer());
2089 for(int i=0;i<nbOfCells*spaceDim;i++)
2091 bbox[2*i]=std::numeric_limits<double>::max();
2092 bbox[2*i+1]=-std::numeric_limits<double>::max();
2094 const double *coordsPtr(_coords->getConstPointer());
2095 const int *conn(_conn->getConstPointer());
2096 for(int i=0;i<nbOfCells;i++)
2099 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
2102 if(nodeId>=0 && nodeId<nbOfNodes)
2104 for(int k=0;k<spaceDim;k++)
2106 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
2107 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
2114 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
2115 throw INTERP_KERNEL::Exception(oss.str().c_str());
2122 * 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.
2124 * \return a new instance of field containing the result. The returned instance has to be deallocated by the caller.
2126 MEDCouplingFieldDouble *MEDCoupling1SGTUMesh::computeDiameterField() const
2128 checkFullyDefined();
2129 MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME));
2130 int nbCells(getNumberOfCells());
2131 MCAuto<DataArrayDouble> arr(DataArrayDouble::New());
2132 arr->alloc(nbCells,1);
2133 INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::DiameterCalculator> dc(_cm->buildInstanceOfDiameterCalulator(getSpaceDimension()));
2134 dc->computeFor1SGTUMeshFrmt(nbCells,_conn->begin(),getCoords()->begin(),arr->getPointer());
2137 ret->setName("Diameter");
2143 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New()
2145 return new MEDCoupling1DGTUMesh;
2148 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
2150 if(type==INTERP_KERNEL::NORM_ERROR)
2151 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
2152 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
2155 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !";
2156 throw INTERP_KERNEL::Exception(oss.str().c_str());
2158 return new MEDCoupling1DGTUMesh(name,cm);
2161 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh()
2165 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
2169 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn_indx(other._conn_indx),_conn(other._conn)
2173 const DataArrayInt *c(other._conn);
2175 _conn=c->deepCopy();
2178 _conn_indx=c->deepCopy();
2182 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const
2184 return new MEDCoupling1DGTUMesh(*this,recDeepCpy);
2188 * This method behaves mostly like MEDCoupling1DGTUMesh::deepCopy method, except that only nodal connectivity arrays are deeply copied.
2189 * The coordinates are shared between \a this and the returned instance.
2191 * \return MEDCoupling1DGTUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
2192 * \sa MEDCoupling1DGTUMesh::deepCopy
2194 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::deepCopyConnectivityOnly() const
2196 checkConsistencyLight();
2197 MCAuto<MEDCoupling1DGTUMesh> ret(clone(false));
2198 MCAuto<DataArrayInt> c(_conn->deepCopy()),ci(_conn_indx->deepCopy());
2199 ret->setNodalConnectivity(c,ci);
2203 void MEDCoupling1DGTUMesh::updateTime() const
2205 MEDCoupling1GTUMesh::updateTime();
2206 const DataArrayInt *c(_conn);
2214 std::size_t MEDCoupling1DGTUMesh::getHeapMemorySizeWithoutChildren() const
2216 return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren();
2219 std::vector<const BigMemoryObject *> MEDCoupling1DGTUMesh::getDirectChildrenWithNull() const
2221 std::vector<const BigMemoryObject *> ret(MEDCoupling1GTUMesh::getDirectChildrenWithNull());
2222 ret.push_back((const DataArrayInt *)_conn);
2223 ret.push_back((const DataArrayInt *)_conn_indx);
2227 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::deepCopy() const
2232 bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
2235 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !");
2236 std::ostringstream oss; oss.precision(15);
2237 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2240 reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !";
2243 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
2245 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2250 reason="in connectivity of single dynamic geometric type exactly one among this and other is null !";
2253 if(!c1->isEqualIfNotWhy(*c2,reason))
2255 reason.insert(0,"Nodal connectivity DataArrayInt differs : ");
2258 c1=_conn_indx; c2=otherC->_conn_indx;
2263 reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !";
2266 if(!c1->isEqualIfNotWhy(*c2,reason))
2268 reason.insert(0,"Nodal connectivity index DataArrayInt differs : ");
2274 bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
2277 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
2278 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2281 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
2283 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2288 if(!c1->isEqualWithoutConsideringStr(*c2))
2291 c1=_conn_indx; c2=otherC->_conn_indx;
2296 if(!c1->isEqualWithoutConsideringStr(*c2))
2302 * Checks if \a this and \a other meshes are geometrically equivalent with high
2303 * probability, else an exception is thrown. The meshes are considered equivalent if
2304 * (1) meshes contain the same number of nodes and the same number of elements of the
2305 * same types (2) three cells of the two meshes (first, last and middle) are based
2306 * on coincident nodes (with a specified precision).
2307 * \param [in] other - the mesh to compare with.
2308 * \param [in] prec - the precision used to compare nodes of the two meshes.
2309 * \throw If the two meshes do not match.
2311 void MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
2313 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
2314 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2316 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single dynamic geometric type !");
2317 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2321 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
2322 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2323 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
2324 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2325 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
2326 if(c1->getHashCode()!=c2->getHashCode())
2327 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs");
2329 c1=_conn_indx; c2=otherC->_conn_indx;
2333 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !");
2334 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2335 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !");
2336 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2337 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !");
2338 if(c1->getHashCode()!=c2->getHashCode())
2339 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs");
2343 void MEDCoupling1DGTUMesh::checkConsistencyOfConnectivity() const
2345 const DataArrayInt *c1(_conn);
2348 if(c1->getNumberOfComponents()!=1)
2349 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
2350 if(c1->getInfoOnComponent(0)!="")
2351 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
2352 c1->checkAllocated();
2355 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
2357 int sz2=_conn->getNumberOfTuples();
2361 if(c1->getNumberOfComponents()!=1)
2362 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
2363 c1->checkAllocated();
2364 if(c1->getNumberOfTuples()<1)
2365 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !");
2366 if(c1->getInfoOnComponent(0)!="")
2367 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
2368 int f=c1->front(),ll=c1->back();
2369 if(f<0 || (sz2>0 && f>=sz2))
2371 std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !";
2372 throw INTERP_KERNEL::Exception(oss.str().c_str());
2376 std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !";
2377 throw INTERP_KERNEL::Exception(oss.str().c_str());
2381 std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !";
2382 throw INTERP_KERNEL::Exception(oss.str().c_str());
2386 throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !");
2387 int szOfC1Exp=_conn_indx->back();
2390 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() << " !";
2391 throw INTERP_KERNEL::Exception(oss.str().c_str());
2396 * 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.
2397 * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one.
2398 * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array.
2400 void MEDCoupling1DGTUMesh::checkConsistencyLight() const
2402 MEDCouplingPointSet::checkConsistencyLight();
2403 checkConsistencyOfConnectivity();
2406 void MEDCoupling1DGTUMesh::checkConsistency(double eps) const
2408 checkConsistencyLight();
2409 const DataArrayInt *c1(_conn),*c2(_conn_indx);
2410 if(!c2->isMonotonic(true))
2411 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkConsistency : the nodal connectivity index is expected to be increasing monotinic !");
2413 int nbOfTuples=c1->getNumberOfTuples();
2414 int nbOfNodes=getNumberOfNodes();
2415 const int *w(c1->begin());
2416 for(int i=0;i<nbOfTuples;i++,w++)
2418 if(*w==-1) continue;
2419 if(*w<0 || *w>=nbOfNodes)
2421 std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !";
2422 throw INTERP_KERNEL::Exception(oss.str().c_str());
2427 int MEDCoupling1DGTUMesh::getNumberOfCells() const
2429 checkConsistencyOfConnectivity();//do not remove
2430 return _conn_indx->getNumberOfTuples()-1;
2434 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2435 * For each cell in \b this the number of nodes constituting cell is computed.
2436 * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned.
2437 * So for pohyhedrons some nodes can be counted several times in the returned result.
2439 * \return a newly allocated array
2441 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const
2443 checkConsistencyLight();
2444 _conn_indx->checkMonotonic(true);
2445 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2446 return _conn_indx->deltaShiftIndex();
2448 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2449 MCAuto<DataArrayInt> ret=DataArrayInt::New();
2450 ret->alloc(nbOfCells,1);
2451 int *retPtr=ret->getPointer();
2452 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2453 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2454 *retPtr=ci[1]-ci[0]-std::count(c+ci[0],c+ci[1],-1);
2459 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2460 * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed.
2462 * \return a newly allocated array
2464 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const
2466 checkConsistencyLight();
2467 _conn_indx->checkMonotonic(true);
2468 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG)
2469 return _conn_indx->deltaShiftIndex();
2470 if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG)
2472 MCAuto<DataArrayInt> ret=_conn_indx->deltaShiftIndex();
2473 ret->applyDivideBy(2);
2477 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2478 MCAuto<DataArrayInt> ret=DataArrayInt::New();
2479 ret->alloc(nbOfCells,1);
2480 int *retPtr=ret->getPointer();
2481 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2482 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2483 *retPtr=std::count(c+ci[0],c+ci[1],-1)+1;
2488 * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell,
2489 * will be counted only once here whereas it will be counted several times in MEDCoupling1DGTUMesh::computeNbOfNodesPerCell method.
2491 * \return DataArrayInt * - new object to be deallocated by the caller.
2492 * \sa MEDCoupling1DGTUMesh::computeNbOfNodesPerCell
2494 DataArrayInt *MEDCoupling1DGTUMesh::computeEffectiveNbOfNodesPerCell() const
2496 checkConsistencyLight();
2497 _conn_indx->checkMonotonic(true);
2498 int nbOfCells(_conn_indx->getNumberOfTuples()-1);
2499 MCAuto<DataArrayInt> ret=DataArrayInt::New();
2500 ret->alloc(nbOfCells,1);
2501 int *retPtr(ret->getPointer());
2502 const int *ci(_conn_indx->begin()),*c(_conn->begin());
2503 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2505 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2507 std::set<int> s(c+ci[0],c+ci[1]);
2508 *retPtr=(int)s.size();
2513 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2515 std::set<int> s(c+ci[0],c+ci[1]); s.erase(-1);
2516 *retPtr=(int)s.size();
2522 void MEDCoupling1DGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
2524 int nbOfCells(getNumberOfCells());//performs checks
2525 if(cellId>=0 && cellId<nbOfCells)
2527 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2528 int nbOfNodes=stp-strt;
2530 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !");
2531 conn.resize(nbOfNodes);
2532 std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin());
2536 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2537 throw INTERP_KERNEL::Exception(oss.str().c_str());
2541 int MEDCoupling1DGTUMesh::getNumberOfNodesInCell(int cellId) const
2543 int nbOfCells(getNumberOfCells());//performs checks
2544 if(cellId>=0 && cellId<nbOfCells)
2546 const int *conn(_conn->begin());
2547 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2548 return stp-strt-std::count(conn+strt,conn+stp,-1);
2552 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNumberOfNodesInCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2553 throw INTERP_KERNEL::Exception(oss.str().c_str());
2557 std::string MEDCoupling1DGTUMesh::simpleRepr() const
2559 static const char msg0[]="No coordinates specified !";
2560 std::ostringstream ret;
2561 ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
2562 ret << "Description of mesh : \"" << getDescription() << "\"\n";
2564 double tt=getTime(tmpp1,tmpp2);
2565 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
2566 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
2567 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
2570 const int spaceDim=getSpaceDimension();
2571 ret << spaceDim << "\nInfo attached on space dimension : ";
2572 for(int i=0;i<spaceDim;i++)
2573 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
2577 ret << msg0 << "\n";
2578 ret << "Number of nodes : ";
2580 ret << getNumberOfNodes() << "\n";
2582 ret << msg0 << "\n";
2583 ret << "Number of cells : ";
2585 try { checkConsistencyLight(); } catch(INTERP_KERNEL::Exception& /* e */)
2587 ret << "Nodal connectivity arrays are not set or badly set !\n";
2591 ret << getNumberOfCells() << "\n";
2592 ret << "Cell type : " << _cm->getRepr() << "\n";
2596 std::string MEDCoupling1DGTUMesh::advancedRepr() const
2598 std::ostringstream ret;
2599 ret << simpleRepr();
2600 ret << "\nCoordinates array : \n___________________\n\n";
2602 _coords->reprWithoutNameStream(ret);
2604 ret << "No array set !\n";
2605 ret << "\n\nNodal Connectivity : \n____________________\n\n";
2608 try { checkConsistency(); } catch(INTERP_KERNEL::Exception& /* e */)
2610 ret << "Nodal connectivity arrays are not set or badly set !\n";
2615 int nbOfCells=getNumberOfCells();
2616 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2617 for(int i=0;i<nbOfCells;i++,ci++)
2619 ret << "Cell #" << i << " : ";
2620 std::copy(c+ci[0],c+ci[1],std::ostream_iterator<int>(ret," "));
2626 DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const
2628 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2629 int spaceDim=getSpaceDimension();
2630 int nbOfCells=getNumberOfCells();//checkConsistencyLight()
2631 int nbOfNodes=getNumberOfNodes();
2632 ret->alloc(nbOfCells,spaceDim);
2633 double *ptToFill=ret->getPointer();
2634 const double *coor=_coords->begin();
2635 const int *nodal=_conn->begin(),*nodali=_conn_indx->begin();
2637 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2639 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2641 std::fill(ptToFill,ptToFill+spaceDim,0.);
2642 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2644 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2646 if(*nodal>=0 && *nodal<nbOfNodes)
2647 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2650 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2651 throw INTERP_KERNEL::Exception(oss.str().c_str());
2653 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(nodali[1]-nodali[0])));
2658 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !";
2659 throw INTERP_KERNEL::Exception(oss.str().c_str());
2665 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2667 std::fill(ptToFill,ptToFill+spaceDim,0.);
2668 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2671 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2673 if(*nodal==-1) continue;
2674 if(*nodal>=0 && *nodal<nbOfNodes)
2676 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2681 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2682 throw INTERP_KERNEL::Exception(oss.str().c_str());
2686 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./nbOfNod));
2689 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !";
2690 throw INTERP_KERNEL::Exception(oss.str().c_str());
2695 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : at cell #" << i << " the nodal index array is invalid !";
2696 throw INTERP_KERNEL::Exception(oss.str().c_str());
2703 void MEDCoupling1DGTUMesh::renumberCells(const int *old2NewBg, bool check)
2705 int nbCells=getNumberOfCells();
2706 MCAuto<DataArrayInt> o2n=DataArrayInt::New();
2707 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
2709 o2n=o2n->checkAndPreparePermutation();
2711 const int *o2nPtr=o2n->getPointer();
2712 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2713 MCAuto<DataArrayInt> newConn=DataArrayInt::New();
2714 MCAuto<DataArrayInt> newConnI=DataArrayInt::New();
2715 newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1);
2716 newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx);
2718 int *newC=newConn->getPointer(),*newCI=newConnI->getPointer();
2719 for(int i=0;i<nbCells;i++)
2721 int newPos=o2nPtr[i];
2722 int sz=conni[i+1]-conni[i];
2727 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !";
2728 throw INTERP_KERNEL::Exception(oss.str().c_str());
2731 newConnI->computeOffsetsFull(); newCI=newConnI->getPointer();
2733 for(int i=0;i<nbCells;i++,conni++)
2736 std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]);
2739 _conn_indx=newConnI;
2742 MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
2744 if(other->getType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED)
2745 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !");
2746 const MEDCoupling1DGTUMesh *otherC=static_cast<const MEDCoupling1DGTUMesh *>(other);
2747 return Merge1DGTUMeshes(this,otherC);
2750 MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const
2752 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
2753 ret->setCoords(getCoords());
2754 const int *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin();
2755 int nbCells=getNumberOfCells();//checkConsistencyLight
2756 int geoType=(int)getCellModelEnum();
2757 MCAuto<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1);
2758 MCAuto<DataArrayInt> cI=DataArrayInt::New(); cI->alloc(nbCells+1);
2759 int *cPtr=c->getPointer(),*ciPtr=cI->getPointer();
2761 for(int i=0;i<nbCells;i++,ciPtr++)
2763 int sz=nodalConnI[i+1]-nodalConnI[i];
2767 cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr);
2768 ciPtr[1]=ciPtr[0]+sz+1;
2772 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !";
2773 throw INTERP_KERNEL::Exception(oss.str().c_str());
2776 ret->setConnectivity(c,cI,true);
2778 { ret->copyTinyInfoFrom(this); }
2779 catch(INTERP_KERNEL::Exception&) { }
2784 * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes
2786 DataArrayInt *MEDCoupling1DGTUMesh::simplexize(int policy)
2788 int nbOfCells=getNumberOfCells();
2789 MCAuto<DataArrayInt> ret=DataArrayInt::New();
2790 ret->alloc(nbOfCells,1);
2795 void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const
2797 stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
2798 stream << " Mesh dimension : " << getMeshDimension() << ".";
2800 { stream << " No coordinates set !"; return ; }
2801 if(!_coords->isAllocated())
2802 { stream << " Coordinates set but not allocated !"; return ; }
2803 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
2804 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
2806 try { checkConsistencyLight(); } catch(INTERP_KERNEL::Exception& /* e */)
2808 stream << std::endl << "Nodal connectivity NOT set properly !\n";
2812 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
2815 void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
2818 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
2819 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2821 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !");
2822 setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex());
2825 MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
2828 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
2829 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2831 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
2832 std::vector<const MEDCoupling1DGTUMesh *> ms(2);
2835 return Merge1DGTUMeshesOnSameCoords(ms);
2838 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
2840 checkConsistencyLight();
2841 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2842 ret->setCoords(_coords);
2843 DataArrayInt *c=0,*ci=0;
2844 MEDCouplingUMesh::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci);
2845 MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
2846 ret->setNodalConnectivity(c,ci);
2850 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoordsSlice(int start, int end, int step) const
2852 checkConsistencyLight();
2853 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2854 ret->setCoords(_coords);
2855 DataArrayInt *c=0,*ci=0;
2856 MEDCouplingUMesh::ExtractFromIndexedArraysSlice(start,end,step,_conn,_conn_indx,c,ci);
2857 MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
2858 ret->setNodalConnectivity(c,ci);
2862 void MEDCoupling1DGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
2865 int sz((int)nodeIdsInUse.size());
2866 for(const int *conn=_conn->begin();conn!=_conn->end();conn++)
2868 if(*conn>=0 && *conn<sz)
2869 nodeIdsInUse[*conn]=true;
2874 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeNodeIdsAlg : At pos #" << std::distance(_conn->begin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !";
2875 throw INTERP_KERNEL::Exception(oss.str().c_str());
2881 void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const
2883 checkFullyDefined();
2884 int nbOfNodes=getNumberOfNodes();
2885 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
2886 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
2887 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
2888 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2889 int nbOfCells=getNumberOfCells();
2890 int nbOfEltsInRevNodal=0;
2891 for(int eltId=0;eltId<nbOfCells;eltId++)
2893 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2894 if(nbOfNodesPerCell>=0)
2896 for(int j=0;j<nbOfNodesPerCell;j++)
2898 int nodeId=conn[conni[eltId]+j];
2899 if(nodeId==-1) continue;
2900 if(nodeId>=0 && nodeId<nbOfNodes)
2902 nbOfEltsInRevNodal++;
2903 revNodalIndxPtr[nodeId+1]++;
2907 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
2908 throw INTERP_KERNEL::Exception(oss.str().c_str());
2914 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << "nodal connectivity is invalid !";
2915 throw INTERP_KERNEL::Exception(oss.str().c_str());
2918 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
2919 conn=_conn->begin();
2920 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
2921 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
2922 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
2923 for(int eltId=0;eltId<nbOfCells;eltId++)
2925 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2926 for(int j=0;j<nbOfNodesPerCell;j++)
2928 int nodeId=conn[conni[eltId]+j];
2930 *std::find_if(revNodalPtr+revNodalIndxPtr[nodeId],revNodalPtr+revNodalIndxPtr[nodeId+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
2935 void MEDCoupling1DGTUMesh::checkFullyDefined() const
2937 if(!((const DataArrayInt *)_conn) || !((const DataArrayInt *)_conn_indx) || !((const DataArrayDouble *)_coords))
2938 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined.");
2941 bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
2943 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !");
2946 void MEDCoupling1DGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
2949 double time=getTime(it,order);
2950 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
2952 littleStrings.push_back(getName());
2953 littleStrings.push_back(getDescription());
2954 littleStrings.push_back(getTimeUnit());
2956 std::vector<std::string> littleStrings2,littleStrings3,littleStrings4;
2957 if((const DataArrayDouble *)_coords)
2958 _coords->getTinySerializationStrInformation(littleStrings2);
2959 if((const DataArrayInt *)_conn)
2960 _conn->getTinySerializationStrInformation(littleStrings3);
2961 if((const DataArrayInt *)_conn_indx)
2962 _conn_indx->getTinySerializationStrInformation(littleStrings4);
2963 int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size()),sz2((int)littleStrings4.size());
2964 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
2965 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
2966 littleStrings.insert(littleStrings.end(),littleStrings4.begin(),littleStrings4.end());
2968 tinyInfo.push_back(getCellModelEnum());
2969 tinyInfo.push_back(it);
2970 tinyInfo.push_back(order);
2971 std::vector<int> tinyInfo2,tinyInfo3,tinyInfo4;
2972 if((const DataArrayDouble *)_coords)
2973 _coords->getTinySerializationIntInformation(tinyInfo2);
2974 if((const DataArrayInt *)_conn)
2975 _conn->getTinySerializationIntInformation(tinyInfo3);
2976 if((const DataArrayInt *)_conn_indx)
2977 _conn_indx->getTinySerializationIntInformation(tinyInfo4);
2978 int sz3((int)tinyInfo2.size()),sz4((int)tinyInfo3.size()),sz5((int)tinyInfo4.size());
2979 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3); tinyInfo.push_back(sz4); tinyInfo.push_back(sz5);
2980 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
2981 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
2982 tinyInfo.insert(tinyInfo.end(),tinyInfo4.begin(),tinyInfo4.end());
2984 tinyInfoD.push_back(time);
2987 void MEDCoupling1DGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
2989 std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+tinyInfo[6]);
2990 std::vector<int> tinyInfo1(tinyInfo.begin()+9+tinyInfo[6],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]);
2991 std::vector<int> tinyInfo12(tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]+tinyInfo[8]);
2992 MCAuto<DataArrayInt> p1(DataArrayInt::New()); p1->resizeForUnserialization(tinyInfo1);
2993 MCAuto<DataArrayInt> p2(DataArrayInt::New()); p2->resizeForUnserialization(tinyInfo12);
2994 std::vector<const DataArrayInt *> v(2); v[0]=p1; v[1]=p2;
2995 p2=DataArrayInt::Aggregate(v);
2996 a2->resizeForUnserialization(tinyInfo2);
2997 a1->alloc(p2->getNbOfElems(),1);
3000 void MEDCoupling1DGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
3003 if((const DataArrayInt *)_conn)
3004 if(_conn->isAllocated())
3005 sz=_conn->getNbOfElems();
3006 if((const DataArrayInt *)_conn_indx)
3007 if(_conn_indx->isAllocated())
3008 sz+=_conn_indx->getNbOfElems();
3009 a1=DataArrayInt::New();
3011 int *work(a1->getPointer());
3012 if(sz!=0 && (const DataArrayInt *)_conn)
3013 work=std::copy(_conn->begin(),_conn->end(),a1->getPointer());
3014 if(sz!=0 && (const DataArrayInt *)_conn_indx)
3015 std::copy(_conn_indx->begin(),_conn_indx->end(),work);
3017 if((const DataArrayDouble *)_coords)
3018 if(_coords->isAllocated())
3019 sz=_coords->getNbOfElems();
3020 a2=DataArrayDouble::New();
3022 if(sz!=0 && (const DataArrayDouble *)_coords)
3023 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
3026 void MEDCoupling1DGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
3027 const std::vector<std::string>& littleStrings)
3029 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
3030 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
3031 setName(littleStrings[0]);
3032 setDescription(littleStrings[1]);
3033 setTimeUnit(littleStrings[2]);
3034 setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
3035 int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]),sz4(tinyInfo[7]),sz5(tinyInfo[8]);
3037 _coords=DataArrayDouble::New();
3038 std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+sz3);
3039 _coords->resizeForUnserialization(tinyInfo2);
3040 std::copy(a2->begin(),a2->end(),_coords->getPointer());
3041 _conn=DataArrayInt::New();
3042 std::vector<int> tinyInfo3(tinyInfo.begin()+9+sz3,tinyInfo.begin()+9+sz3+sz4);
3043 _conn->resizeForUnserialization(tinyInfo3);
3044 std::copy(a1->begin(),a1->begin()+_conn->getNbOfElems(),_conn->getPointer());
3045 _conn_indx=DataArrayInt::New();
3046 std::vector<int> tinyInfo4(tinyInfo.begin()+9+sz3+sz4,tinyInfo.begin()+9+sz3+sz4+sz5);
3047 _conn_indx->resizeForUnserialization(tinyInfo4);
3048 std::copy(a1->begin()+_conn->getNbOfElems(),a1->end(),_conn_indx->getPointer());
3049 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
3050 _coords->finishUnserialization(tinyInfo2,littleStrings2);
3051 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
3052 _conn->finishUnserialization(tinyInfo3,littleStrings3);
3053 std::vector<std::string> littleStrings4(littleStrings.begin()+3+sz0+sz1,littleStrings.begin()+3+sz0+sz1+sz2);
3054 _conn_indx->finishUnserialization(tinyInfo4,littleStrings4);
3058 * Finds nodes not used in any cell and returns an array giving a new id to every node
3059 * by excluding the unused nodes, for which the array holds -1. The result array is
3060 * a mapping in "Old to New" mode.
3061 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
3062 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
3063 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
3064 * if the node is unused or a new id else. The caller is to delete this
3065 * array using decrRef() as it is no more needed.
3066 * \throw If the coordinates array is not set.
3067 * \throw If the nodal connectivity of cells is not defined.
3068 * \throw If the nodal connectivity includes an invalid id.
3069 * \sa MEDCoupling1DGTUMesh::getNodeIdsInUse, areAllNodesFetched
3071 DataArrayInt *MEDCoupling1DGTUMesh::computeFetchedNodeIds() const
3074 int nbNodes(getNumberOfNodes());
3075 std::vector<bool> fetchedNodes(nbNodes,false);
3076 computeNodeIdsAlg(fetchedNodes);
3077 int sz((int)std::count(fetchedNodes.begin(),fetchedNodes.end(),true));
3078 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
3079 int *retPtr(ret->getPointer());
3080 for(int i=0;i<nbNodes;i++)
3087 * Finds nodes not used in any cell and returns an array giving a new id to every node
3088 * by excluding the unused nodes, for which the array holds -1. The result array is
3089 * a mapping in "Old to New" mode.
3090 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
3091 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
3092 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
3093 * if the node is unused or a new id else. The caller is to delete this
3094 * array using decrRef() as it is no more needed.
3095 * \throw If the coordinates array is not set.
3096 * \throw If the nodal connectivity of cells is not defined.
3097 * \throw If the nodal connectivity includes an invalid id.
3098 * \sa MEDCoupling1DGTUMesh::computeFetchedNodeIds, areAllNodesFetched
3100 DataArrayInt *MEDCoupling1DGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
3103 int nbOfNodes=getNumberOfNodes();
3104 int nbOfCells=getNumberOfCells();//checkConsistencyLight
3105 MCAuto<DataArrayInt> ret=DataArrayInt::New();
3106 ret->alloc(nbOfNodes,1);
3107 int *traducer=ret->getPointer();
3108 std::fill(traducer,traducer+nbOfNodes,-1);
3109 const int *conn=_conn->begin(),*conni(_conn_indx->begin());
3110 for(int i=0;i<nbOfCells;i++,conni++)
3112 int nbNodesPerCell=conni[1]-conni[0];
3113 for(int j=0;j<nbNodesPerCell;j++)
3115 int nodeId=conn[conni[0]+j];
3116 if(nodeId==-1) continue;
3117 if(nodeId>=0 && nodeId<nbOfNodes)
3121 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << nodeId << " not in [0," << nbOfNodes << ") !";
3122 throw INTERP_KERNEL::Exception(oss.str().c_str());
3126 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
3127 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
3132 * This method renumbers only nodal connectivity in \a this. The renumbering is only an offset applied. So this method is a specialization of
3133 * \a renumberNodesInConn. \b WARNING, this method does not check that the resulting node ids in the nodal connectivity is in a valid range !
3135 * \param [in] offset - specifies the offset to be applied on each element of connectivity.
3137 * \sa renumberNodesInConn
3139 void MEDCoupling1DGTUMesh::renumberNodesWithOffsetInConn(int offset)
3141 getNumberOfCells();//only to check that all is well defined.
3143 int nbOfTuples(_conn->getNumberOfTuples());
3144 int *pt(_conn->getPointer());
3145 for(int i=0;i<nbOfTuples;i++,pt++)
3147 if(*pt==-1) continue;
3155 * Same than renumberNodesInConn(const int *) except that here the format of old-to-new traducer is using map instead
3156 * 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
3159 void MEDCoupling1DGTUMesh::renumberNodesInConn(const INTERP_KERNEL::HashMap<int,int>& newNodeNumbersO2N)
3161 getNumberOfCells();//only to check that all is well defined.
3163 int nbElemsIn(getNumberOfNodes()),nbOfTuples(_conn->getNumberOfTuples());
3164 int *pt(_conn->getPointer());
3165 for(int i=0;i<nbOfTuples;i++,pt++)
3167 if(*pt==-1) continue;
3168 if(*pt>=0 && *pt<nbElemsIn)
3170 INTERP_KERNEL::HashMap<int,int>::const_iterator it(newNodeNumbersO2N.find(*pt));
3171 if(it!=newNodeNumbersO2N.end())
3175 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : At pos #" << i << " of connectivity, node id is " << *pt << ". Not in keys of input map !";
3176 throw INTERP_KERNEL::Exception(oss.str().c_str());
3181 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
3182 throw INTERP_KERNEL::Exception(oss.str().c_str());
3190 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
3191 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
3192 * This method is a generalization of shiftNodeNumbersInConn().
3193 * \warning This method performs no check of validity of new ids. **Use it with care !**
3194 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
3195 * this->getNumberOfNodes(), in "Old to New" mode.
3196 * See \ref numbering for more info on renumbering modes.
3197 * \throw If the nodal connectivity of cells is not defined.
3199 void MEDCoupling1DGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
3201 getNumberOfCells();//only to check that all is well defined.
3203 int nbElemsIn(getNumberOfNodes()),nbOfTuples(_conn->getNumberOfTuples());
3204 int *pt(_conn->getPointer());
3205 for(int i=0;i<nbOfTuples;i++,pt++)
3207 if(*pt==-1) continue;
3208 if(*pt>=0 && *pt<nbElemsIn)
3209 *pt=newNodeNumbersO2N[*pt];
3212 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
3213 throw INTERP_KERNEL::Exception(oss.str().c_str());
3221 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
3222 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
3223 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
3224 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
3226 * \param [in] begin input start of array of node ids.
3227 * \param [in] end input end of array of node ids.
3228 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
3229 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
3231 void MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
3233 int nbOfCells=getNumberOfCells();
3234 MCAuto<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
3236 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
3237 std::vector<bool> fastFinder(sz,false);
3238 for(const int *work=begin;work!=end;work++)
3239 if(*work>=0 && *work<sz)
3240 fastFinder[*work]=true;
3241 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
3242 for(int i=0;i<nbOfCells;i++,conni++)
3244 int ref=0,nbOfHit=0;
3245 int nbNodesPerCell=conni[1]-conni[0];
3246 if(nbNodesPerCell>=0)
3248 for(int j=0;j<nbNodesPerCell;j++)
3250 int nodeId=conn[conni[0]+j];
3254 if(fastFinder[nodeId])
3261 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !";
3262 throw INTERP_KERNEL::Exception(oss.str().c_str());
3264 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
3265 cellIdsKept->pushBackSilent(i);
3267 cellIdsKeptArr=cellIdsKept.retn();
3270 void MEDCoupling1DGTUMesh::allocateCells(int nbOfCells)
3273 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !");
3274 _conn=DataArrayInt::New();
3275 _conn->reserve(nbOfCells*3);
3276 _conn_indx=DataArrayInt::New();
3277 _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0);
3282 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
3284 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
3285 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
3286 * \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
3287 * attached to \a this.
3288 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
3290 void MEDCoupling1DGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd)
3292 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
3293 DataArrayInt *c(_conn),*c2(_conn_indx);
3297 if(pos==c->getNumberOfTuples())
3299 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
3300 c2->pushBackSilent(pos+sz);
3304 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !";
3305 throw INTERP_KERNEL::Exception(oss.str().c_str());
3309 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !");
3312 void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex)
3315 nodalConn->incrRef();
3318 nodalConnIndex->incrRef();
3319 _conn_indx=nodalConnIndex;
3324 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
3326 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivity() const
3328 const DataArrayInt *ret(_conn);
3329 return const_cast<DataArrayInt *>(ret);
3333 * \return DataArrayInt * - the internal reference to the nodal connectivity index. The caller is not reponsible to deallocate it.
3335 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const
3337 const DataArrayInt *ret(_conn_indx);
3338 return const_cast<DataArrayInt *>(ret);
3342 * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here".
3343 * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity).
3344 * 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.
3346 * 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.
3348 * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal
3349 * connectivity arrays are different (false)
3350 * \return a new object to be managed by the caller.
3352 * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked
3354 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const
3356 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3357 DataArrayInt *nc=0,*nci=0;
3358 isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci);
3359 MCAuto<DataArrayInt> ncs(nc),ncis(nci);
3360 ret->_conn=ncs; ret->_conn_indx=ncis;
3361 ret->setCoords(getCoords());
3366 * This method allows to compute, if needed, the packed nodal connectivity pair.
3367 * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges convered by nodal connectivity index array.
3368 * 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.
3370 * 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)
3371 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3373 * 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
3376 * This method return 3 elements.
3377 * \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
3378 * this pointer can be seen as a new object, that is to managed by the caller.
3379 * \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
3380 * this pointer can be seen as a new object, that is to managed by the caller.
3381 * \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
3382 * output parameters are newly created objects.
3384 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkConsistencyLight test
3386 bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const
3388 if(isPacked())//performs the checkConsistencyLight
3390 const DataArrayInt *c0(_conn),*c1(_conn_indx);
3391 nodalConn=const_cast<DataArrayInt *>(c0); nodalConnIndx=const_cast<DataArrayInt *>(c1);
3392 nodalConn->incrRef(); nodalConnIndx->incrRef();
3395 int bg=_conn_indx->front(),end=_conn_indx->back();
3396 MCAuto<DataArrayInt> nc(_conn->selectByTupleIdSafeSlice(bg,end,1));
3397 MCAuto<DataArrayInt> nci(_conn_indx->deepCopy());
3398 nci->applyLin(1,-bg);
3399 nodalConn=nc.retn(); nodalConnIndx=nci.retn();
3404 * 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)
3405 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3406 * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned.
3407 * \return bool - true if \a this looks packed, false is not.
3409 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkConsistencyLight test
3411 bool MEDCoupling1DGTUMesh::isPacked() const
3413 checkConsistencyLight();
3414 return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples();
3417 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2)
3419 std::vector<const MEDCoupling1DGTUMesh *> tmp(2);
3420 tmp[0]=const_cast<MEDCoupling1DGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1DGTUMesh *>(mesh2);
3421 return Merge1DGTUMeshes(tmp);
3424 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a)
3426 std::size_t sz=a.size();
3428 return Merge1DGTUMeshesLL(a);
3429 for(std::size_t ii=0;ii<sz;ii++)
3432 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::Merge1DGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
3433 throw INTERP_KERNEL::Exception(oss.str().c_str());
3435 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
3436 for(std::size_t ii=0;ii<sz;ii++)
3437 if(&(a[ii]->getCellModel())!=cm)
3438 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !");
3439 std::vector< MCAuto<MEDCoupling1DGTUMesh> > bb(sz);
3440 std::vector< const MEDCoupling1DGTUMesh * > aa(sz);
3442 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
3444 const MEDCoupling1DGTUMesh *cur=a[i];
3445 const DataArrayDouble *coo=cur->getCoords();
3447 spaceDim=coo->getNumberOfComponents();
3450 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !");
3451 for(std::size_t i=0;i<sz;i++)
3453 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
3456 return Merge1DGTUMeshesLL(aa);
3460 * \throw If presence of a null instance in the input vector \a a.
3461 * \throw If a is empty
3463 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a)
3466 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !");
3467 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3469 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !");
3470 std::vector< MCAuto<MEDCoupling1DGTUMesh> > objs(a.size());
3471 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3472 (*it)->getNumberOfCells();//to check that all is OK
3473 const DataArrayDouble *coords=(*it)->getCoords();
3474 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3476 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3477 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3479 for(int i=1;it!=a.end();i++,it++)
3482 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !");
3483 if(cm!=&((*it)->getCellModel()))
3484 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3485 (*it)->getNumberOfCells();//to check that all is OK
3486 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3487 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3488 if(coords!=(*it)->getCoords())
3489 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !");
3491 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3492 ret->setCoords(coords);
3493 ret->_conn=DataArrayInt::Aggregate(ncs);
3494 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3499 * 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)
3501 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a)
3504 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : input array must be NON EMPTY !");
3505 std::vector< MCAuto<MEDCoupling1DGTUMesh> > objs(a.size());
3506 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3507 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3508 std::vector<int> nbNodesPerElt(a.size());
3509 int nbOfCells=(*it)->getNumberOfCells();
3511 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3512 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3514 int prevNbOfNodes=(*it)->getNumberOfNodes();
3515 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3517 for(int i=1;it!=a.end();i++,it++)
3519 if(cm!=&((*it)->getCellModel()))
3520 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3521 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3522 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3523 nbOfCells+=(*it)->getNumberOfCells();
3524 nbNodesPerElt[i]=nbNodesPerElt[i-1]+prevNbOfNodes;
3525 prevNbOfNodes=(*it)->getNumberOfNodes();
3527 std::vector<const MEDCouplingPointSet *> aps(a.size());
3528 std::copy(a.begin(),a.end(),aps.begin());
3529 MCAuto<DataArrayDouble> pts=MergeNodesArray(aps);
3530 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3531 ret->setCoords(pts);
3532 ret->_conn=AggregateNodalConnAndShiftNodeIds(ncs,nbNodesPerElt);
3533 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3537 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(int spaceDim) const
3539 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3540 MCAuto<DataArrayInt> tmp1,tmp2;
3541 const DataArrayInt *nodalConn(_conn),*nodalConnI(_conn_indx);
3544 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
3552 tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
3556 ret->_conn_indx=tmp2;
3560 MCAuto<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
3561 ret->setCoords(coords);
3564 ret->setCoords(_coords);
3569 * This method aggregate the bbox of each cell and put it into bbox parameter.
3571 * \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)
3572 * For all other cases this input parameter is ignored.
3573 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
3575 * \throw If \a this is not fully set (coordinates and connectivity).
3576 * \throw If a cell in \a this has no valid nodeId.
3578 DataArrayDouble *MEDCoupling1DGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
3580 checkFullyDefined();
3581 int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes());
3582 MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
3583 double *bbox(ret->getPointer());
3584 for(int i=0;i<nbOfCells*spaceDim;i++)
3586 bbox[2*i]=std::numeric_limits<double>::max();
3587 bbox[2*i+1]=-std::numeric_limits<double>::max();
3589 const double *coordsPtr(_coords->getConstPointer());
3590 const int *conn(_conn->getConstPointer()),*connI(_conn_indx->getConstPointer());
3591 for(int i=0;i<nbOfCells;i++)
3593 int offset=connI[i];
3594 int nbOfNodesForCell(connI[i+1]-offset),kk(0);
3595 for(int j=0;j<nbOfNodesForCell;j++)
3597 int nodeId=conn[offset+j];
3598 if(nodeId>=0 && nodeId<nbOfNodes)
3600 for(int k=0;k<spaceDim;k++)
3602 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
3603 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
3610 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
3611 throw INTERP_KERNEL::Exception(oss.str().c_str());
3618 * 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.
3620 * \return a new instance of field containing the result. The returned instance has to be deallocated by the caller.
3622 MEDCouplingFieldDouble *MEDCoupling1DGTUMesh::computeDiameterField() const
3624 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::computeDiameterField : not implemented yet for dynamic types !");
3627 std::vector<int> MEDCoupling1DGTUMesh::BuildAPolygonFromParts(const std::vector< std::vector<int> >& parts)
3629 std::vector<int> ret;
3632 ret.insert(ret.end(),parts[0].begin(),parts[0].end());
3633 int ref(ret.back());
3634 std::size_t sz(parts.size()),nbh(1);
3635 std::vector<bool> b(sz,true); b[0]=false;
3639 for(;i<sz;i++) if(b[i] && parts[i].front()==ref) { ret.insert(ret.end(),parts[i].begin()+1,parts[i].end()); nbh++; break; }
3643 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::BuildAPolygonFromParts : the input vector is not a part of a single polygon !");
3645 if(ret.back()==ret.front())
3651 * This method performs an aggregation of \a nodalConns (as DataArrayInt::Aggregate does) but in addition of that a shift is applied on the
3652 * values contained in \a nodalConns using corresponding offset specified in input \a offsetInNodeIdsPerElt.
3653 * But it also manage the values -1, that have a semantic in MEDCoupling1DGTUMesh class (separator for polyhedron).
3655 * \param [in] nodalConns - a list of nodal connectivity arrays same size than \a offsetInNodeIdsPerElt.
3656 * \param [in] offsetInNodeIdsPerElt - a list of offsets to apply.
3657 * \return DataArrayInt * - A new object (to be managed by the caller) that is the result of the aggregation.
3658 * \throw If \a nodalConns or \a offsetInNodeIdsPerElt are empty.
3659 * \throw If \a nodalConns and \a offsetInNodeIdsPerElt have not the same size.
3660 * \throw If presence of null pointer in \a nodalConns.
3661 * \throw If presence of not allocated or array with not exactly one component in \a nodalConns.
3663 DataArrayInt *MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds(const std::vector<const DataArrayInt *>& nodalConns, const std::vector<int>& offsetInNodeIdsPerElt)
3665 std::size_t sz1(nodalConns.size()),sz2(offsetInNodeIdsPerElt.size());
3667 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : input vectors do not have the same size !");
3669 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : empty vectors in input !");
3671 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++)
3674 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of null pointer in input vector !");
3675 if(!(*it)->isAllocated())
3676 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of non allocated array in input vector !");
3677 if((*it)->getNumberOfComponents()!=1)
3678 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of array with not exactly one component !");
3679 nbOfTuples+=(*it)->getNumberOfTuples();
3681 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
3682 int *pt=ret->getPointer();
3684 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++,i++)
3686 int curNbt=(*it)->getNumberOfTuples();
3687 const int *inPt=(*it)->begin();
3688 int offset=offsetInNodeIdsPerElt[i];
3689 for(int j=0;j<curNbt;j++,pt++)
3700 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m)
3703 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh is null !");
3704 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
3706 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh must have exactly one geometric type !");
3707 int geoType((int)*gts.begin());
3708 MCAuto<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(m->getName(),*gts.begin()));
3709 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription());
3710 int nbCells(m->getNumberOfCells());
3711 MCAuto<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
3712 conn->alloc(m->getNodalConnectivityArrayLen()-nbCells,1); connI->alloc(nbCells+1,1);
3713 int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
3714 const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
3715 for(int i=0;i<nbCells;i++,ciin++,ci++)
3717 if(cin[ciin[0]]==geoType)
3719 if(ciin[1]-ciin[0]>=1)
3721 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
3722 ci[1]=ci[0]+ciin[1]-ciin[0]-1;
3726 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 !";
3727 throw INTERP_KERNEL::Exception(oss.str().c_str());
3732 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 !";
3733 throw INTERP_KERNEL::Exception(oss.str().c_str());
3736 ret->setNodalConnectivity(conn,connI);