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 std::string& 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 std::string& 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(),meshDim)); ret->setDescription(firstPart->getDescription());
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 std::string& 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 std::string& 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(),*gts.begin()));
505 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription());
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(),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(),*_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(),*_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(),*_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]);
1446 setDescription(littleStrings[1]);
1447 setTimeUnit(littleStrings[2]);
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(),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,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,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 * \param [in] arcDetEps - a parameter specifying in case of 2D quadratic polygon cell the detection limit between linear and arc circle. (By default 1e-12)
1964 * For all other cases this input parameter is ignored.
1965 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
1967 * \throw If \a this is not fully set (coordinates and connectivity).
1968 * \throw If a cell in \a this has no valid nodeId.
1970 DataArrayDouble *MEDCoupling1SGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
1972 int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()),nbOfNodesPerCell(getNumberOfNodesPerCell());
1973 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
1974 double *bbox(ret->getPointer());
1975 for(int i=0;i<nbOfCells*spaceDim;i++)
1977 bbox[2*i]=std::numeric_limits<double>::max();
1978 bbox[2*i+1]=-std::numeric_limits<double>::max();
1980 const double *coordsPtr(_coords->getConstPointer());
1981 const int *conn(_conn->getConstPointer());
1982 for(int i=0;i<nbOfCells;i++)
1985 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1988 if(nodeId>=0 && nodeId<nbOfNodes)
1990 for(int k=0;k<spaceDim;k++)
1992 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
1993 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
2000 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
2001 throw INTERP_KERNEL::Exception(oss.str().c_str());
2009 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New()
2011 return new MEDCoupling1DGTUMesh;
2014 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
2016 if(type==INTERP_KERNEL::NORM_ERROR)
2017 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
2018 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
2021 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !";
2022 throw INTERP_KERNEL::Exception(oss.str().c_str());
2024 return new MEDCoupling1DGTUMesh(name,cm);
2027 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh()
2031 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
2035 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
2039 const DataArrayInt *c(other._conn);
2044 _conn_indx=c->deepCpy();
2048 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const
2050 return new MEDCoupling1DGTUMesh(*this,recDeepCpy);
2054 * This method behaves mostly like MEDCoupling1DGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
2055 * The coordinates are shared between \a this and the returned instance.
2057 * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
2058 * \sa MEDCoupling1DGTUMesh::deepCpy
2060 MEDCouplingPointSet *MEDCoupling1DGTUMesh::deepCpyConnectivityOnly() const
2063 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(clone(false));
2064 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy()),ci(_conn_indx->deepCpy());
2065 ret->setNodalConnectivity(c,ci);
2069 void MEDCoupling1DGTUMesh::updateTime() const
2071 MEDCoupling1GTUMesh::updateTime();
2072 const DataArrayInt *c(_conn);
2080 std::size_t MEDCoupling1DGTUMesh::getHeapMemorySizeWithoutChildren() const
2082 return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren();
2085 std::vector<const BigMemoryObject *> MEDCoupling1DGTUMesh::getDirectChildren() const
2087 std::vector<const BigMemoryObject *> ret(MEDCoupling1GTUMesh::getDirectChildren());
2088 const DataArrayInt *c(_conn);
2097 MEDCouplingMesh *MEDCoupling1DGTUMesh::deepCpy() const
2102 bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
2105 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !");
2106 std::ostringstream oss; oss.precision(15);
2107 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2110 reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !";
2113 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
2115 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2120 reason="in connectivity of single dynamic geometric type exactly one among this and other is null !";
2123 if(!c1->isEqualIfNotWhy(*c2,reason))
2125 reason.insert(0,"Nodal connectivity DataArrayInt differs : ");
2128 c1=_conn_indx; c2=otherC->_conn_indx;
2133 reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !";
2136 if(!c1->isEqualIfNotWhy(*c2,reason))
2138 reason.insert(0,"Nodal connectivity index DataArrayInt differs : ");
2144 bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
2147 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
2148 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2151 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
2153 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2158 if(!c1->isEqualWithoutConsideringStr(*c2))
2161 c1=_conn_indx; c2=otherC->_conn_indx;
2166 if(!c1->isEqualWithoutConsideringStr(*c2))
2172 * Checks if \a this and \a other meshes are geometrically equivalent with high
2173 * probability, else an exception is thrown. The meshes are considered equivalent if
2174 * (1) meshes contain the same number of nodes and the same number of elements of the
2175 * same types (2) three cells of the two meshes (first, last and middle) are based
2176 * on coincident nodes (with a specified precision).
2177 * \param [in] other - the mesh to compare with.
2178 * \param [in] prec - the precision used to compare nodes of the two meshes.
2179 * \throw If the two meshes do not match.
2181 void MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
2183 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
2184 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2186 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single dynamic geometric type !");
2187 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2191 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
2192 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2193 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
2194 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2195 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
2196 if(c1->getHashCode()!=c2->getHashCode())
2197 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs");
2199 c1=_conn_indx; c2=otherC->_conn_indx;
2203 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !");
2204 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2205 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !");
2206 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2207 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !");
2208 if(c1->getHashCode()!=c2->getHashCode())
2209 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs");
2213 void MEDCoupling1DGTUMesh::checkCoherencyOfConnectivity() const
2215 const DataArrayInt *c1(_conn);
2218 if(c1->getNumberOfComponents()!=1)
2219 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
2220 if(c1->getInfoOnComponent(0)!="")
2221 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
2222 c1->checkAllocated();
2225 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
2227 int sz2=_conn->getNumberOfTuples();
2231 if(c1->getNumberOfComponents()!=1)
2232 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
2233 c1->checkAllocated();
2234 if(c1->getNumberOfTuples()<1)
2235 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !");
2236 if(c1->getInfoOnComponent(0)!="")
2237 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
2238 int f=c1->front(),ll=c1->back();
2241 std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !";
2242 throw INTERP_KERNEL::Exception(oss.str().c_str());
2246 std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !";
2247 throw INTERP_KERNEL::Exception(oss.str().c_str());
2251 std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !";
2252 throw INTERP_KERNEL::Exception(oss.str().c_str());
2256 throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !");
2257 int szOfC1Exp=_conn_indx->back();
2260 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() << " !";
2261 throw INTERP_KERNEL::Exception(oss.str().c_str());
2266 * 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.
2267 * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one.
2268 * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array.
2270 void MEDCoupling1DGTUMesh::checkCoherency() const
2272 MEDCouplingPointSet::checkCoherency();
2273 checkCoherencyOfConnectivity();
2276 void MEDCoupling1DGTUMesh::checkCoherency1(double eps) const
2279 const DataArrayInt *c1(_conn),*c2(_conn_indx);
2280 if(!c2->isMonotonic(true))
2281 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkCoherency1 : the nodal connectivity index is expected to be increasing monotinic !");
2283 int nbOfTuples=c1->getNumberOfTuples();
2284 int nbOfNodes=getNumberOfNodes();
2285 const int *w(c1->begin());
2286 for(int i=0;i<nbOfTuples;i++,w++)
2288 if(*w==-1) continue;
2289 if(*w<0 || *w>=nbOfNodes)
2291 std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !";
2292 throw INTERP_KERNEL::Exception(oss.str().c_str());
2297 void MEDCoupling1DGTUMesh::checkCoherency2(double eps) const
2299 checkCoherency1(eps);
2302 int MEDCoupling1DGTUMesh::getNumberOfCells() const
2304 checkCoherencyOfConnectivity();//do not remove
2305 return _conn_indx->getNumberOfTuples()-1;
2309 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2310 * For each cell in \b this the number of nodes constituting cell is computed.
2311 * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned.
2312 * So for pohyhedrons some nodes can be counted several times in the returned result.
2314 * \return a newly allocated array
2316 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const
2319 _conn_indx->checkMonotonic(true);
2320 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2321 return _conn_indx->deltaShiftIndex();
2323 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2324 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2325 ret->alloc(nbOfCells,1);
2326 int *retPtr=ret->getPointer();
2327 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2328 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2329 *retPtr=ci[1]-ci[0]-std::count(c+ci[0],c+ci[1],-1);
2334 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2335 * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed.
2337 * \return a newly allocated array
2339 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const
2342 _conn_indx->checkMonotonic(true);
2343 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG)
2344 return _conn_indx->deltaShiftIndex();
2345 if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG)
2347 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=_conn_indx->deltaShiftIndex();
2348 ret->applyDivideBy(2);
2352 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2353 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2354 ret->alloc(nbOfCells,1);
2355 int *retPtr=ret->getPointer();
2356 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2357 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2358 *retPtr=std::count(c+ci[0],c+ci[1],-1)+1;
2363 * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell,
2364 * will be counted only once here whereas it will be counted several times in MEDCoupling1DGTUMesh::computeNbOfNodesPerCell method.
2366 * \return DataArrayInt * - new object to be deallocated by the caller.
2367 * \sa MEDCoupling1DGTUMesh::computeNbOfNodesPerCell
2369 DataArrayInt *MEDCoupling1DGTUMesh::computeEffectiveNbOfNodesPerCell() const
2372 _conn_indx->checkMonotonic(true);
2373 int nbOfCells(_conn_indx->getNumberOfTuples()-1);
2374 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2375 ret->alloc(nbOfCells,1);
2376 int *retPtr(ret->getPointer());
2377 const int *ci(_conn_indx->begin()),*c(_conn->begin());
2378 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2380 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2382 std::set<int> s(c+ci[0],c+ci[1]);
2383 *retPtr=(int)s.size();
2388 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2390 std::set<int> s(c+ci[0],c+ci[1]); s.erase(-1);
2391 *retPtr=(int)s.size();
2397 void MEDCoupling1DGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
2399 int nbOfCells(getNumberOfCells());//performs checks
2400 if(cellId>=0 && cellId<nbOfCells)
2402 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2403 int nbOfNodes=stp-strt;
2405 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !");
2406 conn.resize(nbOfNodes);
2407 std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin());
2411 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2412 throw INTERP_KERNEL::Exception(oss.str().c_str());
2416 int MEDCoupling1DGTUMesh::getNumberOfNodesInCell(int cellId) const
2418 int nbOfCells(getNumberOfCells());//performs checks
2419 if(cellId>=0 && cellId<nbOfCells)
2421 const int *conn(_conn->begin());
2422 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2423 return stp-strt-std::count(conn+strt,conn+stp,-1);
2427 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNumberOfNodesInCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2428 throw INTERP_KERNEL::Exception(oss.str().c_str());
2432 std::string MEDCoupling1DGTUMesh::simpleRepr() const
2434 static const char msg0[]="No coordinates specified !";
2435 std::ostringstream ret;
2436 ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
2437 ret << "Description of mesh : \"" << getDescription() << "\"\n";
2439 double tt=getTime(tmpp1,tmpp2);
2440 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
2441 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
2442 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
2445 const int spaceDim=getSpaceDimension();
2446 ret << spaceDim << "\nInfo attached on space dimension : ";
2447 for(int i=0;i<spaceDim;i++)
2448 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
2452 ret << msg0 << "\n";
2453 ret << "Number of nodes : ";
2455 ret << getNumberOfNodes() << "\n";
2457 ret << msg0 << "\n";
2458 ret << "Number of cells : ";
2460 try { checkCoherency(); } catch(INTERP_KERNEL::Exception& /* e */)
2462 ret << "Nodal connectivity arrays are not set or badly set !\n";
2466 ret << getNumberOfCells() << "\n";
2467 ret << "Cell type : " << _cm->getRepr() << "\n";
2471 std::string MEDCoupling1DGTUMesh::advancedRepr() const
2473 std::ostringstream ret;
2474 ret << simpleRepr();
2475 ret << "\nCoordinates array : \n___________________\n\n";
2477 _coords->reprWithoutNameStream(ret);
2479 ret << "No array set !\n";
2480 ret << "\n\nNodal Connectivity : \n____________________\n\n";
2483 try { checkCoherency1(); } catch(INTERP_KERNEL::Exception& /* e */)
2485 ret << "Nodal connectivity arrays are not set or badly set !\n";
2490 int nbOfCells=getNumberOfCells();
2491 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2492 for(int i=0;i<nbOfCells;i++,ci++)
2494 ret << "Cell #" << i << " : ";
2495 std::copy(c+ci[0],c+ci[1],std::ostream_iterator<int>(ret," "));
2501 DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const
2503 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
2504 int spaceDim=getSpaceDimension();
2505 int nbOfCells=getNumberOfCells();//checkCoherency()
2506 int nbOfNodes=getNumberOfNodes();
2507 ret->alloc(nbOfCells,spaceDim);
2508 double *ptToFill=ret->getPointer();
2509 const double *coor=_coords->begin();
2510 const int *nodal=_conn->begin(),*nodali=_conn_indx->begin();
2512 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2514 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2516 std::fill(ptToFill,ptToFill+spaceDim,0.);
2517 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2519 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2521 if(*nodal>=0 && *nodal<nbOfNodes)
2522 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2525 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2526 throw INTERP_KERNEL::Exception(oss.str().c_str());
2528 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(nodali[1]-nodali[0])));
2533 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !";
2534 throw INTERP_KERNEL::Exception(oss.str().c_str());
2540 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2542 std::fill(ptToFill,ptToFill+spaceDim,0.);
2543 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2546 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2548 if(*nodal==-1) continue;
2549 if(*nodal>=0 && *nodal<nbOfNodes)
2551 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2556 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2557 throw INTERP_KERNEL::Exception(oss.str().c_str());
2561 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./nbOfNod));
2564 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !";
2565 throw INTERP_KERNEL::Exception(oss.str().c_str());
2570 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : at cell #" << i << " the nodal index array is invalid !";
2571 throw INTERP_KERNEL::Exception(oss.str().c_str());
2578 void MEDCoupling1DGTUMesh::renumberCells(const int *old2NewBg, bool check)
2580 int nbCells=getNumberOfCells();
2581 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
2582 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
2584 o2n=o2n->checkAndPreparePermutation();
2586 const int *o2nPtr=o2n->getPointer();
2587 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2588 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
2589 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
2590 newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1);
2591 newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx);
2593 int *newC=newConn->getPointer(),*newCI=newConnI->getPointer();
2594 for(int i=0;i<nbCells;i++)
2596 int newPos=o2nPtr[i];
2597 int sz=conni[i+1]-conni[i];
2602 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !";
2603 throw INTERP_KERNEL::Exception(oss.str().c_str());
2606 newConnI->computeOffsets2(); newCI=newConnI->getPointer();
2608 for(int i=0;i<nbCells;i++,conni++)
2611 std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]);
2614 _conn_indx=newConnI;
2617 MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
2619 if(other->getType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED)
2620 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !");
2621 const MEDCoupling1DGTUMesh *otherC=static_cast<const MEDCoupling1DGTUMesh *>(other);
2622 return Merge1DGTUMeshes(this,otherC);
2625 MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const
2627 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
2628 ret->setCoords(getCoords());
2629 const int *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin();
2630 int nbCells=getNumberOfCells();//checkCoherency
2631 int geoType=(int)getCellModelEnum();
2632 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1);
2633 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::New(); cI->alloc(nbCells+1);
2634 int *cPtr=c->getPointer(),*ciPtr=cI->getPointer();
2636 for(int i=0;i<nbCells;i++,ciPtr++)
2638 int sz=nodalConnI[i+1]-nodalConnI[i];
2642 cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr);
2643 ciPtr[1]=ciPtr[0]+sz+1;
2647 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !";
2648 throw INTERP_KERNEL::Exception(oss.str().c_str());
2651 ret->setConnectivity(c,cI,true);
2656 * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes
2658 DataArrayInt *MEDCoupling1DGTUMesh::simplexize(int policy)
2660 int nbOfCells=getNumberOfCells();
2661 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2662 ret->alloc(nbOfCells,1);
2667 void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const
2669 stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
2670 stream << " Mesh dimension : " << getMeshDimension() << ".";
2672 { stream << " No coordinates set !"; return ; }
2673 if(!_coords->isAllocated())
2674 { stream << " Coordinates set but not allocated !"; return ; }
2675 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
2676 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
2678 try { checkCoherency(); } catch(INTERP_KERNEL::Exception& /* e */)
2680 stream << std::endl << "Nodal connectivity NOT set properly !\n";
2684 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
2687 void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
2690 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
2691 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2693 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !");
2694 setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex());
2697 MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
2700 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
2701 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2703 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
2704 std::vector<const MEDCoupling1DGTUMesh *> ms(2);
2707 return Merge1DGTUMeshesOnSameCoords(ms);
2710 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
2713 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2714 ret->setCoords(_coords);
2715 DataArrayInt *c=0,*ci=0;
2716 MEDCouplingUMesh::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci);
2717 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2718 ret->setNodalConnectivity(c,ci);
2722 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
2725 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2726 ret->setCoords(_coords);
2727 DataArrayInt *c=0,*ci=0;
2728 MEDCouplingUMesh::ExtractFromIndexedArrays2(start,end,step,_conn,_conn_indx,c,ci);
2729 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2730 ret->setNodalConnectivity(c,ci);
2734 void MEDCoupling1DGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
2736 int sz((int)nodeIdsInUse.size());
2737 int nbCells(getNumberOfCells());
2738 const int *w(_conn->begin()),*wi(_conn_indx->begin());
2739 for(int i=0;i<nbCells;i++,wi++)
2740 for(const int *pt=w+wi[0];pt!=w+wi[1];pt++)
2743 if(*pt>=0 && *pt<sz)
2744 nodeIdsInUse[*pt]=true;
2747 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeNodeIdsAlg : At cell #" << i << " presence of node id #" << *pt << " should be in [0," << sz << ") !";
2748 throw INTERP_KERNEL::Exception(oss.str().c_str());
2753 void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const
2755 checkFullyDefined();
2756 int nbOfNodes=getNumberOfNodes();
2757 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
2758 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
2759 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
2760 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2761 int nbOfCells=getNumberOfCells();
2762 int nbOfEltsInRevNodal=0;
2763 for(int eltId=0;eltId<nbOfCells;eltId++)
2765 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2766 if(nbOfNodesPerCell>=0)
2768 for(int j=0;j<nbOfNodesPerCell;j++)
2770 int nodeId=conn[conni[eltId]+j];
2771 if(nodeId==-1) continue;
2772 if(nodeId>=0 && nodeId<nbOfNodes)
2774 nbOfEltsInRevNodal++;
2775 revNodalIndxPtr[nodeId+1]++;
2779 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
2780 throw INTERP_KERNEL::Exception(oss.str().c_str());
2786 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << "nodal connectivity is invalid !";
2787 throw INTERP_KERNEL::Exception(oss.str().c_str());
2790 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
2791 conn=_conn->begin();
2792 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
2793 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
2794 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
2795 for(int eltId=0;eltId<nbOfCells;eltId++)
2797 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2798 for(int j=0;j<nbOfNodesPerCell;j++)
2800 int nodeId=conn[conni[eltId]+j];
2802 *std::find_if(revNodalPtr+revNodalIndxPtr[nodeId],revNodalPtr+revNodalIndxPtr[nodeId+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
2807 void MEDCoupling1DGTUMesh::checkFullyDefined() const
2809 if(!((const DataArrayInt *)_conn) || !((const DataArrayInt *)_conn_indx) || !((const DataArrayDouble *)_coords))
2810 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined.");
2813 bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
2815 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !");
2818 void MEDCoupling1DGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
2821 double time=getTime(it,order);
2822 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
2824 littleStrings.push_back(getName());
2825 littleStrings.push_back(getDescription());
2826 littleStrings.push_back(getTimeUnit());
2828 std::vector<std::string> littleStrings2,littleStrings3,littleStrings4;
2829 if((const DataArrayDouble *)_coords)
2830 _coords->getTinySerializationStrInformation(littleStrings2);
2831 if((const DataArrayInt *)_conn)
2832 _conn->getTinySerializationStrInformation(littleStrings3);
2833 if((const DataArrayInt *)_conn_indx)
2834 _conn_indx->getTinySerializationStrInformation(littleStrings4);
2835 int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size()),sz2((int)littleStrings4.size());
2836 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
2837 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
2838 littleStrings.insert(littleStrings.end(),littleStrings4.begin(),littleStrings4.end());
2840 tinyInfo.push_back(getCellModelEnum());
2841 tinyInfo.push_back(it);
2842 tinyInfo.push_back(order);
2843 std::vector<int> tinyInfo2,tinyInfo3,tinyInfo4;
2844 if((const DataArrayDouble *)_coords)
2845 _coords->getTinySerializationIntInformation(tinyInfo2);
2846 if((const DataArrayInt *)_conn)
2847 _conn->getTinySerializationIntInformation(tinyInfo3);
2848 if((const DataArrayInt *)_conn_indx)
2849 _conn_indx->getTinySerializationIntInformation(tinyInfo4);
2850 int sz3((int)tinyInfo2.size()),sz4((int)tinyInfo3.size()),sz5((int)tinyInfo4.size());
2851 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3); tinyInfo.push_back(sz4); tinyInfo.push_back(sz5);
2852 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
2853 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
2854 tinyInfo.insert(tinyInfo.end(),tinyInfo4.begin(),tinyInfo4.end());
2856 tinyInfoD.push_back(time);
2859 void MEDCoupling1DGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
2861 std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+tinyInfo[6]);
2862 std::vector<int> tinyInfo1(tinyInfo.begin()+9+tinyInfo[6],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]);
2863 std::vector<int> tinyInfo12(tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]+tinyInfo[8]);
2864 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(DataArrayInt::New()); p1->resizeForUnserialization(tinyInfo1);
2865 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(DataArrayInt::New()); p2->resizeForUnserialization(tinyInfo12);
2866 std::vector<const DataArrayInt *> v(2); v[0]=p1; v[1]=p2;
2867 p2=DataArrayInt::Aggregate(v);
2868 a2->resizeForUnserialization(tinyInfo2);
2869 a1->alloc(p2->getNbOfElems(),1);
2872 void MEDCoupling1DGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
2875 if((const DataArrayInt *)_conn)
2876 if(_conn->isAllocated())
2877 sz=_conn->getNbOfElems();
2878 if((const DataArrayInt *)_conn_indx)
2879 if(_conn_indx->isAllocated())
2880 sz+=_conn_indx->getNbOfElems();
2881 a1=DataArrayInt::New();
2883 int *work(a1->getPointer());
2884 if(sz!=0 && (const DataArrayInt *)_conn)
2885 work=std::copy(_conn->begin(),_conn->end(),a1->getPointer());
2886 if(sz!=0 && (const DataArrayInt *)_conn_indx)
2887 std::copy(_conn_indx->begin(),_conn_indx->end(),work);
2889 if((const DataArrayDouble *)_coords)
2890 if(_coords->isAllocated())
2891 sz=_coords->getNbOfElems();
2892 a2=DataArrayDouble::New();
2894 if(sz!=0 && (const DataArrayDouble *)_coords)
2895 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
2898 void MEDCoupling1DGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
2899 const std::vector<std::string>& littleStrings)
2901 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
2902 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
2903 setName(littleStrings[0]);
2904 setDescription(littleStrings[1]);
2905 setTimeUnit(littleStrings[2]);
2906 setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
2907 int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]),sz4(tinyInfo[7]),sz5(tinyInfo[8]);
2909 _coords=DataArrayDouble::New();
2910 std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+sz3);
2911 _coords->resizeForUnserialization(tinyInfo2);
2912 std::copy(a2->begin(),a2->end(),_coords->getPointer());
2913 _conn=DataArrayInt::New();
2914 std::vector<int> tinyInfo3(tinyInfo.begin()+9+sz3,tinyInfo.begin()+9+sz3+sz4);
2915 _conn->resizeForUnserialization(tinyInfo3);
2916 std::copy(a1->begin(),a1->begin()+_conn->getNbOfElems(),_conn->getPointer());
2917 _conn_indx=DataArrayInt::New();
2918 std::vector<int> tinyInfo4(tinyInfo.begin()+9+sz3+sz4,tinyInfo.begin()+9+sz3+sz4+sz5);
2919 _conn_indx->resizeForUnserialization(tinyInfo4);
2920 std::copy(a1->begin()+_conn->getNbOfElems(),a1->end(),_conn_indx->getPointer());
2921 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
2922 _coords->finishUnserialization(tinyInfo2,littleStrings2);
2923 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
2924 _conn->finishUnserialization(tinyInfo3,littleStrings3);
2925 std::vector<std::string> littleStrings4(littleStrings.begin()+3+sz0+sz1,littleStrings.begin()+3+sz0+sz1+sz2);
2926 _conn_indx->finishUnserialization(tinyInfo4,littleStrings4);
2930 * Finds nodes not used in any cell and returns an array giving a new id to every node
2931 * by excluding the unused nodes, for which the array holds -1. The result array is
2932 * a mapping in "Old to New" mode.
2933 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
2934 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
2935 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
2936 * if the node is unused or a new id else. The caller is to delete this
2937 * array using decrRef() as it is no more needed.
2938 * \throw If the coordinates array is not set.
2939 * \throw If the nodal connectivity of cells is not defined.
2940 * \throw If the nodal connectivity includes an invalid id.
2942 DataArrayInt *MEDCoupling1DGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
2945 int nbOfNodes=getNumberOfNodes();
2946 int nbOfCells=getNumberOfCells();//checkCoherency
2947 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2948 ret->alloc(nbOfNodes,1);
2949 int *traducer=ret->getPointer();
2950 std::fill(traducer,traducer+nbOfNodes,-1);
2951 const int *conn=_conn->begin(),*conni(_conn_indx->begin());
2952 for(int i=0;i<nbOfCells;i++,conni++)
2954 int nbNodesPerCell=conni[1]-conni[0];
2955 for(int j=0;j<nbNodesPerCell;j++)
2957 int nodeId=conn[conni[0]+j];
2958 if(nodeId==-1) continue;
2959 if(nodeId>=0 && nodeId<nbOfNodes)
2963 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << nodeId << " not in [0," << nbOfNodes << ") !";
2964 throw INTERP_KERNEL::Exception(oss.str().c_str());
2968 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
2969 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
2974 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
2975 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
2976 * This method is a generalization of shiftNodeNumbersInConn().
2977 * \warning This method performs no check of validity of new ids. **Use it with care !**
2978 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
2979 * this->getNumberOfNodes(), in "Old to New" mode.
2980 * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
2981 * \throw If the nodal connectivity of cells is not defined.
2983 void MEDCoupling1DGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
2985 getNumberOfCells();//only to check that all is well defined.
2987 int nbElemsIn=getNumberOfNodes();
2988 int nbOfTuples=_conn->getNumberOfTuples();
2989 int *pt=_conn->getPointer();
2990 for(int i=0;i<nbOfTuples;i++,pt++)
2992 if(*pt==-1) continue;
2993 if(*pt>=0 && *pt<nbElemsIn)
2994 *pt=newNodeNumbersO2N[*pt];
2997 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
2998 throw INTERP_KERNEL::Exception(oss.str().c_str());
3001 _conn->declareAsNew();
3007 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
3008 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
3009 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
3010 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
3012 * \param [in] begin input start of array of node ids.
3013 * \param [in] end input end of array of node ids.
3014 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
3015 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
3017 void MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
3019 int nbOfCells=getNumberOfCells();
3020 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
3022 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
3023 std::vector<bool> fastFinder(sz,false);
3024 for(const int *work=begin;work!=end;work++)
3025 if(*work>=0 && *work<sz)
3026 fastFinder[*work]=true;
3027 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
3028 for(int i=0;i<nbOfCells;i++,conni++)
3030 int ref=0,nbOfHit=0;
3031 int nbNodesPerCell=conni[1]-conni[0];
3032 if(nbNodesPerCell>=0)
3034 for(int j=0;j<nbNodesPerCell;j++)
3036 int nodeId=conn[conni[0]+j];
3040 if(fastFinder[nodeId])
3047 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !";
3048 throw INTERP_KERNEL::Exception(oss.str().c_str());
3050 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
3051 cellIdsKept->pushBackSilent(i);
3053 cellIdsKeptArr=cellIdsKept.retn();
3056 void MEDCoupling1DGTUMesh::allocateCells(int nbOfCells)
3059 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !");
3060 _conn=DataArrayInt::New();
3061 _conn->reserve(nbOfCells*3);
3062 _conn_indx=DataArrayInt::New();
3063 _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0);
3068 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
3070 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
3071 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
3072 * \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
3073 * attached to \a this.
3074 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
3076 void MEDCoupling1DGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd)
3078 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
3079 DataArrayInt *c(_conn),*c2(_conn_indx);
3083 if(pos==c->getNumberOfTuples())
3085 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
3086 c2->pushBackSilent(pos+sz);
3090 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !";
3091 throw INTERP_KERNEL::Exception(oss.str().c_str());
3095 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !");
3098 void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex)
3101 nodalConn->incrRef();
3104 nodalConnIndex->incrRef();
3105 _conn_indx=nodalConnIndex;
3110 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
3112 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivity() const
3114 const DataArrayInt *ret(_conn);
3115 return const_cast<DataArrayInt *>(ret);
3119 * \return DataArrayInt * - the internal reference to the nodal connectivity index. The caller is not reponsible to deallocate it.
3121 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const
3123 const DataArrayInt *ret(_conn_indx);
3124 return const_cast<DataArrayInt *>(ret);
3128 * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here".
3129 * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity).
3130 * 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.
3132 * 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.
3134 * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal
3135 * connectivity arrays are different (false)
3136 * \return a new object to be managed by the caller.
3138 * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked
3140 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const
3142 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3143 DataArrayInt *nc=0,*nci=0;
3144 isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci);
3145 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ncs(nc),ncis(nci);
3146 ret->_conn=ncs; ret->_conn_indx=ncis;
3147 ret->setCoords(getCoords());
3152 * This method allows to compute, if needed, the packed nodal connectivity pair.
3153 * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges convered by nodal connectivity index array.
3154 * 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.
3156 * 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)
3157 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3159 * 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
3162 * This method return 3 elements.
3163 * \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
3164 * this pointer can be seen as a new object, that is to managed by the caller.
3165 * \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
3166 * this pointer can be seen as a new object, that is to managed by the caller.
3167 * \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
3168 * output parameters are newly created objects.
3170 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
3172 bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const
3174 if(isPacked())//performs the checkCoherency
3176 const DataArrayInt *c0(_conn),*c1(_conn_indx);
3177 nodalConn=const_cast<DataArrayInt *>(c0); nodalConnIndx=const_cast<DataArrayInt *>(c1);
3178 nodalConn->incrRef(); nodalConnIndx->incrRef();
3181 int bg=_conn_indx->front(),end=_conn_indx->back();
3182 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nc(_conn->selectByTupleId2(bg,end,1));
3183 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nci(_conn_indx->deepCpy());
3184 nci->applyLin(1,-bg);
3185 nodalConn=nc.retn(); nodalConnIndx=nci.retn();
3190 * 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)
3191 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3192 * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned.
3193 * \return bool - true if \a this looks packed, false is not.
3195 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
3197 bool MEDCoupling1DGTUMesh::isPacked() const
3200 return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples();
3203 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2)
3205 std::vector<const MEDCoupling1DGTUMesh *> tmp(2);
3206 tmp[0]=const_cast<MEDCoupling1DGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1DGTUMesh *>(mesh2);
3207 return Merge1DGTUMeshes(tmp);
3210 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a)
3212 std::size_t sz=a.size();
3214 return Merge1DGTUMeshesLL(a);
3215 for(std::size_t ii=0;ii<sz;ii++)
3218 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::Merge1DGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
3219 throw INTERP_KERNEL::Exception(oss.str().c_str());
3221 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
3222 for(std::size_t ii=0;ii<sz;ii++)
3223 if(&(a[ii]->getCellModel())!=cm)
3224 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !");
3225 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > bb(sz);
3226 std::vector< const MEDCoupling1DGTUMesh * > aa(sz);
3228 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
3230 const MEDCoupling1DGTUMesh *cur=a[i];
3231 const DataArrayDouble *coo=cur->getCoords();
3233 spaceDim=coo->getNumberOfComponents();
3236 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !");
3237 for(std::size_t i=0;i<sz;i++)
3239 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
3242 return Merge1DGTUMeshesLL(aa);
3246 * \throw If presence of a null instance in the input vector \a a.
3247 * \throw If a is empty
3249 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a)
3252 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !");
3253 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3255 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !");
3256 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
3257 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3258 (*it)->getNumberOfCells();//to check that all is OK
3259 const DataArrayDouble *coords=(*it)->getCoords();
3260 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3262 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3263 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3265 for(int i=1;it!=a.end();i++,it++)
3268 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !");
3269 if(cm!=&((*it)->getCellModel()))
3270 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3271 (*it)->getNumberOfCells();//to check that all is OK
3272 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3273 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3274 if(coords!=(*it)->getCoords())
3275 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !");
3277 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3278 ret->setCoords(coords);
3279 ret->_conn=DataArrayInt::Aggregate(ncs);
3280 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3285 * 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)
3287 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a)
3290 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : input array must be NON EMPTY !");
3291 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
3292 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3293 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3294 std::vector<int> nbNodesPerElt(a.size());
3295 int nbOfCells=(*it)->getNumberOfCells();
3297 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3298 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3300 int prevNbOfNodes=(*it)->getNumberOfNodes();
3301 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3303 for(int i=1;it!=a.end();i++,it++)
3305 if(cm!=&((*it)->getCellModel()))
3306 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3307 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3308 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3309 nbOfCells+=(*it)->getNumberOfCells();
3310 nbNodesPerElt[i]=nbNodesPerElt[i-1]+prevNbOfNodes;
3311 prevNbOfNodes=(*it)->getNumberOfNodes();
3313 std::vector<const MEDCouplingPointSet *> aps(a.size());
3314 std::copy(a.begin(),a.end(),aps.begin());
3315 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
3316 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3317 ret->setCoords(pts);
3318 ret->_conn=AggregateNodalConnAndShiftNodeIds(ncs,nbNodesPerElt);
3319 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3323 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(int spaceDim) const
3325 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3326 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1,tmp2;
3327 const DataArrayInt *nodalConn(_conn),*nodalConnI(_conn_indx);
3330 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
3338 tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
3342 ret->_conn_indx=tmp2;
3346 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
3347 ret->setCoords(coords);
3350 ret->setCoords(_coords);
3355 * This method aggregate the bbox of each cell and put it into bbox parameter.
3357 * \param [in] arcDetEps - a parameter specifying in case of 2D quadratic polygon cell the detection limit between linear and arc circle. (By default 1e-12)
3358 * For all other cases this input parameter is ignored.
3359 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
3361 * \throw If \a this is not fully set (coordinates and connectivity).
3362 * \throw If a cell in \a this has no valid nodeId.
3364 DataArrayDouble *MEDCoupling1DGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
3366 checkFullyDefined();
3367 int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes());
3368 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
3369 double *bbox(ret->getPointer());
3370 for(int i=0;i<nbOfCells*spaceDim;i++)
3372 bbox[2*i]=std::numeric_limits<double>::max();
3373 bbox[2*i+1]=-std::numeric_limits<double>::max();
3375 const double *coordsPtr(_coords->getConstPointer());
3376 const int *conn(_conn->getConstPointer()),*connI(_conn_indx->getConstPointer());
3377 for(int i=0;i<nbOfCells;i++)
3379 int offset=connI[i];
3380 int nbOfNodesForCell(connI[i+1]-offset),kk(0);
3381 for(int j=0;j<nbOfNodesForCell;j++)
3383 int nodeId=conn[offset+j];
3384 if(nodeId>=0 && nodeId<nbOfNodes)
3386 for(int k=0;k<spaceDim;k++)
3388 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
3389 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
3396 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
3397 throw INTERP_KERNEL::Exception(oss.str().c_str());
3403 std::vector<int> MEDCoupling1DGTUMesh::BuildAPolygonFromParts(const std::vector< std::vector<int> >& parts)
3405 std::vector<int> ret;
3408 ret.insert(ret.end(),parts[0].begin(),parts[0].end());
3409 int ref(ret.back());
3410 std::size_t sz(parts.size()),nbh(1);
3411 std::vector<bool> b(sz,true); b[0]=false;
3415 for(;i<sz;i++) if(b[i] && parts[i].front()==ref) { ret.insert(ret.end(),parts[i].begin()+1,parts[i].end()); nbh++; break; }
3419 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::BuildAPolygonFromParts : the input vector is not a part of a single polygon !");
3421 if(ret.back()==ret.front())
3427 * This method performs an aggregation of \a nodalConns (as DataArrayInt::Aggregate does) but in addition of that a shift is applied on the
3428 * values contained in \a nodalConns using corresponding offset specified in input \a offsetInNodeIdsPerElt.
3429 * But it also manage the values -1, that have a semantic in MEDCoupling1DGTUMesh class (separator for polyhedron).
3431 * \param [in] nodalConns - a list of nodal connectivity arrays same size than \a offsetInNodeIdsPerElt.
3432 * \param [in] offsetInNodeIdsPerElt - a list of offsets to apply.
3433 * \return DataArrayInt * - A new object (to be managed by the caller) that is the result of the aggregation.
3434 * \throw If \a nodalConns or \a offsetInNodeIdsPerElt are empty.
3435 * \throw If \a nodalConns and \a offsetInNodeIdsPerElt have not the same size.
3436 * \throw If presence of null pointer in \a nodalConns.
3437 * \throw If presence of not allocated or array with not exactly one component in \a nodalConns.
3439 DataArrayInt *MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds(const std::vector<const DataArrayInt *>& nodalConns, const std::vector<int>& offsetInNodeIdsPerElt)
3441 std::size_t sz1(nodalConns.size()),sz2(offsetInNodeIdsPerElt.size());
3443 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : input vectors do not have the same size !");
3445 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : empty vectors in input !");
3447 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++)
3450 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of null pointer in input vector !");
3451 if(!(*it)->isAllocated())
3452 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of non allocated array in input vector !");
3453 if((*it)->getNumberOfComponents()!=1)
3454 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of array with not exactly one component !");
3455 nbOfTuples+=(*it)->getNumberOfTuples();
3457 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
3458 int *pt=ret->getPointer();
3460 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++,i++)
3462 int curNbt=(*it)->getNumberOfTuples();
3463 const int *inPt=(*it)->begin();
3464 int offset=offsetInNodeIdsPerElt[i];
3465 for(int j=0;j<curNbt;j++,pt++)
3476 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m)
3479 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh is null !");
3480 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
3482 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh must have exactly one geometric type !");
3483 int geoType((int)*gts.begin());
3484 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(m->getName(),*gts.begin()));
3485 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription());
3486 int nbCells(m->getNumberOfCells());
3487 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
3488 conn->alloc(m->getMeshLength()-nbCells,1); connI->alloc(nbCells+1,1);
3489 int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
3490 const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
3491 for(int i=0;i<nbCells;i++,ciin++,ci++)
3493 if(cin[ciin[0]]==geoType)
3495 if(ciin[1]-ciin[0]>=1)
3497 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
3498 ci[1]=ci[0]+ciin[1]-ciin[0]-1;
3502 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 !";
3503 throw INTERP_KERNEL::Exception(oss.str().c_str());
3508 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 !";
3509 throw INTERP_KERNEL::Exception(oss.str().c_str());
3512 ret->setNodalConnectivity(conn,connI);