1 // Copyright (C) 2007-2013 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.
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"
25 #include "SplitterTetra.hxx"
27 using namespace ParaMEDMEM;
29 const int MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[6]={0,1,2,4,3,5};
31 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh()
35 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):_cm(&cm)
40 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const MEDCoupling1GTUMesh& other, bool recDeepCpy):MEDCouplingPointSet(other,recDeepCpy),_cm(other._cm)
44 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type)
46 if(type==INTERP_KERNEL::NORM_ERROR)
47 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
48 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
50 return MEDCoupling1SGTUMesh::New(name,type);
52 return MEDCoupling1DGTUMesh::New(name,type);
55 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const MEDCouplingUMesh *m)
58 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh is null !");
59 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
61 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh must have exactly one geometric type !");
62 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*gts.begin());
64 return MEDCoupling1SGTUMesh::New(m);
66 return MEDCoupling1DGTUMesh::New(m);
69 const INTERP_KERNEL::CellModel& MEDCoupling1GTUMesh::getCellModel() const
74 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getCellModelEnum() const
76 return _cm->getEnum();
79 int MEDCoupling1GTUMesh::getMeshDimension() const
81 return (int)_cm->getDimension();
85 * This method returns a newly allocated array containing cell ids (ascendingly sorted) whose geometric type are equal to type.
86 * This method does not throw exception if geometric type \a type is not in \a this.
87 * This method throws an INTERP_KERNEL::Exception if meshdimension of \b this is not equal to those of \b type.
88 * The coordinates array is not considered here.
90 * \param [in] type the geometric type
91 * \return cell ids in this having geometric type \a type.
93 DataArrayInt *MEDCoupling1GTUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
95 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
96 if(type==getCellModelEnum())
97 ret->alloc(getNumberOfCells(),1);
105 * Returns nb of cells having the geometric type \a type. No throw if no cells in \a this has the geometric type \a type.
107 int MEDCoupling1GTUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
109 return type==getCellModelEnum()?getNumberOfCells():0;
113 * Returns a type of a cell by its id.
114 * \param [in] cellId - the id of the cell of interest.
115 * \return INTERP_KERNEL::NormalizedCellType - enumeration item describing the cell type.
116 * \throw If \a cellId is invalid. Valid range is [0, \a this->getNumberOfCells() ).
118 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getTypeOfCell(int cellId) const
120 if(cellId>=0 && cellId<getNumberOfCells())
121 return getCellModelEnum();
122 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::getTypeOfCell : Requesting type of cell #" << cellId << " but it should be in [0," << getNumberOfCells() << ") !";
123 throw INTERP_KERNEL::Exception(oss.str().c_str());
127 * Returns a set of all cell types available in \a this mesh.
128 * \return std::set<INTERP_KERNEL::NormalizedCellType> - the set of cell types.
129 * \warning this method does not throw any exception even if \a this is not defined.
131 std::set<INTERP_KERNEL::NormalizedCellType> MEDCoupling1GTUMesh::getAllGeoTypes() const
133 std::set<INTERP_KERNEL::NormalizedCellType> ret;
134 ret.insert(getCellModelEnum());
139 * This method expects that \a this is sorted by types. If not an exception will be thrown.
140 * This method returns in the same format as code (see MEDCouplingUMesh::checkTypeConsistencyAndContig or MEDCouplingUMesh::splitProfilePerType) how
141 * \a this is composed in cell types.
142 * The returned array is of size 3*n where n is the number of different types present in \a this.
143 * For every k in [0,n] ret[3*k+2]==-1 because it has no sense here.
144 * This parameter is kept only for compatibility with other methode listed above.
146 std::vector<int> MEDCoupling1GTUMesh::getDistributionOfTypes() const
148 std::vector<int> ret(3);
149 ret[0]=(int)getCellModelEnum(); ret[1]=getNumberOfCells(); ret[2]=-1;
154 * 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.
155 * 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.
156 * This method has 1 input \a profile and 3 outputs \a code \a idsInPflPerType and \a idsPerType.
158 * \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.
159 * \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,
160 * \a idsInPflPerType[i] stores the tuple ids in \a profile that correspond to the geometric type code[3*i+0]
161 * \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.
162 * This vector can be empty in case of all geometric type cells are fully covered in ascending in the given input \a profile.
164 * \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.
166 * \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
169 * - Before \a this has 3 cells \a profile contains [0,1,2]
170 * - After \a code contains [NORM_...,nbCells,-1], \a idsInPflPerType [[0,1,2]] and \a idsPerType is empty <br>
173 * - Before \a this has 3 cells \a profile contains [1,2]
174 * - After \a code contains [NORM_...,nbCells,0], \a idsInPflPerType [[0,1]] and \a idsPerType is [[1,2]] <br>
177 void MEDCoupling1GTUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const
180 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile is NULL !");
181 if(profile->getNumberOfComponents()!=1)
182 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile should have exactly one component !");
183 int nbTuples=profile->getNumberOfTuples();
184 int nbOfCells=getNumberOfCells();
185 code.resize(3); idsInPflPerType.resize(1);
186 code[0]=(int)getCellModelEnum(); code[1]=nbTuples;
187 idsInPflPerType.resize(1);
188 if(profile->isIdentity() && nbTuples==nbOfCells)
191 idsInPflPerType[0]=const_cast<DataArrayInt *>(profile); idsInPflPerType[0]->incrRef();
196 profile->checkAllIdsInRange(0,nbOfCells);
197 idsPerType.resize(1);
198 idsPerType[0]=const_cast<DataArrayInt *>(profile); idsPerType[0]->incrRef();
199 idsInPflPerType[0]=DataArrayInt::Range(0,nbTuples,1);
203 * This method tries to minimize at most the number of deep copy.
204 * So if \a idsPerType is not empty it can be returned directly (without copy, but with ref count incremented) in return.
206 * \sa MEDCouplingUMesh::checkTypeConsistencyAndContig
208 DataArrayInt *MEDCoupling1GTUMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const
210 int nbOfCells=getNumberOfCells();
212 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : invalid input code should be exactly of size 3 !");
213 if(code[0]!=(int)getCellModelEnum())
215 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() << ") !";
216 throw INTERP_KERNEL::Exception(oss.str().c_str());
220 if(code[1]==nbOfCells)
224 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : mismatch between the number of cells in this (" << nbOfCells << ") and the number of non profile (" << code[1] << ") !";
225 throw INTERP_KERNEL::Exception(oss.str().c_str());
229 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : single geo type mesh ! 0 or -1 is expected at pos #2 of input code !");
230 if(idsPerType.size()!=1)
231 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input code points to DataArrayInt #0 whereas the size of idsPerType is not equal to 1 !");
232 const DataArrayInt *pfl=idsPerType[0];
234 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : the input code points to a NULL DataArrayInt at rank 0 !");
235 if(pfl->getNumberOfComponents()!=1)
236 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input profile should have exactly one component !");
237 pfl->checkAllIdsInRange(0,nbOfCells);
239 return const_cast<DataArrayInt *>(pfl);
242 void MEDCoupling1GTUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const
244 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
245 m->writeVTKLL(ofs,cellData,pointData,byteData);
248 std::string MEDCoupling1GTUMesh::getVTKDataSetType() const
250 return std::string("UnstructuredGrid");
253 std::size_t MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren() const
255 return MEDCouplingPointSet::getHeapMemorySizeWithoutChildren();
258 bool MEDCoupling1GTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
260 if(!MEDCouplingPointSet::isEqualIfNotWhy(other,prec,reason))
263 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualIfNotWhy : input other pointer is null !");
264 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
267 reason="mesh given in input is not castable in MEDCouplingSGTUMesh !";
272 reason="mismatch in geometric type !";
278 bool MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
280 if(!MEDCouplingPointSet::isEqualWithoutConsideringStr(other,prec))
283 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
284 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
292 void MEDCoupling1GTUMesh::checkCoherency() const
294 MEDCouplingPointSet::checkCoherency();
297 DataArrayDouble *MEDCoupling1GTUMesh::getBarycenterAndOwner() const
299 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
300 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=m->getBarycenterAndOwner();
304 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureField(bool isAbs) const
306 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
307 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureField(isAbs);
312 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureFieldOnNode(bool isAbs) const
314 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
315 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureFieldOnNode(isAbs);
323 int MEDCoupling1GTUMesh::getCellContainingPoint(const double *pos, double eps) const
325 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
326 return m->getCellContainingPoint(pos,eps);
329 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::buildOrthogonalField() const
331 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
332 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->buildOrthogonalField();
337 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const double *bbox, double eps) const
339 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
340 return m->getCellsInBoundingBox(bbox,eps);
343 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps)
345 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
346 return m->getCellsInBoundingBox(bbox,eps);
349 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const
351 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
352 return m->buildFacePartOfMySelfNode(start,end,fullyIn);
355 DataArrayInt *MEDCoupling1GTUMesh::findBoundaryNodes() const
357 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
358 return m->findBoundaryNodes();
361 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildBoundaryMesh(bool keepCoords) const
363 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
364 return m->buildBoundaryMesh(keepCoords);
367 void MEDCoupling1GTUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const
369 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
370 m->findCommonCells(compType,startCellId,commonCellsArr,commonCellsIArr);
373 int MEDCoupling1GTUMesh::getNodalConnectivityLength() const
375 const DataArrayInt *c1(getNodalConnectivity());
377 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : no connectivity set !");
378 if(c1->getNumberOfComponents()!=1)
379 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array set must have exactly one component !");
380 if(!c1->isAllocated())
381 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array must be allocated !");
382 return c1->getNumberOfTuples();
386 * This method aggregates all the meshes in \a parts to put them in a single unstructured mesh (those returned).
387 * The order of cells is the returned instance is those in the order of instances in \a parts.
389 * \param [in] parts - all not null parts of single geo type meshes to be aggreagated having the same mesh dimension and same coordinates.
390 * \return MEDCouplingUMesh * - new object to be dealt by the caller.
392 * \throw If one element is null in \a parts.
393 * \throw If not all the parts do not have the same mesh dimension.
394 * \throw If not all the parts do not share the same coordinates.
395 * \throw If not all the parts have their connectivity set properly.
396 * \throw If \a parts is empty.
398 MEDCouplingUMesh *MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh(const std::vector< const MEDCoupling1GTUMesh *>& parts)
401 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : input parts vector is empty !");
402 const MEDCoupling1GTUMesh *firstPart(parts[0]);
404 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : the first instance in input parts is null !");
405 const DataArrayDouble *coords(firstPart->getCoords());
406 int meshDim(firstPart->getMeshDimension());
407 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret(MEDCouplingUMesh::New(firstPart->getName().c_str(),meshDim)); ret->setDescription(firstPart->getDescription().c_str());
408 ret->setCoords(coords);
409 int nbOfCells(0),connSize(0);
410 for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
413 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of null pointer in input vector !");
414 if((*it)->getMeshDimension()!=meshDim)
415 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances in input vector must have same mesh dimension !");
416 if((*it)->getCoords()!=coords)
417 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances must share the same coordinates pointer !");
418 nbOfCells+=(*it)->getNumberOfCells();
419 connSize+=(*it)->getNodalConnectivityLength();
421 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
422 connI->alloc(nbOfCells+1,1); conn->alloc(connSize+nbOfCells,1);
423 int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
424 for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
426 int curNbCells((*it)->getNumberOfCells());
427 int geoType((int)(*it)->getCellModelEnum());
428 const int *cinPtr((*it)->getNodalConnectivity()->begin());
429 const MEDCoupling1SGTUMesh *ps(dynamic_cast<const MEDCoupling1SGTUMesh *>(*it));
430 const MEDCoupling1DGTUMesh *pd(dynamic_cast<const MEDCoupling1DGTUMesh *>(*it));
433 int nNodesPerCell(ps->getNumberOfNodesPerCell());
434 for(int i=0;i<curNbCells;i++,ci++,cinPtr+=nNodesPerCell)
437 c=std::copy(cinPtr,cinPtr+nNodesPerCell,c);
438 ci[1]=ci[0]+nNodesPerCell+1;
443 const int *ciinPtr(pd->getNodalConnectivityIndex()->begin());
444 for(int i=0;i<curNbCells;i++,ci++,ciinPtr++)
447 c=std::copy(cinPtr+ciinPtr[0],cinPtr+ciinPtr[1],c);
448 ci[1]=ci[0]+ciinPtr[1]-ciinPtr[0]+1;
452 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of instance which type is not in [MEDCoupling1SGTUMesh,MEDCoupling1DGTUMesh] !");
454 ret->setConnectivity(conn,connI,true);
460 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const MEDCoupling1SGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
464 const DataArrayInt *c(other._conn);
470 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
474 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh()
478 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New()
480 return new MEDCoupling1SGTUMesh;
483 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type)
485 if(type==INTERP_KERNEL::NORM_ERROR)
486 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
487 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
490 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New : the input geometric type " << cm.getRepr() << " is dynamic ! Only static types are allowed here !";
491 throw INTERP_KERNEL::Exception(oss.str().c_str());
493 return new MEDCoupling1SGTUMesh(name,cm);
496 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m)
499 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh is null !");
500 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
502 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh must have exactly one geometric type !");
503 int geoType((int)*gts.begin());
504 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(m->getName().c_str(),*gts.begin()));
505 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription().c_str());
506 int nbCells(m->getNumberOfCells());
507 int nbOfNodesPerCell(ret->getNumberOfNodesPerCell());
508 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()); conn->alloc(nbCells*nbOfNodesPerCell,1);
509 int *c(conn->getPointer());
510 const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
511 for(int i=0;i<nbCells;i++,ciin++)
513 if(cin[ciin[0]]==geoType)
515 if(ciin[1]-ciin[0]==nbOfNodesPerCell+1)
516 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
519 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 << ") !";
520 throw INTERP_KERNEL::Exception(oss.str().c_str());
525 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 !";
526 throw INTERP_KERNEL::Exception(oss.str().c_str());
529 ret->setNodalConnectivity(conn);
533 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::clone(bool recDeepCpy) const
535 return new MEDCoupling1SGTUMesh(*this,recDeepCpy);
539 * This method behaves mostly like MEDCoupling1SGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
540 * The coordinates are shared between \a this and the returned instance.
542 * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
543 * \sa MEDCoupling1SGTUMesh::deepCpy
545 MEDCouplingPointSet *MEDCoupling1SGTUMesh::deepCpyConnectivityOnly() const
548 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(clone(false));
549 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy());
550 ret->setNodalConnectivity(c);
554 void MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
557 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
558 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
560 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1SGTUMesh instance !");
561 setNodalConnectivity(otherC->getNodalConnectivity());
564 void MEDCoupling1SGTUMesh::updateTime() const
566 MEDCoupling1GTUMesh::updateTime();
567 const DataArrayInt *c(_conn);
572 std::size_t MEDCoupling1SGTUMesh::getHeapMemorySizeWithoutChildren() const
574 return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren();
577 std::vector<const BigMemoryObject *> MEDCoupling1SGTUMesh::getDirectChildren() const
579 std::vector<const BigMemoryObject *> ret(MEDCoupling1GTUMesh::getDirectChildren());
580 const DataArrayInt *c(_conn);
586 MEDCouplingMesh *MEDCoupling1SGTUMesh::deepCpy() const
591 bool MEDCoupling1SGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
594 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualIfNotWhy : input other pointer is null !");
595 std::ostringstream oss; oss.precision(15);
596 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
599 reason="mesh given in input is not castable in MEDCoupling1SGTUMesh !";
602 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
604 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
609 reason="in connectivity of single static geometric type exactly one among this and other is null !";
612 if(!c1->isEqualIfNotWhy(*c2,reason))
614 reason.insert(0,"Nodal connectivity DataArrayInt differ : ");
620 bool MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
623 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
624 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
627 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
629 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
634 if(!c1->isEqualWithoutConsideringStr(*c2))
639 void MEDCoupling1SGTUMesh::checkCoherencyOfConnectivity() const
641 const DataArrayInt *c1(_conn);
644 if(c1->getNumberOfComponents()!=1)
645 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
646 if(c1->getInfoOnComponent(0)!="")
647 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
648 c1->checkAllocated();
651 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
654 void MEDCoupling1SGTUMesh::checkCoherency() const
656 MEDCouplingPointSet::checkCoherency();
657 checkCoherencyOfConnectivity();
660 void MEDCoupling1SGTUMesh::checkCoherency1(double eps) const
663 const DataArrayInt *c1(_conn);
664 int nbOfTuples=c1->getNumberOfTuples();
665 int nbOfNodesPerCell=(int)_cm->getNumberOfNodes();
666 if(nbOfTuples%nbOfNodesPerCell!=0)
668 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::checkCoherency1 : the nb of tuples in conn is " << nbOfTuples << " and number of nodes per cell is " << nbOfNodesPerCell << ". But " << nbOfTuples << "%" << nbOfNodesPerCell << " !=0 !";
669 throw INTERP_KERNEL::Exception(oss.str().c_str());
671 int nbOfNodes=getNumberOfNodes();
672 int nbOfCells=nbOfTuples/nbOfNodesPerCell;
673 const int *w(c1->begin());
674 for(int i=0;i<nbOfCells;i++)
675 for(int j=0;j<nbOfNodesPerCell;j++,w++)
677 if(*w<0 || *w>=nbOfNodes)
679 std::ostringstream oss; oss << "At node #" << j << " of cell #" << i << ", is equal to " << *w << " must be in [0," << nbOfNodes << ") !";
680 throw INTERP_KERNEL::Exception(oss.str().c_str());
685 void MEDCoupling1SGTUMesh::checkCoherency2(double eps) const
687 checkCoherency1(eps);
690 int MEDCoupling1SGTUMesh::getNumberOfCells() const
692 int nbOfTuples=getNodalConnectivityLength();
693 int nbOfNodesPerCell=getNumberOfNodesPerCell();
694 if(nbOfTuples%nbOfNodesPerCell!=0)
696 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 !";
697 throw INTERP_KERNEL::Exception(oss.str().c_str());
699 return nbOfTuples/nbOfNodesPerCell;
702 int MEDCoupling1SGTUMesh::getNumberOfNodesInCell(int cellId) const
704 return getNumberOfNodesPerCell();
707 int MEDCoupling1SGTUMesh::getNumberOfNodesPerCell() const
709 checkNonDynamicGeoType();
710 return (int)_cm->getNumberOfNodes();
713 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfNodesPerCell() const
715 checkNonDynamicGeoType();
716 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
717 ret->alloc(getNumberOfCells(),1);
718 ret->fillWithValue((int)_cm->getNumberOfNodes());
722 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfFacesPerCell() const
724 checkNonDynamicGeoType();
725 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
726 ret->alloc(getNumberOfCells(),1);
727 ret->fillWithValue((int)_cm->getNumberOfSons());
731 DataArrayInt *MEDCoupling1SGTUMesh::computeEffectiveNbOfNodesPerCell() const
733 checkNonDynamicGeoType();
734 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
735 int nbCells(getNumberOfCells());
736 ret->alloc(nbCells,1);
737 int *retPtr(ret->getPointer());
738 int nbNodesPerCell(getNumberOfNodesPerCell());
739 const int *conn(_conn->begin());
740 for(int i=0;i<nbCells;i++,conn+=nbNodesPerCell,retPtr++)
742 std::set<int> s(conn,conn+nbNodesPerCell);
743 *retPtr=(int)s.size();
748 void MEDCoupling1SGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
750 int sz=getNumberOfNodesPerCell();
752 if(cellId>=0 && cellId<getNumberOfCells())
753 std::copy(_conn->begin()+cellId*sz,_conn->begin()+(cellId+1)*sz,conn.begin());
756 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << getNumberOfCells() << ") !";
757 throw INTERP_KERNEL::Exception(oss.str().c_str());
761 void MEDCoupling1SGTUMesh::checkNonDynamicGeoType() const
764 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkNonDynamicGeoType : internal error ! the internal geo type is dynamic ! should be static !");
767 std::string MEDCoupling1SGTUMesh::simpleRepr() const
769 static const char msg0[]="No coordinates specified !";
770 std::ostringstream ret;
771 ret << "Single static geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
772 ret << "Description of mesh : \"" << getDescription() << "\"\n";
774 double tt=getTime(tmpp1,tmpp2);
775 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
776 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
777 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
780 const int spaceDim=getSpaceDimension();
781 ret << spaceDim << "\nInfo attached on space dimension : ";
782 for(int i=0;i<spaceDim;i++)
783 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
788 ret << "Number of nodes : ";
790 ret << getNumberOfNodes() << "\n";
793 ret << "Number of cells : ";
794 if((const DataArrayInt *)_conn)
796 if(_conn->isAllocated())
798 if(_conn->getNumberOfComponents()==1)
799 ret << getNumberOfCells() << "\n";
801 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
804 ret << "Nodal connectivity array specified but not allocated !" << "\n";
807 ret << "No connectivity specified !" << "\n";
808 ret << "Cell type : " << _cm->getRepr() << "\n";
812 std::string MEDCoupling1SGTUMesh::advancedRepr() const
814 std::ostringstream ret;
816 ret << "\nCoordinates array : \n___________________\n\n";
818 _coords->reprWithoutNameStream(ret);
820 ret << "No array set !\n";
821 ret << "\n\nConnectivity array : \n____________________\n\n";
823 if((const DataArrayInt *)_conn)
825 if(_conn->isAllocated())
827 if(_conn->getNumberOfComponents()==1)
829 int nbOfCells=getNumberOfCells();
830 int sz=getNumberOfNodesPerCell();
831 const int *connPtr=_conn->begin();
832 for(int i=0;i<nbOfCells;i++,connPtr+=sz)
834 ret << "Cell #" << i << " : ";
835 std::copy(connPtr,connPtr+sz,std::ostream_iterator<int>(ret," "));
840 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
843 ret << "Nodal connectivity array specified but not allocated !" << "\n";
846 ret << "No connectivity specified !" << "\n";
850 DataArrayDouble *MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell() const
852 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
853 int spaceDim=getSpaceDimension();
854 int nbOfCells=getNumberOfCells();//checkCoherency()
855 int nbOfNodes=getNumberOfNodes();
856 ret->alloc(nbOfCells,spaceDim);
857 double *ptToFill=ret->getPointer();
858 const double *coor=_coords->begin();
859 const int *nodal=_conn->begin();
860 int sz=getNumberOfNodesPerCell();
861 double coeff=1./(double)sz;
862 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim)
864 std::fill(ptToFill,ptToFill+spaceDim,0.);
865 for(int j=0;j<sz;j++,nodal++)
866 if(*nodal>=0 && *nodal<nbOfNodes)
867 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
870 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
871 throw INTERP_KERNEL::Exception(oss.str().c_str());
873 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),coeff));
878 void MEDCoupling1SGTUMesh::renumberCells(const int *old2NewBg, bool check)
880 int nbCells=getNumberOfCells();
881 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
882 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
884 o2n=o2n->checkAndPreparePermutation();
886 const int *conn=_conn->begin();
887 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o=o2n->invertArrayO2N2N2O(nbCells);
888 const int *n2oPtr=n2o->begin();
889 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
890 newConn->alloc(_conn->getNumberOfTuples(),1);
891 newConn->copyStringInfoFrom(*_conn);
892 int sz=getNumberOfNodesPerCell();
894 int *newC=newConn->getPointer();
895 for(int i=0;i<nbCells;i++,newC+=sz)
898 std::copy(conn+pos*sz,conn+(pos+1)*sz,newC);
904 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
905 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
906 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
907 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
909 * \param [in] begin input start of array of node ids.
910 * \param [in] end input end of array of node ids.
911 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
912 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
914 void MEDCoupling1SGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
916 int nbOfCells=getNumberOfCells();
917 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
919 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
920 std::vector<bool> fastFinder(sz,false);
921 for(const int *work=begin;work!=end;work++)
922 if(*work>=0 && *work<sz)
923 fastFinder[*work]=true;
924 const int *conn=_conn->begin();
925 int nbNodesPerCell=getNumberOfNodesPerCell();
926 for(int i=0;i<nbOfCells;i++,conn+=nbNodesPerCell)
929 for(int j=0;j<nbNodesPerCell;j++)
933 if(fastFinder[conn[j]])
936 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
937 cellIdsKept->pushBackSilent(i);
939 cellIdsKeptArr=cellIdsKept.retn();
942 MEDCouplingMesh *MEDCoupling1SGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
944 if(other->getType()!=SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED)
945 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single static geo type each other !");
946 const MEDCoupling1SGTUMesh *otherC=static_cast<const MEDCoupling1SGTUMesh *>(other);
947 return Merge1SGTUMeshes(this,otherC);
950 MEDCouplingUMesh *MEDCoupling1SGTUMesh::buildUnstructured() const
952 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName().c_str(),getMeshDimension());
953 ret->setCoords(getCoords());
954 const int *nodalConn=_conn->begin();
955 int nbCells=getNumberOfCells();
956 int nbNodesPerCell=getNumberOfNodesPerCell();
957 int geoType=(int)getCellModelEnum();
958 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells*(nbNodesPerCell+1),1);
959 int *cPtr=c->getPointer();
960 for(int i=0;i<nbCells;i++,nodalConn+=nbNodesPerCell)
963 cPtr=std::copy(nodalConn,nodalConn+nbNodesPerCell,cPtr);
965 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::Range(0,(nbCells+1)*(nbNodesPerCell+1),nbNodesPerCell+1);
966 ret->setConnectivity(c,cI,true);
970 DataArrayInt *MEDCoupling1SGTUMesh::simplexize(int policy)
975 return simplexizePol0();
977 return simplexizePol1();
978 case (int) INTERP_KERNEL::PLANAR_FACE_5:
979 return simplexizePlanarFace5();
980 case (int) INTERP_KERNEL::PLANAR_FACE_6:
981 return simplexizePlanarFace6();
983 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)");
989 struct MEDCouplingAccVisit
991 MEDCouplingAccVisit():_new_nb_of_nodes(0) { }
992 int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; }
993 int _new_nb_of_nodes;
999 * Finds nodes not used in any cell and returns an array giving a new id to every node
1000 * by excluding the unused nodes, for which the array holds -1. The result array is
1001 * a mapping in "Old to New" mode.
1002 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
1003 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
1004 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
1005 * if the node is unused or a new id else. The caller is to delete this
1006 * array using decrRef() as it is no more needed.
1007 * \throw If the coordinates array is not set.
1008 * \throw If the nodal connectivity of cells is not defined.
1009 * \throw If the nodal connectivity includes an invalid id.
1011 DataArrayInt *MEDCoupling1SGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
1014 int nbOfNodes=getNumberOfNodes();
1015 int nbOfCells=getNumberOfCells();
1016 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1017 ret->alloc(nbOfNodes,1);
1018 int *traducer=ret->getPointer();
1019 std::fill(traducer,traducer+nbOfNodes,-1);
1020 const int *conn=_conn->begin();
1021 int nbNodesPerCell=getNumberOfNodesPerCell();
1022 for(int i=0;i<nbOfCells;i++)
1023 for(int j=0;j<nbNodesPerCell;j++,conn++)
1024 if(*conn>=0 && *conn<nbOfNodes)
1028 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << conn[j] << " not in [0," << nbOfNodes << ") !";
1029 throw INTERP_KERNEL::Exception(oss.str().c_str());
1031 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
1032 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
1037 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
1038 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
1039 * This method is a generalization of shiftNodeNumbersInConn().
1040 * \warning This method performs no check of validity of new ids. **Use it with care !**
1041 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
1042 * this->getNumberOfNodes(), in "Old to New" mode.
1043 * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
1044 * \throw If the nodal connectivity of cells is not defined.
1046 void MEDCoupling1SGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
1048 getNumberOfCells();//only to check that all is well defined.
1049 _conn->transformWithIndArr(newNodeNumbersO2N,newNodeNumbersO2N+getNumberOfNodes());
1053 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2)
1055 std::vector<const MEDCoupling1SGTUMesh *> tmp(2);
1056 tmp[0]=const_cast<MEDCoupling1SGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1SGTUMesh *>(mesh2);
1057 return Merge1SGTUMeshes(tmp);
1060 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(std::vector<const MEDCoupling1SGTUMesh *>& a)
1062 std::size_t sz=a.size();
1064 return Merge1SGTUMeshesLL(a);
1065 for(std::size_t ii=0;ii<sz;ii++)
1068 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::Merge1SGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
1069 throw INTERP_KERNEL::Exception(oss.str().c_str());
1071 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
1072 for(std::size_t ii=0;ii<sz;ii++)
1073 if(&(a[ii]->getCellModel())!=cm)
1074 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : all items must have the same geo type !");
1075 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> > bb(sz);
1076 std::vector< const MEDCoupling1SGTUMesh * > aa(sz);
1078 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
1080 const MEDCoupling1SGTUMesh *cur=a[i];
1081 const DataArrayDouble *coo=cur->getCoords();
1083 spaceDim=coo->getNumberOfComponents();
1086 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : no spaceDim specified ! unable to perform merge !");
1087 for(std::size_t i=0;i<sz;i++)
1089 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
1092 return Merge1SGTUMeshesLL(aa);
1096 * \throw If presence of a null instance in the input vector \a a.
1097 * \throw If a is empty
1099 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::vector<const MEDCoupling1SGTUMesh *>& a)
1102 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : input array must be NON EMPTY !");
1103 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1105 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : null instance in the first element of input vector !");
1106 std::vector<const DataArrayInt *> ncs(a.size());
1107 (*it)->getNumberOfCells();//to check that all is OK
1108 const DataArrayDouble *coords=(*it)->getCoords();
1109 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1110 ncs[0]=(*it)->getNodalConnectivity();
1112 for(int i=1;it!=a.end();i++,it++)
1115 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : presence of a null instance in the input vector !");
1116 if(cm!=&((*it)->getCellModel()))
1117 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1118 (*it)->getNumberOfCells();//to check that all is OK
1119 ncs[i]=(*it)->getNodalConnectivity();
1120 if(coords!=(*it)->getCoords())
1121 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : not lying on same coords !");
1123 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1124 ret->setCoords(coords);
1125 ret->_conn=DataArrayInt::Aggregate(ncs);
1130 * 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)
1132 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector<const MEDCoupling1SGTUMesh *>& a)
1135 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : input array must be NON EMPTY !");
1136 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1137 int nbOfCells=(*it)->getNumberOfCells();
1138 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1139 int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
1141 for(;it!=a.end();it++)
1143 if(cm!=&((*it)->getCellModel()))
1144 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1145 nbOfCells+=(*it)->getNumberOfCells();
1147 std::vector<const MEDCouplingPointSet *> aps(a.size());
1148 std::copy(a.begin(),a.end(),aps.begin());
1149 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
1150 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1151 ret->setCoords(pts);
1152 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New();
1153 c->alloc(nbOfCells*nbNodesPerCell,1);
1154 int *cPtr=c->getPointer();
1156 for(it=a.begin();it!=a.end();it++)
1158 int curConnLgth=(*it)->getNodalConnectivityLength();
1159 const int *curC=(*it)->_conn->begin();
1160 cPtr=std::transform(curC,curC+curConnLgth,cPtr,std::bind2nd(std::plus<int>(),offset));
1161 offset+=(*it)->getNumberOfNodes();
1164 ret->setNodalConnectivity(c);
1168 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
1170 int ncell=getNumberOfCells();
1171 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName().c_str(),*_cm));
1172 ret->setCoords(_coords);
1173 std::size_t nbOfElemsRet=std::distance(begin,end);
1174 const int *inConn=_conn->getConstPointer();
1175 int sz=getNumberOfNodesPerCell();
1176 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1177 int *connPtr=connRet->getPointer();
1178 for(const int *work=begin;work!=end;work++,connPtr+=sz)
1180 if(*work>=0 && *work<ncell)
1181 std::copy(inConn+(work[0])*sz,inConn+(work[0]+1)*sz,connPtr);
1184 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !";
1185 throw INTERP_KERNEL::Exception(oss.str().c_str());
1189 ret->copyTinyInfoFrom(this);
1193 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
1195 int ncell=getNumberOfCells();
1196 int nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : ");
1197 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName().c_str(),*_cm));
1198 ret->setCoords(_coords);
1199 const int *inConn=_conn->getConstPointer();
1200 int sz=getNumberOfNodesPerCell();
1201 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1202 int *connPtr=connRet->getPointer();
1204 for(int i=0;i<nbOfElemsRet;i++,connPtr+=sz,curId+=step)
1206 if(curId>=0 && curId<ncell)
1207 std::copy(inConn+curId*sz,inConn+(curId+1)*sz,connPtr);
1210 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : On pos #" << i << " input cell id =" << curId << " should be in [0," << ncell << ") !";
1211 throw INTERP_KERNEL::Exception(oss.str().c_str());
1215 ret->copyTinyInfoFrom(this);
1219 void MEDCoupling1SGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
1221 int sz((int)nodeIdsInUse.size());
1222 int nbCells(getNumberOfCells());
1223 int nbOfNodesPerCell(getNumberOfNodesPerCell());
1224 const int *w(_conn->begin());
1225 for(int i=0;i<nbCells;i++)
1226 for(int j=0;j<nbOfNodesPerCell;j++,w++)
1229 nodeIdsInUse[*w]=true;
1232 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeNodeIdsAlg : At cell #" << i << " presence of node id #" << *w << " should be in [0," << sz << ") !";
1233 throw INTERP_KERNEL::Exception(oss.str().c_str());
1238 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(int spaceDim) const
1240 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName().c_str(),*_cm));
1241 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1;
1242 const DataArrayInt *nodalConn(_conn);
1245 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
1252 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
1253 ret->setCoords(coords);
1256 ret->setCoords(_coords);
1260 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol0()
1262 int nbOfCells=getNumberOfCells();
1263 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1264 return DataArrayInt::Range(0,nbOfCells,1);
1265 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1266 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1267 const int *c(_conn->begin());
1268 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1269 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1271 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[2];
1272 newConnPtr[3]=c[0]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1273 retPtr[0]=i; retPtr[1]=i;
1276 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1281 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol1()
1283 int nbOfCells=getNumberOfCells();
1284 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1285 return DataArrayInt::Range(0,nbOfCells,1);
1286 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1287 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1288 const int *c(_conn->begin());
1289 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1290 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1292 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[3];
1293 newConnPtr[3]=c[1]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1294 retPtr[0]=i; retPtr[1]=i;
1297 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1302 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace5()
1304 int nbOfCells=getNumberOfCells();
1305 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1306 return DataArrayInt::Range(0,nbOfCells,1);
1307 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(5*4*nbOfCells,1);
1308 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(5*nbOfCells,1);
1309 const int *c(_conn->begin());
1310 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1311 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=20,retPtr+=5)
1313 for(int j=0;j<20;j++)
1314 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_5_WO[j]];
1315 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i;
1318 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1323 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace6()
1325 int nbOfCells=getNumberOfCells();
1326 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1327 return DataArrayInt::Range(0,nbOfCells,1);
1328 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(6*4*nbOfCells,1);
1329 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(6*nbOfCells,1);
1330 const int *c(_conn->begin());
1331 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1332 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=24,retPtr+=6)
1334 for(int j=0;j<24;j++)
1335 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_6_WO[j]];
1336 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i; retPtr[5]=i;
1339 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1344 void MEDCoupling1SGTUMesh::reprQuickOverview(std::ostream& stream) const
1346 stream << "MEDCoupling1SGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
1347 stream << " Mesh dimension : " << getMeshDimension() << ".";
1349 { stream << " No coordinates set !"; return ; }
1350 if(!_coords->isAllocated())
1351 { stream << " Coordinates set but not allocated !"; return ; }
1352 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
1353 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
1354 if(!(const DataArrayInt *)_conn)
1355 { stream << std::endl << "Nodal connectivity NOT set !"; return ; }
1356 if(_conn->isAllocated())
1358 if(_conn->getNumberOfComponents()==1)
1359 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
1363 void MEDCoupling1SGTUMesh::checkFullyDefined() const
1365 if(!((const DataArrayInt *)_conn) || !((const DataArrayDouble *)_coords))
1366 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFullyDefined : part of this is not fully defined.");
1370 * First step of unserialization process.
1372 bool MEDCoupling1SGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
1374 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEmptyMesh : not implemented yet !");
1377 void MEDCoupling1SGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
1380 double time=getTime(it,order);
1381 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
1383 littleStrings.push_back(getName());
1384 littleStrings.push_back(getDescription());
1385 littleStrings.push_back(getTimeUnit());
1387 std::vector<std::string> littleStrings2,littleStrings3;
1388 if((const DataArrayDouble *)_coords)
1389 _coords->getTinySerializationStrInformation(littleStrings2);
1390 if((const DataArrayInt *)_conn)
1391 _conn->getTinySerializationStrInformation(littleStrings3);
1392 int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size());
1393 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
1394 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
1396 tinyInfo.push_back(getCellModelEnum());
1397 tinyInfo.push_back(it);
1398 tinyInfo.push_back(order);
1399 std::vector<int> tinyInfo2,tinyInfo3;
1400 if((const DataArrayDouble *)_coords)
1401 _coords->getTinySerializationIntInformation(tinyInfo2);
1402 if((const DataArrayInt *)_conn)
1403 _conn->getTinySerializationIntInformation(tinyInfo3);
1404 int sz2((int)tinyInfo2.size()),sz3((int)tinyInfo3.size());
1405 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3);
1406 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1407 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
1409 tinyInfoD.push_back(time);
1412 void MEDCoupling1SGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
1414 std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+tinyInfo[5]);
1415 std::vector<int> tinyInfo1(tinyInfo.begin()+7+tinyInfo[5],tinyInfo.begin()+7+tinyInfo[5]+tinyInfo[6]);
1416 a1->resizeForUnserialization(tinyInfo1);
1417 a2->resizeForUnserialization(tinyInfo2);
1420 void MEDCoupling1SGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
1423 if((const DataArrayInt *)_conn)
1424 if(_conn->isAllocated())
1425 sz=_conn->getNbOfElems();
1426 a1=DataArrayInt::New();
1428 if(sz!=0 && (const DataArrayInt *)_conn)
1429 std::copy(_conn->begin(),_conn->end(),a1->getPointer());
1431 if((const DataArrayDouble *)_coords)
1432 if(_coords->isAllocated())
1433 sz=_coords->getNbOfElems();
1434 a2=DataArrayDouble::New();
1436 if(sz!=0 && (const DataArrayDouble *)_coords)
1437 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
1440 void MEDCoupling1SGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
1441 const std::vector<std::string>& littleStrings)
1443 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
1444 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
1445 setName(littleStrings[0].c_str());
1446 setDescription(littleStrings[1].c_str());
1447 setTimeUnit(littleStrings[2].c_str());
1448 setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
1449 int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]);
1451 _coords=DataArrayDouble::New();
1452 std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+sz2);
1453 _coords->resizeForUnserialization(tinyInfo2);
1454 std::copy(a2->begin(),a2->end(),_coords->getPointer());
1455 _conn=DataArrayInt::New();
1456 std::vector<int> tinyInfo3(tinyInfo.begin()+7+sz2,tinyInfo.begin()+7+sz2+sz3);
1457 _conn->resizeForUnserialization(tinyInfo3);
1458 std::copy(a1->begin(),a1->end(),_conn->getPointer());
1459 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
1460 _coords->finishUnserialization(tinyInfo2,littleStrings2);
1461 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
1462 _conn->finishUnserialization(tinyInfo3,littleStrings3);
1466 * Checks if \a this and \a other meshes are geometrically equivalent with high
1467 * probability, else an exception is thrown. The meshes are considered equivalent if
1468 * (1) meshes contain the same number of nodes and the same number of elements of the
1469 * same types (2) three cells of the two meshes (first, last and middle) are based
1470 * on coincident nodes (with a specified precision).
1471 * \param [in] other - the mesh to compare with.
1472 * \param [in] prec - the precision used to compare nodes of the two meshes.
1473 * \throw If the two meshes do not match.
1475 void MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
1477 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1478 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1480 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single static geometric type !");
1481 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1485 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1486 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1487 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1488 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1489 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1490 if(c1->getHashCode()!=c2->getHashCode())
1491 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1494 MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
1497 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
1498 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1500 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
1501 std::vector<const MEDCoupling1SGTUMesh *> ms(2);
1504 return Merge1SGTUMeshesOnSameCoords(ms);
1507 void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const
1509 checkFullyDefined();
1510 int nbOfNodes=getNumberOfNodes();
1511 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
1512 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
1513 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
1514 const int *conn=_conn->begin();
1515 int nbOfCells=getNumberOfCells();
1516 int nbOfEltsInRevNodal=0;
1517 int nbOfNodesPerCell=getNumberOfNodesPerCell();
1518 for(int eltId=0;eltId<nbOfCells;eltId++)
1520 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1522 if(conn[0]>=0 && conn[0]<nbOfNodes)
1524 nbOfEltsInRevNodal++;
1525 revNodalIndxPtr[conn[0]+1]++;
1529 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
1530 throw INTERP_KERNEL::Exception(oss.str().c_str());
1534 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
1535 conn=_conn->begin();
1536 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
1537 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
1538 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
1539 for(int eltId=0;eltId<nbOfCells;eltId++)
1541 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1543 *std::find_if(revNodalPtr+revNodalIndxPtr[*conn],revNodalPtr+revNodalIndxPtr[*conn+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
1549 * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null.
1551 void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn)
1554 nodalConn->incrRef();
1560 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
1562 DataArrayInt *MEDCoupling1SGTUMesh::getNodalConnectivity() const
1564 const DataArrayInt *ret(_conn);
1565 return const_cast<DataArrayInt *>(ret);
1569 * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted,
1570 * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter.
1571 * If a nodal connectivity previouly existed before the call of this method, it will be reset.
1573 * \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain.
1575 void MEDCoupling1SGTUMesh::allocateCells(int nbOfCells)
1578 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !");
1579 _conn=DataArrayInt::New();
1580 _conn->reserve(getNumberOfNodesPerCell()*nbOfCells);
1585 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
1587 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
1588 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
1589 * \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
1590 * attached to \a this.
1591 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
1593 void MEDCoupling1SGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd)
1595 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
1596 int ref=getNumberOfNodesPerCell();
1599 DataArrayInt *c(_conn);
1601 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
1603 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !");
1607 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this (";
1608 oss << ref << ") !";
1609 throw INTERP_KERNEL::Exception(oss.str().c_str());
1614 * This method builds the dual mesh of \a this and returns it.
1616 * \return MEDCoupling1SGTUMesh * - newly object created to be managed by the caller.
1617 * \throw If \a this is not a mesh containing only simplex cells.
1618 * \throw If \a this is not correctly allocated (coordinates and connectivities have to be correctly set !).
1619 * \throw If at least one node in \a this is orphan (without any simplex cell lying on it !)
1621 MEDCoupling1GTUMesh *MEDCoupling1SGTUMesh::computeDualMesh() const
1623 const INTERP_KERNEL::CellModel& cm(getCellModel());
1625 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : this mesh is not a simplex mesh ! Please invoke simplexize of tetrahedrize on this before calling this method !");
1626 switch(getMeshDimension())
1629 return computeDualMesh3D();
1631 return computeDualMesh2D();
1633 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : meshdimension must be in [2,3] !");
1638 * This method explode each NORM_HEXA8 cells in \a this into 6 NORM_QUAD4 cells and put the result into the MEDCoupling1SGTUMesh returned instance.
1640 * \return MEDCoupling1SGTUMesh * - a newly allocated instances (to be managed by the caller) storing the result of the explosion.
1641 * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
1642 * \throw If \a this is not properly allocated.
1644 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4() const
1646 const INTERP_KERNEL::CellModel& cm(getCellModel());
1647 if(cm.getEnum()!=INTERP_KERNEL::NORM_HEXA8)
1648 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4 : this method can be applied only on HEXA8 mesh !");
1649 int nbHexa8(getNumberOfCells());
1650 const int *inConnPtr(getNodalConnectivity()->begin());
1651 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(getName().c_str(),INTERP_KERNEL::NORM_QUAD4));
1652 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()); c->alloc(nbHexa8*6*4,1);
1653 int *cPtr(c->getPointer());
1654 for(int i=0;i<nbHexa8;i++,inConnPtr+=8)
1656 for(int j=0;j<6;j++,cPtr+=4)
1657 cm.fillSonCellNodalConnectivity(j,inConnPtr,cPtr);
1659 ret->setCoords(getCoords());
1660 ret->setNodalConnectivity(c);
1666 bool UpdateHexa8Cell(int validAxis, int neighId, const int *validConnQuad4NeighSide, int *allFacesNodalConn, int *myNeighbours)
1668 static const int TAB[48]={
1676 static const int TAB2[6]={0,0,3,3,3,3};
1677 if(myNeighbours[validAxis]==neighId && allFacesNodalConn[4*validAxis+0]==validConnQuad4NeighSide[TAB2[validAxis]])
1679 int oldAxis((int)std::distance(myNeighbours,std::find(myNeighbours,myNeighbours+6,neighId)));
1680 std::size_t pos(std::distance(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,std::find(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS+6,oldAxis)));
1681 std::size_t pos0(pos/2),pos1(pos%2);
1682 int oldAxisOpp(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[2*pos0+(pos1+1)%2]);
1683 int oldConn[8],myConn2[8]={-1,-1,-1,-1,-1,-1,-1,-1},myConn[8],edgeConn[2],allFacesTmp[24],neighTmp[6];
1684 oldConn[0]=allFacesNodalConn[0]; oldConn[1]=allFacesNodalConn[1]; oldConn[2]=allFacesNodalConn[2]; oldConn[3]=allFacesNodalConn[3];
1685 oldConn[4]=allFacesNodalConn[4]; oldConn[5]=allFacesNodalConn[7]; oldConn[6]=allFacesNodalConn[6]; oldConn[7]=allFacesNodalConn[5];
1686 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_HEXA8));
1687 for(int i=0;i<4;i++)
1688 myConn2[i]=validConnQuad4NeighSide[(4-i+TAB2[validAxis])%4];
1689 for(int i=0;i<4;i++)
1691 int nodeId(myConn2[i]);//the node id for which the opposite one will be found
1693 INTERP_KERNEL::NormalizedCellType typeOfSon;
1694 for(int j=0;j<12 && !found;j++)
1696 cm.fillSonEdgesNodalConnectivity3D(j,oldConn,-1,edgeConn,typeOfSon);
1697 if(edgeConn[0]==nodeId || edgeConn[1]==nodeId)
1699 if(std::find(allFacesNodalConn+4*oldAxisOpp,allFacesNodalConn+4*oldAxisOpp+4,edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0])!=allFacesNodalConn+4*oldAxisOpp+4)
1701 myConn2[i+4]=edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0];
1707 throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error !");
1709 const int *myTab(TAB+8*validAxis);
1710 for(int i=0;i<8;i++)
1711 myConn[i]=myConn2[myTab[i]];
1712 for(int i=0;i<6;i++)
1714 cm.fillSonCellNodalConnectivity(i,myConn,allFacesTmp+4*i);
1715 std::set<int> s(allFacesTmp+4*i,allFacesTmp+4*i+4);
1717 for(int j=0;j<6 && !found;j++)
1719 std::set<int> s1(allFacesNodalConn+4*j,allFacesNodalConn+4*j+4);
1722 neighTmp[i]=myNeighbours[j];
1727 throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error #2 !");
1729 std::copy(allFacesTmp,allFacesTmp+24,allFacesNodalConn);
1730 std::copy(neighTmp,neighTmp+6,myNeighbours);
1737 * 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
1738 * homogeneous. If it succeeds the result of MEDCouplingUMesh::tetrahedrize will return a conform mesh.
1740 * \return DataArrayInt * - a newly allocated array (to be managed by the caller) containing renumbered cell ids.
1742 * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
1743 * \throw If \a this is not properly allocated.
1744 * \sa MEDCouplingUMesh::tetrahedrize, MEDCouplingUMesh::simplexize.
1746 DataArrayInt *MEDCoupling1SGTUMesh::sortHexa8EachOther()
1748 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> quads(explodeEachHexa8To6Quad4());//checks that only hexa8
1749 int nbHexa8(getNumberOfCells()),*cQuads(quads->getNodalConnectivity()->getPointer());
1750 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> neighOfQuads(DataArrayInt::New()); neighOfQuads->alloc(nbHexa8*6,1); neighOfQuads->fillWithValue(-1);
1751 int *ptNeigh(neighOfQuads->getPointer());
1752 {//neighOfQuads tells for each face of each Quad8 which cell (if!=-1) is connected to this face.
1753 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> quadsTmp(quads->buildUnstructured());
1754 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ccSafe,cciSafe;
1755 DataArrayInt *cc(0),*cci(0);
1756 quadsTmp->findCommonCells(3,0,cc,cci);
1757 ccSafe=cc; cciSafe=cci;
1758 const int *ccPtr(ccSafe->begin()),nbOfPair(cci->getNumberOfTuples()-1);
1759 for(int i=0;i<nbOfPair;i++)
1760 { ptNeigh[ccPtr[2*i+0]]=ccPtr[2*i+1]/6; ptNeigh[ccPtr[2*i+1]]=ccPtr[2*i+0]/6; }
1762 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
1763 std::vector<bool> fetched(nbHexa8,false);
1764 std::vector<bool>::iterator it(std::find(fetched.begin(),fetched.end(),false));
1765 while(it!=fetched.end())//it will turns as time as number of connected zones
1767 int cellId((int)std::distance(fetched.begin(),it));//it is the seed of the connected zone.
1768 std::set<int> s; s.insert(cellId);//s contains already organized.
1771 std::set<int> sNext;
1772 for(std::set<int>::const_iterator it0=s.begin();it0!=s.end();it0++)
1775 int *myNeighb(ptNeigh+6*(*it0));
1776 for(int i=0;i<6;i++)
1778 if(myNeighb[i]!=-1 && !fetched[myNeighb[i]])
1780 std::size_t pos(std::distance(HEXA8_FACE_PAIRS,std::find(HEXA8_FACE_PAIRS,HEXA8_FACE_PAIRS+6,i)));
1781 std::size_t pos0(pos/2),pos1(pos%2);
1782 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]))
1783 ret->pushBackSilent(myNeighb[i]);
1784 fetched[myNeighb[i]]=true;
1785 sNext.insert(myNeighb[i]);
1791 it=std::find(fetched.begin(),fetched.end(),false);
1795 int *conn(getNodalConnectivity()->getPointer());
1796 for(const int *pt=ret->begin();pt!=ret->end();pt++)
1799 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];
1800 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];
1807 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh3D() const
1809 static const int DUAL_TETRA_0[36]={
1810 4,1,0, 6,0,3, 7,3,1,
1811 4,0,1, 5,2,0, 8,1,2,
1812 6,3,0, 5,0,2, 9,2,3,
1815 static const int DUAL_TETRA_1[36]={
1816 8,4,10, 11,5,8, 10,7,11,
1817 9,4,8, 8,5,12, 12,6,9,
1818 10,4,9, 9,6,13, 13,7,10,
1819 12,5,11, 13,6,12, 11,7,13
1821 static const int FACEID_NOT_SH_NODE[4]={2,3,1,0};
1822 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TETRA4)
1823 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh3D : only TETRA4 supported !");
1824 checkFullyDefined();
1825 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured());
1826 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1827 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1828 const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1829 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d1Arr(DataArrayInt::New()),di1Arr(DataArrayInt::New()),rd1Arr(DataArrayInt::New()),rdi1Arr(DataArrayInt::New());
1830 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->explode3DMeshTo1D(d1Arr,di1Arr,rd1Arr,rdi1Arr));
1831 const int *d1(d1Arr->begin());
1832 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1833 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> faces(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
1834 const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
1835 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),facesBaryArr(faces->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
1836 const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+faces->getNumberOfCells()),offset1(offset0+edges->getNumberOfCells());
1838 std::vector<const DataArrayDouble *> v(4); v[0]=getCoords(); v[1]=facesBaryArr; v[2]=edgesBaryArr; v[3]=baryArr;
1839 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0; facesBaryArr=0;
1840 std::string name("DualOf_"); name+=getName();
1841 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name.c_str(),INTERP_KERNEL::NORM_POLYHED)); ret->setCoords(zeArr);
1842 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1843 for(int i=0;i<nbOfNodes;i++,revNodI++)
1845 int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1846 if(nbOfCellsSharingNode==0)
1848 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh3D : Node #" << i << " is orphan !";
1849 throw INTERP_KERNEL::Exception(oss.str().c_str());
1851 for(int j=0;j<nbOfCellsSharingNode;j++)
1853 int curCellId(revNod[revNodI[0]+j]);
1854 const int *connOfCurCell(nodal+4*curCellId);
1855 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1856 if(j!=0) cArr->pushBackSilent(-1);
1859 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;
1860 tmp[2]=curCellId+offset1; tmp[3]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+2]]+nbOfNodes;
1862 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;
1863 tmp[7]=curCellId+offset1; tmp[8]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+5]]+nbOfNodes;
1865 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;
1866 tmp[12]=curCellId+offset1; tmp[13]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+8]]+nbOfNodes;
1867 cArr->insertAtTheEnd(tmp,tmp+14);
1869 for(int k=0;k<4;k++)
1871 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1873 const int *faceId(d2+4*curCellId+k);
1874 if(rdi2[*faceId+1]-rdi2[*faceId]==1)
1876 int tmp2[5]; tmp2[0]=-1; tmp2[1]=i;
1877 tmp2[2]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+0]-8]+offset0;
1878 tmp2[3]=d2[4*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+1]-4]+nbOfNodes;
1879 tmp2[4]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+2]-8]+offset0;
1880 cArr->insertAtTheEnd(tmp2,tmp2+5);
1886 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
1888 ret->setNodalConnectivity(cArr,ciArr);
1892 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh2D() const
1894 static const int DUAL_TRI_0[6]={0,2, 1,0, 2,1};
1895 static const int DUAL_TRI_1[6]={-3,+5, +3,-4, +4,-5};
1896 static const int FACEID_NOT_SH_NODE[3]={1,2,0};
1897 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TRI3)
1898 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh2D : only TRI3 supported !");
1899 checkFullyDefined();
1900 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured());
1901 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1902 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1903 const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1904 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1905 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
1906 const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
1907 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
1908 const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+edges->getNumberOfCells());
1910 std::vector<const DataArrayDouble *> v(3); v[0]=getCoords(); v[1]=edgesBaryArr; v[2]=baryArr;
1911 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0;
1912 std::string name("DualOf_"); name+=getName();
1913 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name.c_str(),INTERP_KERNEL::NORM_POLYGON)); ret->setCoords(zeArr);
1914 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1915 for(int i=0;i<nbOfNodes;i++,revNodI++)
1917 int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1918 if(nbOfCellsSharingNode==0)
1920 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh2D : Node #" << i << " is orphan !";
1921 throw INTERP_KERNEL::Exception(oss.str().c_str());
1923 std::vector< std::vector<int> > polyg;
1924 for(int j=0;j<nbOfCellsSharingNode;j++)
1926 int curCellId(revNod[revNodI[0]+j]);
1927 const int *connOfCurCell(nodal+3*curCellId);
1928 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1929 std::vector<int> locV(3);
1930 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;
1931 polyg.push_back(locV);
1933 for(int k=0;k<3;k++)
1935 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1937 const int *edgeId(d2+3*curCellId+k);
1938 if(rdi2[*edgeId+1]-rdi2[*edgeId]==1)
1940 std::vector<int> locV2(2);
1941 int zeLocEdgeIdRel(DUAL_TRI_1[2*nodePosInCurCell+kk]);
1942 if(zeLocEdgeIdRel>0)
1943 { locV2[0]=d2[3*curCellId+zeLocEdgeIdRel-3]+nbOfNodes; locV2[1]=i; }
1945 { locV2[0]=i; locV2[1]=d2[3*curCellId-zeLocEdgeIdRel-3]+nbOfNodes; }
1946 polyg.push_back(locV2);
1952 std::vector<int> zePolyg(MEDCoupling1DGTUMesh::BuildAPolygonFromParts(polyg));
1953 cArr->insertAtTheEnd(zePolyg.begin(),zePolyg.end());
1954 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
1956 ret->setNodalConnectivity(cArr,ciArr);
1961 * This method aggregate the bbox of each cell and put it into bbox
1963 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
1965 * \throw If \a this is not fully set (coordinates and connectivity).
1966 * \throw If a cell in \a this has no valid nodeId.
1968 DataArrayDouble *MEDCoupling1SGTUMesh::getBoundingBoxForBBTree() const
1970 int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()),nbOfNodesPerCell(getNumberOfNodesPerCell());
1971 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
1972 double *bbox(ret->getPointer());
1973 for(int i=0;i<nbOfCells*spaceDim;i++)
1975 bbox[2*i]=std::numeric_limits<double>::max();
1976 bbox[2*i+1]=-std::numeric_limits<double>::max();
1978 const double *coordsPtr(_coords->getConstPointer());
1979 const int *conn(_conn->getConstPointer());
1980 for(int i=0;i<nbOfCells;i++)
1983 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1986 if(nodeId>=0 && nodeId<nbOfNodes)
1988 for(int k=0;k<spaceDim;k++)
1990 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
1991 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
1998 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
1999 throw INTERP_KERNEL::Exception(oss.str().c_str());
2007 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New()
2009 return new MEDCoupling1DGTUMesh;
2012 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type)
2014 if(type==INTERP_KERNEL::NORM_ERROR)
2015 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
2016 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
2019 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !";
2020 throw INTERP_KERNEL::Exception(oss.str().c_str());
2022 return new MEDCoupling1DGTUMesh(name,cm);
2025 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh()
2029 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
2033 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
2037 const DataArrayInt *c(other._conn);
2042 _conn_indx=c->deepCpy();
2046 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const
2048 return new MEDCoupling1DGTUMesh(*this,recDeepCpy);
2052 * This method behaves mostly like MEDCoupling1DGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
2053 * The coordinates are shared between \a this and the returned instance.
2055 * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
2056 * \sa MEDCoupling1DGTUMesh::deepCpy
2058 MEDCouplingPointSet *MEDCoupling1DGTUMesh::deepCpyConnectivityOnly() const
2061 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(clone(false));
2062 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy()),ci(_conn_indx->deepCpy());
2063 ret->setNodalConnectivity(c,ci);
2067 void MEDCoupling1DGTUMesh::updateTime() const
2069 MEDCoupling1GTUMesh::updateTime();
2070 const DataArrayInt *c(_conn);
2078 std::size_t MEDCoupling1DGTUMesh::getHeapMemorySizeWithoutChildren() const
2080 return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren();
2083 std::vector<const BigMemoryObject *> MEDCoupling1DGTUMesh::getDirectChildren() const
2085 std::vector<const BigMemoryObject *> ret(MEDCoupling1GTUMesh::getDirectChildren());
2086 const DataArrayInt *c(_conn);
2095 MEDCouplingMesh *MEDCoupling1DGTUMesh::deepCpy() const
2100 bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
2103 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !");
2104 std::ostringstream oss; oss.precision(15);
2105 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2108 reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !";
2111 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
2113 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2118 reason="in connectivity of single dynamic geometric type exactly one among this and other is null !";
2121 if(!c1->isEqualIfNotWhy(*c2,reason))
2123 reason.insert(0,"Nodal connectivity DataArrayInt differs : ");
2126 c1=_conn_indx; c2=otherC->_conn_indx;
2131 reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !";
2134 if(!c1->isEqualIfNotWhy(*c2,reason))
2136 reason.insert(0,"Nodal connectivity index DataArrayInt differs : ");
2142 bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
2145 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
2146 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2149 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
2151 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2156 if(!c1->isEqualWithoutConsideringStr(*c2))
2159 c1=_conn_indx; c2=otherC->_conn_indx;
2164 if(!c1->isEqualWithoutConsideringStr(*c2))
2170 * Checks if \a this and \a other meshes are geometrically equivalent with high
2171 * probability, else an exception is thrown. The meshes are considered equivalent if
2172 * (1) meshes contain the same number of nodes and the same number of elements of the
2173 * same types (2) three cells of the two meshes (first, last and middle) are based
2174 * on coincident nodes (with a specified precision).
2175 * \param [in] other - the mesh to compare with.
2176 * \param [in] prec - the precision used to compare nodes of the two meshes.
2177 * \throw If the two meshes do not match.
2179 void MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
2181 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
2182 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2184 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single dynamic geometric type !");
2185 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2189 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
2190 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2191 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
2192 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2193 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
2194 if(c1->getHashCode()!=c2->getHashCode())
2195 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs");
2197 c1=_conn_indx; c2=otherC->_conn_indx;
2201 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !");
2202 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2203 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !");
2204 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2205 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !");
2206 if(c1->getHashCode()!=c2->getHashCode())
2207 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs");
2211 void MEDCoupling1DGTUMesh::checkCoherencyOfConnectivity() const
2213 const DataArrayInt *c1(_conn);
2216 if(c1->getNumberOfComponents()!=1)
2217 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
2218 if(c1->getInfoOnComponent(0)!="")
2219 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
2220 c1->checkAllocated();
2223 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
2225 int sz2=_conn->getNumberOfTuples();
2229 if(c1->getNumberOfComponents()!=1)
2230 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
2231 c1->checkAllocated();
2232 if(c1->getNumberOfTuples()<1)
2233 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !");
2234 if(c1->getInfoOnComponent(0)!="")
2235 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
2236 int f=c1->front(),ll=c1->back();
2239 std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !";
2240 throw INTERP_KERNEL::Exception(oss.str().c_str());
2244 std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !";
2245 throw INTERP_KERNEL::Exception(oss.str().c_str());
2249 std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !";
2250 throw INTERP_KERNEL::Exception(oss.str().c_str());
2254 throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !");
2255 int szOfC1Exp=_conn_indx->back();
2258 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::checkCoherencyOfConnectivity : The expected length of nodal connectivity array regarding index is " << szOfC1Exp << " but the actual size of it is " << c1->getNumberOfTuples() << " !";
2259 throw INTERP_KERNEL::Exception(oss.str().c_str());
2264 * 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.
2265 * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one.
2266 * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array.
2268 void MEDCoupling1DGTUMesh::checkCoherency() const
2270 MEDCouplingPointSet::checkCoherency();
2271 checkCoherencyOfConnectivity();
2274 void MEDCoupling1DGTUMesh::checkCoherency1(double eps) const
2277 const DataArrayInt *c1(_conn),*c2(_conn_indx);
2278 if(!c2->isMonotonic(true))
2279 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkCoherency1 : the nodal connectivity index is expected to be increasing monotinic !");
2281 int nbOfTuples=c1->getNumberOfTuples();
2282 int nbOfNodes=getNumberOfNodes();
2283 const int *w(c1->begin());
2284 for(int i=0;i<nbOfTuples;i++,w++)
2286 if(*w==-1) continue;
2287 if(*w<0 || *w>=nbOfNodes)
2289 std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !";
2290 throw INTERP_KERNEL::Exception(oss.str().c_str());
2295 void MEDCoupling1DGTUMesh::checkCoherency2(double eps) const
2297 checkCoherency1(eps);
2300 int MEDCoupling1DGTUMesh::getNumberOfCells() const
2302 checkCoherencyOfConnectivity();//do not remove
2303 return _conn_indx->getNumberOfTuples()-1;
2307 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2308 * For each cell in \b this the number of nodes constituting cell is computed.
2309 * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned.
2310 * So for pohyhedrons some nodes can be counted several times in the returned result.
2312 * \return a newly allocated array
2314 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const
2317 _conn_indx->checkMonotonic(true);
2318 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2319 return _conn_indx->deltaShiftIndex();
2321 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2322 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2323 ret->alloc(nbOfCells,1);
2324 int *retPtr=ret->getPointer();
2325 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2326 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2327 *retPtr=ci[1]-ci[0]-std::count(c+ci[0],c+ci[1],-1);
2332 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2333 * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed.
2335 * \return a newly allocated array
2337 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const
2340 _conn_indx->checkMonotonic(true);
2341 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG)
2342 return _conn_indx->deltaShiftIndex();
2343 if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG)
2345 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=_conn_indx->deltaShiftIndex();
2346 ret->applyDivideBy(2);
2350 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2351 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2352 ret->alloc(nbOfCells,1);
2353 int *retPtr=ret->getPointer();
2354 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2355 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2356 *retPtr=std::count(c+ci[0],c+ci[1],-1)+1;
2361 * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell,
2362 * will be counted only once here whereas it will be counted several times in MEDCoupling1DGTUMesh::computeNbOfNodesPerCell method.
2364 * \return DataArrayInt * - new object to be deallocated by the caller.
2365 * \sa MEDCoupling1DGTUMesh::computeNbOfNodesPerCell
2367 DataArrayInt *MEDCoupling1DGTUMesh::computeEffectiveNbOfNodesPerCell() const
2370 _conn_indx->checkMonotonic(true);
2371 int nbOfCells(_conn_indx->getNumberOfTuples()-1);
2372 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2373 ret->alloc(nbOfCells,1);
2374 int *retPtr(ret->getPointer());
2375 const int *ci(_conn_indx->begin()),*c(_conn->begin());
2376 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2378 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2380 std::set<int> s(c+ci[0],c+ci[1]);
2381 *retPtr=(int)s.size();
2386 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2388 std::set<int> s(c+ci[0],c+ci[1]); s.erase(-1);
2389 *retPtr=(int)s.size();
2395 void MEDCoupling1DGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
2397 int nbOfCells(getNumberOfCells());//performs checks
2398 if(cellId>=0 && cellId<nbOfCells)
2400 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2401 int nbOfNodes=stp-strt;
2403 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !");
2404 conn.resize(nbOfNodes);
2405 std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin());
2409 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2410 throw INTERP_KERNEL::Exception(oss.str().c_str());
2414 int MEDCoupling1DGTUMesh::getNumberOfNodesInCell(int cellId) const
2416 int nbOfCells(getNumberOfCells());//performs checks
2417 if(cellId>=0 && cellId<nbOfCells)
2419 const int *conn(_conn->begin());
2420 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2421 return stp-strt-std::count(conn+strt,conn+stp,-1);
2425 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNumberOfNodesInCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2426 throw INTERP_KERNEL::Exception(oss.str().c_str());
2430 std::string MEDCoupling1DGTUMesh::simpleRepr() const
2432 static const char msg0[]="No coordinates specified !";
2433 std::ostringstream ret;
2434 ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
2435 ret << "Description of mesh : \"" << getDescription() << "\"\n";
2437 double tt=getTime(tmpp1,tmpp2);
2438 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
2439 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
2440 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
2443 const int spaceDim=getSpaceDimension();
2444 ret << spaceDim << "\nInfo attached on space dimension : ";
2445 for(int i=0;i<spaceDim;i++)
2446 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
2450 ret << msg0 << "\n";
2451 ret << "Number of nodes : ";
2453 ret << getNumberOfNodes() << "\n";
2455 ret << msg0 << "\n";
2456 ret << "Number of cells : ";
2458 try { checkCoherency(); } catch(INTERP_KERNEL::Exception& /* e */)
2460 ret << "Nodal connectivity arrays are not set or badly set !\n";
2464 ret << getNumberOfCells() << "\n";
2465 ret << "Cell type : " << _cm->getRepr() << "\n";
2469 std::string MEDCoupling1DGTUMesh::advancedRepr() const
2471 std::ostringstream ret;
2472 ret << simpleRepr();
2473 ret << "\nCoordinates array : \n___________________\n\n";
2475 _coords->reprWithoutNameStream(ret);
2477 ret << "No array set !\n";
2478 ret << "\n\nNodal Connectivity : \n____________________\n\n";
2481 try { checkCoherency1(); } catch(INTERP_KERNEL::Exception& /* e */)
2483 ret << "Nodal connectivity arrays are not set or badly set !\n";
2488 int nbOfCells=getNumberOfCells();
2489 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2490 for(int i=0;i<nbOfCells;i++,ci++)
2492 ret << "Cell #" << i << " : ";
2493 std::copy(c+ci[0],c+ci[1],std::ostream_iterator<int>(ret," "));
2499 DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const
2501 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
2502 int spaceDim=getSpaceDimension();
2503 int nbOfCells=getNumberOfCells();//checkCoherency()
2504 int nbOfNodes=getNumberOfNodes();
2505 ret->alloc(nbOfCells,spaceDim);
2506 double *ptToFill=ret->getPointer();
2507 const double *coor=_coords->begin();
2508 const int *nodal=_conn->begin(),*nodali=_conn_indx->begin();
2510 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2512 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2514 std::fill(ptToFill,ptToFill+spaceDim,0.);
2515 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2517 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2519 if(*nodal>=0 && *nodal<nbOfNodes)
2520 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2523 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2524 throw INTERP_KERNEL::Exception(oss.str().c_str());
2526 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(nodali[1]-nodali[0])));
2531 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !";
2532 throw INTERP_KERNEL::Exception(oss.str().c_str());
2538 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2540 std::fill(ptToFill,ptToFill+spaceDim,0.);
2541 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2544 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2546 if(*nodal==-1) continue;
2547 if(*nodal>=0 && *nodal<nbOfNodes)
2549 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2554 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2555 throw INTERP_KERNEL::Exception(oss.str().c_str());
2559 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./nbOfNod));
2562 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !";
2563 throw INTERP_KERNEL::Exception(oss.str().c_str());
2568 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : at cell #" << i << " the nodal index array is invalid !";
2569 throw INTERP_KERNEL::Exception(oss.str().c_str());
2576 void MEDCoupling1DGTUMesh::renumberCells(const int *old2NewBg, bool check)
2578 int nbCells=getNumberOfCells();
2579 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
2580 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
2582 o2n=o2n->checkAndPreparePermutation();
2584 const int *o2nPtr=o2n->getPointer();
2585 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2586 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
2587 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
2588 newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1);
2589 newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx);
2591 int *newC=newConn->getPointer(),*newCI=newConnI->getPointer();
2592 for(int i=0;i<nbCells;i++)
2594 int newPos=o2nPtr[i];
2595 int sz=conni[i+1]-conni[i];
2600 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !";
2601 throw INTERP_KERNEL::Exception(oss.str().c_str());
2604 newConnI->computeOffsets2(); newCI=newConnI->getPointer();
2606 for(int i=0;i<nbCells;i++,conni++)
2609 std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]);
2612 _conn_indx=newConnI;
2615 MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
2617 if(other->getType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED)
2618 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !");
2619 const MEDCoupling1DGTUMesh *otherC=static_cast<const MEDCoupling1DGTUMesh *>(other);
2620 return Merge1DGTUMeshes(this,otherC);
2623 MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const
2625 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName().c_str(),getMeshDimension());
2626 ret->setCoords(getCoords());
2627 const int *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin();
2628 int nbCells=getNumberOfCells();//checkCoherency
2629 int geoType=(int)getCellModelEnum();
2630 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1);
2631 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::New(); cI->alloc(nbCells+1);
2632 int *cPtr=c->getPointer(),*ciPtr=cI->getPointer();
2634 for(int i=0;i<nbCells;i++,ciPtr++)
2636 int sz=nodalConnI[i+1]-nodalConnI[i];
2640 cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr);
2641 ciPtr[1]=ciPtr[0]+sz+1;
2645 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !";
2646 throw INTERP_KERNEL::Exception(oss.str().c_str());
2649 ret->setConnectivity(c,cI,true);
2654 * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes
2656 DataArrayInt *MEDCoupling1DGTUMesh::simplexize(int policy)
2658 int nbOfCells=getNumberOfCells();
2659 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2660 ret->alloc(nbOfCells,1);
2665 void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const
2667 stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
2668 stream << " Mesh dimension : " << getMeshDimension() << ".";
2670 { stream << " No coordinates set !"; return ; }
2671 if(!_coords->isAllocated())
2672 { stream << " Coordinates set but not allocated !"; return ; }
2673 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
2674 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
2676 try { checkCoherency(); } catch(INTERP_KERNEL::Exception& /* e */)
2678 stream << std::endl << "Nodal connectivity NOT set properly !\n";
2682 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
2685 void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
2688 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
2689 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2691 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !");
2692 setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex());
2695 MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
2698 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
2699 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2701 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
2702 std::vector<const MEDCoupling1DGTUMesh *> ms(2);
2705 return Merge1DGTUMeshesOnSameCoords(ms);
2708 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
2711 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2712 ret->setCoords(_coords);
2713 DataArrayInt *c=0,*ci=0;
2714 MEDCouplingUMesh::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci);
2715 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2716 ret->setNodalConnectivity(c,ci);
2720 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
2723 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2724 ret->setCoords(_coords);
2725 DataArrayInt *c=0,*ci=0;
2726 MEDCouplingUMesh::ExtractFromIndexedArrays2(start,end,step,_conn,_conn_indx,c,ci);
2727 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2728 ret->setNodalConnectivity(c,ci);
2732 void MEDCoupling1DGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
2734 int sz((int)nodeIdsInUse.size());
2735 int nbCells(getNumberOfCells());
2736 const int *w(_conn->begin()),*wi(_conn_indx->begin());
2737 for(int i=0;i<nbCells;i++,wi++)
2738 for(const int *pt=w+wi[0];pt!=w+wi[1];pt++)
2741 if(*pt>=0 && *pt<sz)
2742 nodeIdsInUse[*pt]=true;
2745 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeNodeIdsAlg : At cell #" << i << " presence of node id #" << *pt << " should be in [0," << sz << ") !";
2746 throw INTERP_KERNEL::Exception(oss.str().c_str());
2751 void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const
2753 checkFullyDefined();
2754 int nbOfNodes=getNumberOfNodes();
2755 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
2756 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
2757 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
2758 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2759 int nbOfCells=getNumberOfCells();
2760 int nbOfEltsInRevNodal=0;
2761 for(int eltId=0;eltId<nbOfCells;eltId++)
2763 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2764 if(nbOfNodesPerCell>=0)
2766 for(int j=0;j<nbOfNodesPerCell;j++)
2768 int nodeId=conn[conni[eltId]+j];
2769 if(nodeId==-1) continue;
2770 if(nodeId>=0 && nodeId<nbOfNodes)
2772 nbOfEltsInRevNodal++;
2773 revNodalIndxPtr[nodeId+1]++;
2777 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
2778 throw INTERP_KERNEL::Exception(oss.str().c_str());
2784 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << "nodal connectivity is invalid !";
2785 throw INTERP_KERNEL::Exception(oss.str().c_str());
2788 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
2789 conn=_conn->begin();
2790 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
2791 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
2792 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
2793 for(int eltId=0;eltId<nbOfCells;eltId++)
2795 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2796 for(int j=0;j<nbOfNodesPerCell;j++)
2798 int nodeId=conn[conni[eltId]+j];
2800 *std::find_if(revNodalPtr+revNodalIndxPtr[nodeId],revNodalPtr+revNodalIndxPtr[nodeId+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
2805 void MEDCoupling1DGTUMesh::checkFullyDefined() const
2807 if(!((const DataArrayInt *)_conn) || !((const DataArrayInt *)_conn_indx) || !((const DataArrayDouble *)_coords))
2808 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined.");
2811 bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
2813 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !");
2816 void MEDCoupling1DGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
2819 double time=getTime(it,order);
2820 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
2822 littleStrings.push_back(getName());
2823 littleStrings.push_back(getDescription());
2824 littleStrings.push_back(getTimeUnit());
2826 std::vector<std::string> littleStrings2,littleStrings3,littleStrings4;
2827 if((const DataArrayDouble *)_coords)
2828 _coords->getTinySerializationStrInformation(littleStrings2);
2829 if((const DataArrayInt *)_conn)
2830 _conn->getTinySerializationStrInformation(littleStrings3);
2831 if((const DataArrayInt *)_conn_indx)
2832 _conn_indx->getTinySerializationStrInformation(littleStrings4);
2833 int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size()),sz2((int)littleStrings4.size());
2834 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
2835 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
2836 littleStrings.insert(littleStrings.end(),littleStrings4.begin(),littleStrings4.end());
2838 tinyInfo.push_back(getCellModelEnum());
2839 tinyInfo.push_back(it);
2840 tinyInfo.push_back(order);
2841 std::vector<int> tinyInfo2,tinyInfo3,tinyInfo4;
2842 if((const DataArrayDouble *)_coords)
2843 _coords->getTinySerializationIntInformation(tinyInfo2);
2844 if((const DataArrayInt *)_conn)
2845 _conn->getTinySerializationIntInformation(tinyInfo3);
2846 if((const DataArrayInt *)_conn_indx)
2847 _conn_indx->getTinySerializationIntInformation(tinyInfo4);
2848 int sz3((int)tinyInfo2.size()),sz4((int)tinyInfo3.size()),sz5((int)tinyInfo4.size());
2849 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3); tinyInfo.push_back(sz4); tinyInfo.push_back(sz5);
2850 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
2851 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
2852 tinyInfo.insert(tinyInfo.end(),tinyInfo4.begin(),tinyInfo4.end());
2854 tinyInfoD.push_back(time);
2857 void MEDCoupling1DGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
2859 std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+tinyInfo[6]);
2860 std::vector<int> tinyInfo1(tinyInfo.begin()+9+tinyInfo[6],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]);
2861 std::vector<int> tinyInfo12(tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]+tinyInfo[8]);
2862 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(DataArrayInt::New()); p1->resizeForUnserialization(tinyInfo1);
2863 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(DataArrayInt::New()); p2->resizeForUnserialization(tinyInfo12);
2864 std::vector<const DataArrayInt *> v(2); v[0]=p1; v[1]=p2;
2865 p2=DataArrayInt::Aggregate(v);
2866 a2->resizeForUnserialization(tinyInfo2);
2867 a1->alloc(p2->getNbOfElems(),1);
2870 void MEDCoupling1DGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
2873 if((const DataArrayInt *)_conn)
2874 if(_conn->isAllocated())
2875 sz=_conn->getNbOfElems();
2876 if((const DataArrayInt *)_conn_indx)
2877 if(_conn_indx->isAllocated())
2878 sz+=_conn_indx->getNbOfElems();
2879 a1=DataArrayInt::New();
2881 int *work(a1->getPointer());
2882 if(sz!=0 && (const DataArrayInt *)_conn)
2883 work=std::copy(_conn->begin(),_conn->end(),a1->getPointer());
2884 if(sz!=0 && (const DataArrayInt *)_conn_indx)
2885 std::copy(_conn_indx->begin(),_conn_indx->end(),work);
2887 if((const DataArrayDouble *)_coords)
2888 if(_coords->isAllocated())
2889 sz=_coords->getNbOfElems();
2890 a2=DataArrayDouble::New();
2892 if(sz!=0 && (const DataArrayDouble *)_coords)
2893 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
2896 void MEDCoupling1DGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
2897 const std::vector<std::string>& littleStrings)
2899 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
2900 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
2901 setName(littleStrings[0].c_str());
2902 setDescription(littleStrings[1].c_str());
2903 setTimeUnit(littleStrings[2].c_str());
2904 setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
2905 int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]),sz4(tinyInfo[7]),sz5(tinyInfo[8]);
2907 _coords=DataArrayDouble::New();
2908 std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+sz3);
2909 _coords->resizeForUnserialization(tinyInfo2);
2910 std::copy(a2->begin(),a2->end(),_coords->getPointer());
2911 _conn=DataArrayInt::New();
2912 std::vector<int> tinyInfo3(tinyInfo.begin()+9+sz3,tinyInfo.begin()+9+sz3+sz4);
2913 _conn->resizeForUnserialization(tinyInfo3);
2914 std::copy(a1->begin(),a1->begin()+_conn->getNbOfElems(),_conn->getPointer());
2915 _conn_indx=DataArrayInt::New();
2916 std::vector<int> tinyInfo4(tinyInfo.begin()+9+sz3+sz4,tinyInfo.begin()+9+sz3+sz4+sz5);
2917 _conn_indx->resizeForUnserialization(tinyInfo4);
2918 std::copy(a1->begin()+_conn->getNbOfElems(),a1->end(),_conn_indx->getPointer());
2919 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
2920 _coords->finishUnserialization(tinyInfo2,littleStrings2);
2921 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
2922 _conn->finishUnserialization(tinyInfo3,littleStrings3);
2923 std::vector<std::string> littleStrings4(littleStrings.begin()+3+sz0+sz1,littleStrings.begin()+3+sz0+sz1+sz2);
2924 _conn_indx->finishUnserialization(tinyInfo4,littleStrings4);
2928 * Finds nodes not used in any cell and returns an array giving a new id to every node
2929 * by excluding the unused nodes, for which the array holds -1. The result array is
2930 * a mapping in "Old to New" mode.
2931 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
2932 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
2933 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
2934 * if the node is unused or a new id else. The caller is to delete this
2935 * array using decrRef() as it is no more needed.
2936 * \throw If the coordinates array is not set.
2937 * \throw If the nodal connectivity of cells is not defined.
2938 * \throw If the nodal connectivity includes an invalid id.
2940 DataArrayInt *MEDCoupling1DGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
2943 int nbOfNodes=getNumberOfNodes();
2944 int nbOfCells=getNumberOfCells();//checkCoherency
2945 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2946 ret->alloc(nbOfNodes,1);
2947 int *traducer=ret->getPointer();
2948 std::fill(traducer,traducer+nbOfNodes,-1);
2949 const int *conn=_conn->begin(),*conni(_conn_indx->begin());
2950 for(int i=0;i<nbOfCells;i++,conni++)
2952 int nbNodesPerCell=conni[1]-conni[0];
2953 for(int j=0;j<nbNodesPerCell;j++)
2955 int nodeId=conn[conni[0]+j];
2956 if(nodeId==-1) continue;
2957 if(nodeId>=0 && nodeId<nbOfNodes)
2961 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << nodeId << " not in [0," << nbOfNodes << ") !";
2962 throw INTERP_KERNEL::Exception(oss.str().c_str());
2966 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
2967 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
2972 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
2973 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
2974 * This method is a generalization of shiftNodeNumbersInConn().
2975 * \warning This method performs no check of validity of new ids. **Use it with care !**
2976 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
2977 * this->getNumberOfNodes(), in "Old to New" mode.
2978 * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
2979 * \throw If the nodal connectivity of cells is not defined.
2981 void MEDCoupling1DGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
2983 getNumberOfCells();//only to check that all is well defined.
2985 int nbElemsIn=getNumberOfNodes();
2986 int nbOfTuples=_conn->getNumberOfTuples();
2987 int *pt=_conn->getPointer();
2988 for(int i=0;i<nbOfTuples;i++,pt++)
2990 if(*pt==-1) continue;
2991 if(*pt>=0 && *pt<nbElemsIn)
2992 *pt=newNodeNumbersO2N[*pt];
2995 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
2996 throw INTERP_KERNEL::Exception(oss.str().c_str());
2999 _conn->declareAsNew();
3005 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
3006 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
3007 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
3008 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
3010 * \param [in] begin input start of array of node ids.
3011 * \param [in] end input end of array of node ids.
3012 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
3013 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
3015 void MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
3017 int nbOfCells=getNumberOfCells();
3018 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
3020 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
3021 std::vector<bool> fastFinder(sz,false);
3022 for(const int *work=begin;work!=end;work++)
3023 if(*work>=0 && *work<sz)
3024 fastFinder[*work]=true;
3025 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
3026 for(int i=0;i<nbOfCells;i++,conni++)
3028 int ref=0,nbOfHit=0;
3029 int nbNodesPerCell=conni[1]-conni[0];
3030 if(nbNodesPerCell>=0)
3032 for(int j=0;j<nbNodesPerCell;j++)
3034 int nodeId=conn[conni[0]+j];
3038 if(fastFinder[nodeId])
3045 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !";
3046 throw INTERP_KERNEL::Exception(oss.str().c_str());
3048 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
3049 cellIdsKept->pushBackSilent(i);
3051 cellIdsKeptArr=cellIdsKept.retn();
3054 void MEDCoupling1DGTUMesh::allocateCells(int nbOfCells)
3057 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !");
3058 _conn=DataArrayInt::New();
3059 _conn->reserve(nbOfCells*3);
3060 _conn_indx=DataArrayInt::New();
3061 _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0);
3066 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
3068 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
3069 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
3070 * \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
3071 * attached to \a this.
3072 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
3074 void MEDCoupling1DGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd)
3076 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
3077 DataArrayInt *c(_conn),*c2(_conn_indx);
3081 if(pos==c->getNumberOfTuples())
3083 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
3084 c2->pushBackSilent(pos+sz);
3088 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !";
3089 throw INTERP_KERNEL::Exception(oss.str().c_str());
3093 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !");
3096 void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex)
3099 nodalConn->incrRef();
3102 nodalConnIndex->incrRef();
3103 _conn_indx=nodalConnIndex;
3108 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
3110 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivity() const
3112 const DataArrayInt *ret(_conn);
3113 return const_cast<DataArrayInt *>(ret);
3117 * \return DataArrayInt * - the internal reference to the nodal connectivity index. The caller is not reponsible to deallocate it.
3119 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const
3121 const DataArrayInt *ret(_conn_indx);
3122 return const_cast<DataArrayInt *>(ret);
3126 * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here".
3127 * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity).
3128 * 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.
3130 * 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.
3132 * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal
3133 * connectivity arrays are different (false)
3134 * \return a new object to be managed by the caller.
3136 * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked
3138 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const
3140 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
3141 DataArrayInt *nc=0,*nci=0;
3142 isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci);
3143 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ncs(nc),ncis(nci);
3144 ret->_conn=ncs; ret->_conn_indx=ncis;
3145 ret->setCoords(getCoords());
3150 * This method allows to compute, if needed, the packed nodal connectivity pair.
3151 * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges convered by nodal connectivity index array.
3152 * 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.
3154 * 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)
3155 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3157 * 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
3160 * This method return 3 elements.
3161 * \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
3162 * this pointer can be seen as a new object, that is to managed by the caller.
3163 * \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
3164 * this pointer can be seen as a new object, that is to managed by the caller.
3165 * \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
3166 * output parameters are newly created objects.
3168 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
3170 bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const
3172 if(isPacked())//performs the checkCoherency
3174 const DataArrayInt *c0(_conn),*c1(_conn_indx);
3175 nodalConn=const_cast<DataArrayInt *>(c0); nodalConnIndx=const_cast<DataArrayInt *>(c1);
3176 nodalConn->incrRef(); nodalConnIndx->incrRef();
3179 int bg=_conn_indx->front(),end=_conn_indx->back();
3180 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nc(_conn->selectByTupleId2(bg,end,1));
3181 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nci(_conn_indx->deepCpy());
3182 nci->applyLin(1,-bg);
3183 nodalConn=nc.retn(); nodalConnIndx=nci.retn();
3188 * 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)
3189 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3190 * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned.
3191 * \return bool - true if \a this looks packed, false is not.
3193 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
3195 bool MEDCoupling1DGTUMesh::isPacked() const
3198 return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples();
3201 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2)
3203 std::vector<const MEDCoupling1DGTUMesh *> tmp(2);
3204 tmp[0]=const_cast<MEDCoupling1DGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1DGTUMesh *>(mesh2);
3205 return Merge1DGTUMeshes(tmp);
3208 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a)
3210 std::size_t sz=a.size();
3212 return Merge1DGTUMeshesLL(a);
3213 for(std::size_t ii=0;ii<sz;ii++)
3216 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::Merge1DGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
3217 throw INTERP_KERNEL::Exception(oss.str().c_str());
3219 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
3220 for(std::size_t ii=0;ii<sz;ii++)
3221 if(&(a[ii]->getCellModel())!=cm)
3222 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !");
3223 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > bb(sz);
3224 std::vector< const MEDCoupling1DGTUMesh * > aa(sz);
3226 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
3228 const MEDCoupling1DGTUMesh *cur=a[i];
3229 const DataArrayDouble *coo=cur->getCoords();
3231 spaceDim=coo->getNumberOfComponents();
3234 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !");
3235 for(std::size_t i=0;i<sz;i++)
3237 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
3240 return Merge1DGTUMeshesLL(aa);
3244 * \throw If presence of a null instance in the input vector \a a.
3245 * \throw If a is empty
3247 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a)
3250 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !");
3251 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3253 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !");
3254 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
3255 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3256 (*it)->getNumberOfCells();//to check that all is OK
3257 const DataArrayDouble *coords=(*it)->getCoords();
3258 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3260 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3261 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3263 for(int i=1;it!=a.end();i++,it++)
3266 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !");
3267 if(cm!=&((*it)->getCellModel()))
3268 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3269 (*it)->getNumberOfCells();//to check that all is OK
3270 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3271 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3272 if(coords!=(*it)->getCoords())
3273 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !");
3275 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3276 ret->setCoords(coords);
3277 ret->_conn=DataArrayInt::Aggregate(ncs);
3278 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3283 * 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)
3285 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a)
3288 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : input array must be NON EMPTY !");
3289 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
3290 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3291 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3292 std::vector<int> nbNodesPerElt(a.size());
3293 int nbOfCells=(*it)->getNumberOfCells();
3295 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3296 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3298 int prevNbOfNodes=(*it)->getNumberOfNodes();
3299 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3301 for(int i=1;it!=a.end();i++,it++)
3303 if(cm!=&((*it)->getCellModel()))
3304 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3305 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3306 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3307 nbOfCells+=(*it)->getNumberOfCells();
3308 nbNodesPerElt[i]=nbNodesPerElt[i-1]+prevNbOfNodes;
3309 prevNbOfNodes=(*it)->getNumberOfNodes();
3311 std::vector<const MEDCouplingPointSet *> aps(a.size());
3312 std::copy(a.begin(),a.end(),aps.begin());
3313 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
3314 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3315 ret->setCoords(pts);
3316 ret->_conn=AggregateNodalConnAndShiftNodeIds(ncs,nbNodesPerElt);
3317 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3321 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(int spaceDim) const
3323 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
3324 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1,tmp2;
3325 const DataArrayInt *nodalConn(_conn),*nodalConnI(_conn_indx);
3328 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
3336 tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
3340 ret->_conn_indx=tmp2;
3344 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
3345 ret->setCoords(coords);
3348 ret->setCoords(_coords);
3353 * This method aggregate the bbox of each cell and put it into bbox parameter.
3355 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
3357 * \throw If \a this is not fully set (coordinates and connectivity).
3358 * \throw If a cell in \a this has no valid nodeId.
3360 DataArrayDouble *MEDCoupling1DGTUMesh::getBoundingBoxForBBTree() const
3362 checkFullyDefined();
3363 int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes());
3364 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
3365 double *bbox(ret->getPointer());
3366 for(int i=0;i<nbOfCells*spaceDim;i++)
3368 bbox[2*i]=std::numeric_limits<double>::max();
3369 bbox[2*i+1]=-std::numeric_limits<double>::max();
3371 const double *coordsPtr(_coords->getConstPointer());
3372 const int *conn(_conn->getConstPointer()),*connI(_conn_indx->getConstPointer());
3373 for(int i=0;i<nbOfCells;i++)
3375 int offset=connI[i];
3376 int nbOfNodesForCell(connI[i+1]-offset),kk(0);
3377 for(int j=0;j<nbOfNodesForCell;j++)
3379 int nodeId=conn[offset+j];
3380 if(nodeId>=0 && nodeId<nbOfNodes)
3382 for(int k=0;k<spaceDim;k++)
3384 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
3385 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
3392 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
3393 throw INTERP_KERNEL::Exception(oss.str().c_str());
3399 std::vector<int> MEDCoupling1DGTUMesh::BuildAPolygonFromParts(const std::vector< std::vector<int> >& parts)
3401 std::vector<int> ret;
3404 ret.insert(ret.end(),parts[0].begin(),parts[0].end());
3405 int ref(ret.back());
3406 std::size_t sz(parts.size()),nbh(1);
3407 std::vector<bool> b(sz,true); b[0]=false;
3411 for(;i<sz;i++) if(b[i] && parts[i].front()==ref) { ret.insert(ret.end(),parts[i].begin()+1,parts[i].end()); nbh++; break; }
3415 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::BuildAPolygonFromParts : the input vector is not a part of a single polygon !");
3417 if(ret.back()==ret.front())
3423 * This method performs an aggregation of \a nodalConns (as DataArrayInt::Aggregate does) but in addition of that a shift is applied on the
3424 * values contained in \a nodalConns using corresponding offset specified in input \a offsetInNodeIdsPerElt.
3425 * But it also manage the values -1, that have a semantic in MEDCoupling1DGTUMesh class (separator for polyhedron).
3427 * \param [in] nodalConns - a list of nodal connectivity arrays same size than \a offsetInNodeIdsPerElt.
3428 * \param [in] offsetInNodeIdsPerElt - a list of offsets to apply.
3429 * \return DataArrayInt * - A new object (to be managed by the caller) that is the result of the aggregation.
3430 * \throw If \a nodalConns or \a offsetInNodeIdsPerElt are empty.
3431 * \throw If \a nodalConns and \a offsetInNodeIdsPerElt have not the same size.
3432 * \throw If presence of null pointer in \a nodalConns.
3433 * \throw If presence of not allocated or array with not exactly one component in \a nodalConns.
3435 DataArrayInt *MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds(const std::vector<const DataArrayInt *>& nodalConns, const std::vector<int>& offsetInNodeIdsPerElt)
3437 std::size_t sz1(nodalConns.size()),sz2(offsetInNodeIdsPerElt.size());
3439 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : input vectors do not have the same size !");
3441 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : empty vectors in input !");
3443 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++)
3446 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of null pointer in input vector !");
3447 if(!(*it)->isAllocated())
3448 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of non allocated array in input vector !");
3449 if((*it)->getNumberOfComponents()!=1)
3450 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of array with not exactly one component !");
3451 nbOfTuples+=(*it)->getNumberOfTuples();
3453 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
3454 int *pt=ret->getPointer();
3456 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++,i++)
3458 int curNbt=(*it)->getNumberOfTuples();
3459 const int *inPt=(*it)->begin();
3460 int offset=offsetInNodeIdsPerElt[i];
3461 for(int j=0;j<curNbt;j++,pt++)
3472 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m)
3475 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh is null !");
3476 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
3478 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh must have exactly one geometric type !");
3479 int geoType((int)*gts.begin());
3480 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(m->getName().c_str(),*gts.begin()));
3481 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription().c_str());
3482 int nbCells(m->getNumberOfCells());
3483 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
3484 conn->alloc(m->getMeshLength()-nbCells,1); connI->alloc(nbCells+1,1);
3485 int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
3486 const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
3487 for(int i=0;i<nbCells;i++,ciin++,ci++)
3489 if(cin[ciin[0]]==geoType)
3491 if(ciin[1]-ciin[0]>=1)
3493 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
3494 ci[1]=ci[0]+ciin[1]-ciin[0]-1;
3498 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 !";
3499 throw INTERP_KERNEL::Exception(oss.str().c_str());
3504 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 !";
3505 throw INTERP_KERNEL::Exception(oss.str().c_str());
3508 ret->setNodalConnectivity(conn,connI);