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);
336 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::buildOrthogonalField() const
338 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
339 MCAuto<MEDCouplingFieldDouble> ret=m->buildOrthogonalField();
344 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const double *bbox, double eps) const
346 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
347 return m->getCellsInBoundingBox(bbox,eps);
350 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps)
352 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
353 return m->getCellsInBoundingBox(bbox,eps);
356 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const
358 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
359 return m->buildFacePartOfMySelfNode(start,end,fullyIn);
362 DataArrayInt *MEDCoupling1GTUMesh::findBoundaryNodes() const
364 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
365 return m->findBoundaryNodes();
368 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildBoundaryMesh(bool keepCoords) const
370 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
371 return m->buildBoundaryMesh(keepCoords);
374 void MEDCoupling1GTUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const
376 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
377 m->findCommonCells(compType,startCellId,commonCellsArr,commonCellsIArr);
380 int MEDCoupling1GTUMesh::getNodalConnectivityLength() const
382 const DataArrayInt *c1(getNodalConnectivity());
384 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : no connectivity set !");
385 if(c1->getNumberOfComponents()!=1)
386 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array set must have exactly one component !");
387 if(!c1->isAllocated())
388 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array must be allocated !");
389 return c1->getNumberOfTuples();
393 * This method aggregates all the meshes in \a parts to put them in a single unstructured mesh (those returned).
394 * The order of cells is the returned instance is those in the order of instances in \a parts.
396 * \param [in] parts - all not null parts of single geo type meshes to be aggreagated having the same mesh dimension and same coordinates.
397 * \return MEDCouplingUMesh * - new object to be dealt by the caller.
399 * \throw If one element is null in \a parts.
400 * \throw If not all the parts do not have the same mesh dimension.
401 * \throw If not all the parts do not share the same coordinates.
402 * \throw If not all the parts have their connectivity set properly.
403 * \throw If \a parts is empty.
405 MEDCouplingUMesh *MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh(const std::vector< const MEDCoupling1GTUMesh *>& parts)
408 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : input parts vector is empty !");
409 const MEDCoupling1GTUMesh *firstPart(parts[0]);
411 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : the first instance in input parts is null !");
412 const DataArrayDouble *coords(firstPart->getCoords());
413 int meshDim(firstPart->getMeshDimension());
414 MCAuto<MEDCouplingUMesh> ret(MEDCouplingUMesh::New(firstPart->getName(),meshDim)); ret->setDescription(firstPart->getDescription());
415 ret->setCoords(coords);
416 int nbOfCells(0),connSize(0);
417 for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
420 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of null pointer in input vector !");
421 if((*it)->getMeshDimension()!=meshDim)
422 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances in input vector must have same mesh dimension !");
423 if((*it)->getCoords()!=coords)
424 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances must share the same coordinates pointer !");
425 nbOfCells+=(*it)->getNumberOfCells();
426 connSize+=(*it)->getNodalConnectivityLength();
428 MCAuto<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
429 connI->alloc(nbOfCells+1,1); conn->alloc(connSize+nbOfCells,1);
430 int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
431 for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
433 int curNbCells((*it)->getNumberOfCells());
434 int geoType((int)(*it)->getCellModelEnum());
435 const int *cinPtr((*it)->getNodalConnectivity()->begin());
436 const MEDCoupling1SGTUMesh *ps(dynamic_cast<const MEDCoupling1SGTUMesh *>(*it));
437 const MEDCoupling1DGTUMesh *pd(dynamic_cast<const MEDCoupling1DGTUMesh *>(*it));
440 int nNodesPerCell(ps->getNumberOfNodesPerCell());
441 for(int i=0;i<curNbCells;i++,ci++,cinPtr+=nNodesPerCell)
444 c=std::copy(cinPtr,cinPtr+nNodesPerCell,c);
445 ci[1]=ci[0]+nNodesPerCell+1;
450 const int *ciinPtr(pd->getNodalConnectivityIndex()->begin());
451 for(int i=0;i<curNbCells;i++,ci++,ciinPtr++)
454 c=std::copy(cinPtr+ciinPtr[0],cinPtr+ciinPtr[1],c);
455 ci[1]=ci[0]+ciinPtr[1]-ciinPtr[0]+1;
459 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of instance which type is not in [MEDCoupling1SGTUMesh,MEDCoupling1DGTUMesh] !");
461 ret->setConnectivity(conn,connI,true);
467 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const MEDCoupling1SGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
471 const DataArrayInt *c(other._conn);
477 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
481 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh()
485 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New()
487 return new MEDCoupling1SGTUMesh;
490 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
492 if(type==INTERP_KERNEL::NORM_ERROR)
493 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
494 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
497 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New : the input geometric type " << cm.getRepr() << " is dynamic ! Only static types are allowed here !";
498 throw INTERP_KERNEL::Exception(oss.str().c_str());
500 return new MEDCoupling1SGTUMesh(name,cm);
503 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m)
506 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh is null !");
507 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
509 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh must have exactly one geometric type !");
510 int geoType((int)*gts.begin());
511 MCAuto<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(m->getName(),*gts.begin()));
512 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription());
513 int nbCells(m->getNumberOfCells());
514 int nbOfNodesPerCell(ret->getNumberOfNodesPerCell());
515 MCAuto<DataArrayInt> conn(DataArrayInt::New()); conn->alloc(nbCells*nbOfNodesPerCell,1);
516 int *c(conn->getPointer());
517 const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
518 for(int i=0;i<nbCells;i++,ciin++)
520 if(cin[ciin[0]]==geoType)
522 if(ciin[1]-ciin[0]==nbOfNodesPerCell+1)
523 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
526 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 << ") !";
527 throw INTERP_KERNEL::Exception(oss.str().c_str());
532 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 !";
533 throw INTERP_KERNEL::Exception(oss.str().c_str());
536 ret->setNodalConnectivity(conn);
538 { ret->copyTinyInfoFrom(m); }
539 catch(INTERP_KERNEL::Exception&) { }
543 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::clone(bool recDeepCpy) const
545 return new MEDCoupling1SGTUMesh(*this,recDeepCpy);
549 * This method behaves mostly like MEDCoupling1SGTUMesh::deepCopy method, except that only nodal connectivity arrays are deeply copied.
550 * The coordinates are shared between \a this and the returned instance.
552 * \return MEDCoupling1SGTUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
553 * \sa MEDCoupling1SGTUMesh::deepCopy
555 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::deepCopyConnectivityOnly() const
557 checkConsistencyLight();
558 MCAuto<MEDCoupling1SGTUMesh> ret(clone(false));
559 MCAuto<DataArrayInt> c(_conn->deepCopy());
560 ret->setNodalConnectivity(c);
564 void MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
567 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
568 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
570 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1SGTUMesh instance !");
571 setNodalConnectivity(otherC->getNodalConnectivity());
574 void MEDCoupling1SGTUMesh::updateTime() const
576 MEDCoupling1GTUMesh::updateTime();
577 const DataArrayInt *c(_conn);
582 std::size_t MEDCoupling1SGTUMesh::getHeapMemorySizeWithoutChildren() const
584 return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren();
587 std::vector<const BigMemoryObject *> MEDCoupling1SGTUMesh::getDirectChildrenWithNull() const
589 std::vector<const BigMemoryObject *> ret(MEDCoupling1GTUMesh::getDirectChildrenWithNull());
590 ret.push_back((const DataArrayInt *)_conn);
594 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::deepCopy() const
599 bool MEDCoupling1SGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
602 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualIfNotWhy : input other pointer is null !");
603 std::ostringstream oss; oss.precision(15);
604 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
607 reason="mesh given in input is not castable in MEDCoupling1SGTUMesh !";
610 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
612 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
617 reason="in connectivity of single static geometric type exactly one among this and other is null !";
620 if(!c1->isEqualIfNotWhy(*c2,reason))
622 reason.insert(0,"Nodal connectivity DataArrayInt differ : ");
628 bool MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
631 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
632 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
635 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
637 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
642 if(!c1->isEqualWithoutConsideringStr(*c2))
647 void MEDCoupling1SGTUMesh::checkConsistencyOfConnectivity() const
649 const DataArrayInt *c1(_conn);
652 if(c1->getNumberOfComponents()!=1)
653 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
654 if(c1->getInfoOnComponent(0)!="")
655 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
656 c1->checkAllocated();
659 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
662 void MEDCoupling1SGTUMesh::checkConsistencyLight() const
664 MEDCouplingPointSet::checkConsistencyLight();
665 checkConsistencyOfConnectivity();
668 void MEDCoupling1SGTUMesh::checkConsistency(double eps) const
670 checkConsistencyLight();
671 const DataArrayInt *c1(_conn);
672 int nbOfTuples=c1->getNumberOfTuples();
673 int nbOfNodesPerCell=(int)_cm->getNumberOfNodes();
674 if(nbOfTuples%nbOfNodesPerCell!=0)
676 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 !";
677 throw INTERP_KERNEL::Exception(oss.str().c_str());
679 int nbOfNodes=getNumberOfNodes();
680 int nbOfCells=nbOfTuples/nbOfNodesPerCell;
681 const int *w(c1->begin());
682 for(int i=0;i<nbOfCells;i++)
683 for(int j=0;j<nbOfNodesPerCell;j++,w++)
685 if(*w<0 || *w>=nbOfNodes)
687 std::ostringstream oss; oss << "At node #" << j << " of cell #" << i << ", is equal to " << *w << " must be in [0," << nbOfNodes << ") !";
688 throw INTERP_KERNEL::Exception(oss.str().c_str());
693 int MEDCoupling1SGTUMesh::getNumberOfCells() const
695 int nbOfTuples=getNodalConnectivityLength();
696 int nbOfNodesPerCell=getNumberOfNodesPerCell();
697 if(nbOfTuples%nbOfNodesPerCell!=0)
699 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 !";
700 throw INTERP_KERNEL::Exception(oss.str().c_str());
702 return nbOfTuples/nbOfNodesPerCell;
705 int MEDCoupling1SGTUMesh::getNumberOfNodesInCell(int cellId) const
707 return getNumberOfNodesPerCell();
710 int MEDCoupling1SGTUMesh::getNumberOfNodesPerCell() const
712 checkNonDynamicGeoType();
713 return (int)_cm->getNumberOfNodes();
716 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfNodesPerCell() const
718 checkNonDynamicGeoType();
719 MCAuto<DataArrayInt> ret=DataArrayInt::New();
720 ret->alloc(getNumberOfCells(),1);
721 ret->fillWithValue((int)_cm->getNumberOfNodes());
725 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfFacesPerCell() const
727 checkNonDynamicGeoType();
728 MCAuto<DataArrayInt> ret=DataArrayInt::New();
729 ret->alloc(getNumberOfCells(),1);
730 ret->fillWithValue((int)_cm->getNumberOfSons());
734 DataArrayInt *MEDCoupling1SGTUMesh::computeEffectiveNbOfNodesPerCell() const
736 checkNonDynamicGeoType();
737 MCAuto<DataArrayInt> ret=DataArrayInt::New();
738 int nbCells(getNumberOfCells());
739 ret->alloc(nbCells,1);
740 int *retPtr(ret->getPointer());
741 int nbNodesPerCell(getNumberOfNodesPerCell());
742 const int *conn(_conn->begin());
743 for(int i=0;i<nbCells;i++,conn+=nbNodesPerCell,retPtr++)
745 std::set<int> s(conn,conn+nbNodesPerCell);
746 *retPtr=(int)s.size();
751 void MEDCoupling1SGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
753 int sz=getNumberOfNodesPerCell();
755 if(cellId>=0 && cellId<getNumberOfCells())
756 std::copy(_conn->begin()+cellId*sz,_conn->begin()+(cellId+1)*sz,conn.begin());
759 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << getNumberOfCells() << ") !";
760 throw INTERP_KERNEL::Exception(oss.str().c_str());
764 void MEDCoupling1SGTUMesh::checkNonDynamicGeoType() const
767 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkNonDynamicGeoType : internal error ! the internal geo type is dynamic ! should be static !");
770 std::string MEDCoupling1SGTUMesh::simpleRepr() const
772 static const char msg0[]="No coordinates specified !";
773 std::ostringstream ret;
774 ret << "Single static geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
775 ret << "Description of mesh : \"" << getDescription() << "\"\n";
777 double tt=getTime(tmpp1,tmpp2);
778 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
779 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
780 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
783 const int spaceDim=getSpaceDimension();
784 ret << spaceDim << "\nInfo attached on space dimension : ";
785 for(int i=0;i<spaceDim;i++)
786 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
791 ret << "Number of nodes : ";
793 ret << getNumberOfNodes() << "\n";
796 ret << "Number of cells : ";
797 if((const DataArrayInt *)_conn)
799 if(_conn->isAllocated())
801 if(_conn->getNumberOfComponents()==1)
802 ret << getNumberOfCells() << "\n";
804 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
807 ret << "Nodal connectivity array specified but not allocated !" << "\n";
810 ret << "No connectivity specified !" << "\n";
811 ret << "Cell type : " << _cm->getRepr() << "\n";
815 std::string MEDCoupling1SGTUMesh::advancedRepr() const
817 std::ostringstream ret;
819 ret << "\nCoordinates array : \n___________________\n\n";
821 _coords->reprWithoutNameStream(ret);
823 ret << "No array set !\n";
824 ret << "\n\nConnectivity array : \n____________________\n\n";
826 if((const DataArrayInt *)_conn)
828 if(_conn->isAllocated())
830 if(_conn->getNumberOfComponents()==1)
832 int nbOfCells=getNumberOfCells();
833 int sz=getNumberOfNodesPerCell();
834 const int *connPtr=_conn->begin();
835 for(int i=0;i<nbOfCells;i++,connPtr+=sz)
837 ret << "Cell #" << i << " : ";
838 std::copy(connPtr,connPtr+sz,std::ostream_iterator<int>(ret," "));
843 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
846 ret << "Nodal connectivity array specified but not allocated !" << "\n";
849 ret << "No connectivity specified !" << "\n";
853 DataArrayDouble *MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell() const
855 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
856 int spaceDim=getSpaceDimension();
857 int nbOfCells=getNumberOfCells();//checkConsistencyLight()
858 int nbOfNodes=getNumberOfNodes();
859 ret->alloc(nbOfCells,spaceDim);
860 double *ptToFill=ret->getPointer();
861 const double *coor=_coords->begin();
862 const int *nodal=_conn->begin();
863 int sz=getNumberOfNodesPerCell();
864 double coeff=1./(double)sz;
865 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim)
867 std::fill(ptToFill,ptToFill+spaceDim,0.);
868 for(int j=0;j<sz;j++,nodal++)
869 if(*nodal>=0 && *nodal<nbOfNodes)
870 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
873 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
874 throw INTERP_KERNEL::Exception(oss.str().c_str());
876 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),coeff));
881 void MEDCoupling1SGTUMesh::renumberCells(const int *old2NewBg, bool check)
883 int nbCells=getNumberOfCells();
884 MCAuto<DataArrayInt> o2n=DataArrayInt::New();
885 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
887 o2n=o2n->checkAndPreparePermutation();
889 const int *conn=_conn->begin();
890 MCAuto<DataArrayInt> n2o=o2n->invertArrayO2N2N2O(nbCells);
891 const int *n2oPtr=n2o->begin();
892 MCAuto<DataArrayInt> newConn=DataArrayInt::New();
893 newConn->alloc(_conn->getNumberOfTuples(),1);
894 newConn->copyStringInfoFrom(*_conn);
895 int sz=getNumberOfNodesPerCell();
897 int *newC=newConn->getPointer();
898 for(int i=0;i<nbCells;i++,newC+=sz)
901 std::copy(conn+pos*sz,conn+(pos+1)*sz,newC);
907 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
908 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
909 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
910 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
912 * \param [in] begin input start of array of node ids.
913 * \param [in] end input end of array of node ids.
914 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
915 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
917 void MEDCoupling1SGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
919 int nbOfCells=getNumberOfCells();
920 MCAuto<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
922 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
923 std::vector<bool> fastFinder(sz,false);
924 for(const int *work=begin;work!=end;work++)
925 if(*work>=0 && *work<sz)
926 fastFinder[*work]=true;
927 const int *conn=_conn->begin();
928 int nbNodesPerCell=getNumberOfNodesPerCell();
929 for(int i=0;i<nbOfCells;i++,conn+=nbNodesPerCell)
932 for(int j=0;j<nbNodesPerCell;j++)
936 if(fastFinder[conn[j]])
939 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
940 cellIdsKept->pushBackSilent(i);
942 cellIdsKeptArr=cellIdsKept.retn();
945 MEDCouplingMesh *MEDCoupling1SGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
947 if(other->getType()!=SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED)
948 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single static geo type each other !");
949 const MEDCoupling1SGTUMesh *otherC=static_cast<const MEDCoupling1SGTUMesh *>(other);
950 return Merge1SGTUMeshes(this,otherC);
953 MEDCouplingUMesh *MEDCoupling1SGTUMesh::buildUnstructured() const
955 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
956 ret->setCoords(getCoords());
957 const int *nodalConn=_conn->begin();
958 int nbCells=getNumberOfCells();
959 int nbNodesPerCell=getNumberOfNodesPerCell();
960 int geoType=(int)getCellModelEnum();
961 MCAuto<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells*(nbNodesPerCell+1),1);
962 int *cPtr=c->getPointer();
963 for(int i=0;i<nbCells;i++,nodalConn+=nbNodesPerCell)
966 cPtr=std::copy(nodalConn,nodalConn+nbNodesPerCell,cPtr);
968 MCAuto<DataArrayInt> cI=DataArrayInt::Range(0,(nbCells+1)*(nbNodesPerCell+1),nbNodesPerCell+1);
969 ret->setConnectivity(c,cI,true);
971 { ret->copyTinyInfoFrom(this); }
972 catch(INTERP_KERNEL::Exception&) { }
976 DataArrayInt *MEDCoupling1SGTUMesh::simplexize(int policy)
981 return simplexizePol0();
983 return simplexizePol1();
984 case (int) INTERP_KERNEL::PLANAR_FACE_5:
985 return simplexizePlanarFace5();
986 case (int) INTERP_KERNEL::PLANAR_FACE_6:
987 return simplexizePlanarFace6();
989 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)");
995 struct MEDCouplingAccVisit
997 MEDCouplingAccVisit():_new_nb_of_nodes(0) { }
998 int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; }
999 int _new_nb_of_nodes;
1005 * This method returns all node ids used in \b this. The data array returned has to be dealt by the caller.
1006 * The returned node ids are sortes ascendingly. This method is closed to MEDCoupling1SGTUMesh::getNodeIdsInUse except
1007 * the format of returned DataArrayInt instance.
1009 * \return a newly allocated DataArrayInt sorted ascendingly of fetched node ids.
1010 * \sa MEDCoupling1SGTUMesh::getNodeIdsInUse, areAllNodesFetched
1012 DataArrayInt *MEDCoupling1SGTUMesh::computeFetchedNodeIds() const
1014 checkConsistencyOfConnectivity();
1015 int nbNodes(getNumberOfNodes());
1016 std::vector<bool> fetchedNodes(nbNodes,false);
1017 computeNodeIdsAlg(fetchedNodes);
1018 int sz((int)std::count(fetchedNodes.begin(),fetchedNodes.end(),true));
1019 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
1020 int *retPtr(ret->getPointer());
1021 for(int i=0;i<nbNodes;i++)
1028 * Finds nodes not used in any cell and returns an array giving a new id to every node
1029 * by excluding the unused nodes, for which the array holds -1. The result array is
1030 * a mapping in "Old to New" mode.
1031 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
1032 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
1033 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
1034 * if the node is unused or a new id else. The caller is to delete this
1035 * array using decrRef() as it is no more needed.
1036 * \throw If the coordinates array is not set.
1037 * \throw If the nodal connectivity of cells is not defined.
1038 * \throw If the nodal connectivity includes an invalid id.
1039 * \sa MEDCoupling1SGTUMesh::computeFetchedNodeIds, areAllNodesFetched
1041 DataArrayInt *MEDCoupling1SGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
1044 int nbOfNodes=getNumberOfNodes();
1045 int nbOfCells=getNumberOfCells();
1046 MCAuto<DataArrayInt> ret(DataArrayInt::New());
1047 ret->alloc(nbOfNodes,1);
1048 int *traducer=ret->getPointer();
1049 std::fill(traducer,traducer+nbOfNodes,-1);
1050 const int *conn=_conn->begin();
1051 int nbNodesPerCell=getNumberOfNodesPerCell();
1052 for(int i=0;i<nbOfCells;i++)
1053 for(int j=0;j<nbNodesPerCell;j++,conn++)
1054 if(*conn>=0 && *conn<nbOfNodes)
1058 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << conn[j] << " not in [0," << nbOfNodes << ") !";
1059 throw INTERP_KERNEL::Exception(oss.str().c_str());
1061 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
1062 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
1067 * This method renumbers only nodal connectivity in \a this. The renumbering is only an offset applied. So this method is a specialization of
1068 * \a renumberNodesInConn. \b WARNING, this method does not check that the resulting node ids in the nodal connectivity is in a valid range !
1070 * \param [in] offset - specifies the offset to be applied on each element of connectivity.
1072 * \sa renumberNodesInConn
1074 void MEDCoupling1SGTUMesh::renumberNodesWithOffsetInConn(int offset)
1076 getNumberOfCells();//only to check that all is well defined.
1077 _conn->applyLin(1,offset);
1082 * Same than renumberNodesInConn(const int *) except that here the format of old-to-new traducer is using map instead
1083 * 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
1086 void MEDCoupling1SGTUMesh::renumberNodesInConn(const INTERP_KERNEL::HashMap<int,int>& newNodeNumbersO2N)
1088 getNumberOfCells();//only to check that all is well defined.
1089 int *begPtr(_conn->getPointer());
1090 int nbElt(_conn->getNumberOfTuples());
1091 int *endPtr(begPtr+nbElt);
1092 for(int *it=begPtr;it!=endPtr;it++)
1094 INTERP_KERNEL::HashMap<int,int>::const_iterator it2(newNodeNumbersO2N.find(*it));
1095 if(it2!=newNodeNumbersO2N.end())
1101 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::renumberNodesInConn : At pos #" << std::distance(begPtr,it) << " of nodal connectivity value is " << *it << ". Not in map !";
1102 throw INTERP_KERNEL::Exception(oss.str().c_str());
1109 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
1110 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
1111 * This method is a generalization of shiftNodeNumbersInConn().
1112 * \warning This method performs no check of validity of new ids. **Use it with care !**
1113 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
1114 * this->getNumberOfNodes(), in "Old to New" mode.
1115 * See \ref numbering for more info on renumbering modes.
1116 * \throw If the nodal connectivity of cells is not defined.
1118 void MEDCoupling1SGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
1120 getNumberOfCells();//only to check that all is well defined.
1121 _conn->transformWithIndArr(newNodeNumbersO2N,newNodeNumbersO2N+getNumberOfNodes());
1125 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2)
1127 std::vector<const MEDCoupling1SGTUMesh *> tmp(2);
1128 tmp[0]=const_cast<MEDCoupling1SGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1SGTUMesh *>(mesh2);
1129 return Merge1SGTUMeshes(tmp);
1132 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(std::vector<const MEDCoupling1SGTUMesh *>& a)
1134 std::size_t sz=a.size();
1136 return Merge1SGTUMeshesLL(a);
1137 for(std::size_t ii=0;ii<sz;ii++)
1140 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::Merge1SGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
1141 throw INTERP_KERNEL::Exception(oss.str().c_str());
1143 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
1144 for(std::size_t ii=0;ii<sz;ii++)
1145 if(&(a[ii]->getCellModel())!=cm)
1146 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : all items must have the same geo type !");
1147 std::vector< MCAuto<MEDCoupling1SGTUMesh> > bb(sz);
1148 std::vector< const MEDCoupling1SGTUMesh * > aa(sz);
1150 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
1152 const MEDCoupling1SGTUMesh *cur=a[i];
1153 const DataArrayDouble *coo=cur->getCoords();
1155 spaceDim=coo->getNumberOfComponents();
1158 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : no spaceDim specified ! unable to perform merge !");
1159 for(std::size_t i=0;i<sz;i++)
1161 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
1164 return Merge1SGTUMeshesLL(aa);
1168 * \throw If presence of a null instance in the input vector \a a.
1169 * \throw If a is empty
1171 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::vector<const MEDCoupling1SGTUMesh *>& a)
1174 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : input array must be NON EMPTY !");
1175 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1177 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : null instance in the first element of input vector !");
1178 std::vector<const DataArrayInt *> ncs(a.size());
1179 (*it)->getNumberOfCells();//to check that all is OK
1180 const DataArrayDouble *coords=(*it)->getCoords();
1181 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1182 ncs[0]=(*it)->getNodalConnectivity();
1184 for(int i=1;it!=a.end();i++,it++)
1187 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : presence of a null instance in the input vector !");
1188 if(cm!=&((*it)->getCellModel()))
1189 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1190 (*it)->getNumberOfCells();//to check that all is OK
1191 ncs[i]=(*it)->getNodalConnectivity();
1192 if(coords!=(*it)->getCoords())
1193 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : not lying on same coords !");
1195 MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1196 ret->setCoords(coords);
1197 ret->_conn=DataArrayInt::Aggregate(ncs);
1202 * 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)
1204 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector<const MEDCoupling1SGTUMesh *>& a)
1207 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : input array must be NON EMPTY !");
1208 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1209 int nbOfCells=(*it)->getNumberOfCells();
1210 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1211 int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
1213 for(;it!=a.end();it++)
1215 if(cm!=&((*it)->getCellModel()))
1216 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1217 nbOfCells+=(*it)->getNumberOfCells();
1219 std::vector<const MEDCouplingPointSet *> aps(a.size());
1220 std::copy(a.begin(),a.end(),aps.begin());
1221 MCAuto<DataArrayDouble> pts=MergeNodesArray(aps);
1222 MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1223 ret->setCoords(pts);
1224 MCAuto<DataArrayInt> c=DataArrayInt::New();
1225 c->alloc(nbOfCells*nbNodesPerCell,1);
1226 int *cPtr=c->getPointer();
1228 for(it=a.begin();it!=a.end();it++)
1230 int curConnLgth=(*it)->getNodalConnectivityLength();
1231 const int *curC=(*it)->_conn->begin();
1232 cPtr=std::transform(curC,curC+curConnLgth,cPtr,std::bind2nd(std::plus<int>(),offset));
1233 offset+=(*it)->getNumberOfNodes();
1236 ret->setNodalConnectivity(c);
1240 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
1242 int ncell=getNumberOfCells();
1243 MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1244 ret->setCoords(_coords);
1245 std::size_t nbOfElemsRet=std::distance(begin,end);
1246 const int *inConn=_conn->getConstPointer();
1247 int sz=getNumberOfNodesPerCell();
1248 MCAuto<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1249 int *connPtr=connRet->getPointer();
1250 for(const int *work=begin;work!=end;work++,connPtr+=sz)
1252 if(*work>=0 && *work<ncell)
1253 std::copy(inConn+(work[0])*sz,inConn+(work[0]+1)*sz,connPtr);
1256 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !";
1257 throw INTERP_KERNEL::Exception(oss.str().c_str());
1261 ret->copyTinyInfoFrom(this);
1265 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoordsSlice(int start, int end, int step) const
1267 int ncell=getNumberOfCells();
1268 int nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoordsSlice : ");
1269 MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1270 ret->setCoords(_coords);
1271 const int *inConn=_conn->getConstPointer();
1272 int sz=getNumberOfNodesPerCell();
1273 MCAuto<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1274 int *connPtr=connRet->getPointer();
1276 for(int i=0;i<nbOfElemsRet;i++,connPtr+=sz,curId+=step)
1278 if(curId>=0 && curId<ncell)
1279 std::copy(inConn+curId*sz,inConn+(curId+1)*sz,connPtr);
1282 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoordsSlice : On pos #" << i << " input cell id =" << curId << " should be in [0," << ncell << ") !";
1283 throw INTERP_KERNEL::Exception(oss.str().c_str());
1287 ret->copyTinyInfoFrom(this);
1291 void MEDCoupling1SGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
1293 int sz((int)nodeIdsInUse.size());
1294 for(const int *conn=_conn->begin();conn!=_conn->end();conn++)
1296 if(*conn>=0 && *conn<sz)
1297 nodeIdsInUse[*conn]=true;
1300 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeFetchedNodeIds : At pos #" << std::distance(_conn->begin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !";
1301 throw INTERP_KERNEL::Exception(oss.str().c_str());
1306 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(int spaceDim) const
1308 MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1309 MCAuto<DataArrayInt> tmp1;
1310 const DataArrayInt *nodalConn(_conn);
1313 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
1320 MCAuto<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
1321 ret->setCoords(coords);
1324 ret->setCoords(_coords);
1328 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol0()
1330 int nbOfCells=getNumberOfCells();
1331 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1332 return DataArrayInt::Range(0,nbOfCells,1);
1333 MCAuto<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1334 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1335 const int *c(_conn->begin());
1336 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1337 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1339 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[2];
1340 newConnPtr[3]=c[0]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1341 retPtr[0]=i; retPtr[1]=i;
1344 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1349 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol1()
1351 int nbOfCells=getNumberOfCells();
1352 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1353 return DataArrayInt::Range(0,nbOfCells,1);
1354 MCAuto<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1355 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1356 const int *c(_conn->begin());
1357 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1358 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1360 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[3];
1361 newConnPtr[3]=c[1]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1362 retPtr[0]=i; retPtr[1]=i;
1365 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1370 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace5()
1372 int nbOfCells=getNumberOfCells();
1373 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1374 return DataArrayInt::Range(0,nbOfCells,1);
1375 MCAuto<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(5*4*nbOfCells,1);
1376 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(5*nbOfCells,1);
1377 const int *c(_conn->begin());
1378 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1379 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=20,retPtr+=5)
1381 for(int j=0;j<20;j++)
1382 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_5_WO[j]];
1383 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i;
1386 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1391 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace6()
1393 int nbOfCells=getNumberOfCells();
1394 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1395 return DataArrayInt::Range(0,nbOfCells,1);
1396 MCAuto<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(6*4*nbOfCells,1);
1397 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(6*nbOfCells,1);
1398 const int *c(_conn->begin());
1399 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1400 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=24,retPtr+=6)
1402 for(int j=0;j<24;j++)
1403 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_6_WO[j]];
1404 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i; retPtr[5]=i;
1407 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1412 void MEDCoupling1SGTUMesh::reprQuickOverview(std::ostream& stream) const
1414 stream << "MEDCoupling1SGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
1415 stream << " Mesh dimension : " << getMeshDimension() << ".";
1417 { stream << " No coordinates set !"; return ; }
1418 if(!_coords->isAllocated())
1419 { stream << " Coordinates set but not allocated !"; return ; }
1420 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
1421 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
1422 if(!(const DataArrayInt *)_conn)
1423 { stream << std::endl << "Nodal connectivity NOT set !"; return ; }
1424 if(_conn->isAllocated())
1426 if(_conn->getNumberOfComponents()==1)
1427 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
1431 void MEDCoupling1SGTUMesh::checkFullyDefined() const
1433 if(!((const DataArrayInt *)_conn) || !((const DataArrayDouble *)_coords))
1434 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFullyDefined : part of this is not fully defined.");
1438 * First step of unserialization process.
1440 bool MEDCoupling1SGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
1442 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEmptyMesh : not implemented yet !");
1445 void MEDCoupling1SGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
1448 double time=getTime(it,order);
1449 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
1451 littleStrings.push_back(getName());
1452 littleStrings.push_back(getDescription());
1453 littleStrings.push_back(getTimeUnit());
1455 std::vector<std::string> littleStrings2,littleStrings3;
1456 if((const DataArrayDouble *)_coords)
1457 _coords->getTinySerializationStrInformation(littleStrings2);
1458 if((const DataArrayInt *)_conn)
1459 _conn->getTinySerializationStrInformation(littleStrings3);
1460 int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size());
1461 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
1462 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
1464 tinyInfo.push_back(getCellModelEnum());
1465 tinyInfo.push_back(it);
1466 tinyInfo.push_back(order);
1467 std::vector<int> tinyInfo2,tinyInfo3;
1468 if((const DataArrayDouble *)_coords)
1469 _coords->getTinySerializationIntInformation(tinyInfo2);
1470 if((const DataArrayInt *)_conn)
1471 _conn->getTinySerializationIntInformation(tinyInfo3);
1472 int sz2((int)tinyInfo2.size()),sz3((int)tinyInfo3.size());
1473 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3);
1474 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1475 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
1477 tinyInfoD.push_back(time);
1480 void MEDCoupling1SGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
1482 std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+tinyInfo[5]);
1483 std::vector<int> tinyInfo1(tinyInfo.begin()+7+tinyInfo[5],tinyInfo.begin()+7+tinyInfo[5]+tinyInfo[6]);
1484 a1->resizeForUnserialization(tinyInfo1);
1485 a2->resizeForUnserialization(tinyInfo2);
1488 void MEDCoupling1SGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
1491 if((const DataArrayInt *)_conn)
1492 if(_conn->isAllocated())
1493 sz=_conn->getNbOfElems();
1494 a1=DataArrayInt::New();
1496 if(sz!=0 && (const DataArrayInt *)_conn)
1497 std::copy(_conn->begin(),_conn->end(),a1->getPointer());
1499 if((const DataArrayDouble *)_coords)
1500 if(_coords->isAllocated())
1501 sz=_coords->getNbOfElems();
1502 a2=DataArrayDouble::New();
1504 if(sz!=0 && (const DataArrayDouble *)_coords)
1505 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
1508 void MEDCoupling1SGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
1509 const std::vector<std::string>& littleStrings)
1511 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
1512 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
1513 setName(littleStrings[0]);
1514 setDescription(littleStrings[1]);
1515 setTimeUnit(littleStrings[2]);
1516 setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
1517 int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]);
1519 _coords=DataArrayDouble::New();
1520 std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+sz2);
1521 _coords->resizeForUnserialization(tinyInfo2);
1522 std::copy(a2->begin(),a2->end(),_coords->getPointer());
1523 _conn=DataArrayInt::New();
1524 std::vector<int> tinyInfo3(tinyInfo.begin()+7+sz2,tinyInfo.begin()+7+sz2+sz3);
1525 _conn->resizeForUnserialization(tinyInfo3);
1526 std::copy(a1->begin(),a1->end(),_conn->getPointer());
1527 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
1528 _coords->finishUnserialization(tinyInfo2,littleStrings2);
1529 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
1530 _conn->finishUnserialization(tinyInfo3,littleStrings3);
1534 * Checks if \a this and \a other meshes are geometrically equivalent with high
1535 * probability, else an exception is thrown. The meshes are considered equivalent if
1536 * (1) meshes contain the same number of nodes and the same number of elements of the
1537 * same types (2) three cells of the two meshes (first, last and middle) are based
1538 * on coincident nodes (with a specified precision).
1539 * \param [in] other - the mesh to compare with.
1540 * \param [in] prec - the precision used to compare nodes of the two meshes.
1541 * \throw If the two meshes do not match.
1543 void MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
1545 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1546 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1548 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single static geometric type !");
1549 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1553 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1554 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1555 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1556 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1557 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1558 if(c1->getHashCode()!=c2->getHashCode())
1559 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1562 MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
1565 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
1566 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1568 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
1569 std::vector<const MEDCoupling1SGTUMesh *> ms(2);
1572 return Merge1SGTUMeshesOnSameCoords(ms);
1575 void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const
1577 checkFullyDefined();
1578 int nbOfNodes=getNumberOfNodes();
1579 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
1580 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
1581 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
1582 const int *conn=_conn->begin();
1583 int nbOfCells=getNumberOfCells();
1584 int nbOfEltsInRevNodal=0;
1585 int nbOfNodesPerCell=getNumberOfNodesPerCell();
1586 for(int eltId=0;eltId<nbOfCells;eltId++)
1588 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1590 if(conn[0]>=0 && conn[0]<nbOfNodes)
1592 nbOfEltsInRevNodal++;
1593 revNodalIndxPtr[conn[0]+1]++;
1597 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
1598 throw INTERP_KERNEL::Exception(oss.str().c_str());
1602 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
1603 conn=_conn->begin();
1604 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
1605 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
1606 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
1607 for(int eltId=0;eltId<nbOfCells;eltId++)
1609 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1611 *std::find_if(revNodalPtr+revNodalIndxPtr[*conn],revNodalPtr+revNodalIndxPtr[*conn+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
1617 * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null.
1619 void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn)
1622 nodalConn->incrRef();
1628 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
1630 DataArrayInt *MEDCoupling1SGTUMesh::getNodalConnectivity() const
1632 const DataArrayInt *ret(_conn);
1633 return const_cast<DataArrayInt *>(ret);
1637 * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted,
1638 * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter.
1639 * If a nodal connectivity previouly existed before the call of this method, it will be reset.
1641 * \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain.
1643 void MEDCoupling1SGTUMesh::allocateCells(int nbOfCells)
1646 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !");
1647 _conn=DataArrayInt::New();
1648 _conn->reserve(getNumberOfNodesPerCell()*nbOfCells);
1653 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
1655 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
1656 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
1657 * \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
1658 * attached to \a this.
1659 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
1661 void MEDCoupling1SGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd)
1663 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
1664 int ref=getNumberOfNodesPerCell();
1667 DataArrayInt *c(_conn);
1669 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
1671 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !");
1675 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this (";
1676 oss << ref << ") !";
1677 throw INTERP_KERNEL::Exception(oss.str().c_str());
1682 * This method builds the dual mesh of \a this and returns it.
1684 * \return MEDCoupling1SGTUMesh * - newly object created to be managed by the caller.
1685 * \throw If \a this is not a mesh containing only simplex cells.
1686 * \throw If \a this is not correctly allocated (coordinates and connectivities have to be correctly set !).
1687 * \throw If at least one node in \a this is orphan (without any simplex cell lying on it !)
1689 MEDCoupling1GTUMesh *MEDCoupling1SGTUMesh::computeDualMesh() const
1691 const INTERP_KERNEL::CellModel& cm(getCellModel());
1693 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : this mesh is not a simplex mesh ! Please invoke simplexize of tetrahedrize on this before calling this method !");
1694 switch(getMeshDimension())
1697 return computeDualMesh3D();
1699 return computeDualMesh2D();
1701 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : meshdimension must be in [2,3] !");
1706 * This method explode each NORM_HEXA8 cells in \a this into 6 NORM_QUAD4 cells and put the result into the MEDCoupling1SGTUMesh returned instance.
1708 * \return MEDCoupling1SGTUMesh * - a newly allocated instances (to be managed by the caller) storing the result of the explosion.
1709 * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
1710 * \throw If \a this is not properly allocated.
1712 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4() const
1714 const INTERP_KERNEL::CellModel& cm(getCellModel());
1715 if(cm.getEnum()!=INTERP_KERNEL::NORM_HEXA8)
1716 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4 : this method can be applied only on HEXA8 mesh !");
1717 int nbHexa8(getNumberOfCells());
1718 const int *inConnPtr(getNodalConnectivity()->begin());
1719 MCAuto<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(getName(),INTERP_KERNEL::NORM_QUAD4));
1720 MCAuto<DataArrayInt> c(DataArrayInt::New()); c->alloc(nbHexa8*6*4,1);
1721 int *cPtr(c->getPointer());
1722 for(int i=0;i<nbHexa8;i++,inConnPtr+=8)
1724 for(int j=0;j<6;j++,cPtr+=4)
1725 cm.fillSonCellNodalConnectivity(j,inConnPtr,cPtr);
1727 ret->setCoords(getCoords());
1728 ret->setNodalConnectivity(c);
1733 * This method starts from an unstructured mesh that hides in reality a cartesian mesh.
1734 * If it is not the case, an exception will be thrown.
1735 * This method returns three objects : The cartesian mesh geometrically equivalent to \a this (within a precision of \a eps) and a permutation of cells
1736 * and a permutation of nodes.
1738 * - this[cellPerm[i]]=ret[i]
1740 * \param [out] cellPerm the permutation array of size \c this->getNumberOfCells()
1741 * \param [out] nodePerm the permutation array of size \c this->getNumberOfNodes()
1742 * \return MEDCouplingCMesh * - a newly allocated mesh that is the result of the structurization of \a this.
1744 MEDCouplingCMesh *MEDCoupling1SGTUMesh::structurizeMe(DataArrayInt *& cellPerm, DataArrayInt *& nodePerm, double eps) const
1746 checkConsistencyLight();
1747 int spaceDim(getSpaceDimension()),meshDim(getMeshDimension()),nbNodes(getNumberOfNodes());
1748 if(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim)!=getCellModelEnum())
1749 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::structurizeMe : the unique geo type in this is not compatible with the geometric type regarding mesh dimension !");
1750 MCAuto<MEDCouplingCMesh> cm(MEDCouplingCMesh::New());
1751 for(int i=0;i<spaceDim;i++)
1753 std::vector<int> tmp(1,i);
1754 MCAuto<DataArrayDouble> elt(static_cast<DataArrayDouble*>(getCoords()->keepSelectedComponents(tmp)));
1755 elt=elt->getDifferentValues(eps);
1757 cm->setCoordsAt(i,elt);
1759 if(nbNodes!=cm->getNumberOfNodes())
1760 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 ?");
1762 { cm->copyTinyInfoFrom(this); }
1763 catch(INTERP_KERNEL::Exception&) { }
1764 MCAuto<MEDCouplingUMesh> um(cm->buildUnstructured()),self(buildUnstructured());
1765 self->checkGeoEquivalWith(um,12,eps,cellPerm,nodePerm);
1771 bool UpdateHexa8Cell(int validAxis, int neighId, const int *validConnQuad4NeighSide, int *allFacesNodalConn, int *myNeighbours)
1773 static const int TAB[48]={
1781 static const int TAB2[6]={0,0,3,3,3,3};
1782 if(myNeighbours[validAxis]==neighId && allFacesNodalConn[4*validAxis+0]==validConnQuad4NeighSide[TAB2[validAxis]])
1784 int oldAxis((int)std::distance(myNeighbours,std::find(myNeighbours,myNeighbours+6,neighId)));
1785 std::size_t pos(std::distance(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,std::find(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS+6,oldAxis)));
1786 std::size_t pos0(pos/2),pos1(pos%2);
1787 int oldAxisOpp(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[2*pos0+(pos1+1)%2]);
1788 int oldConn[8],myConn2[8]={-1,-1,-1,-1,-1,-1,-1,-1},myConn[8],edgeConn[2],allFacesTmp[24],neighTmp[6];
1789 oldConn[0]=allFacesNodalConn[0]; oldConn[1]=allFacesNodalConn[1]; oldConn[2]=allFacesNodalConn[2]; oldConn[3]=allFacesNodalConn[3];
1790 oldConn[4]=allFacesNodalConn[4]; oldConn[5]=allFacesNodalConn[7]; oldConn[6]=allFacesNodalConn[6]; oldConn[7]=allFacesNodalConn[5];
1791 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_HEXA8));
1792 for(int i=0;i<4;i++)
1793 myConn2[i]=validConnQuad4NeighSide[(4-i+TAB2[validAxis])%4];
1794 for(int i=0;i<4;i++)
1796 int nodeId(myConn2[i]);//the node id for which the opposite one will be found
1798 INTERP_KERNEL::NormalizedCellType typeOfSon;
1799 for(int j=0;j<12 && !found;j++)
1801 cm.fillSonEdgesNodalConnectivity3D(j,oldConn,-1,edgeConn,typeOfSon);
1802 if(edgeConn[0]==nodeId || edgeConn[1]==nodeId)
1804 if(std::find(allFacesNodalConn+4*oldAxisOpp,allFacesNodalConn+4*oldAxisOpp+4,edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0])!=allFacesNodalConn+4*oldAxisOpp+4)
1806 myConn2[i+4]=edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0];
1812 throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error !");
1814 const int *myTab(TAB+8*validAxis);
1815 for(int i=0;i<8;i++)
1816 myConn[i]=myConn2[myTab[i]];
1817 for(int i=0;i<6;i++)
1819 cm.fillSonCellNodalConnectivity(i,myConn,allFacesTmp+4*i);
1820 std::set<int> s(allFacesTmp+4*i,allFacesTmp+4*i+4);
1822 for(int j=0;j<6 && !found;j++)
1824 std::set<int> s1(allFacesNodalConn+4*j,allFacesNodalConn+4*j+4);
1827 neighTmp[i]=myNeighbours[j];
1832 throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error #2 !");
1834 std::copy(allFacesTmp,allFacesTmp+24,allFacesNodalConn);
1835 std::copy(neighTmp,neighTmp+6,myNeighbours);
1842 * 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
1843 * homogeneous. If it succeeds the result of MEDCouplingUMesh::tetrahedrize will return a conform mesh.
1845 * \return DataArrayInt * - a newly allocated array (to be managed by the caller) containing renumbered cell ids.
1847 * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
1848 * \throw If \a this is not properly allocated.
1849 * \sa MEDCouplingUMesh::tetrahedrize, MEDCouplingUMesh::simplexize.
1851 DataArrayInt *MEDCoupling1SGTUMesh::sortHexa8EachOther()
1853 MCAuto<MEDCoupling1SGTUMesh> quads(explodeEachHexa8To6Quad4());//checks that only hexa8
1854 int nbHexa8(getNumberOfCells()),*cQuads(quads->getNodalConnectivity()->getPointer());
1855 MCAuto<DataArrayInt> neighOfQuads(DataArrayInt::New()); neighOfQuads->alloc(nbHexa8*6,1); neighOfQuads->fillWithValue(-1);
1856 int *ptNeigh(neighOfQuads->getPointer());
1857 {//neighOfQuads tells for each face of each Quad8 which cell (if!=-1) is connected to this face.
1858 MCAuto<MEDCouplingUMesh> quadsTmp(quads->buildUnstructured());
1859 MCAuto<DataArrayInt> ccSafe,cciSafe;
1860 DataArrayInt *cc(0),*cci(0);
1861 quadsTmp->findCommonCells(3,0,cc,cci);
1862 ccSafe=cc; cciSafe=cci;
1863 const int *ccPtr(ccSafe->begin()),nbOfPair(cci->getNumberOfTuples()-1);
1864 for(int i=0;i<nbOfPair;i++)
1865 { ptNeigh[ccPtr[2*i+0]]=ccPtr[2*i+1]/6; ptNeigh[ccPtr[2*i+1]]=ccPtr[2*i+0]/6; }
1867 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
1868 std::vector<bool> fetched(nbHexa8,false);
1869 std::vector<bool>::iterator it(std::find(fetched.begin(),fetched.end(),false));
1870 while(it!=fetched.end())//it will turns as time as number of connected zones
1872 int cellId((int)std::distance(fetched.begin(),it));//it is the seed of the connected zone.
1873 std::set<int> s; s.insert(cellId);//s contains already organized.
1876 std::set<int> sNext;
1877 for(std::set<int>::const_iterator it0=s.begin();it0!=s.end();it0++)
1880 int *myNeighb(ptNeigh+6*(*it0));
1881 for(int i=0;i<6;i++)
1883 if(myNeighb[i]!=-1 && !fetched[myNeighb[i]])
1885 std::size_t pos(std::distance(HEXA8_FACE_PAIRS,std::find(HEXA8_FACE_PAIRS,HEXA8_FACE_PAIRS+6,i)));
1886 std::size_t pos0(pos/2),pos1(pos%2);
1887 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]))
1888 ret->pushBackSilent(myNeighb[i]);
1889 fetched[myNeighb[i]]=true;
1890 sNext.insert(myNeighb[i]);
1896 it=std::find(fetched.begin(),fetched.end(),false);
1900 int *conn(getNodalConnectivity()->getPointer());
1901 for(const int *pt=ret->begin();pt!=ret->end();pt++)
1904 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];
1905 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];
1912 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh3D() const
1914 static const int DUAL_TETRA_0[36]={
1915 4,1,0, 6,0,3, 7,3,1,
1916 4,0,1, 5,2,0, 8,1,2,
1917 6,3,0, 5,0,2, 9,2,3,
1920 static const int DUAL_TETRA_1[36]={
1921 8,4,10, 11,5,8, 10,7,11,
1922 9,4,8, 8,5,12, 12,6,9,
1923 10,4,9, 9,6,13, 13,7,10,
1924 12,5,11, 13,6,12, 11,7,13
1926 static const int FACEID_NOT_SH_NODE[4]={2,3,1,0};
1927 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TETRA4)
1928 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh3D : only TETRA4 supported !");
1929 checkFullyDefined();
1930 MCAuto<MEDCouplingUMesh> thisu(buildUnstructured());
1931 MCAuto<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1932 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1933 const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1934 MCAuto<DataArrayInt> d1Arr(DataArrayInt::New()),di1Arr(DataArrayInt::New()),rd1Arr(DataArrayInt::New()),rdi1Arr(DataArrayInt::New());
1935 MCAuto<MEDCouplingUMesh> edges(thisu->explode3DMeshTo1D(d1Arr,di1Arr,rd1Arr,rdi1Arr));
1936 const int *d1(d1Arr->begin());
1937 MCAuto<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1938 MCAuto<MEDCouplingUMesh> faces(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
1939 const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
1940 MCAuto<DataArrayDouble> edgesBaryArr(edges->computeCellCenterOfMass()),facesBaryArr(faces->computeCellCenterOfMass()),baryArr(computeCellCenterOfMass());
1941 const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+faces->getNumberOfCells()),offset1(offset0+edges->getNumberOfCells());
1943 std::vector<const DataArrayDouble *> v(4); v[0]=getCoords(); v[1]=facesBaryArr; v[2]=edgesBaryArr; v[3]=baryArr;
1944 MCAuto<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0; facesBaryArr=0;
1945 std::string name("DualOf_"); name+=getName();
1946 MCAuto<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYHED)); ret->setCoords(zeArr);
1947 MCAuto<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1948 for(int i=0;i<nbOfNodes;i++,revNodI++)
1950 int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1951 if(nbOfCellsSharingNode==0)
1953 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh3D : Node #" << i << " is orphan !";
1954 throw INTERP_KERNEL::Exception(oss.str().c_str());
1956 for(int j=0;j<nbOfCellsSharingNode;j++)
1958 int curCellId(revNod[revNodI[0]+j]);
1959 const int *connOfCurCell(nodal+4*curCellId);
1960 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1961 if(j!=0) cArr->pushBackSilent(-1);
1964 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;
1965 tmp[2]=curCellId+offset1; tmp[3]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+2]]+nbOfNodes;
1967 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;
1968 tmp[7]=curCellId+offset1; tmp[8]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+5]]+nbOfNodes;
1970 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;
1971 tmp[12]=curCellId+offset1; tmp[13]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+8]]+nbOfNodes;
1972 cArr->insertAtTheEnd(tmp,tmp+14);
1974 for(int k=0;k<4;k++)
1976 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1978 const int *faceId(d2+4*curCellId+k);
1979 if(rdi2[*faceId+1]-rdi2[*faceId]==1)
1981 int tmp2[5]; tmp2[0]=-1; tmp2[1]=i;
1982 tmp2[2]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+0]-8]+offset0;
1983 tmp2[3]=d2[4*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+1]-4]+nbOfNodes;
1984 tmp2[4]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+2]-8]+offset0;
1985 cArr->insertAtTheEnd(tmp2,tmp2+5);
1991 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
1993 ret->setNodalConnectivity(cArr,ciArr);
1997 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh2D() const
1999 static const int DUAL_TRI_0[6]={0,2, 1,0, 2,1};
2000 static const int DUAL_TRI_1[6]={-3,+5, +3,-4, +4,-5};
2001 static const int FACEID_NOT_SH_NODE[3]={1,2,0};
2002 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TRI3)
2003 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh2D : only TRI3 supported !");
2004 checkFullyDefined();
2005 MCAuto<MEDCouplingUMesh> thisu(buildUnstructured());
2006 MCAuto<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
2007 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
2008 const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
2009 MCAuto<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
2010 MCAuto<MEDCouplingUMesh> edges(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
2011 const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
2012 MCAuto<DataArrayDouble> edgesBaryArr(edges->computeCellCenterOfMass()),baryArr(computeCellCenterOfMass());
2013 const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+edges->getNumberOfCells());
2015 std::vector<const DataArrayDouble *> v(3); v[0]=getCoords(); v[1]=edgesBaryArr; v[2]=baryArr;
2016 MCAuto<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0;
2017 std::string name("DualOf_"); name+=getName();
2018 MCAuto<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYGON)); ret->setCoords(zeArr);
2019 MCAuto<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
2020 for(int i=0;i<nbOfNodes;i++,revNodI++)
2022 int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
2023 if(nbOfCellsSharingNode==0)
2025 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh2D : Node #" << i << " is orphan !";
2026 throw INTERP_KERNEL::Exception(oss.str().c_str());
2028 std::vector< std::vector<int> > polyg;
2029 for(int j=0;j<nbOfCellsSharingNode;j++)
2031 int curCellId(revNod[revNodI[0]+j]);
2032 const int *connOfCurCell(nodal+3*curCellId);
2033 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
2034 std::vector<int> locV(3);
2035 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;
2036 polyg.push_back(locV);
2038 for(int k=0;k<3;k++)
2040 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
2042 const int *edgeId(d2+3*curCellId+k);
2043 if(rdi2[*edgeId+1]-rdi2[*edgeId]==1)
2045 std::vector<int> locV2(2);
2046 int zeLocEdgeIdRel(DUAL_TRI_1[2*nodePosInCurCell+kk]);
2047 if(zeLocEdgeIdRel>0)
2048 { locV2[0]=d2[3*curCellId+zeLocEdgeIdRel-3]+nbOfNodes; locV2[1]=i; }
2050 { locV2[0]=i; locV2[1]=d2[3*curCellId-zeLocEdgeIdRel-3]+nbOfNodes; }
2051 polyg.push_back(locV2);
2057 std::vector<int> zePolyg(MEDCoupling1DGTUMesh::BuildAPolygonFromParts(polyg));
2058 cArr->insertAtTheEnd(zePolyg.begin(),zePolyg.end());
2059 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
2061 ret->setNodalConnectivity(cArr,ciArr);
2066 * This method aggregate the bbox of each cell and put it into bbox
2068 * \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)
2069 * For all other cases this input parameter is ignored.
2070 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
2072 * \throw If \a this is not fully set (coordinates and connectivity).
2073 * \throw If a cell in \a this has no valid nodeId.
2075 DataArrayDouble *MEDCoupling1SGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
2077 int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()),nbOfNodesPerCell(getNumberOfNodesPerCell());
2078 MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
2079 double *bbox(ret->getPointer());
2080 for(int i=0;i<nbOfCells*spaceDim;i++)
2082 bbox[2*i]=std::numeric_limits<double>::max();
2083 bbox[2*i+1]=-std::numeric_limits<double>::max();
2085 const double *coordsPtr(_coords->getConstPointer());
2086 const int *conn(_conn->getConstPointer());
2087 for(int i=0;i<nbOfCells;i++)
2090 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
2093 if(nodeId>=0 && nodeId<nbOfNodes)
2095 for(int k=0;k<spaceDim;k++)
2097 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
2098 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
2105 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
2106 throw INTERP_KERNEL::Exception(oss.str().c_str());
2113 * 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.
2115 * \return a new instance of field containing the result. The returned instance has to be deallocated by the caller.
2117 MEDCouplingFieldDouble *MEDCoupling1SGTUMesh::computeDiameterField() const
2119 checkFullyDefined();
2120 MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME));
2121 int nbCells(getNumberOfCells());
2122 MCAuto<DataArrayDouble> arr(DataArrayDouble::New());
2123 arr->alloc(nbCells,1);
2124 INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::DiameterCalculator> dc(_cm->buildInstanceOfDiameterCalulator(getSpaceDimension()));
2125 dc->computeFor1SGTUMeshFrmt(nbCells,_conn->begin(),getCoords()->begin(),arr->getPointer());
2128 ret->setName("Diameter");
2134 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New()
2136 return new MEDCoupling1DGTUMesh;
2139 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
2141 if(type==INTERP_KERNEL::NORM_ERROR)
2142 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
2143 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
2146 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !";
2147 throw INTERP_KERNEL::Exception(oss.str().c_str());
2149 return new MEDCoupling1DGTUMesh(name,cm);
2152 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh()
2156 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
2160 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn_indx(other._conn_indx),_conn(other._conn)
2164 const DataArrayInt *c(other._conn);
2166 _conn=c->deepCopy();
2169 _conn_indx=c->deepCopy();
2173 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const
2175 return new MEDCoupling1DGTUMesh(*this,recDeepCpy);
2179 * This method behaves mostly like MEDCoupling1DGTUMesh::deepCopy method, except that only nodal connectivity arrays are deeply copied.
2180 * The coordinates are shared between \a this and the returned instance.
2182 * \return MEDCoupling1DGTUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
2183 * \sa MEDCoupling1DGTUMesh::deepCopy
2185 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::deepCopyConnectivityOnly() const
2187 checkConsistencyLight();
2188 MCAuto<MEDCoupling1DGTUMesh> ret(clone(false));
2189 MCAuto<DataArrayInt> c(_conn->deepCopy()),ci(_conn_indx->deepCopy());
2190 ret->setNodalConnectivity(c,ci);
2194 void MEDCoupling1DGTUMesh::updateTime() const
2196 MEDCoupling1GTUMesh::updateTime();
2197 const DataArrayInt *c(_conn);
2205 std::size_t MEDCoupling1DGTUMesh::getHeapMemorySizeWithoutChildren() const
2207 return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren();
2210 std::vector<const BigMemoryObject *> MEDCoupling1DGTUMesh::getDirectChildrenWithNull() const
2212 std::vector<const BigMemoryObject *> ret(MEDCoupling1GTUMesh::getDirectChildrenWithNull());
2213 ret.push_back((const DataArrayInt *)_conn);
2214 ret.push_back((const DataArrayInt *)_conn_indx);
2218 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::deepCopy() const
2223 bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
2226 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !");
2227 std::ostringstream oss; oss.precision(15);
2228 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2231 reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !";
2234 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
2236 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2241 reason="in connectivity of single dynamic geometric type exactly one among this and other is null !";
2244 if(!c1->isEqualIfNotWhy(*c2,reason))
2246 reason.insert(0,"Nodal connectivity DataArrayInt differs : ");
2249 c1=_conn_indx; c2=otherC->_conn_indx;
2254 reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !";
2257 if(!c1->isEqualIfNotWhy(*c2,reason))
2259 reason.insert(0,"Nodal connectivity index DataArrayInt differs : ");
2265 bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
2268 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
2269 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2272 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
2274 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2279 if(!c1->isEqualWithoutConsideringStr(*c2))
2282 c1=_conn_indx; c2=otherC->_conn_indx;
2287 if(!c1->isEqualWithoutConsideringStr(*c2))
2293 * Checks if \a this and \a other meshes are geometrically equivalent with high
2294 * probability, else an exception is thrown. The meshes are considered equivalent if
2295 * (1) meshes contain the same number of nodes and the same number of elements of the
2296 * same types (2) three cells of the two meshes (first, last and middle) are based
2297 * on coincident nodes (with a specified precision).
2298 * \param [in] other - the mesh to compare with.
2299 * \param [in] prec - the precision used to compare nodes of the two meshes.
2300 * \throw If the two meshes do not match.
2302 void MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
2304 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
2305 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2307 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single dynamic geometric type !");
2308 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2312 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
2313 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2314 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
2315 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2316 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
2317 if(c1->getHashCode()!=c2->getHashCode())
2318 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs");
2320 c1=_conn_indx; c2=otherC->_conn_indx;
2324 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !");
2325 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2326 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !");
2327 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2328 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !");
2329 if(c1->getHashCode()!=c2->getHashCode())
2330 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs");
2334 void MEDCoupling1DGTUMesh::checkConsistencyOfConnectivity() const
2336 const DataArrayInt *c1(_conn);
2339 if(c1->getNumberOfComponents()!=1)
2340 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
2341 if(c1->getInfoOnComponent(0)!="")
2342 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
2343 c1->checkAllocated();
2346 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
2348 int sz2=_conn->getNumberOfTuples();
2352 if(c1->getNumberOfComponents()!=1)
2353 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
2354 c1->checkAllocated();
2355 if(c1->getNumberOfTuples()<1)
2356 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !");
2357 if(c1->getInfoOnComponent(0)!="")
2358 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
2359 int f=c1->front(),ll=c1->back();
2360 if(f<0 || (sz2>0 && f>=sz2))
2362 std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !";
2363 throw INTERP_KERNEL::Exception(oss.str().c_str());
2367 std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !";
2368 throw INTERP_KERNEL::Exception(oss.str().c_str());
2372 std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !";
2373 throw INTERP_KERNEL::Exception(oss.str().c_str());
2377 throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !");
2378 int szOfC1Exp=_conn_indx->back();
2381 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() << " !";
2382 throw INTERP_KERNEL::Exception(oss.str().c_str());
2387 * 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.
2388 * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one.
2389 * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array.
2391 void MEDCoupling1DGTUMesh::checkConsistencyLight() const
2393 MEDCouplingPointSet::checkConsistencyLight();
2394 checkConsistencyOfConnectivity();
2397 void MEDCoupling1DGTUMesh::checkConsistency(double eps) const
2399 checkConsistencyLight();
2400 const DataArrayInt *c1(_conn),*c2(_conn_indx);
2401 if(!c2->isMonotonic(true))
2402 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkConsistency : the nodal connectivity index is expected to be increasing monotinic !");
2404 int nbOfTuples=c1->getNumberOfTuples();
2405 int nbOfNodes=getNumberOfNodes();
2406 const int *w(c1->begin());
2407 for(int i=0;i<nbOfTuples;i++,w++)
2409 if(*w==-1) continue;
2410 if(*w<0 || *w>=nbOfNodes)
2412 std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !";
2413 throw INTERP_KERNEL::Exception(oss.str().c_str());
2418 int MEDCoupling1DGTUMesh::getNumberOfCells() const
2420 checkConsistencyOfConnectivity();//do not remove
2421 return _conn_indx->getNumberOfTuples()-1;
2425 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2426 * For each cell in \b this the number of nodes constituting cell is computed.
2427 * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned.
2428 * So for pohyhedrons some nodes can be counted several times in the returned result.
2430 * \return a newly allocated array
2432 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const
2434 checkConsistencyLight();
2435 _conn_indx->checkMonotonic(true);
2436 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2437 return _conn_indx->deltaShiftIndex();
2439 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2440 MCAuto<DataArrayInt> ret=DataArrayInt::New();
2441 ret->alloc(nbOfCells,1);
2442 int *retPtr=ret->getPointer();
2443 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2444 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2445 *retPtr=ci[1]-ci[0]-std::count(c+ci[0],c+ci[1],-1);
2450 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2451 * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed.
2453 * \return a newly allocated array
2455 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const
2457 checkConsistencyLight();
2458 _conn_indx->checkMonotonic(true);
2459 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG)
2460 return _conn_indx->deltaShiftIndex();
2461 if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG)
2463 MCAuto<DataArrayInt> ret=_conn_indx->deltaShiftIndex();
2464 ret->applyDivideBy(2);
2468 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2469 MCAuto<DataArrayInt> ret=DataArrayInt::New();
2470 ret->alloc(nbOfCells,1);
2471 int *retPtr=ret->getPointer();
2472 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2473 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2474 *retPtr=std::count(c+ci[0],c+ci[1],-1)+1;
2479 * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell,
2480 * will be counted only once here whereas it will be counted several times in MEDCoupling1DGTUMesh::computeNbOfNodesPerCell method.
2482 * \return DataArrayInt * - new object to be deallocated by the caller.
2483 * \sa MEDCoupling1DGTUMesh::computeNbOfNodesPerCell
2485 DataArrayInt *MEDCoupling1DGTUMesh::computeEffectiveNbOfNodesPerCell() const
2487 checkConsistencyLight();
2488 _conn_indx->checkMonotonic(true);
2489 int nbOfCells(_conn_indx->getNumberOfTuples()-1);
2490 MCAuto<DataArrayInt> ret=DataArrayInt::New();
2491 ret->alloc(nbOfCells,1);
2492 int *retPtr(ret->getPointer());
2493 const int *ci(_conn_indx->begin()),*c(_conn->begin());
2494 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2496 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2498 std::set<int> s(c+ci[0],c+ci[1]);
2499 *retPtr=(int)s.size();
2504 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2506 std::set<int> s(c+ci[0],c+ci[1]); s.erase(-1);
2507 *retPtr=(int)s.size();
2513 void MEDCoupling1DGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
2515 int nbOfCells(getNumberOfCells());//performs checks
2516 if(cellId>=0 && cellId<nbOfCells)
2518 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2519 int nbOfNodes=stp-strt;
2521 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !");
2522 conn.resize(nbOfNodes);
2523 std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin());
2527 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2528 throw INTERP_KERNEL::Exception(oss.str().c_str());
2532 int MEDCoupling1DGTUMesh::getNumberOfNodesInCell(int cellId) const
2534 int nbOfCells(getNumberOfCells());//performs checks
2535 if(cellId>=0 && cellId<nbOfCells)
2537 const int *conn(_conn->begin());
2538 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2539 return stp-strt-std::count(conn+strt,conn+stp,-1);
2543 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNumberOfNodesInCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2544 throw INTERP_KERNEL::Exception(oss.str().c_str());
2548 std::string MEDCoupling1DGTUMesh::simpleRepr() const
2550 static const char msg0[]="No coordinates specified !";
2551 std::ostringstream ret;
2552 ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
2553 ret << "Description of mesh : \"" << getDescription() << "\"\n";
2555 double tt=getTime(tmpp1,tmpp2);
2556 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
2557 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
2558 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
2561 const int spaceDim=getSpaceDimension();
2562 ret << spaceDim << "\nInfo attached on space dimension : ";
2563 for(int i=0;i<spaceDim;i++)
2564 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
2568 ret << msg0 << "\n";
2569 ret << "Number of nodes : ";
2571 ret << getNumberOfNodes() << "\n";
2573 ret << msg0 << "\n";
2574 ret << "Number of cells : ";
2576 try { checkConsistencyLight(); } catch(INTERP_KERNEL::Exception& /* e */)
2578 ret << "Nodal connectivity arrays are not set or badly set !\n";
2582 ret << getNumberOfCells() << "\n";
2583 ret << "Cell type : " << _cm->getRepr() << "\n";
2587 std::string MEDCoupling1DGTUMesh::advancedRepr() const
2589 std::ostringstream ret;
2590 ret << simpleRepr();
2591 ret << "\nCoordinates array : \n___________________\n\n";
2593 _coords->reprWithoutNameStream(ret);
2595 ret << "No array set !\n";
2596 ret << "\n\nNodal Connectivity : \n____________________\n\n";
2599 try { checkConsistency(); } catch(INTERP_KERNEL::Exception& /* e */)
2601 ret << "Nodal connectivity arrays are not set or badly set !\n";
2606 int nbOfCells=getNumberOfCells();
2607 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2608 for(int i=0;i<nbOfCells;i++,ci++)
2610 ret << "Cell #" << i << " : ";
2611 std::copy(c+ci[0],c+ci[1],std::ostream_iterator<int>(ret," "));
2617 DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const
2619 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2620 int spaceDim=getSpaceDimension();
2621 int nbOfCells=getNumberOfCells();//checkConsistencyLight()
2622 int nbOfNodes=getNumberOfNodes();
2623 ret->alloc(nbOfCells,spaceDim);
2624 double *ptToFill=ret->getPointer();
2625 const double *coor=_coords->begin();
2626 const int *nodal=_conn->begin(),*nodali=_conn_indx->begin();
2628 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2630 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2632 std::fill(ptToFill,ptToFill+spaceDim,0.);
2633 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2635 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2637 if(*nodal>=0 && *nodal<nbOfNodes)
2638 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2641 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2642 throw INTERP_KERNEL::Exception(oss.str().c_str());
2644 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(nodali[1]-nodali[0])));
2649 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !";
2650 throw INTERP_KERNEL::Exception(oss.str().c_str());
2656 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2658 std::fill(ptToFill,ptToFill+spaceDim,0.);
2659 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2662 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2664 if(*nodal==-1) continue;
2665 if(*nodal>=0 && *nodal<nbOfNodes)
2667 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2672 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2673 throw INTERP_KERNEL::Exception(oss.str().c_str());
2677 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./nbOfNod));
2680 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !";
2681 throw INTERP_KERNEL::Exception(oss.str().c_str());
2686 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : at cell #" << i << " the nodal index array is invalid !";
2687 throw INTERP_KERNEL::Exception(oss.str().c_str());
2694 void MEDCoupling1DGTUMesh::renumberCells(const int *old2NewBg, bool check)
2696 int nbCells=getNumberOfCells();
2697 MCAuto<DataArrayInt> o2n=DataArrayInt::New();
2698 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
2700 o2n=o2n->checkAndPreparePermutation();
2702 const int *o2nPtr=o2n->getPointer();
2703 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2704 MCAuto<DataArrayInt> newConn=DataArrayInt::New();
2705 MCAuto<DataArrayInt> newConnI=DataArrayInt::New();
2706 newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1);
2707 newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx);
2709 int *newC=newConn->getPointer(),*newCI=newConnI->getPointer();
2710 for(int i=0;i<nbCells;i++)
2712 int newPos=o2nPtr[i];
2713 int sz=conni[i+1]-conni[i];
2718 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !";
2719 throw INTERP_KERNEL::Exception(oss.str().c_str());
2722 newConnI->computeOffsetsFull(); newCI=newConnI->getPointer();
2724 for(int i=0;i<nbCells;i++,conni++)
2727 std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]);
2730 _conn_indx=newConnI;
2733 MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
2735 if(other->getType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED)
2736 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !");
2737 const MEDCoupling1DGTUMesh *otherC=static_cast<const MEDCoupling1DGTUMesh *>(other);
2738 return Merge1DGTUMeshes(this,otherC);
2741 MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const
2743 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
2744 ret->setCoords(getCoords());
2745 const int *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin();
2746 int nbCells=getNumberOfCells();//checkConsistencyLight
2747 int geoType=(int)getCellModelEnum();
2748 MCAuto<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1);
2749 MCAuto<DataArrayInt> cI=DataArrayInt::New(); cI->alloc(nbCells+1);
2750 int *cPtr=c->getPointer(),*ciPtr=cI->getPointer();
2752 for(int i=0;i<nbCells;i++,ciPtr++)
2754 int sz=nodalConnI[i+1]-nodalConnI[i];
2758 cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr);
2759 ciPtr[1]=ciPtr[0]+sz+1;
2763 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !";
2764 throw INTERP_KERNEL::Exception(oss.str().c_str());
2767 ret->setConnectivity(c,cI,true);
2769 { ret->copyTinyInfoFrom(this); }
2770 catch(INTERP_KERNEL::Exception&) { }
2775 * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes
2777 DataArrayInt *MEDCoupling1DGTUMesh::simplexize(int policy)
2779 int nbOfCells=getNumberOfCells();
2780 MCAuto<DataArrayInt> ret=DataArrayInt::New();
2781 ret->alloc(nbOfCells,1);
2786 void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const
2788 stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
2789 stream << " Mesh dimension : " << getMeshDimension() << ".";
2791 { stream << " No coordinates set !"; return ; }
2792 if(!_coords->isAllocated())
2793 { stream << " Coordinates set but not allocated !"; return ; }
2794 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
2795 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
2797 try { checkConsistencyLight(); } catch(INTERP_KERNEL::Exception& /* e */)
2799 stream << std::endl << "Nodal connectivity NOT set properly !\n";
2803 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
2806 void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
2809 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
2810 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2812 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !");
2813 setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex());
2816 MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
2819 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
2820 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2822 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
2823 std::vector<const MEDCoupling1DGTUMesh *> ms(2);
2826 return Merge1DGTUMeshesOnSameCoords(ms);
2829 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
2831 checkConsistencyLight();
2832 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2833 ret->setCoords(_coords);
2834 DataArrayInt *c=0,*ci=0;
2835 MEDCouplingUMesh::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci);
2836 MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
2837 ret->setNodalConnectivity(c,ci);
2841 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoordsSlice(int start, int end, int step) const
2843 checkConsistencyLight();
2844 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2845 ret->setCoords(_coords);
2846 DataArrayInt *c=0,*ci=0;
2847 MEDCouplingUMesh::ExtractFromIndexedArraysSlice(start,end,step,_conn,_conn_indx,c,ci);
2848 MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
2849 ret->setNodalConnectivity(c,ci);
2853 void MEDCoupling1DGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
2856 int sz((int)nodeIdsInUse.size());
2857 for(const int *conn=_conn->begin();conn!=_conn->end();conn++)
2859 if(*conn>=0 && *conn<sz)
2860 nodeIdsInUse[*conn]=true;
2865 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeNodeIdsAlg : At pos #" << std::distance(_conn->begin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !";
2866 throw INTERP_KERNEL::Exception(oss.str().c_str());
2872 void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const
2874 checkFullyDefined();
2875 int nbOfNodes=getNumberOfNodes();
2876 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
2877 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
2878 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
2879 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2880 int nbOfCells=getNumberOfCells();
2881 int nbOfEltsInRevNodal=0;
2882 for(int eltId=0;eltId<nbOfCells;eltId++)
2884 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2885 if(nbOfNodesPerCell>=0)
2887 for(int j=0;j<nbOfNodesPerCell;j++)
2889 int nodeId=conn[conni[eltId]+j];
2890 if(nodeId==-1) continue;
2891 if(nodeId>=0 && nodeId<nbOfNodes)
2893 nbOfEltsInRevNodal++;
2894 revNodalIndxPtr[nodeId+1]++;
2898 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
2899 throw INTERP_KERNEL::Exception(oss.str().c_str());
2905 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << "nodal connectivity is invalid !";
2906 throw INTERP_KERNEL::Exception(oss.str().c_str());
2909 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
2910 conn=_conn->begin();
2911 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
2912 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
2913 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
2914 for(int eltId=0;eltId<nbOfCells;eltId++)
2916 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2917 for(int j=0;j<nbOfNodesPerCell;j++)
2919 int nodeId=conn[conni[eltId]+j];
2921 *std::find_if(revNodalPtr+revNodalIndxPtr[nodeId],revNodalPtr+revNodalIndxPtr[nodeId+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
2926 void MEDCoupling1DGTUMesh::checkFullyDefined() const
2928 if(!((const DataArrayInt *)_conn) || !((const DataArrayInt *)_conn_indx) || !((const DataArrayDouble *)_coords))
2929 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined.");
2932 bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
2934 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !");
2937 void MEDCoupling1DGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
2940 double time=getTime(it,order);
2941 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
2943 littleStrings.push_back(getName());
2944 littleStrings.push_back(getDescription());
2945 littleStrings.push_back(getTimeUnit());
2947 std::vector<std::string> littleStrings2,littleStrings3,littleStrings4;
2948 if((const DataArrayDouble *)_coords)
2949 _coords->getTinySerializationStrInformation(littleStrings2);
2950 if((const DataArrayInt *)_conn)
2951 _conn->getTinySerializationStrInformation(littleStrings3);
2952 if((const DataArrayInt *)_conn_indx)
2953 _conn_indx->getTinySerializationStrInformation(littleStrings4);
2954 int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size()),sz2((int)littleStrings4.size());
2955 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
2956 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
2957 littleStrings.insert(littleStrings.end(),littleStrings4.begin(),littleStrings4.end());
2959 tinyInfo.push_back(getCellModelEnum());
2960 tinyInfo.push_back(it);
2961 tinyInfo.push_back(order);
2962 std::vector<int> tinyInfo2,tinyInfo3,tinyInfo4;
2963 if((const DataArrayDouble *)_coords)
2964 _coords->getTinySerializationIntInformation(tinyInfo2);
2965 if((const DataArrayInt *)_conn)
2966 _conn->getTinySerializationIntInformation(tinyInfo3);
2967 if((const DataArrayInt *)_conn_indx)
2968 _conn_indx->getTinySerializationIntInformation(tinyInfo4);
2969 int sz3((int)tinyInfo2.size()),sz4((int)tinyInfo3.size()),sz5((int)tinyInfo4.size());
2970 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3); tinyInfo.push_back(sz4); tinyInfo.push_back(sz5);
2971 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
2972 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
2973 tinyInfo.insert(tinyInfo.end(),tinyInfo4.begin(),tinyInfo4.end());
2975 tinyInfoD.push_back(time);
2978 void MEDCoupling1DGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
2980 std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+tinyInfo[6]);
2981 std::vector<int> tinyInfo1(tinyInfo.begin()+9+tinyInfo[6],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]);
2982 std::vector<int> tinyInfo12(tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]+tinyInfo[8]);
2983 MCAuto<DataArrayInt> p1(DataArrayInt::New()); p1->resizeForUnserialization(tinyInfo1);
2984 MCAuto<DataArrayInt> p2(DataArrayInt::New()); p2->resizeForUnserialization(tinyInfo12);
2985 std::vector<const DataArrayInt *> v(2); v[0]=p1; v[1]=p2;
2986 p2=DataArrayInt::Aggregate(v);
2987 a2->resizeForUnserialization(tinyInfo2);
2988 a1->alloc(p2->getNbOfElems(),1);
2991 void MEDCoupling1DGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
2994 if((const DataArrayInt *)_conn)
2995 if(_conn->isAllocated())
2996 sz=_conn->getNbOfElems();
2997 if((const DataArrayInt *)_conn_indx)
2998 if(_conn_indx->isAllocated())
2999 sz+=_conn_indx->getNbOfElems();
3000 a1=DataArrayInt::New();
3002 int *work(a1->getPointer());
3003 if(sz!=0 && (const DataArrayInt *)_conn)
3004 work=std::copy(_conn->begin(),_conn->end(),a1->getPointer());
3005 if(sz!=0 && (const DataArrayInt *)_conn_indx)
3006 std::copy(_conn_indx->begin(),_conn_indx->end(),work);
3008 if((const DataArrayDouble *)_coords)
3009 if(_coords->isAllocated())
3010 sz=_coords->getNbOfElems();
3011 a2=DataArrayDouble::New();
3013 if(sz!=0 && (const DataArrayDouble *)_coords)
3014 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
3017 void MEDCoupling1DGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
3018 const std::vector<std::string>& littleStrings)
3020 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
3021 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
3022 setName(littleStrings[0]);
3023 setDescription(littleStrings[1]);
3024 setTimeUnit(littleStrings[2]);
3025 setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
3026 int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]),sz4(tinyInfo[7]),sz5(tinyInfo[8]);
3028 _coords=DataArrayDouble::New();
3029 std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+sz3);
3030 _coords->resizeForUnserialization(tinyInfo2);
3031 std::copy(a2->begin(),a2->end(),_coords->getPointer());
3032 _conn=DataArrayInt::New();
3033 std::vector<int> tinyInfo3(tinyInfo.begin()+9+sz3,tinyInfo.begin()+9+sz3+sz4);
3034 _conn->resizeForUnserialization(tinyInfo3);
3035 std::copy(a1->begin(),a1->begin()+_conn->getNbOfElems(),_conn->getPointer());
3036 _conn_indx=DataArrayInt::New();
3037 std::vector<int> tinyInfo4(tinyInfo.begin()+9+sz3+sz4,tinyInfo.begin()+9+sz3+sz4+sz5);
3038 _conn_indx->resizeForUnserialization(tinyInfo4);
3039 std::copy(a1->begin()+_conn->getNbOfElems(),a1->end(),_conn_indx->getPointer());
3040 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
3041 _coords->finishUnserialization(tinyInfo2,littleStrings2);
3042 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
3043 _conn->finishUnserialization(tinyInfo3,littleStrings3);
3044 std::vector<std::string> littleStrings4(littleStrings.begin()+3+sz0+sz1,littleStrings.begin()+3+sz0+sz1+sz2);
3045 _conn_indx->finishUnserialization(tinyInfo4,littleStrings4);
3049 * Finds nodes not used in any cell and returns an array giving a new id to every node
3050 * by excluding the unused nodes, for which the array holds -1. The result array is
3051 * a mapping in "Old to New" mode.
3052 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
3053 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
3054 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
3055 * if the node is unused or a new id else. The caller is to delete this
3056 * array using decrRef() as it is no more needed.
3057 * \throw If the coordinates array is not set.
3058 * \throw If the nodal connectivity of cells is not defined.
3059 * \throw If the nodal connectivity includes an invalid id.
3060 * \sa MEDCoupling1DGTUMesh::getNodeIdsInUse, areAllNodesFetched
3062 DataArrayInt *MEDCoupling1DGTUMesh::computeFetchedNodeIds() const
3065 int nbNodes(getNumberOfNodes());
3066 std::vector<bool> fetchedNodes(nbNodes,false);
3067 computeNodeIdsAlg(fetchedNodes);
3068 int sz((int)std::count(fetchedNodes.begin(),fetchedNodes.end(),true));
3069 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
3070 int *retPtr(ret->getPointer());
3071 for(int i=0;i<nbNodes;i++)
3078 * Finds nodes not used in any cell and returns an array giving a new id to every node
3079 * by excluding the unused nodes, for which the array holds -1. The result array is
3080 * a mapping in "Old to New" mode.
3081 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
3082 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
3083 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
3084 * if the node is unused or a new id else. The caller is to delete this
3085 * array using decrRef() as it is no more needed.
3086 * \throw If the coordinates array is not set.
3087 * \throw If the nodal connectivity of cells is not defined.
3088 * \throw If the nodal connectivity includes an invalid id.
3089 * \sa MEDCoupling1DGTUMesh::computeFetchedNodeIds, areAllNodesFetched
3091 DataArrayInt *MEDCoupling1DGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
3094 int nbOfNodes=getNumberOfNodes();
3095 int nbOfCells=getNumberOfCells();//checkConsistencyLight
3096 MCAuto<DataArrayInt> ret=DataArrayInt::New();
3097 ret->alloc(nbOfNodes,1);
3098 int *traducer=ret->getPointer();
3099 std::fill(traducer,traducer+nbOfNodes,-1);
3100 const int *conn=_conn->begin(),*conni(_conn_indx->begin());
3101 for(int i=0;i<nbOfCells;i++,conni++)
3103 int nbNodesPerCell=conni[1]-conni[0];
3104 for(int j=0;j<nbNodesPerCell;j++)
3106 int nodeId=conn[conni[0]+j];
3107 if(nodeId==-1) continue;
3108 if(nodeId>=0 && nodeId<nbOfNodes)
3112 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << nodeId << " not in [0," << nbOfNodes << ") !";
3113 throw INTERP_KERNEL::Exception(oss.str().c_str());
3117 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
3118 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
3123 * This method renumbers only nodal connectivity in \a this. The renumbering is only an offset applied. So this method is a specialization of
3124 * \a renumberNodesInConn. \b WARNING, this method does not check that the resulting node ids in the nodal connectivity is in a valid range !
3126 * \param [in] offset - specifies the offset to be applied on each element of connectivity.
3128 * \sa renumberNodesInConn
3130 void MEDCoupling1DGTUMesh::renumberNodesWithOffsetInConn(int offset)
3132 getNumberOfCells();//only to check that all is well defined.
3134 int nbOfTuples(_conn->getNumberOfTuples());
3135 int *pt(_conn->getPointer());
3136 for(int i=0;i<nbOfTuples;i++,pt++)
3138 if(*pt==-1) continue;
3146 * Same than renumberNodesInConn(const int *) except that here the format of old-to-new traducer is using map instead
3147 * 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
3150 void MEDCoupling1DGTUMesh::renumberNodesInConn(const INTERP_KERNEL::HashMap<int,int>& newNodeNumbersO2N)
3152 getNumberOfCells();//only to check that all is well defined.
3154 int nbElemsIn(getNumberOfNodes()),nbOfTuples(_conn->getNumberOfTuples());
3155 int *pt(_conn->getPointer());
3156 for(int i=0;i<nbOfTuples;i++,pt++)
3158 if(*pt==-1) continue;
3159 if(*pt>=0 && *pt<nbElemsIn)
3161 INTERP_KERNEL::HashMap<int,int>::const_iterator it(newNodeNumbersO2N.find(*pt));
3162 if(it!=newNodeNumbersO2N.end())
3166 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : At pos #" << i << " of connectivity, node id is " << *pt << ". Not in keys of input map !";
3167 throw INTERP_KERNEL::Exception(oss.str().c_str());
3172 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
3173 throw INTERP_KERNEL::Exception(oss.str().c_str());
3181 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
3182 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
3183 * This method is a generalization of shiftNodeNumbersInConn().
3184 * \warning This method performs no check of validity of new ids. **Use it with care !**
3185 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
3186 * this->getNumberOfNodes(), in "Old to New" mode.
3187 * See \ref numbering for more info on renumbering modes.
3188 * \throw If the nodal connectivity of cells is not defined.
3190 void MEDCoupling1DGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
3192 getNumberOfCells();//only to check that all is well defined.
3194 int nbElemsIn(getNumberOfNodes()),nbOfTuples(_conn->getNumberOfTuples());
3195 int *pt(_conn->getPointer());
3196 for(int i=0;i<nbOfTuples;i++,pt++)
3198 if(*pt==-1) continue;
3199 if(*pt>=0 && *pt<nbElemsIn)
3200 *pt=newNodeNumbersO2N[*pt];
3203 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
3204 throw INTERP_KERNEL::Exception(oss.str().c_str());
3212 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
3213 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
3214 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
3215 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
3217 * \param [in] begin input start of array of node ids.
3218 * \param [in] end input end of array of node ids.
3219 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
3220 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
3222 void MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
3224 int nbOfCells=getNumberOfCells();
3225 MCAuto<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
3227 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
3228 std::vector<bool> fastFinder(sz,false);
3229 for(const int *work=begin;work!=end;work++)
3230 if(*work>=0 && *work<sz)
3231 fastFinder[*work]=true;
3232 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
3233 for(int i=0;i<nbOfCells;i++,conni++)
3235 int ref=0,nbOfHit=0;
3236 int nbNodesPerCell=conni[1]-conni[0];
3237 if(nbNodesPerCell>=0)
3239 for(int j=0;j<nbNodesPerCell;j++)
3241 int nodeId=conn[conni[0]+j];
3245 if(fastFinder[nodeId])
3252 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !";
3253 throw INTERP_KERNEL::Exception(oss.str().c_str());
3255 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
3256 cellIdsKept->pushBackSilent(i);
3258 cellIdsKeptArr=cellIdsKept.retn();
3261 void MEDCoupling1DGTUMesh::allocateCells(int nbOfCells)
3264 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !");
3265 _conn=DataArrayInt::New();
3266 _conn->reserve(nbOfCells*3);
3267 _conn_indx=DataArrayInt::New();
3268 _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0);
3273 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
3275 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
3276 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
3277 * \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
3278 * attached to \a this.
3279 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
3281 void MEDCoupling1DGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd)
3283 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
3284 DataArrayInt *c(_conn),*c2(_conn_indx);
3288 if(pos==c->getNumberOfTuples())
3290 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
3291 c2->pushBackSilent(pos+sz);
3295 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !";
3296 throw INTERP_KERNEL::Exception(oss.str().c_str());
3300 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !");
3303 void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex)
3306 nodalConn->incrRef();
3309 nodalConnIndex->incrRef();
3310 _conn_indx=nodalConnIndex;
3315 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
3317 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivity() const
3319 const DataArrayInt *ret(_conn);
3320 return const_cast<DataArrayInt *>(ret);
3324 * \return DataArrayInt * - the internal reference to the nodal connectivity index. The caller is not reponsible to deallocate it.
3326 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const
3328 const DataArrayInt *ret(_conn_indx);
3329 return const_cast<DataArrayInt *>(ret);
3333 * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here".
3334 * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity).
3335 * 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.
3337 * 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.
3339 * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal
3340 * connectivity arrays are different (false)
3341 * \return a new object to be managed by the caller.
3343 * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked
3345 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const
3347 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3348 DataArrayInt *nc=0,*nci=0;
3349 isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci);
3350 MCAuto<DataArrayInt> ncs(nc),ncis(nci);
3351 ret->_conn=ncs; ret->_conn_indx=ncis;
3352 ret->setCoords(getCoords());
3357 * This method allows to compute, if needed, the packed nodal connectivity pair.
3358 * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges convered by nodal connectivity index array.
3359 * 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.
3361 * 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)
3362 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3364 * 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
3367 * This method return 3 elements.
3368 * \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
3369 * this pointer can be seen as a new object, that is to managed by the caller.
3370 * \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
3371 * this pointer can be seen as a new object, that is to managed by the caller.
3372 * \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
3373 * output parameters are newly created objects.
3375 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkConsistencyLight test
3377 bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const
3379 if(isPacked())//performs the checkConsistencyLight
3381 const DataArrayInt *c0(_conn),*c1(_conn_indx);
3382 nodalConn=const_cast<DataArrayInt *>(c0); nodalConnIndx=const_cast<DataArrayInt *>(c1);
3383 nodalConn->incrRef(); nodalConnIndx->incrRef();
3386 int bg=_conn_indx->front(),end=_conn_indx->back();
3387 MCAuto<DataArrayInt> nc(_conn->selectByTupleIdSafeSlice(bg,end,1));
3388 MCAuto<DataArrayInt> nci(_conn_indx->deepCopy());
3389 nci->applyLin(1,-bg);
3390 nodalConn=nc.retn(); nodalConnIndx=nci.retn();
3395 * 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)
3396 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3397 * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned.
3398 * \return bool - true if \a this looks packed, false is not.
3400 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkConsistencyLight test
3402 bool MEDCoupling1DGTUMesh::isPacked() const
3404 checkConsistencyLight();
3405 return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples();
3408 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2)
3410 std::vector<const MEDCoupling1DGTUMesh *> tmp(2);
3411 tmp[0]=const_cast<MEDCoupling1DGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1DGTUMesh *>(mesh2);
3412 return Merge1DGTUMeshes(tmp);
3415 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a)
3417 std::size_t sz=a.size();
3419 return Merge1DGTUMeshesLL(a);
3420 for(std::size_t ii=0;ii<sz;ii++)
3423 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::Merge1DGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
3424 throw INTERP_KERNEL::Exception(oss.str().c_str());
3426 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
3427 for(std::size_t ii=0;ii<sz;ii++)
3428 if(&(a[ii]->getCellModel())!=cm)
3429 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !");
3430 std::vector< MCAuto<MEDCoupling1DGTUMesh> > bb(sz);
3431 std::vector< const MEDCoupling1DGTUMesh * > aa(sz);
3433 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
3435 const MEDCoupling1DGTUMesh *cur=a[i];
3436 const DataArrayDouble *coo=cur->getCoords();
3438 spaceDim=coo->getNumberOfComponents();
3441 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !");
3442 for(std::size_t i=0;i<sz;i++)
3444 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
3447 return Merge1DGTUMeshesLL(aa);
3451 * \throw If presence of a null instance in the input vector \a a.
3452 * \throw If a is empty
3454 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a)
3457 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !");
3458 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3460 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !");
3461 std::vector< MCAuto<MEDCoupling1DGTUMesh> > objs(a.size());
3462 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3463 (*it)->getNumberOfCells();//to check that all is OK
3464 const DataArrayDouble *coords=(*it)->getCoords();
3465 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3467 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3468 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3470 for(int i=1;it!=a.end();i++,it++)
3473 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !");
3474 if(cm!=&((*it)->getCellModel()))
3475 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3476 (*it)->getNumberOfCells();//to check that all is OK
3477 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3478 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3479 if(coords!=(*it)->getCoords())
3480 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !");
3482 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3483 ret->setCoords(coords);
3484 ret->_conn=DataArrayInt::Aggregate(ncs);
3485 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3490 * 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)
3492 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a)
3495 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : input array must be NON EMPTY !");
3496 std::vector< MCAuto<MEDCoupling1DGTUMesh> > objs(a.size());
3497 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3498 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3499 std::vector<int> nbNodesPerElt(a.size());
3500 int nbOfCells=(*it)->getNumberOfCells();
3502 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3503 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3505 int prevNbOfNodes=(*it)->getNumberOfNodes();
3506 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3508 for(int i=1;it!=a.end();i++,it++)
3510 if(cm!=&((*it)->getCellModel()))
3511 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3512 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3513 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3514 nbOfCells+=(*it)->getNumberOfCells();
3515 nbNodesPerElt[i]=nbNodesPerElt[i-1]+prevNbOfNodes;
3516 prevNbOfNodes=(*it)->getNumberOfNodes();
3518 std::vector<const MEDCouplingPointSet *> aps(a.size());
3519 std::copy(a.begin(),a.end(),aps.begin());
3520 MCAuto<DataArrayDouble> pts=MergeNodesArray(aps);
3521 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3522 ret->setCoords(pts);
3523 ret->_conn=AggregateNodalConnAndShiftNodeIds(ncs,nbNodesPerElt);
3524 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3528 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(int spaceDim) const
3530 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3531 MCAuto<DataArrayInt> tmp1,tmp2;
3532 const DataArrayInt *nodalConn(_conn),*nodalConnI(_conn_indx);
3535 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
3543 tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
3547 ret->_conn_indx=tmp2;
3551 MCAuto<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
3552 ret->setCoords(coords);
3555 ret->setCoords(_coords);
3560 * This method aggregate the bbox of each cell and put it into bbox parameter.
3562 * \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)
3563 * For all other cases this input parameter is ignored.
3564 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
3566 * \throw If \a this is not fully set (coordinates and connectivity).
3567 * \throw If a cell in \a this has no valid nodeId.
3569 DataArrayDouble *MEDCoupling1DGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
3571 checkFullyDefined();
3572 int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes());
3573 MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
3574 double *bbox(ret->getPointer());
3575 for(int i=0;i<nbOfCells*spaceDim;i++)
3577 bbox[2*i]=std::numeric_limits<double>::max();
3578 bbox[2*i+1]=-std::numeric_limits<double>::max();
3580 const double *coordsPtr(_coords->getConstPointer());
3581 const int *conn(_conn->getConstPointer()),*connI(_conn_indx->getConstPointer());
3582 for(int i=0;i<nbOfCells;i++)
3584 int offset=connI[i];
3585 int nbOfNodesForCell(connI[i+1]-offset),kk(0);
3586 for(int j=0;j<nbOfNodesForCell;j++)
3588 int nodeId=conn[offset+j];
3589 if(nodeId>=0 && nodeId<nbOfNodes)
3591 for(int k=0;k<spaceDim;k++)
3593 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
3594 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
3601 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
3602 throw INTERP_KERNEL::Exception(oss.str().c_str());
3609 * 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.
3611 * \return a new instance of field containing the result. The returned instance has to be deallocated by the caller.
3613 MEDCouplingFieldDouble *MEDCoupling1DGTUMesh::computeDiameterField() const
3615 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::computeDiameterField : not implemented yet for dynamic types !");
3618 std::vector<int> MEDCoupling1DGTUMesh::BuildAPolygonFromParts(const std::vector< std::vector<int> >& parts)
3620 std::vector<int> ret;
3623 ret.insert(ret.end(),parts[0].begin(),parts[0].end());
3624 int ref(ret.back());
3625 std::size_t sz(parts.size()),nbh(1);
3626 std::vector<bool> b(sz,true); b[0]=false;
3630 for(;i<sz;i++) if(b[i] && parts[i].front()==ref) { ret.insert(ret.end(),parts[i].begin()+1,parts[i].end()); nbh++; break; }
3634 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::BuildAPolygonFromParts : the input vector is not a part of a single polygon !");
3636 if(ret.back()==ret.front())
3642 * This method performs an aggregation of \a nodalConns (as DataArrayInt::Aggregate does) but in addition of that a shift is applied on the
3643 * values contained in \a nodalConns using corresponding offset specified in input \a offsetInNodeIdsPerElt.
3644 * But it also manage the values -1, that have a semantic in MEDCoupling1DGTUMesh class (separator for polyhedron).
3646 * \param [in] nodalConns - a list of nodal connectivity arrays same size than \a offsetInNodeIdsPerElt.
3647 * \param [in] offsetInNodeIdsPerElt - a list of offsets to apply.
3648 * \return DataArrayInt * - A new object (to be managed by the caller) that is the result of the aggregation.
3649 * \throw If \a nodalConns or \a offsetInNodeIdsPerElt are empty.
3650 * \throw If \a nodalConns and \a offsetInNodeIdsPerElt have not the same size.
3651 * \throw If presence of null pointer in \a nodalConns.
3652 * \throw If presence of not allocated or array with not exactly one component in \a nodalConns.
3654 DataArrayInt *MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds(const std::vector<const DataArrayInt *>& nodalConns, const std::vector<int>& offsetInNodeIdsPerElt)
3656 std::size_t sz1(nodalConns.size()),sz2(offsetInNodeIdsPerElt.size());
3658 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : input vectors do not have the same size !");
3660 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : empty vectors in input !");
3662 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++)
3665 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of null pointer in input vector !");
3666 if(!(*it)->isAllocated())
3667 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of non allocated array in input vector !");
3668 if((*it)->getNumberOfComponents()!=1)
3669 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of array with not exactly one component !");
3670 nbOfTuples+=(*it)->getNumberOfTuples();
3672 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
3673 int *pt=ret->getPointer();
3675 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++,i++)
3677 int curNbt=(*it)->getNumberOfTuples();
3678 const int *inPt=(*it)->begin();
3679 int offset=offsetInNodeIdsPerElt[i];
3680 for(int j=0;j<curNbt;j++,pt++)
3691 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m)
3694 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh is null !");
3695 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
3697 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh must have exactly one geometric type !");
3698 int geoType((int)*gts.begin());
3699 MCAuto<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(m->getName(),*gts.begin()));
3700 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription());
3701 int nbCells(m->getNumberOfCells());
3702 MCAuto<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
3703 conn->alloc(m->getNodalConnectivityArrayLen()-nbCells,1); connI->alloc(nbCells+1,1);
3704 int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
3705 const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
3706 for(int i=0;i<nbCells;i++,ciin++,ci++)
3708 if(cin[ciin[0]]==geoType)
3710 if(ciin[1]-ciin[0]>=1)
3712 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
3713 ci[1]=ci[0]+ciin[1]-ciin[0]-1;
3717 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 !";
3718 throw INTERP_KERNEL::Exception(oss.str().c_str());
3723 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 !";
3724 throw INTERP_KERNEL::Exception(oss.str().c_str());
3727 ret->setNodalConnectivity(conn,connI);