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 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh()
33 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):_cm(&cm)
38 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const MEDCoupling1GTUMesh& other, bool recDeepCpy):MEDCouplingPointSet(other,recDeepCpy),_cm(other._cm)
42 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
44 if(type==INTERP_KERNEL::NORM_ERROR)
45 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
46 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
48 return MEDCoupling1SGTUMesh::New(name,type);
50 return MEDCoupling1DGTUMesh::New(name,type);
53 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception)
56 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh is null !");
57 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
59 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh must have exactly one geometric type !");
60 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*gts.begin());
62 return MEDCoupling1SGTUMesh::New(m);
64 return MEDCoupling1DGTUMesh::New(m);
67 const INTERP_KERNEL::CellModel& MEDCoupling1GTUMesh::getCellModel() const throw(INTERP_KERNEL::Exception)
72 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getCellModelEnum() const throw(INTERP_KERNEL::Exception)
74 return _cm->getEnum();
77 int MEDCoupling1GTUMesh::getMeshDimension() const
79 return (int)_cm->getDimension();
83 * This method returns a newly allocated array containing cell ids (ascendingly sorted) whose geometric type are equal to type.
84 * This method does not throw exception if geometric type \a type is not in \a this.
85 * This method throws an INTERP_KERNEL::Exception if meshdimension of \b this is not equal to those of \b type.
86 * The coordinates array is not considered here.
88 * \param [in] type the geometric type
89 * \return cell ids in this having geometric type \a type.
91 DataArrayInt *MEDCoupling1GTUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception)
93 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
94 if(type==getCellModelEnum())
95 ret->alloc(getNumberOfCells(),1);
103 * Returns nb of cells having the geometric type \a type. No throw if no cells in \a this has the geometric type \a type.
105 int MEDCoupling1GTUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
107 return type==getCellModelEnum()?getNumberOfCells():0;
111 * Returns a type of a cell by its id.
112 * \param [in] cellId - the id of the cell of interest.
113 * \return INTERP_KERNEL::NormalizedCellType - enumeration item describing the cell type.
114 * \throw If \a cellId is invalid. Valid range is [0, \a this->getNumberOfCells() ).
116 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getTypeOfCell(int cellId) const
118 if(cellId>=0 && cellId<getNumberOfCells())
119 return getCellModelEnum();
120 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::getTypeOfCell : Requesting type of cell #" << cellId << " but it should be in [0," << getNumberOfCells() << ") !";
121 throw INTERP_KERNEL::Exception(oss.str().c_str());
125 * Returns a set of all cell types available in \a this mesh.
126 * \return std::set<INTERP_KERNEL::NormalizedCellType> - the set of cell types.
127 * \warning this method does not throw any exception even if \a this is not defined.
129 std::set<INTERP_KERNEL::NormalizedCellType> MEDCoupling1GTUMesh::getAllGeoTypes() const
131 std::set<INTERP_KERNEL::NormalizedCellType> ret;
132 ret.insert(getCellModelEnum());
137 * This method expects that \a this is sorted by types. If not an exception will be thrown.
138 * This method returns in the same format as code (see MEDCouplingUMesh::checkTypeConsistencyAndContig or MEDCouplingUMesh::splitProfilePerType) how
139 * \a this is composed in cell types.
140 * The returned array is of size 3*n where n is the number of different types present in \a this.
141 * For every k in [0,n] ret[3*k+2]==-1 because it has no sense here.
142 * This parameter is kept only for compatibility with other methode listed above.
144 std::vector<int> MEDCoupling1GTUMesh::getDistributionOfTypes() const throw(INTERP_KERNEL::Exception)
146 std::vector<int> ret(3);
147 ret[0]=(int)getCellModelEnum(); ret[1]=getNumberOfCells(); ret[2]=-1;
152 * 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.
153 * 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.
154 * This method has 1 input \a profile and 3 outputs \a code \a idsInPflPerType and \a idsPerType.
156 * \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.
157 * \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,
158 * \a idsInPflPerType[i] stores the tuple ids in \a profile that correspond to the geometric type code[3*i+0]
159 * \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.
160 * This vector can be empty in case of all geometric type cells are fully covered in ascending in the given input \a profile.
162 * \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.
164 * \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
167 * - Before \a this has 3 cells \a profile contains [0,1,2]
168 * - After \a code contains [NORM_...,nbCells,-1], \a idsInPflPerType [[0,1,2]] and \a idsPerType is empty <br>
171 * - Before \a this has 3 cells \a profile contains [1,2]
172 * - After \a code contains [NORM_...,nbCells,0], \a idsInPflPerType [[0,1]] and \a idsPerType is [[1,2]] <br>
175 void MEDCoupling1GTUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
178 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile is NULL !");
179 if(profile->getNumberOfComponents()!=1)
180 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile should have exactly one component !");
181 int nbTuples=profile->getNumberOfTuples();
182 int nbOfCells=getNumberOfCells();
183 code.resize(3); idsInPflPerType.resize(1);
184 code[0]=(int)getCellModelEnum(); code[1]=nbTuples;
185 idsInPflPerType.resize(1);
186 if(profile->isIdentity() && nbTuples==nbOfCells)
189 idsInPflPerType[0]=const_cast<DataArrayInt *>(profile); idsInPflPerType[0]->incrRef();
194 profile->checkAllIdsInRange(0,nbOfCells);
195 idsPerType.resize(1);
196 idsPerType[0]=const_cast<DataArrayInt *>(profile); idsPerType[0]->incrRef();
197 idsInPflPerType[0]=DataArrayInt::Range(0,nbTuples,1);
201 * This method tries to minimize at most the number of deep copy.
202 * So if \a idsPerType is not empty it can be returned directly (without copy, but with ref count incremented) in return.
204 * \sa MEDCouplingUMesh::checkTypeConsistencyAndContig
206 DataArrayInt *MEDCoupling1GTUMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
208 int nbOfCells=getNumberOfCells();
210 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : invalid input code should be exactly of size 3 !");
211 if(code[0]!=(int)getCellModelEnum())
213 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() << ") !";
214 throw INTERP_KERNEL::Exception(oss.str().c_str());
218 if(code[1]==nbOfCells)
222 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : mismatch between the number of cells in this (" << nbOfCells << ") and the number of non profile (" << code[1] << ") !";
223 throw INTERP_KERNEL::Exception(oss.str().c_str());
227 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : single geo type mesh ! 0 or -1 is expected at pos #2 of input code !");
228 if(idsPerType.size()!=1)
229 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input code points to DataArrayInt #0 whereas the size of idsPerType is not equal to 1 !");
230 const DataArrayInt *pfl=idsPerType[0];
232 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : the input code points to a NULL DataArrayInt at rank 0 !");
233 if(pfl->getNumberOfComponents()!=1)
234 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input profile should have exactly one component !");
235 pfl->checkAllIdsInRange(0,nbOfCells);
237 return const_cast<DataArrayInt *>(pfl);
240 void MEDCoupling1GTUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception)
242 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
243 m->writeVTKLL(ofs,cellData,pointData);
246 std::string MEDCoupling1GTUMesh::getVTKDataSetType() const throw(INTERP_KERNEL::Exception)
248 return std::string("UnstructuredGrid");
251 std::size_t MEDCoupling1GTUMesh::getHeapMemorySize() const
253 return MEDCouplingPointSet::getHeapMemorySize();
256 bool MEDCoupling1GTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
258 if(!MEDCouplingPointSet::isEqualIfNotWhy(other,prec,reason))
261 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualIfNotWhy : input other pointer is null !");
262 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
265 reason="mesh given in input is not castable in MEDCouplingSGTUMesh !";
270 reason="mismatch in geometric type !";
276 bool MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
278 if(!MEDCouplingPointSet::isEqualWithoutConsideringStr(other,prec))
281 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
282 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
290 void MEDCoupling1GTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
292 MEDCouplingPointSet::checkCoherency();
295 DataArrayDouble *MEDCoupling1GTUMesh::getBarycenterAndOwner() const
297 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
298 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=m->getBarycenterAndOwner();
302 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureField(bool isAbs) const
304 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
305 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureField(isAbs);
310 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureFieldOnNode(bool isAbs) const
312 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
313 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureFieldOnNode(isAbs);
321 int MEDCoupling1GTUMesh::getCellContainingPoint(const double *pos, double eps) const
323 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
324 return m->getCellContainingPoint(pos,eps);
327 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::buildOrthogonalField() const
329 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
330 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->buildOrthogonalField();
335 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const double *bbox, double eps) const
337 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
338 return m->getCellsInBoundingBox(bbox,eps);
341 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps)
343 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
344 return m->getCellsInBoundingBox(bbox,eps);
347 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const
349 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
350 return m->buildFacePartOfMySelfNode(start,end,fullyIn);
353 DataArrayInt *MEDCoupling1GTUMesh::findBoundaryNodes() const
355 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
356 return m->findBoundaryNodes();
359 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildBoundaryMesh(bool keepCoords) const
361 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
362 return m->buildBoundaryMesh(keepCoords);
365 void MEDCoupling1GTUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const throw(INTERP_KERNEL::Exception)
367 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
368 m->findCommonCells(compType,startCellId,commonCellsArr,commonCellsIArr);
371 int MEDCoupling1GTUMesh::getNodalConnectivityLength() const throw(INTERP_KERNEL::Exception)
373 const DataArrayInt *c1(getNodalConnectivity());
375 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : no connectivity set !");
376 if(c1->getNumberOfComponents()!=1)
377 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array set must have exactly one component !");
378 if(!c1->isAllocated())
379 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array must be allocated !");
380 return c1->getNumberOfTuples();
384 * This method aggregates all the meshes in \a parts to put them in a single unstructured mesh (those returned).
385 * The order of cells is the returned instance is those in the order of instances in \a parts.
387 * \param [in] parts - all not null parts of single geo type meshes to be aggreagated having the same mesh dimension and same coordinates.
388 * \return MEDCouplingUMesh * - new object to be dealt by the caller.
390 * \throw If one element is null in \a parts.
391 * \throw If not all the parts do not have the same mesh dimension.
392 * \throw If not all the parts do not share the same coordinates.
393 * \throw If not all the parts have their connectivity set properly.
394 * \throw If \a parts is empty.
396 MEDCouplingUMesh *MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh(const std::vector< const MEDCoupling1GTUMesh *>& parts) throw(INTERP_KERNEL::Exception)
399 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : input parts vector is empty !");
400 const MEDCoupling1GTUMesh *firstPart(parts[0]);
402 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : the first instance in input parts is null !");
403 const DataArrayDouble *coords(firstPart->getCoords());
404 int meshDim(firstPart->getMeshDimension());
405 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret(MEDCouplingUMesh::New(firstPart->getName().c_str(),meshDim)); ret->setDescription(firstPart->getDescription().c_str());
406 ret->setCoords(coords);
407 int nbOfCells(0),connSize(0);
408 for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
411 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of null pointer in input vector !");
412 if((*it)->getMeshDimension()!=meshDim)
413 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances in input vector must have same mesh dimension !");
414 if((*it)->getCoords()!=coords)
415 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances must share the same coordinates pointer !");
416 nbOfCells+=(*it)->getNumberOfCells();
417 connSize+=(*it)->getNodalConnectivityLength();
419 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
420 connI->alloc(nbOfCells+1,1); conn->alloc(connSize+nbOfCells,1);
421 int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
422 for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
424 int curNbCells((*it)->getNumberOfCells());
425 int geoType((int)(*it)->getCellModelEnum());
426 const int *cinPtr((*it)->getNodalConnectivity()->begin());
427 const MEDCoupling1SGTUMesh *ps(dynamic_cast<const MEDCoupling1SGTUMesh *>(*it));
428 const MEDCoupling1DGTUMesh *pd(dynamic_cast<const MEDCoupling1DGTUMesh *>(*it));
431 int nNodesPerCell(ps->getNumberOfNodesPerCell());
432 for(int i=0;i<curNbCells;i++,ci++,cinPtr+=nNodesPerCell)
435 c=std::copy(cinPtr,cinPtr+nNodesPerCell,c);
436 ci[1]=ci[0]+nNodesPerCell+1;
441 const int *ciinPtr(pd->getNodalConnectivityIndex()->begin());
442 for(int i=0;i<curNbCells;i++,ci++,ciinPtr++)
445 c=std::copy(cinPtr+ciinPtr[0],cinPtr+ciinPtr[1],c);
446 ci[1]=ci[0]+ciinPtr[1]-ciinPtr[0]+1;
450 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of instance which type is not in [MEDCoupling1SGTUMesh,MEDCoupling1DGTUMesh] !");
452 ret->setConnectivity(conn,connI,true);
458 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const MEDCoupling1SGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
462 const DataArrayInt *c(other._conn);
468 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
472 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh()
476 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New()
478 return new MEDCoupling1SGTUMesh;
481 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
483 if(type==INTERP_KERNEL::NORM_ERROR)
484 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
485 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
488 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New : the input geometric type " << cm.getRepr() << " is dynamic ! Only static types are allowed here !";
489 throw INTERP_KERNEL::Exception(oss.str().c_str());
491 return new MEDCoupling1SGTUMesh(name,cm);
494 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception)
497 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh is null !");
498 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
500 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh must have exactly one geometric type !");
501 int geoType((int)*gts.begin());
502 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(m->getName().c_str(),*gts.begin()));
503 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription().c_str());
504 int nbCells(m->getNumberOfCells());
505 int nbOfNodesPerCell(ret->getNumberOfNodesPerCell());
506 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()); conn->alloc(nbCells*nbOfNodesPerCell,1);
507 int *c(conn->getPointer());
508 const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
509 for(int i=0;i<nbCells;i++,ciin++)
511 if(cin[ciin[0]]==geoType)
513 if(ciin[1]-ciin[0]==nbOfNodesPerCell+1)
514 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
517 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 << ") !";
518 throw INTERP_KERNEL::Exception(oss.str().c_str());
523 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 !";
524 throw INTERP_KERNEL::Exception(oss.str().c_str());
527 ret->setNodalConnectivity(conn);
531 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::clone(bool recDeepCpy) const
533 return new MEDCoupling1SGTUMesh(*this,recDeepCpy);
537 * This method behaves mostly like MEDCoupling1SGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
538 * The coordinates are shared between \a this and the returned instance.
540 * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
541 * \sa MEDCoupling1SGTUMesh::deepCpy
543 MEDCouplingPointSet *MEDCoupling1SGTUMesh::deepCpyConnectivityOnly() const throw(INTERP_KERNEL::Exception)
546 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(clone(false));
547 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy());
548 ret->setNodalConnectivity(c);
552 void MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception)
555 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
556 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
558 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1SGTUMesh instance !");
559 setNodalConnectivity(otherC->getNodalConnectivity());
562 void MEDCoupling1SGTUMesh::updateTime() const
564 MEDCoupling1GTUMesh::updateTime();
565 const DataArrayInt *c(_conn);
570 std::size_t MEDCoupling1SGTUMesh::getHeapMemorySize() const
573 const DataArrayInt *c(_conn);
575 ret+=c->getHeapMemorySize();
576 return MEDCoupling1GTUMesh::getHeapMemorySize()+ret;
579 MEDCouplingMesh *MEDCoupling1SGTUMesh::deepCpy() const
584 bool MEDCoupling1SGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
587 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualIfNotWhy : input other pointer is null !");
588 std::ostringstream oss; oss.precision(15);
589 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
592 reason="mesh given in input is not castable in MEDCoupling1SGTUMesh !";
595 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
597 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
602 reason="in connectivity of single static geometric type exactly one among this and other is null !";
605 if(!c1->isEqualIfNotWhy(*c2,reason))
607 reason.insert(0,"Nodal connectivity DataArrayInt differ : ");
613 bool MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
616 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
617 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
620 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
622 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
627 if(!c1->isEqualWithoutConsideringStr(*c2))
632 void MEDCoupling1SGTUMesh::checkCoherencyOfConnectivity() const throw(INTERP_KERNEL::Exception)
634 const DataArrayInt *c1(_conn);
637 if(c1->getNumberOfComponents()!=1)
638 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
639 if(c1->getInfoOnComponent(0)!="")
640 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
641 c1->checkAllocated();
644 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
647 void MEDCoupling1SGTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
649 MEDCouplingPointSet::checkCoherency();
650 checkCoherencyOfConnectivity();
653 void MEDCoupling1SGTUMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
656 const DataArrayInt *c1(_conn);
657 int nbOfTuples=c1->getNumberOfTuples();
658 int nbOfNodesPerCell=(int)_cm->getNumberOfNodes();
659 if(nbOfTuples%nbOfNodesPerCell!=0)
661 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 !";
662 throw INTERP_KERNEL::Exception(oss.str().c_str());
664 int nbOfNodes=getNumberOfNodes();
665 int nbOfCells=nbOfTuples/nbOfNodesPerCell;
666 const int *w(c1->begin());
667 for(int i=0;i<nbOfCells;i++)
668 for(int j=0;j<nbOfNodesPerCell;j++,w++)
670 if(*w<0 || *w>=nbOfNodes)
672 std::ostringstream oss; oss << "At node #" << j << " of cell #" << i << ", is equal to " << *w << " must be in [0," << nbOfNodes << ") !";
673 throw INTERP_KERNEL::Exception(oss.str().c_str());
678 void MEDCoupling1SGTUMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
680 checkCoherency1(eps);
683 int MEDCoupling1SGTUMesh::getNumberOfCells() const
685 int nbOfTuples=getNodalConnectivityLength();
686 int nbOfNodesPerCell=getNumberOfNodesPerCell();
687 if(nbOfTuples%nbOfNodesPerCell!=0)
689 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 !";
690 throw INTERP_KERNEL::Exception(oss.str().c_str());
692 return nbOfTuples/nbOfNodesPerCell;
695 int MEDCoupling1SGTUMesh::getNumberOfNodesInCell(int cellId) const throw(INTERP_KERNEL::Exception)
697 return getNumberOfNodesPerCell();
700 int MEDCoupling1SGTUMesh::getNumberOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
702 checkNonDynamicGeoType();
703 return (int)_cm->getNumberOfNodes();
706 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
708 checkNonDynamicGeoType();
709 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
710 ret->alloc(getNumberOfCells(),1);
711 ret->fillWithValue((int)_cm->getNumberOfNodes());
715 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception)
717 checkNonDynamicGeoType();
718 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
719 ret->alloc(getNumberOfCells(),1);
720 ret->fillWithValue((int)_cm->getNumberOfSons());
724 DataArrayInt *MEDCoupling1SGTUMesh::computeEffectiveNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
726 checkNonDynamicGeoType();
727 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
728 int nbCells(getNumberOfCells());
729 ret->alloc(nbCells,1);
730 int *retPtr(ret->getPointer());
731 int nbNodesPerCell(getNumberOfNodesPerCell());
732 const int *conn(_conn->begin());
733 for(int i=0;i<nbCells;i++,conn+=nbNodesPerCell,retPtr++)
735 std::set<int> s(conn,conn+nbNodesPerCell);
736 *retPtr=(int)s.size();
741 void MEDCoupling1SGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
743 int sz=getNumberOfNodesPerCell();
745 if(cellId>=0 && cellId<getNumberOfCells())
746 std::copy(_conn->begin()+cellId*sz,_conn->begin()+(cellId+1)*sz,conn.begin());
749 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << getNumberOfCells() << ") !";
750 throw INTERP_KERNEL::Exception(oss.str().c_str());
754 void MEDCoupling1SGTUMesh::checkNonDynamicGeoType() const throw(INTERP_KERNEL::Exception)
757 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkNonDynamicGeoType : internal error ! the internal geo type is dynamic ! should be static !");
760 std::string MEDCoupling1SGTUMesh::simpleRepr() const
762 static const char msg0[]="No coordinates specified !";
763 std::ostringstream ret;
764 ret << "Single static geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
765 ret << "Description of mesh : \"" << getDescription() << "\"\n";
767 double tt=getTime(tmpp1,tmpp2);
768 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
769 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
770 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
773 const int spaceDim=getSpaceDimension();
774 ret << spaceDim << "\nInfo attached on space dimension : ";
775 for(int i=0;i<spaceDim;i++)
776 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
781 ret << "Number of nodes : ";
783 ret << getNumberOfNodes() << "\n";
786 ret << "Number of cells : ";
787 if((const DataArrayInt *)_conn)
789 if(_conn->isAllocated())
791 if(_conn->getNumberOfComponents()==1)
792 ret << getNumberOfCells() << "\n";
794 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
797 ret << "Nodal connectivity array specified but not allocated !" << "\n";
800 ret << "No connectivity specified !" << "\n";
801 ret << "Cell type : " << _cm->getRepr() << "\n";
805 std::string MEDCoupling1SGTUMesh::advancedRepr() const
807 std::ostringstream ret;
809 ret << "\nCoordinates array : \n___________________\n\n";
811 _coords->reprWithoutNameStream(ret);
813 ret << "No array set !\n";
814 ret << "\n\nConnectivity array : \n____________________\n\n";
816 if((const DataArrayInt *)_conn)
818 if(_conn->isAllocated())
820 if(_conn->getNumberOfComponents()==1)
822 int nbOfCells=getNumberOfCells();
823 int sz=getNumberOfNodesPerCell();
824 const int *connPtr=_conn->begin();
825 for(int i=0;i<nbOfCells;i++,connPtr+=sz)
827 ret << "Cell #" << i << " : ";
828 std::copy(connPtr,connPtr+sz,std::ostream_iterator<int>(ret," "));
833 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
836 ret << "Nodal connectivity array specified but not allocated !" << "\n";
839 ret << "No connectivity specified !" << "\n";
843 DataArrayDouble *MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
845 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
846 int spaceDim=getSpaceDimension();
847 int nbOfCells=getNumberOfCells();//checkCoherency()
848 int nbOfNodes=getNumberOfNodes();
849 ret->alloc(nbOfCells,spaceDim);
850 double *ptToFill=ret->getPointer();
851 const double *coor=_coords->begin();
852 const int *nodal=_conn->begin();
853 int sz=getNumberOfNodesPerCell();
854 double coeff=1./(double)sz;
855 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim)
857 std::fill(ptToFill,ptToFill+spaceDim,0.);
858 for(int j=0;j<sz;j++,nodal++)
859 if(*nodal>=0 && *nodal<nbOfNodes)
860 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
863 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
864 throw INTERP_KERNEL::Exception(oss.str().c_str());
866 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),coeff));
871 void MEDCoupling1SGTUMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
873 int nbCells=getNumberOfCells();
874 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
875 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
877 o2n=o2n->checkAndPreparePermutation();
879 const int *conn=_conn->begin();
880 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o=o2n->invertArrayO2N2N2O(nbCells);
881 const int *n2oPtr=n2o->begin();
882 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
883 newConn->alloc(_conn->getNumberOfTuples(),1);
884 newConn->copyStringInfoFrom(*_conn);
885 int sz=getNumberOfNodesPerCell();
887 int *newC=newConn->getPointer();
888 for(int i=0;i<nbCells;i++,newC+=sz)
891 std::copy(conn+pos*sz,conn+(pos+1)*sz,newC);
897 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
898 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
899 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
900 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
902 * \param [in] begin input start of array of node ids.
903 * \param [in] end input end of array of node ids.
904 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
905 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
907 void MEDCoupling1SGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
909 int nbOfCells=getNumberOfCells();
910 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
912 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
913 std::vector<bool> fastFinder(sz,false);
914 for(const int *work=begin;work!=end;work++)
915 if(*work>=0 && *work<sz)
916 fastFinder[*work]=true;
917 const int *conn=_conn->begin();
918 int nbNodesPerCell=getNumberOfNodesPerCell();
919 for(int i=0;i<nbOfCells;i++,conn+=nbNodesPerCell)
922 for(int j=0;j<nbNodesPerCell;j++)
926 if(fastFinder[conn[j]])
929 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
930 cellIdsKept->pushBackSilent(i);
932 cellIdsKeptArr=cellIdsKept.retn();
935 MEDCouplingMesh *MEDCoupling1SGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
937 if(other->getType()!=SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED)
938 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single static geo type each other !");
939 const MEDCoupling1SGTUMesh *otherC=static_cast<const MEDCoupling1SGTUMesh *>(other);
940 return Merge1SGTUMeshes(this,otherC);
943 MEDCouplingUMesh *MEDCoupling1SGTUMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
945 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName().c_str(),getMeshDimension());
946 ret->setCoords(getCoords());
947 const int *nodalConn=_conn->begin();
948 int nbCells=getNumberOfCells();
949 int nbNodesPerCell=getNumberOfNodesPerCell();
950 int geoType=(int)getCellModelEnum();
951 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells*(nbNodesPerCell+1),1);
952 int *cPtr=c->getPointer();
953 for(int i=0;i<nbCells;i++,nodalConn+=nbNodesPerCell)
956 cPtr=std::copy(nodalConn,nodalConn+nbNodesPerCell,cPtr);
958 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::Range(0,(nbCells+1)*(nbNodesPerCell+1),nbNodesPerCell+1);
959 ret->setConnectivity(c,cI,true);
963 DataArrayInt *MEDCoupling1SGTUMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
968 return simplexizePol0();
970 return simplexizePol1();
971 case (int) INTERP_KERNEL::PLANAR_FACE_5:
972 return simplexizePlanarFace5();
973 case (int) INTERP_KERNEL::PLANAR_FACE_6:
974 return simplexizePlanarFace6();
976 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)");
982 struct MEDCouplingAccVisit
984 MEDCouplingAccVisit():_new_nb_of_nodes(0) { }
985 int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; }
986 int _new_nb_of_nodes;
992 * Finds nodes not used in any cell and returns an array giving a new id to every node
993 * by excluding the unused nodes, for which the array holds -1. The result array is
994 * a mapping in "Old to New" mode.
995 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
996 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
997 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
998 * if the node is unused or a new id else. The caller is to delete this
999 * array using decrRef() as it is no more needed.
1000 * \throw If the coordinates array is not set.
1001 * \throw If the nodal connectivity of cells is not defined.
1002 * \throw If the nodal connectivity includes an invalid id.
1004 DataArrayInt *MEDCoupling1SGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception)
1007 int nbOfNodes=getNumberOfNodes();
1008 int nbOfCells=getNumberOfCells();
1009 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1010 ret->alloc(nbOfNodes,1);
1011 int *traducer=ret->getPointer();
1012 std::fill(traducer,traducer+nbOfNodes,-1);
1013 const int *conn=_conn->begin();
1014 int nbNodesPerCell=getNumberOfNodesPerCell();
1015 for(int i=0;i<nbOfCells;i++)
1016 for(int j=0;j<nbNodesPerCell;j++,conn++)
1017 if(*conn>=0 && *conn<nbOfNodes)
1021 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << conn[j] << " not in [0," << nbOfNodes << ") !";
1022 throw INTERP_KERNEL::Exception(oss.str().c_str());
1024 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
1025 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
1030 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
1031 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
1032 * This method is a generalization of shiftNodeNumbersInConn().
1033 * \warning This method performs no check of validity of new ids. **Use it with care !**
1034 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
1035 * this->getNumberOfNodes(), in "Old to New" mode.
1036 * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
1037 * \throw If the nodal connectivity of cells is not defined.
1039 void MEDCoupling1SGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
1041 getNumberOfCells();//only to check that all is well defined.
1042 _conn->transformWithIndArr(newNodeNumbersO2N,newNodeNumbersO2N+getNumberOfNodes());
1046 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2) throw(INTERP_KERNEL::Exception)
1048 std::vector<const MEDCoupling1SGTUMesh *> tmp(2);
1049 tmp[0]=const_cast<MEDCoupling1SGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1SGTUMesh *>(mesh2);
1050 return Merge1SGTUMeshes(tmp);
1053 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
1055 std::size_t sz=a.size();
1057 return Merge1SGTUMeshesLL(a);
1058 for(std::size_t ii=0;ii<sz;ii++)
1061 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::Merge1SGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
1062 throw INTERP_KERNEL::Exception(oss.str().c_str());
1064 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
1065 for(std::size_t ii=0;ii<sz;ii++)
1066 if(&(a[ii]->getCellModel())!=cm)
1067 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : all items must have the same geo type !");
1068 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> > bb(sz);
1069 std::vector< const MEDCoupling1SGTUMesh * > aa(sz);
1071 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
1073 const MEDCoupling1SGTUMesh *cur=a[i];
1074 const DataArrayDouble *coo=cur->getCoords();
1076 spaceDim=coo->getNumberOfComponents();
1079 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : no spaceDim specified ! unable to perform merge !");
1080 for(std::size_t i=0;i<sz;i++)
1082 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
1085 return Merge1SGTUMeshesLL(aa);
1089 * \throw If presence of a null instance in the input vector \a a.
1090 * \throw If a is empty
1092 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
1095 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : input array must be NON EMPTY !");
1096 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1098 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : null instance in the first element of input vector !");
1099 std::vector<const DataArrayInt *> ncs(a.size());
1100 int nbOfCells=(*it)->getNumberOfCells();
1101 const DataArrayDouble *coords=(*it)->getCoords();
1102 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1103 int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
1104 ncs[0]=(*it)->getNodalConnectivity();
1106 for(int i=1;it!=a.end();i++,it++)
1109 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : presence of a null instance in the input vector !");
1110 if(cm!=&((*it)->getCellModel()))
1111 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1112 (*it)->getNumberOfCells();//to check that all is OK
1113 ncs[i]=(*it)->getNodalConnectivity();
1114 if(coords!=(*it)->getCoords())
1115 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : not lying on same coords !");
1117 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1118 ret->setCoords(coords);
1119 ret->_conn=DataArrayInt::Aggregate(ncs);
1124 * 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)
1126 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
1129 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : input array must be NON EMPTY !");
1130 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1131 int nbOfCells=(*it)->getNumberOfCells();
1132 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1133 int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
1135 for(;it!=a.end();it++)
1137 if(cm!=&((*it)->getCellModel()))
1138 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1139 nbOfCells+=(*it)->getNumberOfCells();
1141 std::vector<const MEDCouplingPointSet *> aps(a.size());
1142 std::copy(a.begin(),a.end(),aps.begin());
1143 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
1144 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1145 ret->setCoords(pts);
1146 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New();
1147 c->alloc(nbOfCells*nbNodesPerCell,1);
1148 int *cPtr=c->getPointer();
1150 for(it=a.begin();it!=a.end();it++)
1152 int curConnLgth=(*it)->getNodalConnectivityLength();
1153 const int *curC=(*it)->_conn->begin();
1154 cPtr=std::transform(curC,curC+curConnLgth,cPtr,std::bind2nd(std::plus<int>(),offset));
1155 offset+=(*it)->getNumberOfNodes();
1158 ret->setNodalConnectivity(c);
1162 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
1164 int ncell=getNumberOfCells();
1165 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName().c_str(),*_cm));
1166 ret->setCoords(_coords);
1167 std::size_t nbOfElemsRet=std::distance(begin,end);
1168 const int *inConn=_conn->getConstPointer();
1169 int sz=getNumberOfNodesPerCell();
1170 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1171 int *connPtr=connRet->getPointer();
1172 for(const int *work=begin;work!=end;work++,connPtr+=sz)
1174 if(*work>=0 && *work<ncell)
1175 std::copy(inConn+(work[0])*sz,inConn+(work[0]+1)*sz,connPtr);
1178 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !";
1179 throw INTERP_KERNEL::Exception(oss.str().c_str());
1183 ret->copyTinyInfoFrom(this);
1187 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
1189 int ncell=getNumberOfCells();
1190 int nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : ");
1191 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName().c_str(),*_cm));
1192 ret->setCoords(_coords);
1193 const int *inConn=_conn->getConstPointer();
1194 int sz=getNumberOfNodesPerCell();
1195 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1196 int *connPtr=connRet->getPointer();
1198 for(int i=0;i<nbOfElemsRet;i++,connPtr+=sz,curId+=step)
1200 if(curId>=0 && curId<ncell)
1201 std::copy(inConn+curId*sz,inConn+(curId+1)*sz,connPtr);
1204 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : On pos #" << i << " input cell id =" << curId << " should be in [0," << ncell << ") !";
1205 throw INTERP_KERNEL::Exception(oss.str().c_str());
1209 ret->copyTinyInfoFrom(this);
1213 void MEDCoupling1SGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const throw(INTERP_KERNEL::Exception)
1215 int sz((int)nodeIdsInUse.size());
1216 int nbCells(getNumberOfCells());
1217 int nbOfNodesPerCell(getNumberOfNodesPerCell());
1218 const int *w(_conn->begin());
1219 for(int i=0;i<nbCells;i++)
1220 for(int j=0;j<nbOfNodesPerCell;j++,w++)
1223 nodeIdsInUse[*w]=true;
1226 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeNodeIdsAlg : At cell #" << i << " presence of node id #" << *w << " should be in [0," << sz << ") !";
1227 throw INTERP_KERNEL::Exception(oss.str().c_str());
1232 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception)
1234 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName().c_str(),*_cm));
1235 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1;
1236 const DataArrayInt *nodalConn(_conn);
1239 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
1246 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
1247 ret->setCoords(coords);
1250 ret->setCoords(_coords);
1254 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol0() throw(INTERP_KERNEL::Exception)
1256 int nbOfCells=getNumberOfCells();
1257 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1258 return DataArrayInt::Range(0,nbOfCells,1);
1259 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1260 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1261 const int *c(_conn->begin());
1262 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1263 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1265 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[2];
1266 newConnPtr[3]=c[0]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1267 retPtr[0]=i; retPtr[1]=i;
1270 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1275 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol1() throw(INTERP_KERNEL::Exception)
1277 int nbOfCells=getNumberOfCells();
1278 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1279 return DataArrayInt::Range(0,nbOfCells,1);
1280 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1281 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1282 const int *c(_conn->begin());
1283 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1284 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1286 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[3];
1287 newConnPtr[3]=c[1]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1288 retPtr[0]=i; retPtr[1]=i;
1291 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1296 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace5() throw(INTERP_KERNEL::Exception)
1298 int nbOfCells=getNumberOfCells();
1299 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1300 return DataArrayInt::Range(0,nbOfCells,1);
1301 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(5*4*nbOfCells,1);
1302 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(5*nbOfCells,1);
1303 const int *c(_conn->begin());
1304 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1305 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=20,retPtr+=5)
1307 for(int j=0;j<20;j++)
1308 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_5_WO[j]];
1309 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i;
1312 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1317 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace6() throw(INTERP_KERNEL::Exception)
1319 int nbOfCells=getNumberOfCells();
1320 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1321 return DataArrayInt::Range(0,nbOfCells,1);
1322 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(6*4*nbOfCells,1);
1323 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(6*nbOfCells,1);
1324 const int *c(_conn->begin());
1325 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1326 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=24,retPtr+=6)
1328 for(int j=0;j<24;j++)
1329 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_6_WO[j]];
1330 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i; retPtr[5]=i;
1333 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1338 void MEDCoupling1SGTUMesh::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1340 stream << "MEDCoupling1SGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
1341 stream << " Mesh dimension : " << getMeshDimension() << ".";
1343 { stream << " No coordinates set !"; return ; }
1344 if(!_coords->isAllocated())
1345 { stream << " Coordinates set but not allocated !"; return ; }
1346 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
1347 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
1348 if(!(const DataArrayInt *)_conn)
1349 { stream << std::endl << "Nodal connectivity NOT set !"; return ; }
1350 if(_conn->isAllocated())
1352 if(_conn->getNumberOfComponents()==1)
1353 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
1357 void MEDCoupling1SGTUMesh::checkFullyDefined() const throw(INTERP_KERNEL::Exception)
1359 if(!((const DataArrayInt *)_conn) || !((const DataArrayDouble *)_coords))
1360 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFullyDefined : part of this is not fully defined.");
1364 * First step of unserialization process.
1366 bool MEDCoupling1SGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
1368 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEmptyMesh : not implemented yet !");
1372 * Checks if \a this and \a other meshes are geometrically equivalent with high
1373 * probability, else an exception is thrown. The meshes are considered equivalent if
1374 * (1) meshes contain the same number of nodes and the same number of elements of the
1375 * same types (2) three cells of the two meshes (first, last and middle) are based
1376 * on coincident nodes (with a specified precision).
1377 * \param [in] other - the mesh to compare with.
1378 * \param [in] prec - the precision used to compare nodes of the two meshes.
1379 * \throw If the two meshes do not match.
1381 void MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception)
1383 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1384 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1386 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single static geometric type !");
1387 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1391 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1392 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1393 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1394 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1395 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1396 if(c1->getHashCode()!=c2->getHashCode())
1397 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1400 MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
1403 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
1404 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1406 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
1407 std::vector<const MEDCoupling1SGTUMesh *> ms(2);
1410 return Merge1SGTUMeshesOnSameCoords(ms);
1413 void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception)
1415 checkFullyDefined();
1416 int nbOfNodes=getNumberOfNodes();
1417 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
1418 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
1419 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
1420 const int *conn=_conn->begin();
1421 int nbOfCells=getNumberOfCells();
1422 int nbOfEltsInRevNodal=0;
1423 int nbOfNodesPerCell=getNumberOfNodesPerCell();
1424 for(int eltId=0;eltId<nbOfCells;eltId++)
1426 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1428 if(conn[0]>=0 && conn[0]<nbOfNodes)
1430 nbOfEltsInRevNodal++;
1431 revNodalIndxPtr[conn[0]+1]++;
1435 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
1436 throw INTERP_KERNEL::Exception(oss.str().c_str());
1440 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
1441 conn=_conn->begin();
1442 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
1443 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
1444 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
1445 for(int eltId=0;eltId<nbOfCells;eltId++)
1447 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1449 *std::find_if(revNodalPtr+revNodalIndxPtr[*conn],revNodalPtr+revNodalIndxPtr[*conn+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
1455 * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null.
1457 void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn) throw(INTERP_KERNEL::Exception)
1460 nodalConn->incrRef();
1466 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
1468 DataArrayInt *MEDCoupling1SGTUMesh::getNodalConnectivity() const throw(INTERP_KERNEL::Exception)
1470 const DataArrayInt *ret(_conn);
1471 return const_cast<DataArrayInt *>(ret);
1475 * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted,
1476 * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter.
1477 * If a nodal connectivity previouly existed before the call of this method, it will be reset.
1479 * \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain.
1481 void MEDCoupling1SGTUMesh::allocateCells(int nbOfCells) throw(INTERP_KERNEL::Exception)
1484 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !");
1485 _conn=DataArrayInt::New();
1486 _conn->reserve(getNumberOfNodesPerCell()*nbOfCells);
1491 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
1493 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
1494 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
1495 * \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
1496 * attached to \a this.
1497 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
1499 void MEDCoupling1SGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) throw(INTERP_KERNEL::Exception)
1501 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
1502 int ref=getNumberOfNodesPerCell();
1505 DataArrayInt *c(_conn);
1507 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
1509 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !");
1513 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this (";
1514 oss << ref << ") !";
1515 throw INTERP_KERNEL::Exception(oss.str().c_str());
1520 * This method builds the dual mesh of \a this and returns it.
1522 * \return MEDCoupling1SGTUMesh * - newly object created to be managed by the caller.
1523 * \throw If \a this is not a mesh containing only simplex cells.
1524 * \throw If \a this is not correctly allocated (coordinates and connectivities have to be correctly set !).
1525 * \throw If at least one node in \a this is orphan (without any simplex cell lying on it !)
1527 MEDCoupling1GTUMesh *MEDCoupling1SGTUMesh::computeDualMesh() const throw(INTERP_KERNEL::Exception)
1529 const INTERP_KERNEL::CellModel& cm(getCellModel());
1531 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : this mesh is not a simplex mesh ! Please invoke simplexize of tetrahedrize on this before calling this method !");
1532 switch(getMeshDimension())
1535 return computeDualMesh3D();
1537 return computeDualMesh2D();
1539 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : meshdimension must be in [2,3] !");
1543 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh3D() const throw(INTERP_KERNEL::Exception)
1545 static const int DUAL_TETRA_0[36]={
1546 4,1,0, 6,0,3, 7,3,1,
1547 4,0,1, 5,2,0, 8,1,2,
1548 6,3,0, 5,0,2, 9,2,3,
1551 static const int DUAL_TETRA_1[36]={
1552 8,4,10, 11,5,8, 10,7,11,
1553 9,4,8, 8,5,12, 12,6,9,
1554 10,4,9, 9,6,13, 13,7,10,
1555 12,5,11, 13,6,12, 11,7,13
1557 static const int FACEID_NOT_SH_NODE[4]={2,3,1,0};
1558 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TETRA4)
1559 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh3D : only TETRA4 supported !");
1560 checkFullyDefined();
1561 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured());
1562 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1563 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1564 const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1565 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d1Arr(DataArrayInt::New()),di1Arr(DataArrayInt::New()),rd1Arr(DataArrayInt::New()),rdi1Arr(DataArrayInt::New());
1566 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->explode3DMeshTo1D(d1Arr,di1Arr,rd1Arr,rdi1Arr));
1567 const int *d1(d1Arr->begin());
1568 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1569 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> faces(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
1570 const int *d2(d2Arr->begin()),*rd2(rd2Arr->begin()),*rdi2(rdi2Arr->begin());
1571 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),facesBaryArr(faces->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
1572 const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+faces->getNumberOfCells()),offset1(offset0+edges->getNumberOfCells());
1574 std::vector<const DataArrayDouble *> v(4); v[0]=getCoords(); v[1]=facesBaryArr; v[2]=edgesBaryArr; v[3]=baryArr;
1575 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0; facesBaryArr=0;
1576 std::string name("DualOf_"); name+=getName();
1577 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name.c_str(),INTERP_KERNEL::NORM_POLYHED)); ret->setCoords(zeArr);
1578 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1579 for(int i=0;i<nbOfNodes;i++,revNodI++)
1581 int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1582 if(nbOfCellsSharingNode==0)
1584 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh3D : Node #" << i << " is orphan !";
1585 throw INTERP_KERNEL::Exception(oss.str().c_str());
1587 for(int j=0;j<nbOfCellsSharingNode;j++)
1589 int curCellId(revNod[revNodI[0]+j]);
1590 const int *connOfCurCell(nodal+4*curCellId);
1591 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1592 if(j!=0) cArr->pushBackSilent(-1);
1595 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;
1596 tmp[2]=curCellId+offset1; tmp[3]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+2]]+nbOfNodes;
1598 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;
1599 tmp[7]=curCellId+offset1; tmp[8]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+5]]+nbOfNodes;
1601 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;
1602 tmp[12]=curCellId+offset1; tmp[13]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+8]]+nbOfNodes;
1603 cArr->insertAtTheEnd(tmp,tmp+14);
1605 for(int k=0;k<4;k++)
1607 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1609 const int *faceId(d2+4*curCellId+k);
1610 if(rdi2[*faceId+1]-rdi2[*faceId]==1)
1612 int tmp2[5]; tmp2[0]=-1; tmp2[1]=i;
1613 tmp2[2]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+0]-8]+offset0;
1614 tmp2[3]=d2[4*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+1]-4]+nbOfNodes;
1615 tmp2[4]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+2]-8]+offset0;
1616 cArr->insertAtTheEnd(tmp2,tmp2+5);
1622 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
1624 ret->setNodalConnectivity(cArr,ciArr);
1628 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh2D() const throw(INTERP_KERNEL::Exception)
1630 static const int DUAL_TRI_0[6]={0,2, 1,0, 2,1};
1631 static const int DUAL_TRI_1[6]={-3,+5, +3,-4, +4,-5};
1632 static const int FACEID_NOT_SH_NODE[3]={1,2,0};
1633 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TRI3)
1634 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh2D : only TRI3 supported !");
1635 checkFullyDefined();
1636 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured());
1637 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1638 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1639 const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1640 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1641 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
1642 const int *d2(d2Arr->begin()),*rd2(rd2Arr->begin()),*rdi2(rdi2Arr->begin());
1643 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
1644 const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+edges->getNumberOfCells());
1646 std::vector<const DataArrayDouble *> v(3); v[0]=getCoords(); v[1]=edgesBaryArr; v[2]=baryArr;
1647 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0;
1648 std::string name("DualOf_"); name+=getName();
1649 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name.c_str(),INTERP_KERNEL::NORM_POLYGON)); ret->setCoords(zeArr);
1650 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1651 for(int i=0;i<nbOfNodes;i++,revNodI++)
1653 int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1654 if(nbOfCellsSharingNode==0)
1656 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh2D : Node #" << i << " is orphan !";
1657 throw INTERP_KERNEL::Exception(oss.str().c_str());
1659 std::vector< std::vector<int> > polyg;
1660 for(int j=0;j<nbOfCellsSharingNode;j++)
1662 int curCellId(revNod[revNodI[0]+j]);
1663 const int *connOfCurCell(nodal+3*curCellId);
1664 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1665 std::vector<int> locV(3);
1666 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;
1667 polyg.push_back(locV);
1669 for(int k=0;k<3;k++)
1671 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1673 const int *edgeId(d2+3*curCellId+k);
1674 if(rdi2[*edgeId+1]-rdi2[*edgeId]==1)
1676 std::vector<int> locV2(2);
1677 int zeLocEdgeIdRel(DUAL_TRI_1[2*nodePosInCurCell+kk]);
1678 if(zeLocEdgeIdRel>0)
1679 { locV2[0]=d2[3*curCellId+zeLocEdgeIdRel-3]+nbOfNodes; locV2[1]=i; }
1681 { locV2[0]=i; locV2[1]=d2[3*curCellId-zeLocEdgeIdRel-3]+nbOfNodes; }
1682 polyg.push_back(locV2);
1688 std::vector<int> zePolyg(MEDCoupling1DGTUMesh::BuildAPolygonFromParts(polyg));
1689 cArr->insertAtTheEnd(zePolyg.begin(),zePolyg.end());
1690 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
1692 ret->setNodalConnectivity(cArr,ciArr);
1698 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New()
1700 return new MEDCoupling1DGTUMesh;
1703 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
1705 if(type==INTERP_KERNEL::NORM_ERROR)
1706 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
1707 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
1710 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !";
1711 throw INTERP_KERNEL::Exception(oss.str().c_str());
1713 return new MEDCoupling1DGTUMesh(name,cm);
1716 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh()
1720 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
1724 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
1728 const DataArrayInt *c(other._conn);
1733 _conn_indx=c->deepCpy();
1737 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const
1739 return new MEDCoupling1DGTUMesh(*this,recDeepCpy);
1743 * This method behaves mostly like MEDCoupling1DGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
1744 * The coordinates are shared between \a this and the returned instance.
1746 * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
1747 * \sa MEDCoupling1DGTUMesh::deepCpy
1749 MEDCouplingPointSet *MEDCoupling1DGTUMesh::deepCpyConnectivityOnly() const throw(INTERP_KERNEL::Exception)
1752 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(clone(false));
1753 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy()),ci(_conn_indx->deepCpy());
1754 ret->setNodalConnectivity(c,ci);
1758 void MEDCoupling1DGTUMesh::updateTime() const
1760 MEDCoupling1GTUMesh::updateTime();
1761 const DataArrayInt *c(_conn);
1769 std::size_t MEDCoupling1DGTUMesh::getHeapMemorySize() const
1772 const DataArrayInt *c(_conn);
1774 ret+=c->getHeapMemorySize();
1777 ret+=c->getHeapMemorySize();
1778 return MEDCoupling1GTUMesh::getHeapMemorySize()+ret;
1781 MEDCouplingMesh *MEDCoupling1DGTUMesh::deepCpy() const
1786 bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
1789 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !");
1790 std::ostringstream oss; oss.precision(15);
1791 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1794 reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !";
1797 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
1799 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1804 reason="in connectivity of single dynamic geometric type exactly one among this and other is null !";
1807 if(!c1->isEqualIfNotWhy(*c2,reason))
1809 reason.insert(0,"Nodal connectivity DataArrayInt differs : ");
1812 c1=_conn_indx; c2=otherC->_conn_indx;
1817 reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !";
1820 if(!c1->isEqualIfNotWhy(*c2,reason))
1822 reason.insert(0,"Nodal connectivity index DataArrayInt differs : ");
1828 bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
1831 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
1832 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1835 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
1837 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1842 if(!c1->isEqualWithoutConsideringStr(*c2))
1845 c1=_conn_indx; c2=otherC->_conn_indx;
1850 if(!c1->isEqualWithoutConsideringStr(*c2))
1856 * Checks if \a this and \a other meshes are geometrically equivalent with high
1857 * probability, else an exception is thrown. The meshes are considered equivalent if
1858 * (1) meshes contain the same number of nodes and the same number of elements of the
1859 * same types (2) three cells of the two meshes (first, last and middle) are based
1860 * on coincident nodes (with a specified precision).
1861 * \param [in] other - the mesh to compare with.
1862 * \param [in] prec - the precision used to compare nodes of the two meshes.
1863 * \throw If the two meshes do not match.
1865 void MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception)
1867 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1868 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1870 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single dynamic geometric type !");
1871 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1875 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1876 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1877 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1878 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1879 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1880 if(c1->getHashCode()!=c2->getHashCode())
1881 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1883 c1=_conn_indx; c2=otherC->_conn_indx;
1887 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !");
1888 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1889 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !");
1890 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1891 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !");
1892 if(c1->getHashCode()!=c2->getHashCode())
1893 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs");
1897 void MEDCoupling1DGTUMesh::checkCoherencyOfConnectivity() const throw(INTERP_KERNEL::Exception)
1899 const DataArrayInt *c1(_conn);
1902 if(c1->getNumberOfComponents()!=1)
1903 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
1904 if(c1->getInfoOnComponent(0)!="")
1905 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
1906 c1->checkAllocated();
1909 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
1911 int sz2=_conn->getNumberOfTuples();
1915 if(c1->getNumberOfComponents()!=1)
1916 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
1917 c1->checkAllocated();
1918 if(c1->getNumberOfTuples()<1)
1919 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !");
1920 if(c1->getInfoOnComponent(0)!="")
1921 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
1922 int f=c1->front(),ll=c1->back();
1925 std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !";
1926 throw INTERP_KERNEL::Exception(oss.str().c_str());
1930 std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !";
1931 throw INTERP_KERNEL::Exception(oss.str().c_str());
1935 std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !";
1936 throw INTERP_KERNEL::Exception(oss.str().c_str());
1940 throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !");
1941 int szOfC1Exp=_conn_indx->back();
1944 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() << " !";
1945 throw INTERP_KERNEL::Exception(oss.str().c_str());
1950 * 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.
1951 * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one.
1952 * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array.
1954 void MEDCoupling1DGTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
1956 MEDCouplingPointSet::checkCoherency();
1957 checkCoherencyOfConnectivity();
1960 void MEDCoupling1DGTUMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
1963 const DataArrayInt *c1(_conn),*c2(_conn_indx);
1964 if(!c2->isMonotonic(true))
1965 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkCoherency1 : the nodal connectivity index is expected to be increasing monotinic !");
1967 int nbOfTuples=c1->getNumberOfTuples();
1968 int nbOfNodes=getNumberOfNodes();
1969 const int *w(c1->begin());
1970 for(int i=0;i<nbOfTuples;i++,w++)
1972 if(*w==-1) continue;
1973 if(*w<0 || *w>=nbOfNodes)
1975 std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !";
1976 throw INTERP_KERNEL::Exception(oss.str().c_str());
1981 void MEDCoupling1DGTUMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
1983 checkCoherency1(eps);
1986 int MEDCoupling1DGTUMesh::getNumberOfCells() const
1988 checkCoherencyOfConnectivity();//do not remove
1989 return _conn_indx->getNumberOfTuples()-1;
1993 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
1994 * For each cell in \b this the number of nodes constituting cell is computed.
1995 * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned.
1996 * So for pohyhedrons some nodes can be counted several times in the returned result.
1998 * \return a newly allocated array
2000 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
2003 _conn_indx->checkMonotonic(true);
2004 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2005 return _conn_indx->deltaShiftIndex();
2007 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2008 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2009 ret->alloc(nbOfCells,1);
2010 int *retPtr=ret->getPointer();
2011 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2012 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2013 *retPtr=ci[1]-ci[0]-std::count(c+ci[0],c+ci[1],-1);
2018 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2019 * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed.
2021 * \return a newly allocated array
2023 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception)
2026 _conn_indx->checkMonotonic(true);
2027 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG)
2028 return _conn_indx->deltaShiftIndex();
2029 if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG)
2031 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=_conn_indx->deltaShiftIndex();
2032 ret->applyDivideBy(2);
2036 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2037 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2038 ret->alloc(nbOfCells,1);
2039 int *retPtr=ret->getPointer();
2040 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2041 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2042 *retPtr=std::count(c+ci[0],c+ci[1],-1)+1;
2047 * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell,
2048 * will be counted only once here whereas it will be counted several times in MEDCoupling1DGTUMesh::computeNbOfNodesPerCell method.
2050 * \return DataArrayInt * - new object to be deallocated by the caller.
2051 * \sa MEDCoupling1DGTUMesh::computeNbOfNodesPerCell
2053 DataArrayInt *MEDCoupling1DGTUMesh::computeEffectiveNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
2056 _conn_indx->checkMonotonic(true);
2057 int nbOfCells(_conn_indx->getNumberOfTuples()-1);
2058 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2059 ret->alloc(nbOfCells,1);
2060 int *retPtr(ret->getPointer());
2061 const int *ci(_conn_indx->begin()),*c(_conn->begin());
2062 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2064 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2066 std::set<int> s(c+ci[0],c+ci[1]);
2067 *retPtr=(int)s.size();
2072 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2074 std::set<int> s(c+ci[0],c+ci[1]); s.erase(-1);
2075 *retPtr=(int)s.size();
2081 void MEDCoupling1DGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
2083 int nbOfCells(getNumberOfCells());//performs checks
2084 if(cellId>=0 && cellId<nbOfCells)
2086 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2087 int nbOfNodes=stp-strt;
2089 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !");
2090 conn.resize(nbOfNodes);
2091 std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin());
2095 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2096 throw INTERP_KERNEL::Exception(oss.str().c_str());
2100 int MEDCoupling1DGTUMesh::getNumberOfNodesInCell(int cellId) const throw(INTERP_KERNEL::Exception)
2102 int nbOfCells(getNumberOfCells());//performs checks
2103 if(cellId>=0 && cellId<nbOfCells)
2105 const int *conn(_conn->begin());
2106 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2107 return stp-strt-std::count(conn+strt,conn+stp,-1);
2111 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNumberOfNodesInCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2112 throw INTERP_KERNEL::Exception(oss.str().c_str());
2116 std::string MEDCoupling1DGTUMesh::simpleRepr() const
2118 static const char msg0[]="No coordinates specified !";
2119 std::ostringstream ret;
2120 ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
2121 ret << "Description of mesh : \"" << getDescription() << "\"\n";
2123 double tt=getTime(tmpp1,tmpp2);
2124 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
2125 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
2126 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
2129 const int spaceDim=getSpaceDimension();
2130 ret << spaceDim << "\nInfo attached on space dimension : ";
2131 for(int i=0;i<spaceDim;i++)
2132 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
2136 ret << msg0 << "\n";
2137 ret << "Number of nodes : ";
2139 ret << getNumberOfNodes() << "\n";
2141 ret << msg0 << "\n";
2142 ret << "Number of cells : ";
2144 try { checkCoherency(); } catch(INTERP_KERNEL::Exception& e)
2146 ret << "Nodal connectivity arrays are not set or badly set !\n";
2150 ret << getNumberOfCells() << "\n";
2151 ret << "Cell type : " << _cm->getRepr() << "\n";
2155 std::string MEDCoupling1DGTUMesh::advancedRepr() const
2157 std::ostringstream ret;
2158 ret << simpleRepr();
2159 ret << "\nCoordinates array : \n___________________\n\n";
2161 _coords->reprWithoutNameStream(ret);
2163 ret << "No array set !\n";
2164 ret << "\n\nNodal Connectivity : \n____________________\n\n";
2167 try { checkCoherency1(); } catch(INTERP_KERNEL::Exception& e)
2169 ret << "Nodal connectivity arrays are not set or badly set !\n";
2174 int nbOfCells=getNumberOfCells();
2175 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2176 for(int i=0;i<nbOfCells;i++,ci++)
2178 ret << "Cell #" << i << " : ";
2179 std::copy(c+ci[0],c+ci[1],std::ostream_iterator<int>(ret," "));
2185 DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
2187 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
2188 int spaceDim=getSpaceDimension();
2189 int nbOfCells=getNumberOfCells();//checkCoherency()
2190 int nbOfNodes=getNumberOfNodes();
2191 ret->alloc(nbOfCells,spaceDim);
2192 double *ptToFill=ret->getPointer();
2193 const double *coor=_coords->begin();
2194 const int *nodal=_conn->begin(),*nodali=_conn_indx->begin();
2196 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2198 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2200 std::fill(ptToFill,ptToFill+spaceDim,0.);
2201 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2203 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2205 if(*nodal>=0 && *nodal<nbOfNodes)
2206 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2209 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2210 throw INTERP_KERNEL::Exception(oss.str().c_str());
2212 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(nodali[1]-nodali[0])));
2217 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !";
2218 throw INTERP_KERNEL::Exception(oss.str().c_str());
2224 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2226 std::fill(ptToFill,ptToFill+spaceDim,0.);
2227 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2230 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2232 if(*nodal==-1) continue;
2233 if(*nodal>=0 && *nodal<nbOfNodes)
2235 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2240 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2241 throw INTERP_KERNEL::Exception(oss.str().c_str());
2245 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./nbOfNod));
2248 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !";
2249 throw INTERP_KERNEL::Exception(oss.str().c_str());
2254 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : at cell #" << i << " the nodal index array is invalid !";
2255 throw INTERP_KERNEL::Exception(oss.str().c_str());
2262 void MEDCoupling1DGTUMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
2264 int nbCells=getNumberOfCells();
2265 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
2266 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
2268 o2n=o2n->checkAndPreparePermutation();
2270 const int *o2nPtr=o2n->getPointer();
2271 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2272 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
2273 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
2274 newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1);
2275 newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx);
2277 int *newC=newConn->getPointer(),*newCI=newConnI->getPointer();
2278 for(int i=0;i<nbCells;i++)
2280 int newPos=o2nPtr[i];
2281 int sz=conni[i+1]-conni[i];
2286 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !";
2287 throw INTERP_KERNEL::Exception(oss.str().c_str());
2290 newConnI->computeOffsets2(); newCI=newConnI->getPointer();
2292 for(int i=0;i<nbCells;i++,conni++)
2294 int sz=conni[1]-conni[0];
2296 std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]);
2299 _conn_indx=newConnI;
2302 MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
2304 if(other->getType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED)
2305 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !");
2306 const MEDCoupling1DGTUMesh *otherC=static_cast<const MEDCoupling1DGTUMesh *>(other);
2307 return Merge1DGTUMeshes(this,otherC);
2310 MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
2312 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName().c_str(),getMeshDimension());
2313 ret->setCoords(getCoords());
2314 const int *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin();
2315 int nbCells=getNumberOfCells();//checkCoherency
2316 int geoType=(int)getCellModelEnum();
2317 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1);
2318 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::New(); cI->alloc(nbCells+1);
2319 int *cPtr=c->getPointer(),*ciPtr=cI->getPointer();
2321 for(int i=0;i<nbCells;i++,ciPtr++)
2323 int sz=nodalConnI[i+1]-nodalConnI[i];
2327 cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr);
2328 ciPtr[1]=ciPtr[0]+sz+1;
2332 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !";
2333 throw INTERP_KERNEL::Exception(oss.str().c_str());
2336 ret->setConnectivity(c,cI,true);
2341 * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes
2343 DataArrayInt *MEDCoupling1DGTUMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
2345 int nbOfCells=getNumberOfCells();
2346 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2347 ret->alloc(nbOfCells,1);
2352 void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
2354 stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
2355 stream << " Mesh dimension : " << getMeshDimension() << ".";
2357 { stream << " No coordinates set !"; return ; }
2358 if(!_coords->isAllocated())
2359 { stream << " Coordinates set but not allocated !"; return ; }
2360 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
2361 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
2363 try { checkCoherency(); } catch(INTERP_KERNEL::Exception& e)
2365 stream << std::endl << "Nodal connectivity NOT set properly !\n";
2369 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
2372 void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception)
2375 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
2376 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2378 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !");
2379 setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex());
2382 MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
2385 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
2386 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2388 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
2389 std::vector<const MEDCoupling1DGTUMesh *> ms(2);
2392 return Merge1DGTUMeshesOnSameCoords(ms);
2395 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
2398 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2399 ret->setCoords(_coords);
2400 DataArrayInt *c=0,*ci=0;
2401 MEDCouplingUMesh::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci);
2402 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2403 ret->setNodalConnectivity(c,ci);
2407 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
2410 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2411 ret->setCoords(_coords);
2412 DataArrayInt *c=0,*ci=0;
2413 MEDCouplingUMesh::ExtractFromIndexedArrays2(start,end,step,_conn,_conn_indx,c,ci);
2414 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2415 ret->setNodalConnectivity(c,ci);
2419 void MEDCoupling1DGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const throw(INTERP_KERNEL::Exception)
2421 int sz((int)nodeIdsInUse.size());
2422 int nbCells(getNumberOfCells());
2423 const int *w(_conn->begin()),*wi(_conn_indx->begin());
2424 for(int i=0;i<nbCells;i++,wi++)
2425 for(const int *pt=w+wi[0];pt!=w+wi[1];pt++)
2428 if(*pt>=0 && *pt<sz)
2429 nodeIdsInUse[*pt]=true;
2432 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeNodeIdsAlg : At cell #" << i << " presence of node id #" << *pt << " should be in [0," << sz << ") !";
2433 throw INTERP_KERNEL::Exception(oss.str().c_str());
2438 void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception)
2440 checkFullyDefined();
2441 int nbOfNodes=getNumberOfNodes();
2442 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
2443 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
2444 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
2445 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2446 int nbOfCells=getNumberOfCells();
2447 int nbOfEltsInRevNodal=0;
2448 for(int eltId=0;eltId<nbOfCells;eltId++)
2450 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2451 if(nbOfNodesPerCell>=0)
2453 for(int j=0;j<nbOfNodesPerCell;j++)
2455 int nodeId=conn[conni[eltId]+j];
2456 if(nodeId==-1) continue;
2457 if(nodeId>=0 && nodeId<nbOfNodes)
2459 nbOfEltsInRevNodal++;
2460 revNodalIndxPtr[nodeId+1]++;
2464 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
2465 throw INTERP_KERNEL::Exception(oss.str().c_str());
2471 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << "nodal connectivity is invalid !";
2472 throw INTERP_KERNEL::Exception(oss.str().c_str());
2475 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
2476 conn=_conn->begin();
2477 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
2478 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
2479 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
2480 for(int eltId=0;eltId<nbOfCells;eltId++)
2482 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2483 for(int j=0;j<nbOfNodesPerCell;j++)
2485 int nodeId=conn[conni[eltId]+j];
2487 *std::find_if(revNodalPtr+revNodalIndxPtr[nodeId],revNodalPtr+revNodalIndxPtr[nodeId+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
2492 void MEDCoupling1DGTUMesh::checkFullyDefined() const throw(INTERP_KERNEL::Exception)
2494 if(!((const DataArrayInt *)_conn) || !((const DataArrayInt *)_conn_indx) || !((const DataArrayDouble *)_coords))
2495 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined.");
2498 bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
2500 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !");
2504 * Finds nodes not used in any cell and returns an array giving a new id to every node
2505 * by excluding the unused nodes, for which the array holds -1. The result array is
2506 * a mapping in "Old to New" mode.
2507 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
2508 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
2509 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
2510 * if the node is unused or a new id else. The caller is to delete this
2511 * array using decrRef() as it is no more needed.
2512 * \throw If the coordinates array is not set.
2513 * \throw If the nodal connectivity of cells is not defined.
2514 * \throw If the nodal connectivity includes an invalid id.
2516 DataArrayInt *MEDCoupling1DGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception)
2519 int nbOfNodes=getNumberOfNodes();
2520 int nbOfCells=getNumberOfCells();//checkCoherency
2521 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2522 ret->alloc(nbOfNodes,1);
2523 int *traducer=ret->getPointer();
2524 std::fill(traducer,traducer+nbOfNodes,-1);
2525 const int *conn=_conn->begin(),*conni(_conn_indx->begin());
2526 for(int i=0;i<nbOfCells;i++,conni++)
2528 int nbNodesPerCell=conni[1]-conni[0];
2529 for(int j=0;j<nbNodesPerCell;j++)
2531 int nodeId=conn[conni[0]+j];
2532 if(nodeId==-1) continue;
2533 if(nodeId>=0 && nodeId<nbOfNodes)
2537 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << nodeId << " not in [0," << nbOfNodes << ") !";
2538 throw INTERP_KERNEL::Exception(oss.str().c_str());
2542 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
2543 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
2548 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
2549 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
2550 * This method is a generalization of shiftNodeNumbersInConn().
2551 * \warning This method performs no check of validity of new ids. **Use it with care !**
2552 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
2553 * this->getNumberOfNodes(), in "Old to New" mode.
2554 * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
2555 * \throw If the nodal connectivity of cells is not defined.
2557 void MEDCoupling1DGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
2559 getNumberOfCells();//only to check that all is well defined.
2561 int nbElemsIn=getNumberOfNodes();
2562 int nbOfTuples=_conn->getNumberOfTuples();
2563 int *pt=_conn->getPointer();
2564 for(int i=0;i<nbOfTuples;i++,pt++)
2566 if(*pt==-1) continue;
2567 if(*pt>=0 && *pt<nbElemsIn)
2568 *pt=newNodeNumbersO2N[*pt];
2571 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
2572 throw INTERP_KERNEL::Exception(oss.str().c_str());
2575 _conn->declareAsNew();
2581 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
2582 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
2583 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
2584 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
2586 * \param [in] begin input start of array of node ids.
2587 * \param [in] end input end of array of node ids.
2588 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
2589 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
2591 void MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
2593 int nbOfCells=getNumberOfCells();
2594 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
2596 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
2597 std::vector<bool> fastFinder(sz,false);
2598 for(const int *work=begin;work!=end;work++)
2599 if(*work>=0 && *work<sz)
2600 fastFinder[*work]=true;
2601 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2602 for(int i=0;i<nbOfCells;i++,conni++)
2604 int ref=0,nbOfHit=0;
2605 int nbNodesPerCell=conni[1]-conni[0];
2606 if(nbNodesPerCell>=0)
2608 for(int j=0;j<nbNodesPerCell;j++)
2610 int nodeId=conn[conni[0]+j];
2614 if(fastFinder[nodeId])
2621 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !";
2622 throw INTERP_KERNEL::Exception(oss.str().c_str());
2624 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
2625 cellIdsKept->pushBackSilent(i);
2627 cellIdsKeptArr=cellIdsKept.retn();
2630 void MEDCoupling1DGTUMesh::allocateCells(int nbOfCells) throw(INTERP_KERNEL::Exception)
2633 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !");
2634 _conn=DataArrayInt::New();
2635 _conn->reserve(nbOfCells*3);
2636 _conn_indx=DataArrayInt::New();
2637 _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0);
2642 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
2644 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
2645 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
2646 * \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
2647 * attached to \a this.
2648 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
2650 void MEDCoupling1DGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) throw(INTERP_KERNEL::Exception)
2652 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
2653 DataArrayInt *c(_conn),*c2(_conn_indx);
2657 if(pos==c->getNumberOfTuples())
2659 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
2660 c2->pushBackSilent(pos+sz);
2664 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !";
2665 throw INTERP_KERNEL::Exception(oss.str().c_str());
2669 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !");
2672 void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex) throw(INTERP_KERNEL::Exception)
2675 nodalConn->incrRef();
2678 nodalConnIndex->incrRef();
2679 _conn_indx=nodalConnIndex;
2684 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
2686 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivity() const throw(INTERP_KERNEL::Exception)
2688 const DataArrayInt *ret(_conn);
2689 return const_cast<DataArrayInt *>(ret);
2693 * \return DataArrayInt * - the internal reference to the nodal connectivity index. The caller is not reponsible to deallocate it.
2695 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const throw(INTERP_KERNEL::Exception)
2697 const DataArrayInt *ret(_conn_indx);
2698 return const_cast<DataArrayInt *>(ret);
2702 * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here".
2703 * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity).
2704 * 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.
2706 * 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.
2708 * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal
2709 * connectivity arrays are different (false)
2710 * \return a new object to be managed by the caller.
2712 * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked
2714 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const throw(INTERP_KERNEL::Exception)
2716 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2717 DataArrayInt *nc=0,*nci=0;
2718 isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci);
2719 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ncs(nc),ncis(nci);
2720 ret->_conn=ncs; ret->_conn_indx=ncis;
2721 ret->setCoords(getCoords());
2726 * This method allows to compute, if needed, the packed nodal connectivity pair.
2727 * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges convered by nodal connectivity index array.
2728 * 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.
2730 * 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)
2731 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
2733 * 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
2736 * This method return 3 elements.
2737 * \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
2738 * this pointer can be seen as a new object, that is to managed by the caller.
2739 * \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
2740 * this pointer can be seen as a new object, that is to managed by the caller.
2741 * \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
2742 * output parameters are newly created objects.
2744 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
2746 bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const throw(INTERP_KERNEL::Exception)
2748 if(isPacked())//performs the checkCoherency
2750 const DataArrayInt *c0(_conn),*c1(_conn_indx);
2751 nodalConn=const_cast<DataArrayInt *>(c0); nodalConnIndx=const_cast<DataArrayInt *>(c1);
2752 nodalConn->incrRef(); nodalConnIndx->incrRef();
2755 int bg=_conn_indx->front(),end=_conn_indx->back();
2756 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nc(_conn->selectByTupleId2(bg,end,1));
2757 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nci(_conn_indx->deepCpy());
2758 nci->applyLin(1,-bg);
2759 nodalConn=nc.retn(); nodalConnIndx=nci.retn();
2764 * 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)
2765 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
2766 * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned.
2767 * \return bool - true if \a this looks packed, false is not.
2769 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
2771 bool MEDCoupling1DGTUMesh::isPacked() const throw(INTERP_KERNEL::Exception)
2774 return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples();
2777 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2) throw(INTERP_KERNEL::Exception)
2779 std::vector<const MEDCoupling1DGTUMesh *> tmp(2);
2780 tmp[0]=const_cast<MEDCoupling1DGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1DGTUMesh *>(mesh2);
2781 return Merge1DGTUMeshes(tmp);
2784 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
2786 std::size_t sz=a.size();
2788 return Merge1DGTUMeshesLL(a);
2789 for(std::size_t ii=0;ii<sz;ii++)
2792 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::Merge1DGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
2793 throw INTERP_KERNEL::Exception(oss.str().c_str());
2795 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
2796 for(std::size_t ii=0;ii<sz;ii++)
2797 if(&(a[ii]->getCellModel())!=cm)
2798 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !");
2799 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > bb(sz);
2800 std::vector< const MEDCoupling1DGTUMesh * > aa(sz);
2802 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
2804 const MEDCoupling1DGTUMesh *cur=a[i];
2805 const DataArrayDouble *coo=cur->getCoords();
2807 spaceDim=coo->getNumberOfComponents();
2810 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !");
2811 for(std::size_t i=0;i<sz;i++)
2813 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
2816 return Merge1DGTUMeshesLL(aa);
2820 * \throw If presence of a null instance in the input vector \a a.
2821 * \throw If a is empty
2823 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
2826 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !");
2827 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
2829 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !");
2830 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
2831 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
2832 int nbOfCells=(*it)->getNumberOfCells();
2833 const DataArrayDouble *coords=(*it)->getCoords();
2834 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
2836 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
2837 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
2839 for(int i=1;it!=a.end();i++,it++)
2842 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !");
2843 if(cm!=&((*it)->getCellModel()))
2844 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
2845 (*it)->getNumberOfCells();//to check that all is OK
2846 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
2847 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
2848 if(coords!=(*it)->getCoords())
2849 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !");
2851 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
2852 ret->setCoords(coords);
2853 ret->_conn=DataArrayInt::Aggregate(ncs);
2854 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
2859 * 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)
2861 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
2864 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : input array must be NON EMPTY !");
2865 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
2866 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
2867 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
2868 std::vector<int> nbNodesPerElt(a.size());
2869 int nbOfCells=(*it)->getNumberOfCells();
2871 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
2872 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
2874 int prevNbOfNodes=(*it)->getNumberOfNodes();
2875 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
2877 for(int i=1;it!=a.end();i++,it++)
2879 if(cm!=&((*it)->getCellModel()))
2880 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
2881 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
2882 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
2883 nbOfCells+=(*it)->getNumberOfCells();
2884 nbNodesPerElt[i]=nbNodesPerElt[i-1]+prevNbOfNodes;
2885 prevNbOfNodes=(*it)->getNumberOfNodes();
2887 std::vector<const MEDCouplingPointSet *> aps(a.size());
2888 std::copy(a.begin(),a.end(),aps.begin());
2889 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
2890 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
2891 ret->setCoords(pts);
2892 ret->_conn=AggregateNodalConnAndShiftNodeIds(ncs,nbNodesPerElt);
2893 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
2897 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception)
2899 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2900 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1,tmp2;
2901 const DataArrayInt *nodalConn(_conn),*nodalConnI(_conn_indx);
2904 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
2912 tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
2916 ret->_conn_indx=tmp2;
2920 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
2921 ret->setCoords(coords);
2924 ret->setCoords(_coords);
2928 std::vector<int> MEDCoupling1DGTUMesh::BuildAPolygonFromParts(const std::vector< std::vector<int> >& parts) throw(INTERP_KERNEL::Exception)
2930 std::vector<int> ret;
2933 ret.insert(ret.end(),parts[0].begin(),parts[0].end());
2934 int ref(ret.back());
2935 std::size_t sz(parts.size()),nbh(1);
2936 std::vector<bool> b(sz,true); b[0]=false;
2940 for(;i<sz;i++) if(b[i] && parts[i].front()==ref) { ret.insert(ret.end(),parts[i].begin()+1,parts[i].end()); nbh++; break; }
2944 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::BuildAPolygonFromParts : the input vector is not a part of a single polygon !");
2946 if(ret.back()==ret.front())
2952 * This method performs an aggregation of \a nodalConns (as DataArrayInt::Aggregate does) but in addition of that a shift is applied on the
2953 * values contained in \a nodalConns using corresponding offset specified in input \a offsetInNodeIdsPerElt.
2954 * But it also manage the values -1, that have a semantic in MEDCoupling1DGTUMesh class (separator for polyhedron).
2956 * \param [in] nodalConns - a list of nodal connectivity arrays same size than \a offsetInNodeIdsPerElt.
2957 * \param [in] offsetInNodeIdsPerElt - a list of offsets to apply.
2958 * \return DataArrayInt * - A new object (to be managed by the caller) that is the result of the aggregation.
2959 * \throw If \a nodalConns or \a offsetInNodeIdsPerElt are empty.
2960 * \throw If \a nodalConns and \a offsetInNodeIdsPerElt have not the same size.
2961 * \throw If presence of null pointer in \a nodalConns.
2962 * \throw If presence of not allocated or array with not exactly one component in \a nodalConns.
2964 DataArrayInt *MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds(const std::vector<const DataArrayInt *>& nodalConns, const std::vector<int>& offsetInNodeIdsPerElt) throw(INTERP_KERNEL::Exception)
2966 std::size_t sz1(nodalConns.size()),sz2(offsetInNodeIdsPerElt.size());
2968 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : input vectors do not have the same size !");
2970 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : empty vectors in input !");
2972 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++)
2975 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of null pointer in input vector !");
2976 if(!(*it)->isAllocated())
2977 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of non allocated array in input vector !");
2978 if((*it)->getNumberOfComponents()!=1)
2979 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of array with not exactly one component !");
2980 nbOfTuples+=(*it)->getNumberOfTuples();
2982 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
2983 int *pt=ret->getPointer();
2985 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++,i++)
2987 int curNbt=(*it)->getNumberOfTuples();
2988 const int *inPt=(*it)->begin();
2989 int offset=offsetInNodeIdsPerElt[i];
2990 for(int j=0;j<curNbt;j++,pt++)
3001 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception)
3004 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh is null !");
3005 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
3007 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh must have exactly one geometric type !");
3008 int geoType((int)*gts.begin());
3009 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(m->getName().c_str(),*gts.begin()));
3010 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription().c_str());
3011 int nbCells(m->getNumberOfCells());
3012 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
3013 conn->alloc(m->getMeshLength()-nbCells,1); connI->alloc(nbCells+1,1);
3014 int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
3015 const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
3016 for(int i=0;i<nbCells;i++,ciin++,ci++)
3018 if(cin[ciin[0]]==geoType)
3020 if(ciin[1]-ciin[0]>=1)
3022 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
3023 ci[1]=ci[0]+ciin[1]-ciin[0]-1;
3027 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 !";
3028 throw INTERP_KERNEL::Exception(oss.str().c_str());
3033 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 !";
3034 throw INTERP_KERNEL::Exception(oss.str().c_str());
3037 ret->setNodalConnectivity(conn,connI);