1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (CEA/DEN)
21 #include "MEDCoupling1GTUMesh.hxx"
22 #include "MEDCouplingUMesh.hxx"
23 #include "MEDCouplingFieldDouble.hxx"
25 #include "SplitterTetra.hxx"
27 using namespace ParaMEDMEM;
29 const int MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[6]={0,1,2,4,3,5};
31 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh()
35 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):_cm(&cm)
40 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const MEDCoupling1GTUMesh& other, bool recDeepCpy):MEDCouplingPointSet(other,recDeepCpy),_cm(other._cm)
44 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type)
46 if(type==INTERP_KERNEL::NORM_ERROR)
47 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
48 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
50 return MEDCoupling1SGTUMesh::New(name,type);
52 return MEDCoupling1DGTUMesh::New(name,type);
55 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const MEDCouplingUMesh *m)
58 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh is null !");
59 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
61 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh must have exactly one geometric type !");
62 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*gts.begin());
64 return MEDCoupling1SGTUMesh::New(m);
66 return MEDCoupling1DGTUMesh::New(m);
69 const INTERP_KERNEL::CellModel& MEDCoupling1GTUMesh::getCellModel() const
74 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getCellModelEnum() const
76 return _cm->getEnum();
79 int MEDCoupling1GTUMesh::getMeshDimension() const
81 return (int)_cm->getDimension();
85 * This method returns a newly allocated array containing cell ids (ascendingly sorted) whose geometric type are equal to type.
86 * This method does not throw exception if geometric type \a type is not in \a this.
87 * This method throws an INTERP_KERNEL::Exception if meshdimension of \b this is not equal to those of \b type.
88 * The coordinates array is not considered here.
90 * \param [in] type the geometric type
91 * \return cell ids in this having geometric type \a type.
93 DataArrayInt *MEDCoupling1GTUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
95 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
96 if(type==getCellModelEnum())
97 ret->alloc(getNumberOfCells(),1);
105 * Returns nb of cells having the geometric type \a type. No throw if no cells in \a this has the geometric type \a type.
107 int MEDCoupling1GTUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
109 return type==getCellModelEnum()?getNumberOfCells():0;
113 * Returns a type of a cell by its id.
114 * \param [in] cellId - the id of the cell of interest.
115 * \return INTERP_KERNEL::NormalizedCellType - enumeration item describing the cell type.
116 * \throw If \a cellId is invalid. Valid range is [0, \a this->getNumberOfCells() ).
118 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getTypeOfCell(int cellId) const
120 if(cellId>=0 && cellId<getNumberOfCells())
121 return getCellModelEnum();
122 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::getTypeOfCell : Requesting type of cell #" << cellId << " but it should be in [0," << getNumberOfCells() << ") !";
123 throw INTERP_KERNEL::Exception(oss.str().c_str());
127 * Returns a set of all cell types available in \a this mesh.
128 * \return std::set<INTERP_KERNEL::NormalizedCellType> - the set of cell types.
129 * \warning this method does not throw any exception even if \a this is not defined.
131 std::set<INTERP_KERNEL::NormalizedCellType> MEDCoupling1GTUMesh::getAllGeoTypes() const
133 std::set<INTERP_KERNEL::NormalizedCellType> ret;
134 ret.insert(getCellModelEnum());
139 * This method expects that \a this is sorted by types. If not an exception will be thrown.
140 * This method returns in the same format as code (see MEDCouplingUMesh::checkTypeConsistencyAndContig or MEDCouplingUMesh::splitProfilePerType) how
141 * \a this is composed in cell types.
142 * The returned array is of size 3*n where n is the number of different types present in \a this.
143 * For every k in [0,n] ret[3*k+2]==-1 because it has no sense here.
144 * This parameter is kept only for compatibility with other methode listed above.
146 std::vector<int> MEDCoupling1GTUMesh::getDistributionOfTypes() const
148 std::vector<int> ret(3);
149 ret[0]=(int)getCellModelEnum(); ret[1]=getNumberOfCells(); ret[2]=-1;
154 * This method is the opposite of MEDCouplingUMesh::checkTypeConsistencyAndContig method. Given a list of cells in \a profile it returns a list of sub-profiles sorted by geo type.
155 * The result is put in the array \a idsPerType. In the returned parameter \a code, foreach i \a code[3*i+2] refers (if different from -1) to a location into the \a idsPerType.
156 * This method has 1 input \a profile and 3 outputs \a code \a idsInPflPerType and \a idsPerType.
158 * \param [out] code is a vector of size 3*n where n is the number of different geometric type in \a this \b reduced to the profile \a profile. \a code has exactly the same semantic than in MEDCouplingUMesh::checkTypeConsistencyAndContig method.
159 * \param [out] idsInPflPerType is a vector of size of different geometric type in the subpart defined by \a profile of \a this ( equal to \a code.size()/3). For each i,
160 * \a idsInPflPerType[i] stores the tuple ids in \a profile that correspond to the geometric type code[3*i+0]
161 * \param [out] idsPerType is a vector of size of different sub profiles needed to be defined to represent the profile \a profile for a given geometric type.
162 * This vector can be empty in case of all geometric type cells are fully covered in ascending in the given input \a profile.
164 * \warning for performance reasons no deep copy will be performed, if \a profile can been used as this in output parameters \a idsInPflPerType and \a idsPerType.
166 * \throw if \a profile has not exactly one component. It throws too, if \a profile contains some values not in [0,getNumberOfCells()) or if \a this is not fully defined
169 * - Before \a this has 3 cells \a profile contains [0,1,2]
170 * - After \a code contains [NORM_...,nbCells,-1], \a idsInPflPerType [[0,1,2]] and \a idsPerType is empty <br>
173 * - Before \a this has 3 cells \a profile contains [1,2]
174 * - After \a code contains [NORM_...,nbCells,0], \a idsInPflPerType [[0,1]] and \a idsPerType is [[1,2]] <br>
177 void MEDCoupling1GTUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const
180 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile is NULL !");
181 if(profile->getNumberOfComponents()!=1)
182 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile should have exactly one component !");
183 int nbTuples=profile->getNumberOfTuples();
184 int nbOfCells=getNumberOfCells();
185 code.resize(3); idsInPflPerType.resize(1);
186 code[0]=(int)getCellModelEnum(); code[1]=nbTuples;
187 idsInPflPerType.resize(1);
188 if(profile->isIdentity() && nbTuples==nbOfCells)
191 idsInPflPerType[0]=const_cast<DataArrayInt *>(profile); idsInPflPerType[0]->incrRef();
196 profile->checkAllIdsInRange(0,nbOfCells);
197 idsPerType.resize(1);
198 idsPerType[0]=const_cast<DataArrayInt *>(profile); idsPerType[0]->incrRef();
199 idsInPflPerType[0]=DataArrayInt::Range(0,nbTuples,1);
203 * This method tries to minimize at most the number of deep copy.
204 * So if \a idsPerType is not empty it can be returned directly (without copy, but with ref count incremented) in return.
206 * \sa MEDCouplingUMesh::checkTypeConsistencyAndContig
208 DataArrayInt *MEDCoupling1GTUMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const
210 int nbOfCells=getNumberOfCells();
212 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : invalid input code should be exactly of size 3 !");
213 if(code[0]!=(int)getCellModelEnum())
215 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : Mismatch of geometric type ! Asking for " << code[0] << " whereas the geometric type is \a this is " << getCellModelEnum() << " (" << _cm->getRepr() << ") !";
216 throw INTERP_KERNEL::Exception(oss.str().c_str());
220 if(code[1]==nbOfCells)
224 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : mismatch between the number of cells in this (" << nbOfCells << ") and the number of non profile (" << code[1] << ") !";
225 throw INTERP_KERNEL::Exception(oss.str().c_str());
229 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : single geo type mesh ! 0 or -1 is expected at pos #2 of input code !");
230 if(idsPerType.size()!=1)
231 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input code points to DataArrayInt #0 whereas the size of idsPerType is not equal to 1 !");
232 const DataArrayInt *pfl=idsPerType[0];
234 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : the input code points to a NULL DataArrayInt at rank 0 !");
235 if(pfl->getNumberOfComponents()!=1)
236 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input profile should have exactly one component !");
237 pfl->checkAllIdsInRange(0,nbOfCells);
239 return const_cast<DataArrayInt *>(pfl);
242 void MEDCoupling1GTUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const
244 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
245 m->writeVTKLL(ofs,cellData,pointData,byteData);
248 std::string MEDCoupling1GTUMesh::getVTKDataSetType() const
250 return std::string("UnstructuredGrid");
253 std::size_t MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren() const
255 return MEDCouplingPointSet::getHeapMemorySizeWithoutChildren();
258 bool MEDCoupling1GTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
260 if(!MEDCouplingPointSet::isEqualIfNotWhy(other,prec,reason))
263 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualIfNotWhy : input other pointer is null !");
264 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
267 reason="mesh given in input is not castable in MEDCouplingSGTUMesh !";
272 reason="mismatch in geometric type !";
278 bool MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
280 if(!MEDCouplingPointSet::isEqualWithoutConsideringStr(other,prec))
283 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
284 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
292 void MEDCoupling1GTUMesh::checkCoherency() const
294 MEDCouplingPointSet::checkCoherency();
297 DataArrayDouble *MEDCoupling1GTUMesh::getBarycenterAndOwner() const
299 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
300 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=m->getBarycenterAndOwner();
304 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureField(bool isAbs) const
306 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
307 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureField(isAbs);
312 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureFieldOnNode(bool isAbs) const
314 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
315 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureFieldOnNode(isAbs);
323 int MEDCoupling1GTUMesh::getCellContainingPoint(const double *pos, double eps) const
325 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
326 return m->getCellContainingPoint(pos,eps);
329 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::buildOrthogonalField() const
331 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
332 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->buildOrthogonalField();
337 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const double *bbox, double eps) const
339 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
340 return m->getCellsInBoundingBox(bbox,eps);
343 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps)
345 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
346 return m->getCellsInBoundingBox(bbox,eps);
349 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const
351 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
352 return m->buildFacePartOfMySelfNode(start,end,fullyIn);
355 DataArrayInt *MEDCoupling1GTUMesh::findBoundaryNodes() const
357 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
358 return m->findBoundaryNodes();
361 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildBoundaryMesh(bool keepCoords) const
363 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
364 return m->buildBoundaryMesh(keepCoords);
367 void MEDCoupling1GTUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const
369 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
370 m->findCommonCells(compType,startCellId,commonCellsArr,commonCellsIArr);
373 int MEDCoupling1GTUMesh::getNodalConnectivityLength() const
375 const DataArrayInt *c1(getNodalConnectivity());
377 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : no connectivity set !");
378 if(c1->getNumberOfComponents()!=1)
379 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array set must have exactly one component !");
380 if(!c1->isAllocated())
381 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array must be allocated !");
382 return c1->getNumberOfTuples();
386 * This method aggregates all the meshes in \a parts to put them in a single unstructured mesh (those returned).
387 * The order of cells is the returned instance is those in the order of instances in \a parts.
389 * \param [in] parts - all not null parts of single geo type meshes to be aggreagated having the same mesh dimension and same coordinates.
390 * \return MEDCouplingUMesh * - new object to be dealt by the caller.
392 * \throw If one element is null in \a parts.
393 * \throw If not all the parts do not have the same mesh dimension.
394 * \throw If not all the parts do not share the same coordinates.
395 * \throw If not all the parts have their connectivity set properly.
396 * \throw If \a parts is empty.
398 MEDCouplingUMesh *MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh(const std::vector< const MEDCoupling1GTUMesh *>& parts)
401 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : input parts vector is empty !");
402 const MEDCoupling1GTUMesh *firstPart(parts[0]);
404 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : the first instance in input parts is null !");
405 const DataArrayDouble *coords(firstPart->getCoords());
406 int meshDim(firstPart->getMeshDimension());
407 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret(MEDCouplingUMesh::New(firstPart->getName().c_str(),meshDim)); ret->setDescription(firstPart->getDescription().c_str());
408 ret->setCoords(coords);
409 int nbOfCells(0),connSize(0);
410 for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
413 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of null pointer in input vector !");
414 if((*it)->getMeshDimension()!=meshDim)
415 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances in input vector must have same mesh dimension !");
416 if((*it)->getCoords()!=coords)
417 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances must share the same coordinates pointer !");
418 nbOfCells+=(*it)->getNumberOfCells();
419 connSize+=(*it)->getNodalConnectivityLength();
421 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
422 connI->alloc(nbOfCells+1,1); conn->alloc(connSize+nbOfCells,1);
423 int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
424 for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
426 int curNbCells((*it)->getNumberOfCells());
427 int geoType((int)(*it)->getCellModelEnum());
428 const int *cinPtr((*it)->getNodalConnectivity()->begin());
429 const MEDCoupling1SGTUMesh *ps(dynamic_cast<const MEDCoupling1SGTUMesh *>(*it));
430 const MEDCoupling1DGTUMesh *pd(dynamic_cast<const MEDCoupling1DGTUMesh *>(*it));
433 int nNodesPerCell(ps->getNumberOfNodesPerCell());
434 for(int i=0;i<curNbCells;i++,ci++,cinPtr+=nNodesPerCell)
437 c=std::copy(cinPtr,cinPtr+nNodesPerCell,c);
438 ci[1]=ci[0]+nNodesPerCell+1;
443 const int *ciinPtr(pd->getNodalConnectivityIndex()->begin());
444 for(int i=0;i<curNbCells;i++,ci++,ciinPtr++)
447 c=std::copy(cinPtr+ciinPtr[0],cinPtr+ciinPtr[1],c);
448 ci[1]=ci[0]+ciinPtr[1]-ciinPtr[0]+1;
452 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of instance which type is not in [MEDCoupling1SGTUMesh,MEDCoupling1DGTUMesh] !");
454 ret->setConnectivity(conn,connI,true);
460 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const MEDCoupling1SGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
464 const DataArrayInt *c(other._conn);
470 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
474 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh()
478 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New()
480 return new MEDCoupling1SGTUMesh;
483 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type)
485 if(type==INTERP_KERNEL::NORM_ERROR)
486 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
487 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
490 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New : the input geometric type " << cm.getRepr() << " is dynamic ! Only static types are allowed here !";
491 throw INTERP_KERNEL::Exception(oss.str().c_str());
493 return new MEDCoupling1SGTUMesh(name,cm);
496 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m)
499 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh is null !");
500 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
502 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh must have exactly one geometric type !");
503 int geoType((int)*gts.begin());
504 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(m->getName().c_str(),*gts.begin()));
505 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription().c_str());
506 int nbCells(m->getNumberOfCells());
507 int nbOfNodesPerCell(ret->getNumberOfNodesPerCell());
508 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()); conn->alloc(nbCells*nbOfNodesPerCell,1);
509 int *c(conn->getPointer());
510 const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
511 for(int i=0;i<nbCells;i++,ciin++)
513 if(cin[ciin[0]]==geoType)
515 if(ciin[1]-ciin[0]==nbOfNodesPerCell+1)
516 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
519 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m) : something is wrong in the input mesh at cell #" << i << " ! The size of cell is not those expected (" << nbOfNodesPerCell << ") !";
520 throw INTERP_KERNEL::Exception(oss.str().c_str());
525 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m) : something is wrong in the input mesh at cell #" << i << " ! The geometric type is not those expected !";
526 throw INTERP_KERNEL::Exception(oss.str().c_str());
529 ret->setNodalConnectivity(conn);
533 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::clone(bool recDeepCpy) const
535 return new MEDCoupling1SGTUMesh(*this,recDeepCpy);
539 * This method behaves mostly like MEDCoupling1SGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
540 * The coordinates are shared between \a this and the returned instance.
542 * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
543 * \sa MEDCoupling1SGTUMesh::deepCpy
545 MEDCouplingPointSet *MEDCoupling1SGTUMesh::deepCpyConnectivityOnly() const
548 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(clone(false));
549 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy());
550 ret->setNodalConnectivity(c);
554 void MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
557 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
558 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
560 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1SGTUMesh instance !");
561 setNodalConnectivity(otherC->getNodalConnectivity());
564 void MEDCoupling1SGTUMesh::updateTime() const
566 MEDCoupling1GTUMesh::updateTime();
567 const DataArrayInt *c(_conn);
572 std::size_t MEDCoupling1SGTUMesh::getHeapMemorySizeWithoutChildren() const
574 return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren();
577 std::vector<const BigMemoryObject *> MEDCoupling1SGTUMesh::getDirectChildren() const
579 std::vector<const BigMemoryObject *> ret(MEDCoupling1GTUMesh::getDirectChildren());
580 const DataArrayInt *c(_conn);
586 MEDCouplingMesh *MEDCoupling1SGTUMesh::deepCpy() const
591 bool MEDCoupling1SGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
594 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualIfNotWhy : input other pointer is null !");
595 std::ostringstream oss; oss.precision(15);
596 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
599 reason="mesh given in input is not castable in MEDCoupling1SGTUMesh !";
602 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
604 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
609 reason="in connectivity of single static geometric type exactly one among this and other is null !";
612 if(!c1->isEqualIfNotWhy(*c2,reason))
614 reason.insert(0,"Nodal connectivity DataArrayInt differ : ");
620 bool MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
623 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
624 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
627 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
629 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
634 if(!c1->isEqualWithoutConsideringStr(*c2))
639 void MEDCoupling1SGTUMesh::checkCoherencyOfConnectivity() const
641 const DataArrayInt *c1(_conn);
644 if(c1->getNumberOfComponents()!=1)
645 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
646 if(c1->getInfoOnComponent(0)!="")
647 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
648 c1->checkAllocated();
651 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
654 void MEDCoupling1SGTUMesh::checkCoherency() const
656 MEDCouplingPointSet::checkCoherency();
657 checkCoherencyOfConnectivity();
660 void MEDCoupling1SGTUMesh::checkCoherency1(double eps) const
663 const DataArrayInt *c1(_conn);
664 int nbOfTuples=c1->getNumberOfTuples();
665 int nbOfNodesPerCell=(int)_cm->getNumberOfNodes();
666 if(nbOfTuples%nbOfNodesPerCell!=0)
668 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::checkCoherency1 : the nb of tuples in conn is " << nbOfTuples << " and number of nodes per cell is " << nbOfNodesPerCell << ". But " << nbOfTuples << "%" << nbOfNodesPerCell << " !=0 !";
669 throw INTERP_KERNEL::Exception(oss.str().c_str());
671 int nbOfNodes=getNumberOfNodes();
672 int nbOfCells=nbOfTuples/nbOfNodesPerCell;
673 const int *w(c1->begin());
674 for(int i=0;i<nbOfCells;i++)
675 for(int j=0;j<nbOfNodesPerCell;j++,w++)
677 if(*w<0 || *w>=nbOfNodes)
679 std::ostringstream oss; oss << "At node #" << j << " of cell #" << i << ", is equal to " << *w << " must be in [0," << nbOfNodes << ") !";
680 throw INTERP_KERNEL::Exception(oss.str().c_str());
685 void MEDCoupling1SGTUMesh::checkCoherency2(double eps) const
687 checkCoherency1(eps);
690 int MEDCoupling1SGTUMesh::getNumberOfCells() const
692 int nbOfTuples=getNodalConnectivityLength();
693 int nbOfNodesPerCell=getNumberOfNodesPerCell();
694 if(nbOfTuples%nbOfNodesPerCell!=0)
696 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh:getNumberOfCells: : the nb of tuples in conn is " << nbOfTuples << " and number of nodes per cell is " << nbOfNodesPerCell << ". But " << nbOfTuples << "%" << nbOfNodesPerCell << " !=0 !";
697 throw INTERP_KERNEL::Exception(oss.str().c_str());
699 return nbOfTuples/nbOfNodesPerCell;
702 int MEDCoupling1SGTUMesh::getNumberOfNodesInCell(int cellId) const
704 return getNumberOfNodesPerCell();
707 int MEDCoupling1SGTUMesh::getNumberOfNodesPerCell() const
709 checkNonDynamicGeoType();
710 return (int)_cm->getNumberOfNodes();
713 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfNodesPerCell() const
715 checkNonDynamicGeoType();
716 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
717 ret->alloc(getNumberOfCells(),1);
718 ret->fillWithValue((int)_cm->getNumberOfNodes());
722 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfFacesPerCell() const
724 checkNonDynamicGeoType();
725 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
726 ret->alloc(getNumberOfCells(),1);
727 ret->fillWithValue((int)_cm->getNumberOfSons());
731 DataArrayInt *MEDCoupling1SGTUMesh::computeEffectiveNbOfNodesPerCell() const
733 checkNonDynamicGeoType();
734 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
735 int nbCells(getNumberOfCells());
736 ret->alloc(nbCells,1);
737 int *retPtr(ret->getPointer());
738 int nbNodesPerCell(getNumberOfNodesPerCell());
739 const int *conn(_conn->begin());
740 for(int i=0;i<nbCells;i++,conn+=nbNodesPerCell,retPtr++)
742 std::set<int> s(conn,conn+nbNodesPerCell);
743 *retPtr=(int)s.size();
748 void MEDCoupling1SGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
750 int sz=getNumberOfNodesPerCell();
752 if(cellId>=0 && cellId<getNumberOfCells())
753 std::copy(_conn->begin()+cellId*sz,_conn->begin()+(cellId+1)*sz,conn.begin());
756 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << getNumberOfCells() << ") !";
757 throw INTERP_KERNEL::Exception(oss.str().c_str());
761 void MEDCoupling1SGTUMesh::checkNonDynamicGeoType() const
764 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkNonDynamicGeoType : internal error ! the internal geo type is dynamic ! should be static !");
767 std::string MEDCoupling1SGTUMesh::simpleRepr() const
769 static const char msg0[]="No coordinates specified !";
770 std::ostringstream ret;
771 ret << "Single static geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
772 ret << "Description of mesh : \"" << getDescription() << "\"\n";
774 double tt=getTime(tmpp1,tmpp2);
775 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
776 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
777 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
780 const int spaceDim=getSpaceDimension();
781 ret << spaceDim << "\nInfo attached on space dimension : ";
782 for(int i=0;i<spaceDim;i++)
783 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
788 ret << "Number of nodes : ";
790 ret << getNumberOfNodes() << "\n";
793 ret << "Number of cells : ";
794 if((const DataArrayInt *)_conn)
796 if(_conn->isAllocated())
798 if(_conn->getNumberOfComponents()==1)
799 ret << getNumberOfCells() << "\n";
801 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
804 ret << "Nodal connectivity array specified but not allocated !" << "\n";
807 ret << "No connectivity specified !" << "\n";
808 ret << "Cell type : " << _cm->getRepr() << "\n";
812 std::string MEDCoupling1SGTUMesh::advancedRepr() const
814 std::ostringstream ret;
816 ret << "\nCoordinates array : \n___________________\n\n";
818 _coords->reprWithoutNameStream(ret);
820 ret << "No array set !\n";
821 ret << "\n\nConnectivity array : \n____________________\n\n";
823 if((const DataArrayInt *)_conn)
825 if(_conn->isAllocated())
827 if(_conn->getNumberOfComponents()==1)
829 int nbOfCells=getNumberOfCells();
830 int sz=getNumberOfNodesPerCell();
831 const int *connPtr=_conn->begin();
832 for(int i=0;i<nbOfCells;i++,connPtr+=sz)
834 ret << "Cell #" << i << " : ";
835 std::copy(connPtr,connPtr+sz,std::ostream_iterator<int>(ret," "));
840 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
843 ret << "Nodal connectivity array specified but not allocated !" << "\n";
846 ret << "No connectivity specified !" << "\n";
850 DataArrayDouble *MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell() const
852 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
853 int spaceDim=getSpaceDimension();
854 int nbOfCells=getNumberOfCells();//checkCoherency()
855 int nbOfNodes=getNumberOfNodes();
856 ret->alloc(nbOfCells,spaceDim);
857 double *ptToFill=ret->getPointer();
858 const double *coor=_coords->begin();
859 const int *nodal=_conn->begin();
860 int sz=getNumberOfNodesPerCell();
861 double coeff=1./(double)sz;
862 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim)
864 std::fill(ptToFill,ptToFill+spaceDim,0.);
865 for(int j=0;j<sz;j++,nodal++)
866 if(*nodal>=0 && *nodal<nbOfNodes)
867 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
870 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
871 throw INTERP_KERNEL::Exception(oss.str().c_str());
873 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),coeff));
878 void MEDCoupling1SGTUMesh::renumberCells(const int *old2NewBg, bool check)
880 int nbCells=getNumberOfCells();
881 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
882 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
884 o2n=o2n->checkAndPreparePermutation();
886 const int *conn=_conn->begin();
887 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o=o2n->invertArrayO2N2N2O(nbCells);
888 const int *n2oPtr=n2o->begin();
889 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
890 newConn->alloc(_conn->getNumberOfTuples(),1);
891 newConn->copyStringInfoFrom(*_conn);
892 int sz=getNumberOfNodesPerCell();
894 int *newC=newConn->getPointer();
895 for(int i=0;i<nbCells;i++,newC+=sz)
898 std::copy(conn+pos*sz,conn+(pos+1)*sz,newC);
904 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
905 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
906 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
907 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
909 * \param [in] begin input start of array of node ids.
910 * \param [in] end input end of array of node ids.
911 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
912 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
914 void MEDCoupling1SGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
916 int nbOfCells=getNumberOfCells();
917 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
919 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
920 std::vector<bool> fastFinder(sz,false);
921 for(const int *work=begin;work!=end;work++)
922 if(*work>=0 && *work<sz)
923 fastFinder[*work]=true;
924 const int *conn=_conn->begin();
925 int nbNodesPerCell=getNumberOfNodesPerCell();
926 for(int i=0;i<nbOfCells;i++,conn+=nbNodesPerCell)
929 for(int j=0;j<nbNodesPerCell;j++)
933 if(fastFinder[conn[j]])
936 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
937 cellIdsKept->pushBackSilent(i);
939 cellIdsKeptArr=cellIdsKept.retn();
942 MEDCouplingMesh *MEDCoupling1SGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
944 if(other->getType()!=SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED)
945 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single static geo type each other !");
946 const MEDCoupling1SGTUMesh *otherC=static_cast<const MEDCoupling1SGTUMesh *>(other);
947 return Merge1SGTUMeshes(this,otherC);
950 MEDCouplingUMesh *MEDCoupling1SGTUMesh::buildUnstructured() const
952 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName().c_str(),getMeshDimension());
953 ret->setCoords(getCoords());
954 const int *nodalConn=_conn->begin();
955 int nbCells=getNumberOfCells();
956 int nbNodesPerCell=getNumberOfNodesPerCell();
957 int geoType=(int)getCellModelEnum();
958 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells*(nbNodesPerCell+1),1);
959 int *cPtr=c->getPointer();
960 for(int i=0;i<nbCells;i++,nodalConn+=nbNodesPerCell)
963 cPtr=std::copy(nodalConn,nodalConn+nbNodesPerCell,cPtr);
965 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::Range(0,(nbCells+1)*(nbNodesPerCell+1),nbNodesPerCell+1);
966 ret->setConnectivity(c,cI,true);
970 DataArrayInt *MEDCoupling1SGTUMesh::simplexize(int policy)
975 return simplexizePol0();
977 return simplexizePol1();
978 case (int) INTERP_KERNEL::PLANAR_FACE_5:
979 return simplexizePlanarFace5();
980 case (int) INTERP_KERNEL::PLANAR_FACE_6:
981 return simplexizePlanarFace6();
983 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::simplexize : unrecognized policy ! Must be :\n - 0 or 1 (only available for meshdim=2) \n - PLANAR_FACE_5, PLANAR_FACE_6 (only for meshdim=3)");
989 struct MEDCouplingAccVisit
991 MEDCouplingAccVisit():_new_nb_of_nodes(0) { }
992 int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; }
993 int _new_nb_of_nodes;
999 * Finds nodes not used in any cell and returns an array giving a new id to every node
1000 * by excluding the unused nodes, for which the array holds -1. The result array is
1001 * a mapping in "Old to New" mode.
1002 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
1003 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
1004 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
1005 * if the node is unused or a new id else. The caller is to delete this
1006 * array using decrRef() as it is no more needed.
1007 * \throw If the coordinates array is not set.
1008 * \throw If the nodal connectivity of cells is not defined.
1009 * \throw If the nodal connectivity includes an invalid id.
1011 DataArrayInt *MEDCoupling1SGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
1014 int nbOfNodes=getNumberOfNodes();
1015 int nbOfCells=getNumberOfCells();
1016 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1017 ret->alloc(nbOfNodes,1);
1018 int *traducer=ret->getPointer();
1019 std::fill(traducer,traducer+nbOfNodes,-1);
1020 const int *conn=_conn->begin();
1021 int nbNodesPerCell=getNumberOfNodesPerCell();
1022 for(int i=0;i<nbOfCells;i++)
1023 for(int j=0;j<nbNodesPerCell;j++,conn++)
1024 if(*conn>=0 && *conn<nbOfNodes)
1028 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << conn[j] << " not in [0," << nbOfNodes << ") !";
1029 throw INTERP_KERNEL::Exception(oss.str().c_str());
1031 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
1032 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
1037 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
1038 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
1039 * This method is a generalization of shiftNodeNumbersInConn().
1040 * \warning This method performs no check of validity of new ids. **Use it with care !**
1041 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
1042 * this->getNumberOfNodes(), in "Old to New" mode.
1043 * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
1044 * \throw If the nodal connectivity of cells is not defined.
1046 void MEDCoupling1SGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
1048 getNumberOfCells();//only to check that all is well defined.
1049 _conn->transformWithIndArr(newNodeNumbersO2N,newNodeNumbersO2N+getNumberOfNodes());
1053 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2)
1055 std::vector<const MEDCoupling1SGTUMesh *> tmp(2);
1056 tmp[0]=const_cast<MEDCoupling1SGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1SGTUMesh *>(mesh2);
1057 return Merge1SGTUMeshes(tmp);
1060 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(std::vector<const MEDCoupling1SGTUMesh *>& a)
1062 std::size_t sz=a.size();
1064 return Merge1SGTUMeshesLL(a);
1065 for(std::size_t ii=0;ii<sz;ii++)
1068 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::Merge1SGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
1069 throw INTERP_KERNEL::Exception(oss.str().c_str());
1071 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
1072 for(std::size_t ii=0;ii<sz;ii++)
1073 if(&(a[ii]->getCellModel())!=cm)
1074 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : all items must have the same geo type !");
1075 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> > bb(sz);
1076 std::vector< const MEDCoupling1SGTUMesh * > aa(sz);
1078 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
1080 const MEDCoupling1SGTUMesh *cur=a[i];
1081 const DataArrayDouble *coo=cur->getCoords();
1083 spaceDim=coo->getNumberOfComponents();
1086 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : no spaceDim specified ! unable to perform merge !");
1087 for(std::size_t i=0;i<sz;i++)
1089 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
1092 return Merge1SGTUMeshesLL(aa);
1096 * \throw If presence of a null instance in the input vector \a a.
1097 * \throw If a is empty
1099 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::vector<const MEDCoupling1SGTUMesh *>& a)
1102 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : input array must be NON EMPTY !");
1103 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1105 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : null instance in the first element of input vector !");
1106 std::vector<const DataArrayInt *> ncs(a.size());
1107 (*it)->getNumberOfCells();//to check that all is OK
1108 const DataArrayDouble *coords=(*it)->getCoords();
1109 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1110 ncs[0]=(*it)->getNodalConnectivity();
1112 for(int i=1;it!=a.end();i++,it++)
1115 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : presence of a null instance in the input vector !");
1116 if(cm!=&((*it)->getCellModel()))
1117 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1118 (*it)->getNumberOfCells();//to check that all is OK
1119 ncs[i]=(*it)->getNodalConnectivity();
1120 if(coords!=(*it)->getCoords())
1121 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : not lying on same coords !");
1123 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1124 ret->setCoords(coords);
1125 ret->_conn=DataArrayInt::Aggregate(ncs);
1130 * Assume that all instances in \a a are non null. If null it leads to a crash. That's why this method is assigned to be low level (LL)
1132 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector<const MEDCoupling1SGTUMesh *>& a)
1135 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : input array must be NON EMPTY !");
1136 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1137 int nbOfCells=(*it)->getNumberOfCells();
1138 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1139 int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
1141 for(;it!=a.end();it++)
1143 if(cm!=&((*it)->getCellModel()))
1144 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1145 nbOfCells+=(*it)->getNumberOfCells();
1147 std::vector<const MEDCouplingPointSet *> aps(a.size());
1148 std::copy(a.begin(),a.end(),aps.begin());
1149 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
1150 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1151 ret->setCoords(pts);
1152 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New();
1153 c->alloc(nbOfCells*nbNodesPerCell,1);
1154 int *cPtr=c->getPointer();
1156 for(it=a.begin();it!=a.end();it++)
1158 int curConnLgth=(*it)->getNodalConnectivityLength();
1159 const int *curC=(*it)->_conn->begin();
1160 cPtr=std::transform(curC,curC+curConnLgth,cPtr,std::bind2nd(std::plus<int>(),offset));
1161 offset+=(*it)->getNumberOfNodes();
1164 ret->setNodalConnectivity(c);
1168 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
1170 int ncell=getNumberOfCells();
1171 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName().c_str(),*_cm));
1172 ret->setCoords(_coords);
1173 std::size_t nbOfElemsRet=std::distance(begin,end);
1174 const int *inConn=_conn->getConstPointer();
1175 int sz=getNumberOfNodesPerCell();
1176 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1177 int *connPtr=connRet->getPointer();
1178 for(const int *work=begin;work!=end;work++,connPtr+=sz)
1180 if(*work>=0 && *work<ncell)
1181 std::copy(inConn+(work[0])*sz,inConn+(work[0]+1)*sz,connPtr);
1184 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !";
1185 throw INTERP_KERNEL::Exception(oss.str().c_str());
1189 ret->copyTinyInfoFrom(this);
1193 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
1195 int ncell=getNumberOfCells();
1196 int nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : ");
1197 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName().c_str(),*_cm));
1198 ret->setCoords(_coords);
1199 const int *inConn=_conn->getConstPointer();
1200 int sz=getNumberOfNodesPerCell();
1201 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1202 int *connPtr=connRet->getPointer();
1204 for(int i=0;i<nbOfElemsRet;i++,connPtr+=sz,curId+=step)
1206 if(curId>=0 && curId<ncell)
1207 std::copy(inConn+curId*sz,inConn+(curId+1)*sz,connPtr);
1210 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : On pos #" << i << " input cell id =" << curId << " should be in [0," << ncell << ") !";
1211 throw INTERP_KERNEL::Exception(oss.str().c_str());
1215 ret->copyTinyInfoFrom(this);
1219 void MEDCoupling1SGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
1221 int sz((int)nodeIdsInUse.size());
1222 int nbCells(getNumberOfCells());
1223 int nbOfNodesPerCell(getNumberOfNodesPerCell());
1224 const int *w(_conn->begin());
1225 for(int i=0;i<nbCells;i++)
1226 for(int j=0;j<nbOfNodesPerCell;j++,w++)
1229 nodeIdsInUse[*w]=true;
1232 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeNodeIdsAlg : At cell #" << i << " presence of node id #" << *w << " should be in [0," << sz << ") !";
1233 throw INTERP_KERNEL::Exception(oss.str().c_str());
1238 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(int spaceDim) const
1240 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName().c_str(),*_cm));
1241 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1;
1242 const DataArrayInt *nodalConn(_conn);
1245 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
1252 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
1253 ret->setCoords(coords);
1256 ret->setCoords(_coords);
1260 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol0()
1262 int nbOfCells=getNumberOfCells();
1263 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1264 return DataArrayInt::Range(0,nbOfCells,1);
1265 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1266 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1267 const int *c(_conn->begin());
1268 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1269 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1271 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[2];
1272 newConnPtr[3]=c[0]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1273 retPtr[0]=i; retPtr[1]=i;
1276 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1281 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol1()
1283 int nbOfCells=getNumberOfCells();
1284 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1285 return DataArrayInt::Range(0,nbOfCells,1);
1286 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1287 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1288 const int *c(_conn->begin());
1289 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1290 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1292 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[3];
1293 newConnPtr[3]=c[1]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1294 retPtr[0]=i; retPtr[1]=i;
1297 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1302 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace5()
1304 int nbOfCells=getNumberOfCells();
1305 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1306 return DataArrayInt::Range(0,nbOfCells,1);
1307 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(5*4*nbOfCells,1);
1308 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(5*nbOfCells,1);
1309 const int *c(_conn->begin());
1310 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1311 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=20,retPtr+=5)
1313 for(int j=0;j<20;j++)
1314 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_5_WO[j]];
1315 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i;
1318 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1323 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace6()
1325 int nbOfCells=getNumberOfCells();
1326 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1327 return DataArrayInt::Range(0,nbOfCells,1);
1328 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(6*4*nbOfCells,1);
1329 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(6*nbOfCells,1);
1330 const int *c(_conn->begin());
1331 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1332 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=24,retPtr+=6)
1334 for(int j=0;j<24;j++)
1335 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_6_WO[j]];
1336 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i; retPtr[5]=i;
1339 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1344 void MEDCoupling1SGTUMesh::reprQuickOverview(std::ostream& stream) const
1346 stream << "MEDCoupling1SGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
1347 stream << " Mesh dimension : " << getMeshDimension() << ".";
1349 { stream << " No coordinates set !"; return ; }
1350 if(!_coords->isAllocated())
1351 { stream << " Coordinates set but not allocated !"; return ; }
1352 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
1353 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
1354 if(!(const DataArrayInt *)_conn)
1355 { stream << std::endl << "Nodal connectivity NOT set !"; return ; }
1356 if(_conn->isAllocated())
1358 if(_conn->getNumberOfComponents()==1)
1359 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
1363 void MEDCoupling1SGTUMesh::checkFullyDefined() const
1365 if(!((const DataArrayInt *)_conn) || !((const DataArrayDouble *)_coords))
1366 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFullyDefined : part of this is not fully defined.");
1370 * First step of unserialization process.
1372 bool MEDCoupling1SGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
1374 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEmptyMesh : not implemented yet !");
1377 void MEDCoupling1SGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
1380 double time=getTime(it,order);
1381 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
1383 littleStrings.push_back(getName());
1384 littleStrings.push_back(getDescription());
1385 littleStrings.push_back(getTimeUnit());
1387 std::vector<std::string> littleStrings2,littleStrings3;
1388 if((const DataArrayDouble *)_coords)
1389 _coords->getTinySerializationStrInformation(littleStrings2);
1390 if((const DataArrayInt *)_conn)
1391 _conn->getTinySerializationStrInformation(littleStrings3);
1392 int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size());
1393 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
1394 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
1396 tinyInfo.push_back(getCellModelEnum());
1397 tinyInfo.push_back(it);
1398 tinyInfo.push_back(order);
1399 std::vector<int> tinyInfo2,tinyInfo3;
1400 if((const DataArrayDouble *)_coords)
1401 _coords->getTinySerializationIntInformation(tinyInfo2);
1402 if((const DataArrayInt *)_conn)
1403 _conn->getTinySerializationIntInformation(tinyInfo3);
1404 int sz2((int)tinyInfo2.size()),sz3((int)tinyInfo3.size());
1405 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3);
1406 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1407 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
1409 tinyInfoD.push_back(time);
1412 void MEDCoupling1SGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
1414 std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+tinyInfo[5]);
1415 std::vector<int> tinyInfo1(tinyInfo.begin()+7+tinyInfo[5],tinyInfo.begin()+7+tinyInfo[5]+tinyInfo[6]);
1416 a1->resizeForUnserialization(tinyInfo1);
1417 a2->resizeForUnserialization(tinyInfo2);
1420 void MEDCoupling1SGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
1423 if((const DataArrayInt *)_conn)
1424 if(_conn->isAllocated())
1425 sz=_conn->getNbOfElems();
1426 a1=DataArrayInt::New();
1428 if(sz!=0 && (const DataArrayInt *)_conn)
1429 std::copy(_conn->begin(),_conn->end(),a1->getPointer());
1431 if((const DataArrayDouble *)_coords)
1432 if(_coords->isAllocated())
1433 sz=_coords->getNbOfElems();
1434 a2=DataArrayDouble::New();
1436 if(sz!=0 && (const DataArrayDouble *)_coords)
1437 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
1440 void MEDCoupling1SGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
1441 const std::vector<std::string>& littleStrings)
1443 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
1444 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
1445 setName(littleStrings[0].c_str());
1446 setDescription(littleStrings[1].c_str());
1447 setTimeUnit(littleStrings[2].c_str());
1448 setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
1449 int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]);
1451 _coords=DataArrayDouble::New();
1452 std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+sz2);
1453 _coords->resizeForUnserialization(tinyInfo2);
1454 std::copy(a2->begin(),a2->end(),_coords->getPointer());
1455 _conn=DataArrayInt::New();
1456 std::vector<int> tinyInfo3(tinyInfo.begin()+7+sz2,tinyInfo.begin()+7+sz2+sz3);
1457 _conn->resizeForUnserialization(tinyInfo3);
1458 std::copy(a1->begin(),a1->end(),_conn->getPointer());
1459 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
1460 _coords->finishUnserialization(tinyInfo2,littleStrings2);
1461 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
1462 _conn->finishUnserialization(tinyInfo3,littleStrings3);
1466 * Checks if \a this and \a other meshes are geometrically equivalent with high
1467 * probability, else an exception is thrown. The meshes are considered equivalent if
1468 * (1) meshes contain the same number of nodes and the same number of elements of the
1469 * same types (2) three cells of the two meshes (first, last and middle) are based
1470 * on coincident nodes (with a specified precision).
1471 * \param [in] other - the mesh to compare with.
1472 * \param [in] prec - the precision used to compare nodes of the two meshes.
1473 * \throw If the two meshes do not match.
1475 void MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
1477 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1478 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1480 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single static geometric type !");
1481 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1485 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1486 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1487 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1488 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1489 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1490 if(c1->getHashCode()!=c2->getHashCode())
1491 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1494 MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
1497 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
1498 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1500 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
1501 std::vector<const MEDCoupling1SGTUMesh *> ms(2);
1504 return Merge1SGTUMeshesOnSameCoords(ms);
1507 void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const
1509 checkFullyDefined();
1510 int nbOfNodes=getNumberOfNodes();
1511 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
1512 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
1513 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
1514 const int *conn=_conn->begin();
1515 int nbOfCells=getNumberOfCells();
1516 int nbOfEltsInRevNodal=0;
1517 int nbOfNodesPerCell=getNumberOfNodesPerCell();
1518 for(int eltId=0;eltId<nbOfCells;eltId++)
1520 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1522 if(conn[0]>=0 && conn[0]<nbOfNodes)
1524 nbOfEltsInRevNodal++;
1525 revNodalIndxPtr[conn[0]+1]++;
1529 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
1530 throw INTERP_KERNEL::Exception(oss.str().c_str());
1534 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
1535 conn=_conn->begin();
1536 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
1537 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
1538 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
1539 for(int eltId=0;eltId<nbOfCells;eltId++)
1541 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1543 *std::find_if(revNodalPtr+revNodalIndxPtr[*conn],revNodalPtr+revNodalIndxPtr[*conn+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
1549 * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null.
1551 void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn)
1554 nodalConn->incrRef();
1560 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
1562 DataArrayInt *MEDCoupling1SGTUMesh::getNodalConnectivity() const
1564 const DataArrayInt *ret(_conn);
1565 return const_cast<DataArrayInt *>(ret);
1569 * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted,
1570 * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter.
1571 * If a nodal connectivity previouly existed before the call of this method, it will be reset.
1573 * \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain.
1575 void MEDCoupling1SGTUMesh::allocateCells(int nbOfCells)
1578 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !");
1579 _conn=DataArrayInt::New();
1580 _conn->reserve(getNumberOfNodesPerCell()*nbOfCells);
1585 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
1587 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
1588 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
1589 * \throw If the length of the input nodal connectivity array of the cell to add is not equal to number of nodes per cell relative to the unique geometric type
1590 * attached to \a this.
1591 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
1593 void MEDCoupling1SGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd)
1595 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
1596 int ref=getNumberOfNodesPerCell();
1599 DataArrayInt *c(_conn);
1601 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
1603 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !");
1607 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this (";
1608 oss << ref << ") !";
1609 throw INTERP_KERNEL::Exception(oss.str().c_str());
1614 * This method builds the dual mesh of \a this and returns it.
1616 * \return MEDCoupling1SGTUMesh * - newly object created to be managed by the caller.
1617 * \throw If \a this is not a mesh containing only simplex cells.
1618 * \throw If \a this is not correctly allocated (coordinates and connectivities have to be correctly set !).
1619 * \throw If at least one node in \a this is orphan (without any simplex cell lying on it !)
1621 MEDCoupling1GTUMesh *MEDCoupling1SGTUMesh::computeDualMesh() const
1623 const INTERP_KERNEL::CellModel& cm(getCellModel());
1625 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : this mesh is not a simplex mesh ! Please invoke simplexize of tetrahedrize on this before calling this method !");
1626 switch(getMeshDimension())
1629 return computeDualMesh3D();
1631 return computeDualMesh2D();
1633 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : meshdimension must be in [2,3] !");
1638 * This method explode each NORM_HEXA8 cells in \a this into 6 NORM_QUAD4 cells and put the result into the MEDCoupling1SGTUMesh returned instance.
1640 * \return MEDCoupling1SGTUMesh * - a newly allocated instances (to be managed by the caller) storing the result of the explosion.
1641 * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
1642 * \throw If \a this is not properly allocated.
1644 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4() const
1646 const INTERP_KERNEL::CellModel& cm(getCellModel());
1647 if(cm.getEnum()!=INTERP_KERNEL::NORM_HEXA8)
1648 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4 : this method can be applied only on HEXA8 mesh !");
1649 int nbHexa8(getNumberOfCells());
1650 const int *inConnPtr(getNodalConnectivity()->begin());
1651 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(getName().c_str(),INTERP_KERNEL::NORM_QUAD4));
1652 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()); c->alloc(nbHexa8*6*4,1);
1653 int *cPtr(c->getPointer());
1654 for(int i=0;i<nbHexa8;i++,inConnPtr+=8)
1656 for(int j=0;j<6;j++,cPtr+=4)
1657 cm.fillSonCellNodalConnectivity(j,inConnPtr,cPtr);
1659 ret->setCoords(getCoords());
1660 ret->setNodalConnectivity(c);
1666 bool UpdateHexa8Cell(int validAxis, int neighId, const int *validConnQuad4NeighSide, int *allFacesNodalConn, int *myNeighbours)
1668 if(myNeighbours[validAxis]==neighId && allFacesNodalConn[4*validAxis+0]==validConnQuad4NeighSide[0])
1670 int oldAxis((int)std::distance(myNeighbours,std::find(myNeighbours,myNeighbours+6,neighId)));
1671 std::size_t pos(std::distance(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,std::find(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS+6,oldAxis)));
1672 std::size_t pos0(pos/2),pos1(pos%2);
1673 int oldAxisOpp(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[2*pos0+(pos1+1)%2]);
1674 int oldConn[8],myConn[8]={-1,-1,-1,-1,-1,-1,-1,-1},tmpConn[4],tmpConn2[8]={0,1,2,3,4,5,6,7},edgeConn[2],allFacesTmp[24],neighTmp[6];
1675 oldConn[0]=allFacesNodalConn[0]; oldConn[1]=allFacesNodalConn[1]; oldConn[2]=allFacesNodalConn[2]; oldConn[3]=allFacesNodalConn[3];
1676 oldConn[4]=allFacesNodalConn[4]; oldConn[5]=allFacesNodalConn[7]; oldConn[6]=allFacesNodalConn[6]; oldConn[7]=allFacesNodalConn[5];
1677 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_HEXA8));
1678 cm.fillSonCellNodalConnectivity(validAxis,tmpConn2,tmpConn);
1679 for(int i=0;i<4;i++)
1680 myConn[tmpConn[i]]=validConnQuad4NeighSide[(4-i)%4];
1681 for(int i=0;i<4;i++)
1683 int nodeId(myConn[i]!=-1?myConn[i]:myConn[4+i]);//the node id for which the opposite one will be found
1685 INTERP_KERNEL::NormalizedCellType typeOfSon;
1686 for(int j=0;j<12 && !found;j++)
1688 cm.fillSonEdgesNodalConnectivity3D(j,oldConn,-1,edgeConn,typeOfSon);
1689 if(edgeConn[0]==nodeId || edgeConn[1]==nodeId)
1691 if(std::find(allFacesNodalConn+4*oldAxisOpp,allFacesNodalConn+4*oldAxisOpp+4,edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0])!=allFacesNodalConn+4*oldAxisOpp+4)
1694 myConn[myConn[i]]=edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0];
1696 myConn[myConn[i]+4]=edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0];
1702 throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error !");
1704 for(int i=0;i<6;i++)
1706 cm.fillSonCellNodalConnectivity(i,myConn,allFacesTmp+4*i);
1707 std::set<int> s(allFacesTmp+4*i,allFacesTmp+4*i+4);
1709 for(int j=0;j<6 && !found;j++)
1711 std::set<int> s1(allFacesNodalConn+4*j,allFacesNodalConn+4*j+4);
1714 neighTmp[i]=myNeighbours[j];
1719 throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error #2 !");
1721 std::copy(allFacesTmp,allFacesTmp+24,allFacesNodalConn);
1722 std::copy(neighTmp,neighTmp+6,myNeighbours);
1729 * 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
1730 * homogeneous. If it succeeds the result of MEDCouplingUMesh::tetrahedrize will return a conform mesh.
1732 * \return DataArrayInt * - a newly allocated array (to be managed by the caller) containing renumbered cell ids.
1734 * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
1735 * \throw If \a this is not properly allocated.
1736 * \sa MEDCouplingUMesh::tetrahedrize, MEDCouplingUMesh::simplexize.
1738 DataArrayInt *MEDCoupling1SGTUMesh::sortHexa8EachOther()
1740 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> quads(explodeEachHexa8To6Quad4());//checks that only hexa8
1741 int nbHexa8(getNumberOfCells()),*cQuads(quads->getNodalConnectivity()->getPointer());
1742 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> neighOfQuads(DataArrayInt::New()); neighOfQuads->alloc(nbHexa8*6,1); neighOfQuads->fillWithValue(-1);
1743 int *ptNeigh(neighOfQuads->getPointer());
1744 {//neighOfQuads tells for each face of each Quad8 which cell (if!=-1) is connected to this face.
1745 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> quadsTmp(quads->buildUnstructured());
1746 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ccSafe,cciSafe;
1747 DataArrayInt *cc(0),*cci(0);
1748 quadsTmp->findCommonCells(3,0,cc,cci);
1749 ccSafe=cc; cciSafe=cci;
1750 const int *ccPtr(ccSafe->begin()),nbOfPair(cci->getNumberOfTuples()-1);
1751 for(int i=0;i<nbOfPair;i++)
1752 { ptNeigh[ccPtr[2*i+0]]=ccPtr[2*i+1]/6; ptNeigh[ccPtr[2*i+1]]=ccPtr[2*i+0]/6; }
1754 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
1755 std::vector<bool> fetched(nbHexa8,false);
1756 std::vector<bool>::iterator it(std::find(fetched.begin(),fetched.end(),true));
1757 while(it!=fetched.end())//it will turns as time as number of connected zones
1759 int cellId((int)std::distance(fetched.begin(),it));//it is the seed of the connected zone.
1760 std::set<int> s; s.insert(cellId);//s contains already organized.
1763 std::set<int> sNext;
1764 for(std::set<int>::const_iterator it0=s.begin();it0!=s.end();it0++)
1767 int *myNeighb(ptNeigh+6*(*it0));
1768 for(int i=0;i<6;i++)
1770 std::size_t pos(std::distance(HEXA8_FACE_PAIRS,std::find(HEXA8_FACE_PAIRS,HEXA8_FACE_PAIRS+6,i)));
1771 std::size_t pos0(pos/2),pos1(pos%2);
1774 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]))
1775 ret->pushBackSilent(myNeighb[i]);
1776 sNext.insert(myNeighb[i]);
1786 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh3D() const
1788 static const int DUAL_TETRA_0[36]={
1789 4,1,0, 6,0,3, 7,3,1,
1790 4,0,1, 5,2,0, 8,1,2,
1791 6,3,0, 5,0,2, 9,2,3,
1794 static const int DUAL_TETRA_1[36]={
1795 8,4,10, 11,5,8, 10,7,11,
1796 9,4,8, 8,5,12, 12,6,9,
1797 10,4,9, 9,6,13, 13,7,10,
1798 12,5,11, 13,6,12, 11,7,13
1800 static const int FACEID_NOT_SH_NODE[4]={2,3,1,0};
1801 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TETRA4)
1802 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh3D : only TETRA4 supported !");
1803 checkFullyDefined();
1804 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured());
1805 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1806 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1807 const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1808 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d1Arr(DataArrayInt::New()),di1Arr(DataArrayInt::New()),rd1Arr(DataArrayInt::New()),rdi1Arr(DataArrayInt::New());
1809 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->explode3DMeshTo1D(d1Arr,di1Arr,rd1Arr,rdi1Arr));
1810 const int *d1(d1Arr->begin());
1811 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1812 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> faces(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
1813 const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
1814 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),facesBaryArr(faces->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
1815 const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+faces->getNumberOfCells()),offset1(offset0+edges->getNumberOfCells());
1817 std::vector<const DataArrayDouble *> v(4); v[0]=getCoords(); v[1]=facesBaryArr; v[2]=edgesBaryArr; v[3]=baryArr;
1818 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0; facesBaryArr=0;
1819 std::string name("DualOf_"); name+=getName();
1820 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name.c_str(),INTERP_KERNEL::NORM_POLYHED)); ret->setCoords(zeArr);
1821 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1822 for(int i=0;i<nbOfNodes;i++,revNodI++)
1824 int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1825 if(nbOfCellsSharingNode==0)
1827 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh3D : Node #" << i << " is orphan !";
1828 throw INTERP_KERNEL::Exception(oss.str().c_str());
1830 for(int j=0;j<nbOfCellsSharingNode;j++)
1832 int curCellId(revNod[revNodI[0]+j]);
1833 const int *connOfCurCell(nodal+4*curCellId);
1834 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1835 if(j!=0) cArr->pushBackSilent(-1);
1838 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;
1839 tmp[2]=curCellId+offset1; tmp[3]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+2]]+nbOfNodes;
1841 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;
1842 tmp[7]=curCellId+offset1; tmp[8]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+5]]+nbOfNodes;
1844 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;
1845 tmp[12]=curCellId+offset1; tmp[13]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+8]]+nbOfNodes;
1846 cArr->insertAtTheEnd(tmp,tmp+14);
1848 for(int k=0;k<4;k++)
1850 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1852 const int *faceId(d2+4*curCellId+k);
1853 if(rdi2[*faceId+1]-rdi2[*faceId]==1)
1855 int tmp2[5]; tmp2[0]=-1; tmp2[1]=i;
1856 tmp2[2]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+0]-8]+offset0;
1857 tmp2[3]=d2[4*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+1]-4]+nbOfNodes;
1858 tmp2[4]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+2]-8]+offset0;
1859 cArr->insertAtTheEnd(tmp2,tmp2+5);
1865 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
1867 ret->setNodalConnectivity(cArr,ciArr);
1871 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh2D() const
1873 static const int DUAL_TRI_0[6]={0,2, 1,0, 2,1};
1874 static const int DUAL_TRI_1[6]={-3,+5, +3,-4, +4,-5};
1875 static const int FACEID_NOT_SH_NODE[3]={1,2,0};
1876 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TRI3)
1877 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh2D : only TRI3 supported !");
1878 checkFullyDefined();
1879 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured());
1880 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1881 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1882 const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1883 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1884 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
1885 const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
1886 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
1887 const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+edges->getNumberOfCells());
1889 std::vector<const DataArrayDouble *> v(3); v[0]=getCoords(); v[1]=edgesBaryArr; v[2]=baryArr;
1890 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0;
1891 std::string name("DualOf_"); name+=getName();
1892 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name.c_str(),INTERP_KERNEL::NORM_POLYGON)); ret->setCoords(zeArr);
1893 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1894 for(int i=0;i<nbOfNodes;i++,revNodI++)
1896 int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1897 if(nbOfCellsSharingNode==0)
1899 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh2D : Node #" << i << " is orphan !";
1900 throw INTERP_KERNEL::Exception(oss.str().c_str());
1902 std::vector< std::vector<int> > polyg;
1903 for(int j=0;j<nbOfCellsSharingNode;j++)
1905 int curCellId(revNod[revNodI[0]+j]);
1906 const int *connOfCurCell(nodal+3*curCellId);
1907 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1908 std::vector<int> locV(3);
1909 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;
1910 polyg.push_back(locV);
1912 for(int k=0;k<3;k++)
1914 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1916 const int *edgeId(d2+3*curCellId+k);
1917 if(rdi2[*edgeId+1]-rdi2[*edgeId]==1)
1919 std::vector<int> locV2(2);
1920 int zeLocEdgeIdRel(DUAL_TRI_1[2*nodePosInCurCell+kk]);
1921 if(zeLocEdgeIdRel>0)
1922 { locV2[0]=d2[3*curCellId+zeLocEdgeIdRel-3]+nbOfNodes; locV2[1]=i; }
1924 { locV2[0]=i; locV2[1]=d2[3*curCellId-zeLocEdgeIdRel-3]+nbOfNodes; }
1925 polyg.push_back(locV2);
1931 std::vector<int> zePolyg(MEDCoupling1DGTUMesh::BuildAPolygonFromParts(polyg));
1932 cArr->insertAtTheEnd(zePolyg.begin(),zePolyg.end());
1933 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
1935 ret->setNodalConnectivity(cArr,ciArr);
1940 * This method aggregate the bbox of each cell and put it into bbox
1942 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
1944 * \throw If \a this is not fully set (coordinates and connectivity).
1945 * \throw If a cell in \a this has no valid nodeId.
1947 DataArrayDouble *MEDCoupling1SGTUMesh::getBoundingBoxForBBTree() const
1949 int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()),nbOfNodesPerCell(getNumberOfNodesPerCell());
1950 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
1951 double *bbox(ret->getPointer());
1952 for(int i=0;i<nbOfCells*spaceDim;i++)
1954 bbox[2*i]=std::numeric_limits<double>::max();
1955 bbox[2*i+1]=-std::numeric_limits<double>::max();
1957 const double *coordsPtr(_coords->getConstPointer());
1958 const int *conn(_conn->getConstPointer());
1959 for(int i=0;i<nbOfCells;i++)
1962 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1965 if(nodeId>=0 && nodeId<nbOfNodes)
1967 for(int k=0;k<spaceDim;k++)
1969 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
1970 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
1977 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
1978 throw INTERP_KERNEL::Exception(oss.str().c_str());
1986 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New()
1988 return new MEDCoupling1DGTUMesh;
1991 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type)
1993 if(type==INTERP_KERNEL::NORM_ERROR)
1994 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
1995 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
1998 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !";
1999 throw INTERP_KERNEL::Exception(oss.str().c_str());
2001 return new MEDCoupling1DGTUMesh(name,cm);
2004 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh()
2008 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
2012 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
2016 const DataArrayInt *c(other._conn);
2021 _conn_indx=c->deepCpy();
2025 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const
2027 return new MEDCoupling1DGTUMesh(*this,recDeepCpy);
2031 * This method behaves mostly like MEDCoupling1DGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
2032 * The coordinates are shared between \a this and the returned instance.
2034 * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
2035 * \sa MEDCoupling1DGTUMesh::deepCpy
2037 MEDCouplingPointSet *MEDCoupling1DGTUMesh::deepCpyConnectivityOnly() const
2040 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(clone(false));
2041 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy()),ci(_conn_indx->deepCpy());
2042 ret->setNodalConnectivity(c,ci);
2046 void MEDCoupling1DGTUMesh::updateTime() const
2048 MEDCoupling1GTUMesh::updateTime();
2049 const DataArrayInt *c(_conn);
2057 std::size_t MEDCoupling1DGTUMesh::getHeapMemorySizeWithoutChildren() const
2059 return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren();
2062 std::vector<const BigMemoryObject *> MEDCoupling1DGTUMesh::getDirectChildren() const
2064 std::vector<const BigMemoryObject *> ret(MEDCoupling1GTUMesh::getDirectChildren());
2065 const DataArrayInt *c(_conn);
2074 MEDCouplingMesh *MEDCoupling1DGTUMesh::deepCpy() const
2079 bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
2082 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !");
2083 std::ostringstream oss; oss.precision(15);
2084 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2087 reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !";
2090 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
2092 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2097 reason="in connectivity of single dynamic geometric type exactly one among this and other is null !";
2100 if(!c1->isEqualIfNotWhy(*c2,reason))
2102 reason.insert(0,"Nodal connectivity DataArrayInt differs : ");
2105 c1=_conn_indx; c2=otherC->_conn_indx;
2110 reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !";
2113 if(!c1->isEqualIfNotWhy(*c2,reason))
2115 reason.insert(0,"Nodal connectivity index DataArrayInt differs : ");
2121 bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
2124 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
2125 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2128 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
2130 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2135 if(!c1->isEqualWithoutConsideringStr(*c2))
2138 c1=_conn_indx; c2=otherC->_conn_indx;
2143 if(!c1->isEqualWithoutConsideringStr(*c2))
2149 * Checks if \a this and \a other meshes are geometrically equivalent with high
2150 * probability, else an exception is thrown. The meshes are considered equivalent if
2151 * (1) meshes contain the same number of nodes and the same number of elements of the
2152 * same types (2) three cells of the two meshes (first, last and middle) are based
2153 * on coincident nodes (with a specified precision).
2154 * \param [in] other - the mesh to compare with.
2155 * \param [in] prec - the precision used to compare nodes of the two meshes.
2156 * \throw If the two meshes do not match.
2158 void MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
2160 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
2161 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2163 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single dynamic geometric type !");
2164 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2168 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
2169 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2170 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
2171 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2172 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
2173 if(c1->getHashCode()!=c2->getHashCode())
2174 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs");
2176 c1=_conn_indx; c2=otherC->_conn_indx;
2180 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !");
2181 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2182 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !");
2183 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2184 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !");
2185 if(c1->getHashCode()!=c2->getHashCode())
2186 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs");
2190 void MEDCoupling1DGTUMesh::checkCoherencyOfConnectivity() const
2192 const DataArrayInt *c1(_conn);
2195 if(c1->getNumberOfComponents()!=1)
2196 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
2197 if(c1->getInfoOnComponent(0)!="")
2198 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
2199 c1->checkAllocated();
2202 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
2204 int sz2=_conn->getNumberOfTuples();
2208 if(c1->getNumberOfComponents()!=1)
2209 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
2210 c1->checkAllocated();
2211 if(c1->getNumberOfTuples()<1)
2212 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !");
2213 if(c1->getInfoOnComponent(0)!="")
2214 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
2215 int f=c1->front(),ll=c1->back();
2218 std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !";
2219 throw INTERP_KERNEL::Exception(oss.str().c_str());
2223 std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !";
2224 throw INTERP_KERNEL::Exception(oss.str().c_str());
2228 std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !";
2229 throw INTERP_KERNEL::Exception(oss.str().c_str());
2233 throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !");
2234 int szOfC1Exp=_conn_indx->back();
2237 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() << " !";
2238 throw INTERP_KERNEL::Exception(oss.str().c_str());
2243 * 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.
2244 * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one.
2245 * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array.
2247 void MEDCoupling1DGTUMesh::checkCoherency() const
2249 MEDCouplingPointSet::checkCoherency();
2250 checkCoherencyOfConnectivity();
2253 void MEDCoupling1DGTUMesh::checkCoherency1(double eps) const
2256 const DataArrayInt *c1(_conn),*c2(_conn_indx);
2257 if(!c2->isMonotonic(true))
2258 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkCoherency1 : the nodal connectivity index is expected to be increasing monotinic !");
2260 int nbOfTuples=c1->getNumberOfTuples();
2261 int nbOfNodes=getNumberOfNodes();
2262 const int *w(c1->begin());
2263 for(int i=0;i<nbOfTuples;i++,w++)
2265 if(*w==-1) continue;
2266 if(*w<0 || *w>=nbOfNodes)
2268 std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !";
2269 throw INTERP_KERNEL::Exception(oss.str().c_str());
2274 void MEDCoupling1DGTUMesh::checkCoherency2(double eps) const
2276 checkCoherency1(eps);
2279 int MEDCoupling1DGTUMesh::getNumberOfCells() const
2281 checkCoherencyOfConnectivity();//do not remove
2282 return _conn_indx->getNumberOfTuples()-1;
2286 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2287 * For each cell in \b this the number of nodes constituting cell is computed.
2288 * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned.
2289 * So for pohyhedrons some nodes can be counted several times in the returned result.
2291 * \return a newly allocated array
2293 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const
2296 _conn_indx->checkMonotonic(true);
2297 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2298 return _conn_indx->deltaShiftIndex();
2300 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2301 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2302 ret->alloc(nbOfCells,1);
2303 int *retPtr=ret->getPointer();
2304 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2305 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2306 *retPtr=ci[1]-ci[0]-std::count(c+ci[0],c+ci[1],-1);
2311 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2312 * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed.
2314 * \return a newly allocated array
2316 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const
2319 _conn_indx->checkMonotonic(true);
2320 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG)
2321 return _conn_indx->deltaShiftIndex();
2322 if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG)
2324 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=_conn_indx->deltaShiftIndex();
2325 ret->applyDivideBy(2);
2329 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2330 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2331 ret->alloc(nbOfCells,1);
2332 int *retPtr=ret->getPointer();
2333 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2334 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2335 *retPtr=std::count(c+ci[0],c+ci[1],-1)+1;
2340 * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell,
2341 * will be counted only once here whereas it will be counted several times in MEDCoupling1DGTUMesh::computeNbOfNodesPerCell method.
2343 * \return DataArrayInt * - new object to be deallocated by the caller.
2344 * \sa MEDCoupling1DGTUMesh::computeNbOfNodesPerCell
2346 DataArrayInt *MEDCoupling1DGTUMesh::computeEffectiveNbOfNodesPerCell() const
2349 _conn_indx->checkMonotonic(true);
2350 int nbOfCells(_conn_indx->getNumberOfTuples()-1);
2351 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2352 ret->alloc(nbOfCells,1);
2353 int *retPtr(ret->getPointer());
2354 const int *ci(_conn_indx->begin()),*c(_conn->begin());
2355 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2357 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2359 std::set<int> s(c+ci[0],c+ci[1]);
2360 *retPtr=(int)s.size();
2365 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2367 std::set<int> s(c+ci[0],c+ci[1]); s.erase(-1);
2368 *retPtr=(int)s.size();
2374 void MEDCoupling1DGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
2376 int nbOfCells(getNumberOfCells());//performs checks
2377 if(cellId>=0 && cellId<nbOfCells)
2379 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2380 int nbOfNodes=stp-strt;
2382 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !");
2383 conn.resize(nbOfNodes);
2384 std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin());
2388 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2389 throw INTERP_KERNEL::Exception(oss.str().c_str());
2393 int MEDCoupling1DGTUMesh::getNumberOfNodesInCell(int cellId) const
2395 int nbOfCells(getNumberOfCells());//performs checks
2396 if(cellId>=0 && cellId<nbOfCells)
2398 const int *conn(_conn->begin());
2399 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2400 return stp-strt-std::count(conn+strt,conn+stp,-1);
2404 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNumberOfNodesInCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2405 throw INTERP_KERNEL::Exception(oss.str().c_str());
2409 std::string MEDCoupling1DGTUMesh::simpleRepr() const
2411 static const char msg0[]="No coordinates specified !";
2412 std::ostringstream ret;
2413 ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
2414 ret << "Description of mesh : \"" << getDescription() << "\"\n";
2416 double tt=getTime(tmpp1,tmpp2);
2417 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
2418 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
2419 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
2422 const int spaceDim=getSpaceDimension();
2423 ret << spaceDim << "\nInfo attached on space dimension : ";
2424 for(int i=0;i<spaceDim;i++)
2425 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
2429 ret << msg0 << "\n";
2430 ret << "Number of nodes : ";
2432 ret << getNumberOfNodes() << "\n";
2434 ret << msg0 << "\n";
2435 ret << "Number of cells : ";
2437 try { checkCoherency(); } catch(INTERP_KERNEL::Exception& /* e */)
2439 ret << "Nodal connectivity arrays are not set or badly set !\n";
2443 ret << getNumberOfCells() << "\n";
2444 ret << "Cell type : " << _cm->getRepr() << "\n";
2448 std::string MEDCoupling1DGTUMesh::advancedRepr() const
2450 std::ostringstream ret;
2451 ret << simpleRepr();
2452 ret << "\nCoordinates array : \n___________________\n\n";
2454 _coords->reprWithoutNameStream(ret);
2456 ret << "No array set !\n";
2457 ret << "\n\nNodal Connectivity : \n____________________\n\n";
2460 try { checkCoherency1(); } catch(INTERP_KERNEL::Exception& /* e */)
2462 ret << "Nodal connectivity arrays are not set or badly set !\n";
2467 int nbOfCells=getNumberOfCells();
2468 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2469 for(int i=0;i<nbOfCells;i++,ci++)
2471 ret << "Cell #" << i << " : ";
2472 std::copy(c+ci[0],c+ci[1],std::ostream_iterator<int>(ret," "));
2478 DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const
2480 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
2481 int spaceDim=getSpaceDimension();
2482 int nbOfCells=getNumberOfCells();//checkCoherency()
2483 int nbOfNodes=getNumberOfNodes();
2484 ret->alloc(nbOfCells,spaceDim);
2485 double *ptToFill=ret->getPointer();
2486 const double *coor=_coords->begin();
2487 const int *nodal=_conn->begin(),*nodali=_conn_indx->begin();
2489 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2491 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2493 std::fill(ptToFill,ptToFill+spaceDim,0.);
2494 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2496 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2498 if(*nodal>=0 && *nodal<nbOfNodes)
2499 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2502 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2503 throw INTERP_KERNEL::Exception(oss.str().c_str());
2505 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(nodali[1]-nodali[0])));
2510 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !";
2511 throw INTERP_KERNEL::Exception(oss.str().c_str());
2517 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2519 std::fill(ptToFill,ptToFill+spaceDim,0.);
2520 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2523 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2525 if(*nodal==-1) continue;
2526 if(*nodal>=0 && *nodal<nbOfNodes)
2528 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2533 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2534 throw INTERP_KERNEL::Exception(oss.str().c_str());
2538 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./nbOfNod));
2541 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !";
2542 throw INTERP_KERNEL::Exception(oss.str().c_str());
2547 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : at cell #" << i << " the nodal index array is invalid !";
2548 throw INTERP_KERNEL::Exception(oss.str().c_str());
2555 void MEDCoupling1DGTUMesh::renumberCells(const int *old2NewBg, bool check)
2557 int nbCells=getNumberOfCells();
2558 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
2559 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
2561 o2n=o2n->checkAndPreparePermutation();
2563 const int *o2nPtr=o2n->getPointer();
2564 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2565 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
2566 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
2567 newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1);
2568 newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx);
2570 int *newC=newConn->getPointer(),*newCI=newConnI->getPointer();
2571 for(int i=0;i<nbCells;i++)
2573 int newPos=o2nPtr[i];
2574 int sz=conni[i+1]-conni[i];
2579 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !";
2580 throw INTERP_KERNEL::Exception(oss.str().c_str());
2583 newConnI->computeOffsets2(); newCI=newConnI->getPointer();
2585 for(int i=0;i<nbCells;i++,conni++)
2588 std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]);
2591 _conn_indx=newConnI;
2594 MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
2596 if(other->getType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED)
2597 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !");
2598 const MEDCoupling1DGTUMesh *otherC=static_cast<const MEDCoupling1DGTUMesh *>(other);
2599 return Merge1DGTUMeshes(this,otherC);
2602 MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const
2604 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName().c_str(),getMeshDimension());
2605 ret->setCoords(getCoords());
2606 const int *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin();
2607 int nbCells=getNumberOfCells();//checkCoherency
2608 int geoType=(int)getCellModelEnum();
2609 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1);
2610 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::New(); cI->alloc(nbCells+1);
2611 int *cPtr=c->getPointer(),*ciPtr=cI->getPointer();
2613 for(int i=0;i<nbCells;i++,ciPtr++)
2615 int sz=nodalConnI[i+1]-nodalConnI[i];
2619 cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr);
2620 ciPtr[1]=ciPtr[0]+sz+1;
2624 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !";
2625 throw INTERP_KERNEL::Exception(oss.str().c_str());
2628 ret->setConnectivity(c,cI,true);
2633 * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes
2635 DataArrayInt *MEDCoupling1DGTUMesh::simplexize(int policy)
2637 int nbOfCells=getNumberOfCells();
2638 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2639 ret->alloc(nbOfCells,1);
2644 void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const
2646 stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
2647 stream << " Mesh dimension : " << getMeshDimension() << ".";
2649 { stream << " No coordinates set !"; return ; }
2650 if(!_coords->isAllocated())
2651 { stream << " Coordinates set but not allocated !"; return ; }
2652 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
2653 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
2655 try { checkCoherency(); } catch(INTERP_KERNEL::Exception& /* e */)
2657 stream << std::endl << "Nodal connectivity NOT set properly !\n";
2661 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
2664 void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
2667 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
2668 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2670 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !");
2671 setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex());
2674 MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
2677 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
2678 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2680 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
2681 std::vector<const MEDCoupling1DGTUMesh *> ms(2);
2684 return Merge1DGTUMeshesOnSameCoords(ms);
2687 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
2690 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2691 ret->setCoords(_coords);
2692 DataArrayInt *c=0,*ci=0;
2693 MEDCouplingUMesh::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci);
2694 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2695 ret->setNodalConnectivity(c,ci);
2699 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
2702 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2703 ret->setCoords(_coords);
2704 DataArrayInt *c=0,*ci=0;
2705 MEDCouplingUMesh::ExtractFromIndexedArrays2(start,end,step,_conn,_conn_indx,c,ci);
2706 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2707 ret->setNodalConnectivity(c,ci);
2711 void MEDCoupling1DGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
2713 int sz((int)nodeIdsInUse.size());
2714 int nbCells(getNumberOfCells());
2715 const int *w(_conn->begin()),*wi(_conn_indx->begin());
2716 for(int i=0;i<nbCells;i++,wi++)
2717 for(const int *pt=w+wi[0];pt!=w+wi[1];pt++)
2720 if(*pt>=0 && *pt<sz)
2721 nodeIdsInUse[*pt]=true;
2724 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeNodeIdsAlg : At cell #" << i << " presence of node id #" << *pt << " should be in [0," << sz << ") !";
2725 throw INTERP_KERNEL::Exception(oss.str().c_str());
2730 void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const
2732 checkFullyDefined();
2733 int nbOfNodes=getNumberOfNodes();
2734 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
2735 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
2736 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
2737 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2738 int nbOfCells=getNumberOfCells();
2739 int nbOfEltsInRevNodal=0;
2740 for(int eltId=0;eltId<nbOfCells;eltId++)
2742 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2743 if(nbOfNodesPerCell>=0)
2745 for(int j=0;j<nbOfNodesPerCell;j++)
2747 int nodeId=conn[conni[eltId]+j];
2748 if(nodeId==-1) continue;
2749 if(nodeId>=0 && nodeId<nbOfNodes)
2751 nbOfEltsInRevNodal++;
2752 revNodalIndxPtr[nodeId+1]++;
2756 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
2757 throw INTERP_KERNEL::Exception(oss.str().c_str());
2763 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << "nodal connectivity is invalid !";
2764 throw INTERP_KERNEL::Exception(oss.str().c_str());
2767 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
2768 conn=_conn->begin();
2769 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
2770 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
2771 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
2772 for(int eltId=0;eltId<nbOfCells;eltId++)
2774 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2775 for(int j=0;j<nbOfNodesPerCell;j++)
2777 int nodeId=conn[conni[eltId]+j];
2779 *std::find_if(revNodalPtr+revNodalIndxPtr[nodeId],revNodalPtr+revNodalIndxPtr[nodeId+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
2784 void MEDCoupling1DGTUMesh::checkFullyDefined() const
2786 if(!((const DataArrayInt *)_conn) || !((const DataArrayInt *)_conn_indx) || !((const DataArrayDouble *)_coords))
2787 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined.");
2790 bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
2792 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !");
2795 void MEDCoupling1DGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
2798 double time=getTime(it,order);
2799 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
2801 littleStrings.push_back(getName());
2802 littleStrings.push_back(getDescription());
2803 littleStrings.push_back(getTimeUnit());
2805 std::vector<std::string> littleStrings2,littleStrings3,littleStrings4;
2806 if((const DataArrayDouble *)_coords)
2807 _coords->getTinySerializationStrInformation(littleStrings2);
2808 if((const DataArrayInt *)_conn)
2809 _conn->getTinySerializationStrInformation(littleStrings3);
2810 if((const DataArrayInt *)_conn_indx)
2811 _conn_indx->getTinySerializationStrInformation(littleStrings4);
2812 int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size()),sz2((int)littleStrings4.size());
2813 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
2814 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
2815 littleStrings.insert(littleStrings.end(),littleStrings4.begin(),littleStrings4.end());
2817 tinyInfo.push_back(getCellModelEnum());
2818 tinyInfo.push_back(it);
2819 tinyInfo.push_back(order);
2820 std::vector<int> tinyInfo2,tinyInfo3,tinyInfo4;
2821 if((const DataArrayDouble *)_coords)
2822 _coords->getTinySerializationIntInformation(tinyInfo2);
2823 if((const DataArrayInt *)_conn)
2824 _conn->getTinySerializationIntInformation(tinyInfo3);
2825 if((const DataArrayInt *)_conn_indx)
2826 _conn_indx->getTinySerializationIntInformation(tinyInfo4);
2827 int sz3((int)tinyInfo2.size()),sz4((int)tinyInfo3.size()),sz5((int)tinyInfo4.size());
2828 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3); tinyInfo.push_back(sz4); tinyInfo.push_back(sz5);
2829 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
2830 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
2831 tinyInfo.insert(tinyInfo.end(),tinyInfo4.begin(),tinyInfo4.end());
2833 tinyInfoD.push_back(time);
2836 void MEDCoupling1DGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
2838 std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+tinyInfo[6]);
2839 std::vector<int> tinyInfo1(tinyInfo.begin()+9+tinyInfo[6],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]);
2840 std::vector<int> tinyInfo12(tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]+tinyInfo[8]);
2841 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(DataArrayInt::New()); p1->resizeForUnserialization(tinyInfo1);
2842 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(DataArrayInt::New()); p2->resizeForUnserialization(tinyInfo12);
2843 std::vector<const DataArrayInt *> v(2); v[0]=p1; v[1]=p2;
2844 p2=DataArrayInt::Aggregate(v);
2845 a2->resizeForUnserialization(tinyInfo2);
2846 a1->alloc(p2->getNbOfElems(),1);
2849 void MEDCoupling1DGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
2852 if((const DataArrayInt *)_conn)
2853 if(_conn->isAllocated())
2854 sz=_conn->getNbOfElems();
2855 if((const DataArrayInt *)_conn_indx)
2856 if(_conn_indx->isAllocated())
2857 sz+=_conn_indx->getNbOfElems();
2858 a1=DataArrayInt::New();
2860 int *work(a1->getPointer());
2861 if(sz!=0 && (const DataArrayInt *)_conn)
2862 work=std::copy(_conn->begin(),_conn->end(),a1->getPointer());
2863 if(sz!=0 && (const DataArrayInt *)_conn_indx)
2864 std::copy(_conn_indx->begin(),_conn_indx->end(),work);
2866 if((const DataArrayDouble *)_coords)
2867 if(_coords->isAllocated())
2868 sz=_coords->getNbOfElems();
2869 a2=DataArrayDouble::New();
2871 if(sz!=0 && (const DataArrayDouble *)_coords)
2872 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
2875 void MEDCoupling1DGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
2876 const std::vector<std::string>& littleStrings)
2878 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
2879 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
2880 setName(littleStrings[0].c_str());
2881 setDescription(littleStrings[1].c_str());
2882 setTimeUnit(littleStrings[2].c_str());
2883 setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
2884 int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]),sz4(tinyInfo[7]),sz5(tinyInfo[8]);
2886 _coords=DataArrayDouble::New();
2887 std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+sz3);
2888 _coords->resizeForUnserialization(tinyInfo2);
2889 std::copy(a2->begin(),a2->end(),_coords->getPointer());
2890 _conn=DataArrayInt::New();
2891 std::vector<int> tinyInfo3(tinyInfo.begin()+9+sz3,tinyInfo.begin()+9+sz3+sz4);
2892 _conn->resizeForUnserialization(tinyInfo3);
2893 std::copy(a1->begin(),a1->begin()+_conn->getNbOfElems(),_conn->getPointer());
2894 _conn_indx=DataArrayInt::New();
2895 std::vector<int> tinyInfo4(tinyInfo.begin()+9+sz3+sz4,tinyInfo.begin()+9+sz3+sz4+sz5);
2896 _conn_indx->resizeForUnserialization(tinyInfo4);
2897 std::copy(a1->begin()+_conn->getNbOfElems(),a1->end(),_conn_indx->getPointer());
2898 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
2899 _coords->finishUnserialization(tinyInfo2,littleStrings2);
2900 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
2901 _conn->finishUnserialization(tinyInfo3,littleStrings3);
2902 std::vector<std::string> littleStrings4(littleStrings.begin()+3+sz0+sz1,littleStrings.begin()+3+sz0+sz1+sz2);
2903 _conn_indx->finishUnserialization(tinyInfo4,littleStrings4);
2907 * Finds nodes not used in any cell and returns an array giving a new id to every node
2908 * by excluding the unused nodes, for which the array holds -1. The result array is
2909 * a mapping in "Old to New" mode.
2910 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
2911 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
2912 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
2913 * if the node is unused or a new id else. The caller is to delete this
2914 * array using decrRef() as it is no more needed.
2915 * \throw If the coordinates array is not set.
2916 * \throw If the nodal connectivity of cells is not defined.
2917 * \throw If the nodal connectivity includes an invalid id.
2919 DataArrayInt *MEDCoupling1DGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
2922 int nbOfNodes=getNumberOfNodes();
2923 int nbOfCells=getNumberOfCells();//checkCoherency
2924 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2925 ret->alloc(nbOfNodes,1);
2926 int *traducer=ret->getPointer();
2927 std::fill(traducer,traducer+nbOfNodes,-1);
2928 const int *conn=_conn->begin(),*conni(_conn_indx->begin());
2929 for(int i=0;i<nbOfCells;i++,conni++)
2931 int nbNodesPerCell=conni[1]-conni[0];
2932 for(int j=0;j<nbNodesPerCell;j++)
2934 int nodeId=conn[conni[0]+j];
2935 if(nodeId==-1) continue;
2936 if(nodeId>=0 && nodeId<nbOfNodes)
2940 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << nodeId << " not in [0," << nbOfNodes << ") !";
2941 throw INTERP_KERNEL::Exception(oss.str().c_str());
2945 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
2946 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
2951 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
2952 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
2953 * This method is a generalization of shiftNodeNumbersInConn().
2954 * \warning This method performs no check of validity of new ids. **Use it with care !**
2955 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
2956 * this->getNumberOfNodes(), in "Old to New" mode.
2957 * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
2958 * \throw If the nodal connectivity of cells is not defined.
2960 void MEDCoupling1DGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
2962 getNumberOfCells();//only to check that all is well defined.
2964 int nbElemsIn=getNumberOfNodes();
2965 int nbOfTuples=_conn->getNumberOfTuples();
2966 int *pt=_conn->getPointer();
2967 for(int i=0;i<nbOfTuples;i++,pt++)
2969 if(*pt==-1) continue;
2970 if(*pt>=0 && *pt<nbElemsIn)
2971 *pt=newNodeNumbersO2N[*pt];
2974 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
2975 throw INTERP_KERNEL::Exception(oss.str().c_str());
2978 _conn->declareAsNew();
2984 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
2985 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
2986 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
2987 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
2989 * \param [in] begin input start of array of node ids.
2990 * \param [in] end input end of array of node ids.
2991 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
2992 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
2994 void MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
2996 int nbOfCells=getNumberOfCells();
2997 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
2999 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
3000 std::vector<bool> fastFinder(sz,false);
3001 for(const int *work=begin;work!=end;work++)
3002 if(*work>=0 && *work<sz)
3003 fastFinder[*work]=true;
3004 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
3005 for(int i=0;i<nbOfCells;i++,conni++)
3007 int ref=0,nbOfHit=0;
3008 int nbNodesPerCell=conni[1]-conni[0];
3009 if(nbNodesPerCell>=0)
3011 for(int j=0;j<nbNodesPerCell;j++)
3013 int nodeId=conn[conni[0]+j];
3017 if(fastFinder[nodeId])
3024 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !";
3025 throw INTERP_KERNEL::Exception(oss.str().c_str());
3027 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
3028 cellIdsKept->pushBackSilent(i);
3030 cellIdsKeptArr=cellIdsKept.retn();
3033 void MEDCoupling1DGTUMesh::allocateCells(int nbOfCells)
3036 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !");
3037 _conn=DataArrayInt::New();
3038 _conn->reserve(nbOfCells*3);
3039 _conn_indx=DataArrayInt::New();
3040 _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0);
3045 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
3047 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
3048 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
3049 * \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
3050 * attached to \a this.
3051 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
3053 void MEDCoupling1DGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd)
3055 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
3056 DataArrayInt *c(_conn),*c2(_conn_indx);
3060 if(pos==c->getNumberOfTuples())
3062 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
3063 c2->pushBackSilent(pos+sz);
3067 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !";
3068 throw INTERP_KERNEL::Exception(oss.str().c_str());
3072 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !");
3075 void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex)
3078 nodalConn->incrRef();
3081 nodalConnIndex->incrRef();
3082 _conn_indx=nodalConnIndex;
3087 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
3089 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivity() const
3091 const DataArrayInt *ret(_conn);
3092 return const_cast<DataArrayInt *>(ret);
3096 * \return DataArrayInt * - the internal reference to the nodal connectivity index. The caller is not reponsible to deallocate it.
3098 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const
3100 const DataArrayInt *ret(_conn_indx);
3101 return const_cast<DataArrayInt *>(ret);
3105 * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here".
3106 * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity).
3107 * 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.
3109 * 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.
3111 * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal
3112 * connectivity arrays are different (false)
3113 * \return a new object to be managed by the caller.
3115 * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked
3117 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const
3119 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
3120 DataArrayInt *nc=0,*nci=0;
3121 isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci);
3122 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ncs(nc),ncis(nci);
3123 ret->_conn=ncs; ret->_conn_indx=ncis;
3124 ret->setCoords(getCoords());
3129 * This method allows to compute, if needed, the packed nodal connectivity pair.
3130 * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges convered by nodal connectivity index array.
3131 * 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.
3133 * 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)
3134 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3136 * 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
3139 * This method return 3 elements.
3140 * \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
3141 * this pointer can be seen as a new object, that is to managed by the caller.
3142 * \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
3143 * this pointer can be seen as a new object, that is to managed by the caller.
3144 * \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
3145 * output parameters are newly created objects.
3147 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
3149 bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const
3151 if(isPacked())//performs the checkCoherency
3153 const DataArrayInt *c0(_conn),*c1(_conn_indx);
3154 nodalConn=const_cast<DataArrayInt *>(c0); nodalConnIndx=const_cast<DataArrayInt *>(c1);
3155 nodalConn->incrRef(); nodalConnIndx->incrRef();
3158 int bg=_conn_indx->front(),end=_conn_indx->back();
3159 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nc(_conn->selectByTupleId2(bg,end,1));
3160 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nci(_conn_indx->deepCpy());
3161 nci->applyLin(1,-bg);
3162 nodalConn=nc.retn(); nodalConnIndx=nci.retn();
3167 * 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)
3168 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3169 * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned.
3170 * \return bool - true if \a this looks packed, false is not.
3172 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
3174 bool MEDCoupling1DGTUMesh::isPacked() const
3177 return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples();
3180 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2)
3182 std::vector<const MEDCoupling1DGTUMesh *> tmp(2);
3183 tmp[0]=const_cast<MEDCoupling1DGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1DGTUMesh *>(mesh2);
3184 return Merge1DGTUMeshes(tmp);
3187 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a)
3189 std::size_t sz=a.size();
3191 return Merge1DGTUMeshesLL(a);
3192 for(std::size_t ii=0;ii<sz;ii++)
3195 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::Merge1DGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
3196 throw INTERP_KERNEL::Exception(oss.str().c_str());
3198 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
3199 for(std::size_t ii=0;ii<sz;ii++)
3200 if(&(a[ii]->getCellModel())!=cm)
3201 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !");
3202 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > bb(sz);
3203 std::vector< const MEDCoupling1DGTUMesh * > aa(sz);
3205 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
3207 const MEDCoupling1DGTUMesh *cur=a[i];
3208 const DataArrayDouble *coo=cur->getCoords();
3210 spaceDim=coo->getNumberOfComponents();
3213 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !");
3214 for(std::size_t i=0;i<sz;i++)
3216 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
3219 return Merge1DGTUMeshesLL(aa);
3223 * \throw If presence of a null instance in the input vector \a a.
3224 * \throw If a is empty
3226 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a)
3229 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !");
3230 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3232 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !");
3233 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
3234 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3235 (*it)->getNumberOfCells();//to check that all is OK
3236 const DataArrayDouble *coords=(*it)->getCoords();
3237 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3239 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3240 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3242 for(int i=1;it!=a.end();i++,it++)
3245 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !");
3246 if(cm!=&((*it)->getCellModel()))
3247 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3248 (*it)->getNumberOfCells();//to check that all is OK
3249 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3250 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3251 if(coords!=(*it)->getCoords())
3252 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !");
3254 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3255 ret->setCoords(coords);
3256 ret->_conn=DataArrayInt::Aggregate(ncs);
3257 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3262 * 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)
3264 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a)
3267 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : input array must be NON EMPTY !");
3268 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
3269 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3270 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3271 std::vector<int> nbNodesPerElt(a.size());
3272 int nbOfCells=(*it)->getNumberOfCells();
3274 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3275 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3277 int prevNbOfNodes=(*it)->getNumberOfNodes();
3278 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3280 for(int i=1;it!=a.end();i++,it++)
3282 if(cm!=&((*it)->getCellModel()))
3283 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3284 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3285 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3286 nbOfCells+=(*it)->getNumberOfCells();
3287 nbNodesPerElt[i]=nbNodesPerElt[i-1]+prevNbOfNodes;
3288 prevNbOfNodes=(*it)->getNumberOfNodes();
3290 std::vector<const MEDCouplingPointSet *> aps(a.size());
3291 std::copy(a.begin(),a.end(),aps.begin());
3292 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
3293 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3294 ret->setCoords(pts);
3295 ret->_conn=AggregateNodalConnAndShiftNodeIds(ncs,nbNodesPerElt);
3296 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3300 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(int spaceDim) const
3302 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
3303 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1,tmp2;
3304 const DataArrayInt *nodalConn(_conn),*nodalConnI(_conn_indx);
3307 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
3315 tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
3319 ret->_conn_indx=tmp2;
3323 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
3324 ret->setCoords(coords);
3327 ret->setCoords(_coords);
3332 * This method aggregate the bbox of each cell and put it into bbox parameter.
3334 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
3336 * \throw If \a this is not fully set (coordinates and connectivity).
3337 * \throw If a cell in \a this has no valid nodeId.
3339 DataArrayDouble *MEDCoupling1DGTUMesh::getBoundingBoxForBBTree() const
3341 checkFullyDefined();
3342 int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes());
3343 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
3344 double *bbox(ret->getPointer());
3345 for(int i=0;i<nbOfCells*spaceDim;i++)
3347 bbox[2*i]=std::numeric_limits<double>::max();
3348 bbox[2*i+1]=-std::numeric_limits<double>::max();
3350 const double *coordsPtr(_coords->getConstPointer());
3351 const int *conn(_conn->getConstPointer()),*connI(_conn_indx->getConstPointer());
3352 for(int i=0;i<nbOfCells;i++)
3354 int offset=connI[i];
3355 int nbOfNodesForCell(connI[i+1]-offset),kk(0);
3356 for(int j=0;j<nbOfNodesForCell;j++)
3358 int nodeId=conn[offset+j];
3359 if(nodeId>=0 && nodeId<nbOfNodes)
3361 for(int k=0;k<spaceDim;k++)
3363 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
3364 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
3371 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
3372 throw INTERP_KERNEL::Exception(oss.str().c_str());
3378 std::vector<int> MEDCoupling1DGTUMesh::BuildAPolygonFromParts(const std::vector< std::vector<int> >& parts)
3380 std::vector<int> ret;
3383 ret.insert(ret.end(),parts[0].begin(),parts[0].end());
3384 int ref(ret.back());
3385 std::size_t sz(parts.size()),nbh(1);
3386 std::vector<bool> b(sz,true); b[0]=false;
3390 for(;i<sz;i++) if(b[i] && parts[i].front()==ref) { ret.insert(ret.end(),parts[i].begin()+1,parts[i].end()); nbh++; break; }
3394 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::BuildAPolygonFromParts : the input vector is not a part of a single polygon !");
3396 if(ret.back()==ret.front())
3402 * This method performs an aggregation of \a nodalConns (as DataArrayInt::Aggregate does) but in addition of that a shift is applied on the
3403 * values contained in \a nodalConns using corresponding offset specified in input \a offsetInNodeIdsPerElt.
3404 * But it also manage the values -1, that have a semantic in MEDCoupling1DGTUMesh class (separator for polyhedron).
3406 * \param [in] nodalConns - a list of nodal connectivity arrays same size than \a offsetInNodeIdsPerElt.
3407 * \param [in] offsetInNodeIdsPerElt - a list of offsets to apply.
3408 * \return DataArrayInt * - A new object (to be managed by the caller) that is the result of the aggregation.
3409 * \throw If \a nodalConns or \a offsetInNodeIdsPerElt are empty.
3410 * \throw If \a nodalConns and \a offsetInNodeIdsPerElt have not the same size.
3411 * \throw If presence of null pointer in \a nodalConns.
3412 * \throw If presence of not allocated or array with not exactly one component in \a nodalConns.
3414 DataArrayInt *MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds(const std::vector<const DataArrayInt *>& nodalConns, const std::vector<int>& offsetInNodeIdsPerElt)
3416 std::size_t sz1(nodalConns.size()),sz2(offsetInNodeIdsPerElt.size());
3418 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : input vectors do not have the same size !");
3420 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : empty vectors in input !");
3422 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++)
3425 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of null pointer in input vector !");
3426 if(!(*it)->isAllocated())
3427 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of non allocated array in input vector !");
3428 if((*it)->getNumberOfComponents()!=1)
3429 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of array with not exactly one component !");
3430 nbOfTuples+=(*it)->getNumberOfTuples();
3432 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
3433 int *pt=ret->getPointer();
3435 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++,i++)
3437 int curNbt=(*it)->getNumberOfTuples();
3438 const int *inPt=(*it)->begin();
3439 int offset=offsetInNodeIdsPerElt[i];
3440 for(int j=0;j<curNbt;j++,pt++)
3451 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m)
3454 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh is null !");
3455 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
3457 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh must have exactly one geometric type !");
3458 int geoType((int)*gts.begin());
3459 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(m->getName().c_str(),*gts.begin()));
3460 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription().c_str());
3461 int nbCells(m->getNumberOfCells());
3462 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
3463 conn->alloc(m->getMeshLength()-nbCells,1); connI->alloc(nbCells+1,1);
3464 int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
3465 const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
3466 for(int i=0;i<nbCells;i++,ciin++,ci++)
3468 if(cin[ciin[0]]==geoType)
3470 if(ciin[1]-ciin[0]>=1)
3472 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
3473 ci[1]=ci[0]+ciin[1]-ciin[0]-1;
3477 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 !";
3478 throw INTERP_KERNEL::Exception(oss.str().c_str());
3483 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 !";
3484 throw INTERP_KERNEL::Exception(oss.str().c_str());
3487 ret->setNodalConnectivity(conn,connI);