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(const char *name, const INTERP_KERNEL::CellModel& cm):_cm(&cm)
34 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const MEDCoupling1GTUMesh& other, bool recDeepCpy):MEDCouplingPointSet(other,recDeepCpy),_cm(other._cm)
38 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
40 if(type==INTERP_KERNEL::NORM_ERROR)
41 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
42 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
44 return MEDCoupling1SGTUMesh::New(name,type);
46 return MEDCoupling1DGTUMesh::New(name,type);
49 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception)
52 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh is null !");
53 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
55 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh must have exactly one geometric type !");
56 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*gts.begin());
58 return MEDCoupling1SGTUMesh::New(m);
60 return MEDCoupling1DGTUMesh::New(m);
63 const INTERP_KERNEL::CellModel& MEDCoupling1GTUMesh::getCellModel() const throw(INTERP_KERNEL::Exception)
68 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getCellModelEnum() const throw(INTERP_KERNEL::Exception)
70 return _cm->getEnum();
73 int MEDCoupling1GTUMesh::getMeshDimension() const
75 return (int)_cm->getDimension();
79 * This method returns a newly allocated array containing cell ids (ascendingly sorted) whose geometric type are equal to type.
80 * This method does not throw exception if geometric type \a type is not in \a this.
81 * This method throws an INTERP_KERNEL::Exception if meshdimension of \b this is not equal to those of \b type.
82 * The coordinates array is not considered here.
84 * \param [in] type the geometric type
85 * \return cell ids in this having geometric type \a type.
87 DataArrayInt *MEDCoupling1GTUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception)
89 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
90 if(type==getCellModelEnum())
91 ret->alloc(getNumberOfCells(),1);
99 * Returns nb of cells having the geometric type \a type. No throw if no cells in \a this has the geometric type \a type.
101 int MEDCoupling1GTUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
103 return type==getCellModelEnum()?getNumberOfCells():0;
107 * Returns a type of a cell by its id.
108 * \param [in] cellId - the id of the cell of interest.
109 * \return INTERP_KERNEL::NormalizedCellType - enumeration item describing the cell type.
110 * \throw If \a cellId is invalid. Valid range is [0, \a this->getNumberOfCells() ).
112 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getTypeOfCell(int cellId) const
114 if(cellId>=0 && cellId<getNumberOfCells())
115 return getCellModelEnum();
116 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::getTypeOfCell : Requesting type of cell #" << cellId << " but it should be in [0," << getNumberOfCells() << ") !";
117 throw INTERP_KERNEL::Exception(oss.str().c_str());
121 * Returns a set of all cell types available in \a this mesh.
122 * \return std::set<INTERP_KERNEL::NormalizedCellType> - the set of cell types.
123 * \warning this method does not throw any exception even if \a this is not defined.
125 std::set<INTERP_KERNEL::NormalizedCellType> MEDCoupling1GTUMesh::getAllGeoTypes() const
127 std::set<INTERP_KERNEL::NormalizedCellType> ret;
128 ret.insert(getCellModelEnum());
133 * This method expects that \a this is sorted by types. If not an exception will be thrown.
134 * This method returns in the same format as code (see MEDCouplingUMesh::checkTypeConsistencyAndContig or MEDCouplingUMesh::splitProfilePerType) how
135 * \a this is composed in cell types.
136 * The returned array is of size 3*n where n is the number of different types present in \a this.
137 * For every k in [0,n] ret[3*k+2]==-1 because it has no sense here.
138 * This parameter is kept only for compatibility with other methode listed above.
140 std::vector<int> MEDCoupling1GTUMesh::getDistributionOfTypes() const throw(INTERP_KERNEL::Exception)
142 std::vector<int> ret(3);
143 ret[0]=(int)getCellModelEnum(); ret[1]=getNumberOfCells(); ret[2]=-1;
148 * 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.
149 * 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.
150 * This method has 1 input \a profile and 3 outputs \a code \a idsInPflPerType and \a idsPerType.
152 * \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.
153 * \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,
154 * \a idsInPflPerType[i] stores the tuple ids in \a profile that correspond to the geometric type code[3*i+0]
155 * \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.
156 * This vector can be empty in case of all geometric type cells are fully covered in ascending in the given input \a profile.
158 * \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.
160 * \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
163 * - Before \a this has 3 cells \a profile contains [0,1,2]
164 * - After \a code contains [NORM_...,nbCells,-1], \a idsInPflPerType [[0,1,2]] and \a idsPerType is empty <br>
167 * - Before \a this has 3 cells \a profile contains [1,2]
168 * - After \a code contains [NORM_...,nbCells,0], \a idsInPflPerType [[0,1]] and \a idsPerType is [[1,2]] <br>
171 void MEDCoupling1GTUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
174 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile is NULL !");
175 if(profile->getNumberOfComponents()!=1)
176 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile should have exactly one component !");
177 int nbTuples=profile->getNumberOfTuples();
178 int nbOfCells=getNumberOfCells();
179 code.resize(3); idsInPflPerType.resize(1);
180 code[0]=(int)getCellModelEnum(); code[1]=nbTuples;
181 idsInPflPerType.resize(1);
182 if(profile->isIdentity() && nbTuples==nbOfCells)
185 idsInPflPerType[0]=const_cast<DataArrayInt *>(profile); idsInPflPerType[0]->incrRef();
190 profile->checkAllIdsInRange(0,nbOfCells);
191 idsPerType.resize(1);
192 idsPerType[0]=const_cast<DataArrayInt *>(profile); idsPerType[0]->incrRef();
193 idsInPflPerType[0]=DataArrayInt::Range(0,nbTuples,1);
197 * This method tries to minimize at most the number of deep copy.
198 * So if \a idsPerType is not empty it can be returned directly (without copy, but with ref count incremented) in return.
200 * \sa MEDCouplingUMesh::checkTypeConsistencyAndContig
202 DataArrayInt *MEDCoupling1GTUMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
204 int nbOfCells=getNumberOfCells();
206 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : invalid input code should be exactly of size 3 !");
207 if(code[0]!=(int)getCellModelEnum())
209 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() << ") !";
210 throw INTERP_KERNEL::Exception(oss.str().c_str());
214 if(code[1]==nbOfCells)
218 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : mismatch between the number of cells in this (" << nbOfCells << ") and the number of non profile (" << code[1] << ") !";
219 throw INTERP_KERNEL::Exception(oss.str().c_str());
223 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : single geo type mesh ! 0 or -1 is expected at pos #2 of input code !");
224 if(idsPerType.size()!=1)
225 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input code points to DataArrayInt #0 whereas the size of idsPerType is not equal to 1 !");
226 const DataArrayInt *pfl=idsPerType[0];
228 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : the input code points to a NULL DataArrayInt at rank 0 !");
229 if(pfl->getNumberOfComponents()!=1)
230 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input profile should have exactly one component !");
231 pfl->checkAllIdsInRange(0,nbOfCells);
233 return const_cast<DataArrayInt *>(pfl);
236 void MEDCoupling1GTUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception)
238 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
239 m->writeVTKLL(ofs,cellData,pointData);
242 std::string MEDCoupling1GTUMesh::getVTKDataSetType() const throw(INTERP_KERNEL::Exception)
244 return std::string("UnstructuredGrid");
247 std::size_t MEDCoupling1GTUMesh::getHeapMemorySize() const
249 return MEDCouplingPointSet::getHeapMemorySize();
252 bool MEDCoupling1GTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
254 if(!MEDCouplingPointSet::isEqualIfNotWhy(other,prec,reason))
257 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualIfNotWhy : input other pointer is null !");
258 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
261 reason="mesh given in input is not castable in MEDCouplingSGTUMesh !";
266 reason="mismatch in geometric type !";
272 bool MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
274 if(!MEDCouplingPointSet::isEqualWithoutConsideringStr(other,prec))
277 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
278 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
286 void MEDCoupling1GTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
288 MEDCouplingPointSet::checkCoherency();
291 DataArrayDouble *MEDCoupling1GTUMesh::getBarycenterAndOwner() const
293 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
294 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=m->getBarycenterAndOwner();
298 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureField(bool isAbs) const
300 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
301 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureField(isAbs);
306 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureFieldOnNode(bool isAbs) const
308 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
309 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureFieldOnNode(isAbs);
317 int MEDCoupling1GTUMesh::getCellContainingPoint(const double *pos, double eps) const
319 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
320 return m->getCellContainingPoint(pos,eps);
323 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::buildOrthogonalField() const
325 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
326 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->buildOrthogonalField();
331 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const double *bbox, double eps) const
333 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
334 return m->getCellsInBoundingBox(bbox,eps);
337 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps)
339 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
340 return m->getCellsInBoundingBox(bbox,eps);
343 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const
345 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
346 return m->buildFacePartOfMySelfNode(start,end,fullyIn);
349 DataArrayInt *MEDCoupling1GTUMesh::findBoundaryNodes() const
351 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
352 return m->findBoundaryNodes();
355 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildBoundaryMesh(bool keepCoords) const
357 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
358 return m->buildBoundaryMesh(keepCoords);
361 void MEDCoupling1GTUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const throw(INTERP_KERNEL::Exception)
363 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
364 m->findCommonCells(compType,startCellId,commonCellsArr,commonCellsIArr);
367 int MEDCoupling1GTUMesh::getNodalConnectivityLength() const throw(INTERP_KERNEL::Exception)
369 const DataArrayInt *c1(getNodalConnectivity());
371 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : no connectivity set !");
372 if(c1->getNumberOfComponents()!=1)
373 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array set must have exactly one component !");
374 if(!c1->isAllocated())
375 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array must be allocated !");
376 return c1->getNumberOfTuples();
380 * This method aggregates all the meshes in \a parts to put them in a single unstructured mesh (those returned).
381 * The order of cells is the returned instance is those in the order of instances in \a parts.
383 * \param [in] parts - all not null parts of single geo type meshes to be aggreagated having the same mesh dimension and same coordinates.
384 * \return MEDCouplingUMesh * - new object to be dealt by the caller.
386 * \throw If one element is null in \a parts.
387 * \throw If not all the parts do not have the same mesh dimension.
388 * \throw If not all the parts do not share the same coordinates.
389 * \throw If not all the parts have their connectivity set properly.
390 * \throw If \a parts is empty.
392 MEDCouplingUMesh *MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh(const std::vector< const MEDCoupling1GTUMesh *>& parts) throw(INTERP_KERNEL::Exception)
395 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : input parts vector is empty !");
396 const MEDCoupling1GTUMesh *firstPart(parts[0]);
398 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : the first instance in input parts is null !");
399 const DataArrayDouble *coords(firstPart->getCoords());
400 int meshDim(firstPart->getMeshDimension());
401 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret(MEDCouplingUMesh::New(firstPart->getName().c_str(),meshDim)); ret->setDescription(firstPart->getDescription().c_str());
402 ret->setCoords(coords);
403 int nbOfCells(0),connSize(0);
404 for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
407 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of null pointer in input vector !");
408 if((*it)->getMeshDimension()!=meshDim)
409 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances in input vector must have same mesh dimension !");
410 if((*it)->getCoords()!=coords)
411 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances must share the same coordinates pointer !");
412 nbOfCells+=(*it)->getNumberOfCells();
413 connSize+=(*it)->getNodalConnectivityLength();
415 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
416 connI->alloc(nbOfCells+1,1); conn->alloc(connSize+nbOfCells,1);
417 int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
418 for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
420 int curNbCells((*it)->getNumberOfCells());
421 int geoType((int)(*it)->getCellModelEnum());
422 const int *cinPtr((*it)->getNodalConnectivity()->begin());
423 const MEDCoupling1SGTUMesh *ps(dynamic_cast<const MEDCoupling1SGTUMesh *>(*it));
424 const MEDCoupling1DGTUMesh *pd(dynamic_cast<const MEDCoupling1DGTUMesh *>(*it));
427 int nNodesPerCell(ps->getNumberOfNodesPerCell());
428 for(int i=0;i<curNbCells;i++,ci++,cinPtr+=nNodesPerCell)
431 c=std::copy(cinPtr,cinPtr+nNodesPerCell,c);
432 ci[1]=ci[0]+nNodesPerCell+1;
437 const int *ciinPtr(pd->getNodalConnectivityIndex()->begin());
438 for(int i=0;i<curNbCells;i++,ci++,ciinPtr++)
441 c=std::copy(cinPtr+ciinPtr[0],cinPtr+ciinPtr[1],c);
442 ci[1]=ci[0]+ciinPtr[1]-ciinPtr[0]+1;
446 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of instance which type is not in [MEDCoupling1SGTUMesh,MEDCoupling1DGTUMesh] !");
448 ret->setConnectivity(conn,connI,true);
454 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const MEDCoupling1SGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
458 const DataArrayInt *c(other._conn);
464 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
468 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
470 if(type==INTERP_KERNEL::NORM_ERROR)
471 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
472 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
475 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New : the input geometric type " << cm.getRepr() << " is dynamic ! Only static types are allowed here !";
476 throw INTERP_KERNEL::Exception(oss.str().c_str());
478 return new MEDCoupling1SGTUMesh(name,cm);
481 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception)
484 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh is null !");
485 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
487 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh must have exactly one geometric type !");
488 int geoType((int)*gts.begin());
489 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(m->getName().c_str(),*gts.begin()));
490 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription().c_str());
491 int nbCells(m->getNumberOfCells());
492 int nbOfNodesPerCell(ret->getNumberOfNodesPerCell());
493 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()); conn->alloc(nbCells*nbOfNodesPerCell,1);
494 int *c(conn->getPointer());
495 const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
496 for(int i=0;i<nbCells;i++,ciin++)
498 if(cin[ciin[0]]==geoType)
500 if(ciin[1]-ciin[0]==nbOfNodesPerCell+1)
501 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
504 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 << ") !";
505 throw INTERP_KERNEL::Exception(oss.str().c_str());
510 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 !";
511 throw INTERP_KERNEL::Exception(oss.str().c_str());
514 ret->setNodalConnectivity(conn);
518 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::clone(bool recDeepCpy) const
520 return new MEDCoupling1SGTUMesh(*this,recDeepCpy);
524 * This method behaves mostly like MEDCoupling1SGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
525 * The coordinates are shared between \a this and the returned instance.
527 * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
528 * \sa MEDCoupling1SGTUMesh::deepCpy
530 MEDCouplingPointSet *MEDCoupling1SGTUMesh::deepCpyConnectivityOnly() const throw(INTERP_KERNEL::Exception)
533 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(clone(false));
534 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy());
535 ret->setNodalConnectivity(c);
539 void MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception)
542 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
543 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
545 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1SGTUMesh instance !");
546 setNodalConnectivity(otherC->getNodalConnectivity());
549 void MEDCoupling1SGTUMesh::updateTime() const
551 MEDCoupling1GTUMesh::updateTime();
552 const DataArrayInt *c(_conn);
557 std::size_t MEDCoupling1SGTUMesh::getHeapMemorySize() const
560 const DataArrayInt *c(_conn);
562 ret+=c->getHeapMemorySize();
563 return MEDCoupling1GTUMesh::getHeapMemorySize()+ret;
566 MEDCouplingMesh *MEDCoupling1SGTUMesh::deepCpy() const
571 bool MEDCoupling1SGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
574 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualIfNotWhy : input other pointer is null !");
575 std::ostringstream oss; oss.precision(15);
576 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
579 reason="mesh given in input is not castable in MEDCoupling1SGTUMesh !";
582 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
584 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
589 reason="in connectivity of single static geometric type exactly one among this and other is null !";
592 if(!c1->isEqualIfNotWhy(*c2,reason))
594 reason.insert(0,"Nodal connectivity DataArrayInt differ : ");
600 bool MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
603 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
604 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
607 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
609 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
614 if(!c1->isEqualWithoutConsideringStr(*c2))
619 void MEDCoupling1SGTUMesh::checkCoherencyOfConnectivity() const throw(INTERP_KERNEL::Exception)
621 const DataArrayInt *c1(_conn);
624 if(c1->getNumberOfComponents()!=1)
625 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
626 if(c1->getInfoOnComponent(0)!="")
627 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
628 c1->checkAllocated();
631 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
634 void MEDCoupling1SGTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
636 MEDCouplingPointSet::checkCoherency();
637 checkCoherencyOfConnectivity();
640 void MEDCoupling1SGTUMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
643 const DataArrayInt *c1(_conn);
644 int nbOfTuples=c1->getNumberOfTuples();
645 int nbOfNodesPerCell=(int)_cm->getNumberOfNodes();
646 if(nbOfTuples%nbOfNodesPerCell!=0)
648 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 !";
649 throw INTERP_KERNEL::Exception(oss.str().c_str());
651 int nbOfNodes=getNumberOfNodes();
652 int nbOfCells=nbOfTuples/nbOfNodesPerCell;
653 const int *w(c1->begin());
654 for(int i=0;i<nbOfCells;i++)
655 for(int j=0;j<nbOfNodesPerCell;j++,w++)
657 if(*w<0 || *w>=nbOfNodes)
659 std::ostringstream oss; oss << "At node #" << j << " of cell #" << i << ", is equal to " << *w << " must be in [0," << nbOfNodes << ") !";
660 throw INTERP_KERNEL::Exception(oss.str().c_str());
665 void MEDCoupling1SGTUMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
667 checkCoherency1(eps);
670 int MEDCoupling1SGTUMesh::getNumberOfCells() const
672 int nbOfTuples=getNodalConnectivityLength();
673 int nbOfNodesPerCell=getNumberOfNodesPerCell();
674 if(nbOfTuples%nbOfNodesPerCell!=0)
676 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 !";
677 throw INTERP_KERNEL::Exception(oss.str().c_str());
679 return nbOfTuples/nbOfNodesPerCell;
682 int MEDCoupling1SGTUMesh::getNumberOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
684 checkNonDynamicGeoType();
685 return (int)_cm->getNumberOfNodes();
688 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
690 checkNonDynamicGeoType();
691 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
692 ret->alloc(getNumberOfCells(),1);
693 ret->fillWithValue((int)_cm->getNumberOfNodes());
697 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception)
699 checkNonDynamicGeoType();
700 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
701 ret->alloc(getNumberOfCells(),1);
702 ret->fillWithValue((int)_cm->getNumberOfSons());
706 void MEDCoupling1SGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
708 int sz=getNumberOfNodesPerCell();
710 if(cellId>=0 && cellId<getNumberOfCells())
711 std::copy(_conn->begin()+cellId*sz,_conn->begin()+(cellId+1)*sz,conn.begin());
714 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << getNumberOfCells() << ") !";
715 throw INTERP_KERNEL::Exception(oss.str().c_str());
719 void MEDCoupling1SGTUMesh::checkNonDynamicGeoType() const throw(INTERP_KERNEL::Exception)
722 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkNonDynamicGeoType : internal error ! the internal geo type is dynamic ! should be static !");
725 std::string MEDCoupling1SGTUMesh::simpleRepr() const
727 static const char msg0[]="No coordinates specified !";
728 std::ostringstream ret;
729 ret << "Single static geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
730 ret << "Description of mesh : \"" << getDescription() << "\"\n";
732 double tt=getTime(tmpp1,tmpp2);
733 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
734 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
735 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
738 const int spaceDim=getSpaceDimension();
739 ret << spaceDim << "\nInfo attached on space dimension : ";
740 for(int i=0;i<spaceDim;i++)
741 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
746 ret << "Number of nodes : ";
748 ret << getNumberOfNodes() << "\n";
751 ret << "Number of cells : ";
752 if((const DataArrayInt *)_conn)
754 if(_conn->isAllocated())
756 if(_conn->getNumberOfComponents()==1)
757 ret << getNumberOfCells() << "\n";
759 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
762 ret << "Nodal connectivity array specified but not allocated !" << "\n";
765 ret << "No connectivity specified !" << "\n";
766 ret << "Cell type : " << _cm->getRepr() << "\n";
770 std::string MEDCoupling1SGTUMesh::advancedRepr() const
772 std::ostringstream ret;
774 ret << "\nCoordinates array : \n___________________\n\n";
776 _coords->reprWithoutNameStream(ret);
778 ret << "No array set !\n";
779 ret << "\n\nConnectivity array : \n____________________\n\n";
781 if((const DataArrayInt *)_conn)
783 if(_conn->isAllocated())
785 if(_conn->getNumberOfComponents()==1)
787 int nbOfCells=getNumberOfCells();
788 int sz=getNumberOfNodesPerCell();
789 const int *connPtr=_conn->begin();
790 for(int i=0;i<nbOfCells;i++,connPtr+=sz)
792 ret << "Cell #" << i << " : ";
793 std::copy(connPtr,connPtr+sz,std::ostream_iterator<int>(ret," "));
798 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
801 ret << "Nodal connectivity array specified but not allocated !" << "\n";
804 ret << "No connectivity specified !" << "\n";
808 DataArrayDouble *MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
810 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
811 int spaceDim=getSpaceDimension();
812 int nbOfCells=getNumberOfCells();//checkCoherency()
813 int nbOfNodes=getNumberOfNodes();
814 ret->alloc(nbOfCells,spaceDim);
815 double *ptToFill=ret->getPointer();
816 const double *coor=_coords->begin();
817 const int *nodal=_conn->begin();
818 int sz=getNumberOfNodesPerCell();
819 double coeff=1./(double)sz;
820 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim)
822 std::fill(ptToFill,ptToFill+spaceDim,0.);
823 for(int j=0;j<sz;j++,nodal++)
824 if(*nodal>=0 && *nodal<nbOfNodes)
825 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
828 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
829 throw INTERP_KERNEL::Exception(oss.str().c_str());
831 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),coeff));
836 void MEDCoupling1SGTUMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
838 int nbCells=getNumberOfCells();
839 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
840 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
842 o2n=o2n->checkAndPreparePermutation();
844 const int *conn=_conn->begin();
845 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o=o2n->invertArrayO2N2N2O(nbCells);
846 const int *n2oPtr=n2o->begin();
847 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
848 newConn->alloc(_conn->getNumberOfTuples(),1);
849 newConn->copyStringInfoFrom(*_conn);
850 int sz=getNumberOfNodesPerCell();
852 int *newC=newConn->getPointer();
853 for(int i=0;i<nbCells;i++,newC+=sz)
856 std::copy(conn+pos*sz,conn+(pos+1)*sz,newC);
862 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
863 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
864 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
865 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
867 * \param [in] begin input start of array of node ids.
868 * \param [in] end input end of array of node ids.
869 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
870 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
872 void MEDCoupling1SGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
874 int nbOfCells=getNumberOfCells();
875 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
877 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
878 std::vector<bool> fastFinder(sz,false);
879 for(const int *work=begin;work!=end;work++)
880 if(*work>=0 && *work<sz)
881 fastFinder[*work]=true;
882 const int *conn=_conn->begin();
883 int nbNodesPerCell=getNumberOfNodesPerCell();
884 for(int i=0;i<nbOfCells;i++,conn+=nbNodesPerCell)
887 for(int j=0;j<nbNodesPerCell;j++)
891 if(fastFinder[conn[j]])
894 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
895 cellIdsKept->pushBackSilent(i);
897 cellIdsKeptArr=cellIdsKept.retn();
900 MEDCouplingMesh *MEDCoupling1SGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
902 if(other->getType()!=SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED)
903 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single static geo type each other !");
904 const MEDCoupling1SGTUMesh *otherC=static_cast<const MEDCoupling1SGTUMesh *>(other);
905 return Merge1SGTUMeshes(this,otherC);
908 MEDCouplingUMesh *MEDCoupling1SGTUMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
910 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName().c_str(),getMeshDimension());
911 ret->setCoords(getCoords());
912 const int *nodalConn=_conn->begin();
913 int nbCells=getNumberOfCells();
914 int nbNodesPerCell=getNumberOfNodesPerCell();
915 int geoType=(int)getCellModelEnum();
916 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells*(nbNodesPerCell+1),1);
917 int *cPtr=c->getPointer();
918 for(int i=0;i<nbCells;i++,nodalConn+=nbNodesPerCell)
921 cPtr=std::copy(nodalConn,nodalConn+nbNodesPerCell,cPtr);
923 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::Range(0,(nbCells+1)*(nbNodesPerCell+1),nbNodesPerCell+1);
924 ret->setConnectivity(c,cI,true);
928 DataArrayInt *MEDCoupling1SGTUMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
933 return simplexizePol0();
935 return simplexizePol1();
936 case (int) INTERP_KERNEL::PLANAR_FACE_5:
937 return simplexizePlanarFace5();
938 case (int) INTERP_KERNEL::PLANAR_FACE_6:
939 return simplexizePlanarFace6();
941 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)");
947 struct MEDCouplingAccVisit
949 MEDCouplingAccVisit():_new_nb_of_nodes(0) { }
950 int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; }
951 int _new_nb_of_nodes;
957 * Finds nodes not used in any cell and returns an array giving a new id to every node
958 * by excluding the unused nodes, for which the array holds -1. The result array is
959 * a mapping in "Old to New" mode.
960 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
961 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
962 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
963 * if the node is unused or a new id else. The caller is to delete this
964 * array using decrRef() as it is no more needed.
965 * \throw If the coordinates array is not set.
966 * \throw If the nodal connectivity of cells is not defined.
967 * \throw If the nodal connectivity includes an invalid id.
969 DataArrayInt *MEDCoupling1SGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception)
972 int nbOfNodes=getNumberOfNodes();
973 int nbOfCells=getNumberOfCells();
974 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
975 ret->alloc(nbOfNodes,1);
976 int *traducer=ret->getPointer();
977 std::fill(traducer,traducer+nbOfNodes,-1);
978 const int *conn=_conn->begin();
979 int nbNodesPerCell=getNumberOfNodesPerCell();
980 for(int i=0;i<nbOfCells;i++)
981 for(int j=0;j<nbNodesPerCell;j++,conn++)
982 if(*conn>=0 && *conn<nbOfNodes)
986 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << conn[j] << " not in [0," << nbOfNodes << ") !";
987 throw INTERP_KERNEL::Exception(oss.str().c_str());
989 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
990 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
995 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
996 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
997 * This method is a generalization of shiftNodeNumbersInConn().
998 * \warning This method performs no check of validity of new ids. **Use it with care !**
999 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
1000 * this->getNumberOfNodes(), in "Old to New" mode.
1001 * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
1002 * \throw If the nodal connectivity of cells is not defined.
1004 void MEDCoupling1SGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
1006 getNumberOfCells();//only to check that all is well defined.
1007 _conn->transformWithIndArr(newNodeNumbersO2N,newNodeNumbersO2N+getNumberOfNodes());
1011 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2) throw(INTERP_KERNEL::Exception)
1013 std::vector<const MEDCoupling1SGTUMesh *> tmp(2);
1014 tmp[0]=const_cast<MEDCoupling1SGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1SGTUMesh *>(mesh2);
1015 return Merge1SGTUMeshes(tmp);
1018 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
1020 std::size_t sz=a.size();
1022 return Merge1SGTUMeshesLL(a);
1023 for(std::size_t ii=0;ii<sz;ii++)
1026 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::Merge1SGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
1027 throw INTERP_KERNEL::Exception(oss.str().c_str());
1029 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
1030 for(std::size_t ii=0;ii<sz;ii++)
1031 if(&(a[ii]->getCellModel())!=cm)
1032 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : all items must have the same geo type !");
1033 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> > bb(sz);
1034 std::vector< const MEDCoupling1SGTUMesh * > aa(sz);
1036 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
1038 const MEDCoupling1SGTUMesh *cur=a[i];
1039 const DataArrayDouble *coo=cur->getCoords();
1041 spaceDim=coo->getNumberOfComponents();
1044 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : no spaceDim specified ! unable to perform merge !");
1045 for(std::size_t i=0;i<sz;i++)
1047 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
1050 return Merge1SGTUMeshesLL(aa);
1054 * \throw If presence of a null instance in the input vector \a a.
1055 * \throw If a is empty
1057 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
1060 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : input array must be NON EMPTY !");
1061 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1063 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : null instance in the first element of input vector !");
1064 std::vector<const DataArrayInt *> ncs(a.size());
1065 int nbOfCells=(*it)->getNumberOfCells();
1066 const DataArrayDouble *coords=(*it)->getCoords();
1067 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1068 int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
1069 ncs[0]=(*it)->getNodalConnectivity();
1071 for(int i=1;it!=a.end();i++,it++)
1074 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : presence of a null instance in the input vector !");
1075 if(cm!=&((*it)->getCellModel()))
1076 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1077 (*it)->getNumberOfCells();//to check that all is OK
1078 ncs[i]=(*it)->getNodalConnectivity();
1079 if(coords!=(*it)->getCoords())
1080 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : not lying on same coords !");
1082 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1083 ret->setCoords(coords);
1084 ret->_conn=DataArrayInt::Aggregate(ncs);
1089 * 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)
1091 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
1094 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : input array must be NON EMPTY !");
1095 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1096 int nbOfCells=(*it)->getNumberOfCells();
1097 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1098 int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
1100 for(;it!=a.end();it++)
1102 if(cm!=&((*it)->getCellModel()))
1103 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1104 nbOfCells+=(*it)->getNumberOfCells();
1106 std::vector<const MEDCouplingPointSet *> aps(a.size());
1107 std::copy(a.begin(),a.end(),aps.begin());
1108 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
1109 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1110 ret->setCoords(pts);
1111 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New();
1112 c->alloc(nbOfCells*nbNodesPerCell,1);
1113 int *cPtr=c->getPointer();
1115 for(it=a.begin();it!=a.end();it++)
1117 int curConnLgth=(*it)->getNodalConnectivityLength();
1118 const int *curC=(*it)->_conn->begin();
1119 cPtr=std::transform(curC,curC+curConnLgth,cPtr,std::bind2nd(std::plus<int>(),offset));
1120 offset+=(*it)->getNumberOfNodes();
1123 ret->setNodalConnectivity(c);
1127 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
1129 int ncell=getNumberOfCells();
1130 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName().c_str(),*_cm));
1131 ret->setCoords(_coords);
1132 std::size_t nbOfElemsRet=std::distance(begin,end);
1133 const int *inConn=_conn->getConstPointer();
1134 int sz=getNumberOfNodesPerCell();
1135 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1136 int *connPtr=connRet->getPointer();
1137 for(const int *work=begin;work!=end;work++,connPtr+=sz)
1139 if(*work>=0 && *work<ncell)
1140 std::copy(inConn+(work[0])*sz,inConn+(work[0]+1)*sz,connPtr);
1143 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !";
1144 throw INTERP_KERNEL::Exception(oss.str().c_str());
1148 ret->copyTinyInfoFrom(this);
1152 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
1154 int ncell=getNumberOfCells();
1155 int nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : ");
1156 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName().c_str(),*_cm));
1157 ret->setCoords(_coords);
1158 const int *inConn=_conn->getConstPointer();
1159 int sz=getNumberOfNodesPerCell();
1160 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1161 int *connPtr=connRet->getPointer();
1163 for(int i=0;i<nbOfElemsRet;i++,connPtr+=sz,curId+=step)
1165 if(curId>=0 && curId<ncell)
1166 std::copy(inConn+curId*sz,inConn+(curId+1)*sz,connPtr);
1169 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : On pos #" << i << " input cell id =" << curId << " should be in [0," << ncell << ") !";
1170 throw INTERP_KERNEL::Exception(oss.str().c_str());
1174 ret->copyTinyInfoFrom(this);
1178 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception)
1180 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName().c_str(),*_cm));
1181 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1;
1182 const DataArrayInt *nodalConn(_conn);
1185 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
1192 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
1193 ret->setCoords(coords);
1196 ret->setCoords(_coords);
1200 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol0() throw(INTERP_KERNEL::Exception)
1202 int nbOfCells=getNumberOfCells();
1203 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1204 return DataArrayInt::Range(0,nbOfCells,1);
1205 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1206 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1207 const int *c(_conn->begin());
1208 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1209 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1211 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[2];
1212 newConnPtr[3]=c[0]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1213 retPtr[0]=i; retPtr[1]=i;
1216 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1221 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol1() throw(INTERP_KERNEL::Exception)
1223 int nbOfCells=getNumberOfCells();
1224 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1225 return DataArrayInt::Range(0,nbOfCells,1);
1226 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1227 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1228 const int *c(_conn->begin());
1229 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1230 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1232 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[3];
1233 newConnPtr[3]=c[1]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1234 retPtr[0]=i; retPtr[1]=i;
1237 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1242 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace5() throw(INTERP_KERNEL::Exception)
1244 int nbOfCells=getNumberOfCells();
1245 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1246 return DataArrayInt::Range(0,nbOfCells,1);
1247 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(5*4*nbOfCells,1);
1248 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(5*nbOfCells,1);
1249 const int *c(_conn->begin());
1250 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1251 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=20,retPtr+=5)
1253 for(int j=0;j<20;j++)
1254 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_5_WO[j]];
1255 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i;
1258 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1263 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace6() throw(INTERP_KERNEL::Exception)
1265 int nbOfCells=getNumberOfCells();
1266 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1267 return DataArrayInt::Range(0,nbOfCells,1);
1268 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(6*4*nbOfCells,1);
1269 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(6*nbOfCells,1);
1270 const int *c(_conn->begin());
1271 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1272 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=24,retPtr+=6)
1274 for(int j=0;j<24;j++)
1275 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_6_WO[j]];
1276 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i; retPtr[5]=i;
1279 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1284 void MEDCoupling1SGTUMesh::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1286 stream << "MEDCoupling1SGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
1287 stream << " Mesh dimension : " << getMeshDimension() << ".";
1289 { stream << " No coordinates set !"; return ; }
1290 if(!_coords->isAllocated())
1291 { stream << " Coordinates set but not allocated !"; return ; }
1292 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
1293 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
1294 if(!(const DataArrayInt *)_conn)
1295 { stream << std::endl << "Nodal connectivity NOT set !"; return ; }
1296 if(_conn->isAllocated())
1298 if(_conn->getNumberOfComponents()==1)
1299 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
1303 void MEDCoupling1SGTUMesh::checkFullyDefined() const throw(INTERP_KERNEL::Exception)
1305 if(!((const DataArrayInt *)_conn) || !((const DataArrayDouble *)_coords))
1306 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFullyDefined : part of this is not fully defined.");
1310 * First step of unserialization process.
1312 bool MEDCoupling1SGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
1314 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEmptyMesh : not implemented yet !");
1318 * Checks if \a this and \a other meshes are geometrically equivalent with high
1319 * probability, else an exception is thrown. The meshes are considered equivalent if
1320 * (1) meshes contain the same number of nodes and the same number of elements of the
1321 * same types (2) three cells of the two meshes (first, last and middle) are based
1322 * on coincident nodes (with a specified precision).
1323 * \param [in] other - the mesh to compare with.
1324 * \param [in] prec - the precision used to compare nodes of the two meshes.
1325 * \throw If the two meshes do not match.
1327 void MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception)
1329 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1330 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1332 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single static geometric type !");
1333 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1337 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1338 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1339 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1340 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1341 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1342 if(c1->getHashCode()!=c2->getHashCode())
1343 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1346 MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
1349 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
1350 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1352 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
1353 std::vector<const MEDCoupling1SGTUMesh *> ms(2);
1356 return Merge1SGTUMeshesOnSameCoords(ms);
1359 void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception)
1361 checkFullyDefined();
1362 int nbOfNodes=getNumberOfNodes();
1363 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
1364 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
1365 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
1366 const int *conn=_conn->begin();
1367 int nbOfCells=getNumberOfCells();
1368 int nbOfEltsInRevNodal=0;
1369 int nbOfNodesPerCell=getNumberOfNodesPerCell();
1370 for(int eltId=0;eltId<nbOfCells;eltId++)
1372 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1374 if(conn[0]>=0 && conn[0]<nbOfNodes)
1376 nbOfEltsInRevNodal++;
1377 revNodalIndxPtr[conn[0]+1]++;
1381 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
1382 throw INTERP_KERNEL::Exception(oss.str().c_str());
1386 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
1387 conn=_conn->begin();
1388 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
1389 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
1390 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
1391 for(int eltId=0;eltId<nbOfCells;eltId++)
1393 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1395 *std::find_if(revNodalPtr+revNodalIndxPtr[*conn],revNodalPtr+revNodalIndxPtr[*conn+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
1401 * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null.
1403 void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn) throw(INTERP_KERNEL::Exception)
1406 nodalConn->incrRef();
1412 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
1414 DataArrayInt *MEDCoupling1SGTUMesh::getNodalConnectivity() const throw(INTERP_KERNEL::Exception)
1416 const DataArrayInt *ret(_conn);
1417 return const_cast<DataArrayInt *>(ret);
1421 * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted,
1422 * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter.
1423 * If a nodal connectivity previouly existed before the call of this method, it will be reset.
1425 * \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain.
1427 void MEDCoupling1SGTUMesh::allocateCells(int nbOfCells) throw(INTERP_KERNEL::Exception)
1430 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !");
1431 _conn=DataArrayInt::New();
1432 _conn->reserve(getNumberOfNodesPerCell()*nbOfCells);
1437 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
1439 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
1440 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
1441 * \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
1442 * attached to \a this.
1443 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
1445 void MEDCoupling1SGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) throw(INTERP_KERNEL::Exception)
1447 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
1448 int ref=getNumberOfNodesPerCell();
1451 DataArrayInt *c(_conn);
1453 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
1455 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !");
1459 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this (";
1460 oss << ref << ") !";
1461 throw INTERP_KERNEL::Exception(oss.str().c_str());
1467 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
1469 if(type==INTERP_KERNEL::NORM_ERROR)
1470 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
1471 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
1474 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !";
1475 throw INTERP_KERNEL::Exception(oss.str().c_str());
1477 return new MEDCoupling1DGTUMesh(name,cm);
1480 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
1484 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
1488 const DataArrayInt *c(other._conn);
1493 _conn_indx=c->deepCpy();
1497 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const
1499 return new MEDCoupling1DGTUMesh(*this,recDeepCpy);
1503 * This method behaves mostly like MEDCoupling1DGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
1504 * The coordinates are shared between \a this and the returned instance.
1506 * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
1507 * \sa MEDCoupling1DGTUMesh::deepCpy
1509 MEDCouplingPointSet *MEDCoupling1DGTUMesh::deepCpyConnectivityOnly() const throw(INTERP_KERNEL::Exception)
1512 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(clone(false));
1513 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy()),ci(_conn_indx->deepCpy());
1514 ret->setNodalConnectivity(c,ci);
1518 void MEDCoupling1DGTUMesh::updateTime() const
1520 MEDCoupling1GTUMesh::updateTime();
1521 const DataArrayInt *c(_conn);
1529 std::size_t MEDCoupling1DGTUMesh::getHeapMemorySize() const
1532 const DataArrayInt *c(_conn);
1534 ret+=c->getHeapMemorySize();
1537 ret+=c->getHeapMemorySize();
1538 return MEDCoupling1GTUMesh::getHeapMemorySize()+ret;
1541 MEDCouplingMesh *MEDCoupling1DGTUMesh::deepCpy() const
1546 bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
1549 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !");
1550 std::ostringstream oss; oss.precision(15);
1551 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1554 reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !";
1557 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
1559 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1564 reason="in connectivity of single dynamic geometric type exactly one among this and other is null !";
1567 if(!c1->isEqualIfNotWhy(*c2,reason))
1569 reason.insert(0,"Nodal connectivity DataArrayInt differs : ");
1572 c1=_conn_indx; c2=otherC->_conn_indx;
1577 reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !";
1580 if(!c1->isEqualIfNotWhy(*c2,reason))
1582 reason.insert(0,"Nodal connectivity index DataArrayInt differs : ");
1588 bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
1591 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
1592 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1595 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
1597 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1602 if(!c1->isEqualWithoutConsideringStr(*c2))
1605 c1=_conn_indx; c2=otherC->_conn_indx;
1610 if(!c1->isEqualWithoutConsideringStr(*c2))
1616 * Checks if \a this and \a other meshes are geometrically equivalent with high
1617 * probability, else an exception is thrown. The meshes are considered equivalent if
1618 * (1) meshes contain the same number of nodes and the same number of elements of the
1619 * same types (2) three cells of the two meshes (first, last and middle) are based
1620 * on coincident nodes (with a specified precision).
1621 * \param [in] other - the mesh to compare with.
1622 * \param [in] prec - the precision used to compare nodes of the two meshes.
1623 * \throw If the two meshes do not match.
1625 void MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception)
1627 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1628 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1630 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single dynamic geometric type !");
1631 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1635 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1636 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1637 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1638 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1639 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1640 if(c1->getHashCode()!=c2->getHashCode())
1641 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1643 c1=_conn_indx; c2=otherC->_conn_indx;
1647 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !");
1648 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1649 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !");
1650 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1651 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !");
1652 if(c1->getHashCode()!=c2->getHashCode())
1653 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs");
1657 void MEDCoupling1DGTUMesh::checkCoherencyOfConnectivity() const throw(INTERP_KERNEL::Exception)
1659 const DataArrayInt *c1(_conn);
1662 if(c1->getNumberOfComponents()!=1)
1663 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
1664 if(c1->getInfoOnComponent(0)!="")
1665 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
1666 c1->checkAllocated();
1669 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
1671 int sz2=_conn->getNumberOfTuples();
1675 if(c1->getNumberOfComponents()!=1)
1676 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
1677 c1->checkAllocated();
1678 if(c1->getNumberOfTuples()<1)
1679 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !");
1680 if(c1->getInfoOnComponent(0)!="")
1681 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
1682 int f=c1->front(),ll=c1->back();
1685 std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !";
1686 throw INTERP_KERNEL::Exception(oss.str().c_str());
1690 std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !";
1691 throw INTERP_KERNEL::Exception(oss.str().c_str());
1695 std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !";
1696 throw INTERP_KERNEL::Exception(oss.str().c_str());
1700 throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !");
1701 int szOfC1Exp=_conn_indx->back();
1704 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() << " !";
1705 throw INTERP_KERNEL::Exception(oss.str().c_str());
1710 * 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.
1711 * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one.
1712 * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array.
1714 void MEDCoupling1DGTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
1716 MEDCouplingPointSet::checkCoherency();
1717 checkCoherencyOfConnectivity();
1720 void MEDCoupling1DGTUMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
1723 const DataArrayInt *c1(_conn),*c2(_conn_indx);
1724 if(!c2->isMonotonic(true))
1725 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkCoherency1 : the nodal connectivity index is expected to be increasing monotinic !");
1727 int nbOfTuples=c1->getNumberOfTuples();
1728 int nbOfNodes=getNumberOfNodes();
1729 const int *w(c1->begin());
1730 for(int i=0;i<nbOfTuples;i++,w++)
1732 if(*w==-1) continue;
1733 if(*w<0 || *w>=nbOfNodes)
1735 std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !";
1736 throw INTERP_KERNEL::Exception(oss.str().c_str());
1741 void MEDCoupling1DGTUMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
1743 checkCoherency1(eps);
1746 int MEDCoupling1DGTUMesh::getNumberOfCells() const
1748 checkCoherencyOfConnectivity();//do not remove
1749 return _conn_indx->getNumberOfTuples()-1;
1753 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
1754 * For each cell in \b this the number of nodes constituting cell is computed.
1755 * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned.
1756 * So for pohyhedrons some nodes can be counted several times in the returned result.
1758 * \return a newly allocated array
1760 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
1763 _conn_indx->checkMonotonic(true);
1764 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
1765 return _conn_indx->deltaShiftIndex();
1767 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
1768 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1769 ret->alloc(nbOfCells,1);
1770 int *retPtr=ret->getPointer();
1771 const int *ci=_conn_indx->begin(),*c=_conn->begin();
1772 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
1773 *retPtr=ci[1]-ci[0]-std::count(c+ci[0],c+ci[1],-1);
1778 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
1779 * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed.
1781 * \return a newly allocated array
1783 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception)
1786 _conn_indx->checkMonotonic(true);
1787 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG)
1788 return _conn_indx->deltaShiftIndex();
1789 if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG)
1791 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=_conn_indx->deltaShiftIndex();
1792 ret->applyDivideBy(2);
1796 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
1797 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1798 ret->alloc(nbOfCells,1);
1799 int *retPtr=ret->getPointer();
1800 const int *ci=_conn_indx->begin(),*c=_conn->begin();
1801 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
1802 *retPtr=std::count(c+ci[0],c+ci[1],-1)+1;
1806 void MEDCoupling1DGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
1808 int nbOfCells=getNumberOfCells();//performs checks
1809 if(cellId>=0 && cellId<nbOfCells)
1811 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
1812 int nbOfNodes=stp-strt;
1814 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !");
1815 conn.resize(nbOfNodes);
1816 std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin());
1820 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
1821 throw INTERP_KERNEL::Exception(oss.str().c_str());
1825 std::string MEDCoupling1DGTUMesh::simpleRepr() const
1827 static const char msg0[]="No coordinates specified !";
1828 std::ostringstream ret;
1829 ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
1830 ret << "Description of mesh : \"" << getDescription() << "\"\n";
1832 double tt=getTime(tmpp1,tmpp2);
1833 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
1834 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
1835 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
1838 const int spaceDim=getSpaceDimension();
1839 ret << spaceDim << "\nInfo attached on space dimension : ";
1840 for(int i=0;i<spaceDim;i++)
1841 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
1845 ret << msg0 << "\n";
1846 ret << "Number of nodes : ";
1848 ret << getNumberOfNodes() << "\n";
1850 ret << msg0 << "\n";
1851 ret << "Number of cells : ";
1853 try { checkCoherency(); } catch(INTERP_KERNEL::Exception& e)
1855 ret << "Nodal connectivity arrays are not set or badly set !\n";
1859 ret << getNumberOfCells() << "\n";
1860 ret << "Cell type : " << _cm->getRepr() << "\n";
1864 std::string MEDCoupling1DGTUMesh::advancedRepr() const
1866 std::ostringstream ret;
1867 ret << simpleRepr();
1868 ret << "\nCoordinates array : \n___________________\n\n";
1870 _coords->reprWithoutNameStream(ret);
1872 ret << "No array set !\n";
1873 ret << "\n\nNodal Connectivity : \n____________________\n\n";
1876 try { checkCoherency1(); } catch(INTERP_KERNEL::Exception& e)
1878 ret << "Nodal connectivity arrays are not set or badly set !\n";
1883 int nbOfCells=getNumberOfCells();
1884 const int *ci=_conn_indx->begin(),*c=_conn->begin();
1885 for(int i=0;i<nbOfCells;i++,ci++)
1887 ret << "Cell #" << i << " : ";
1888 std::copy(c+ci[0],c+ci[1],std::ostream_iterator<int>(ret," "));
1894 DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
1896 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1897 int spaceDim=getSpaceDimension();
1898 int nbOfCells=getNumberOfCells();//checkCoherency()
1899 int nbOfNodes=getNumberOfNodes();
1900 ret->alloc(nbOfCells,spaceDim);
1901 double *ptToFill=ret->getPointer();
1902 const double *coor=_coords->begin();
1903 const int *nodal=_conn->begin(),*nodali=_conn_indx->begin();
1905 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
1907 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
1909 std::fill(ptToFill,ptToFill+spaceDim,0.);
1910 if(nodali[0]<nodali[1])// >= to avoid division by 0.
1912 for(int j=nodali[0];j<nodali[1];j++,nodal++)
1914 if(*nodal>=0 && *nodal<nbOfNodes)
1915 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
1918 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
1919 throw INTERP_KERNEL::Exception(oss.str().c_str());
1921 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(nodali[1]-nodali[0])));
1926 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !";
1927 throw INTERP_KERNEL::Exception(oss.str().c_str());
1933 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
1935 std::fill(ptToFill,ptToFill+spaceDim,0.);
1936 if(nodali[0]<nodali[1])// >= to avoid division by 0.
1939 for(int j=nodali[0];j<nodali[1];j++,nodal++)
1941 if(*nodal==-1) continue;
1942 if(*nodal>=0 && *nodal<nbOfNodes)
1944 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
1949 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
1950 throw INTERP_KERNEL::Exception(oss.str().c_str());
1954 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./nbOfNod));
1957 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !";
1958 throw INTERP_KERNEL::Exception(oss.str().c_str());
1963 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : at cell #" << i << " the nodal index array is invalid !";
1964 throw INTERP_KERNEL::Exception(oss.str().c_str());
1971 void MEDCoupling1DGTUMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
1973 int nbCells=getNumberOfCells();
1974 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
1975 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
1977 o2n=o2n->checkAndPreparePermutation();
1979 const int *o2nPtr=o2n->getPointer();
1980 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
1981 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
1982 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
1983 newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1);
1984 newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx);
1986 int *newC=newConn->getPointer(),*newCI=newConnI->getPointer();
1987 for(int i=0;i<nbCells;i++)
1989 int newPos=o2nPtr[i];
1990 int sz=conni[i+1]-conni[i];
1995 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !";
1996 throw INTERP_KERNEL::Exception(oss.str().c_str());
1999 newConnI->computeOffsets2(); newCI=newConnI->getPointer();
2001 for(int i=0;i<nbCells;i++,conni++)
2003 int sz=conni[1]-conni[0];
2005 std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]);
2008 _conn_indx=newConnI;
2011 MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
2013 if(other->getType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED)
2014 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !");
2015 const MEDCoupling1DGTUMesh *otherC=static_cast<const MEDCoupling1DGTUMesh *>(other);
2016 return Merge1DGTUMeshes(this,otherC);
2019 MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
2021 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName().c_str(),getMeshDimension());
2022 ret->setCoords(getCoords());
2023 const int *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin();
2024 int nbCells=getNumberOfCells();//checkCoherency
2025 int geoType=(int)getCellModelEnum();
2026 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1);
2027 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::New(); cI->alloc(nbCells+1);
2028 int *cPtr=c->getPointer(),*ciPtr=cI->getPointer();
2030 for(int i=0;i<nbCells;i++,ciPtr++)
2032 int sz=nodalConnI[i+1]-nodalConnI[i];
2036 cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr);
2037 ciPtr[1]=ciPtr[0]+sz+1;
2041 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !";
2042 throw INTERP_KERNEL::Exception(oss.str().c_str());
2045 ret->setConnectivity(c,cI,true);
2050 * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes
2052 DataArrayInt *MEDCoupling1DGTUMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
2054 int nbOfCells=getNumberOfCells();
2055 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2056 ret->alloc(nbOfCells,1);
2061 void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
2063 stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
2064 stream << " Mesh dimension : " << getMeshDimension() << ".";
2066 { stream << " No coordinates set !"; return ; }
2067 if(!_coords->isAllocated())
2068 { stream << " Coordinates set but not allocated !"; return ; }
2069 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
2070 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
2072 try { checkCoherency(); } catch(INTERP_KERNEL::Exception& e)
2074 stream << std::endl << "Nodal connectivity NOT set properly !\n";
2078 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
2081 void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception)
2084 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
2085 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2087 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !");
2088 setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex());
2091 MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
2094 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
2095 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2097 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
2098 std::vector<const MEDCoupling1DGTUMesh *> ms(2);
2101 return Merge1DGTUMeshesOnSameCoords(ms);
2104 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
2107 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2108 ret->setCoords(_coords);
2109 DataArrayInt *c=0,*ci=0;
2110 MEDCouplingUMesh::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci);
2111 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2112 ret->setNodalConnectivity(c,ci);
2116 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
2119 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2120 ret->setCoords(_coords);
2121 DataArrayInt *c=0,*ci=0;
2122 MEDCouplingUMesh::ExtractFromIndexedArrays2(start,end,step,_conn,_conn_indx,c,ci);
2123 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2124 ret->setNodalConnectivity(c,ci);
2128 void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception)
2130 checkFullyDefined();
2131 int nbOfNodes=getNumberOfNodes();
2132 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
2133 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
2134 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
2135 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2136 int nbOfCells=getNumberOfCells();
2137 int nbOfEltsInRevNodal=0;
2138 for(int eltId=0;eltId<nbOfCells;eltId++)
2140 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2141 if(nbOfNodesPerCell>=0)
2143 for(int j=0;j<nbOfNodesPerCell;j++)
2145 int nodeId=conn[conni[eltId]+j];
2146 if(nodeId==-1) continue;
2147 if(nodeId>=0 && nodeId<nbOfNodes)
2149 nbOfEltsInRevNodal++;
2150 revNodalIndxPtr[nodeId+1]++;
2154 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
2155 throw INTERP_KERNEL::Exception(oss.str().c_str());
2161 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << "nodal connectivity is invalid !";
2162 throw INTERP_KERNEL::Exception(oss.str().c_str());
2165 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
2166 conn=_conn->begin();
2167 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
2168 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
2169 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
2170 for(int eltId=0;eltId<nbOfCells;eltId++)
2172 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2173 for(int j=0;j<nbOfNodesPerCell;j++)
2175 int nodeId=conn[conni[eltId]+j];
2177 *std::find_if(revNodalPtr+revNodalIndxPtr[nodeId],revNodalPtr+revNodalIndxPtr[nodeId+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
2182 void MEDCoupling1DGTUMesh::checkFullyDefined() const throw(INTERP_KERNEL::Exception)
2184 if(!((const DataArrayInt *)_conn) || !((const DataArrayInt *)_conn_indx) || !((const DataArrayDouble *)_coords))
2185 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined.");
2188 bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
2190 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !");
2194 * Finds nodes not used in any cell and returns an array giving a new id to every node
2195 * by excluding the unused nodes, for which the array holds -1. The result array is
2196 * a mapping in "Old to New" mode.
2197 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
2198 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
2199 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
2200 * if the node is unused or a new id else. The caller is to delete this
2201 * array using decrRef() as it is no more needed.
2202 * \throw If the coordinates array is not set.
2203 * \throw If the nodal connectivity of cells is not defined.
2204 * \throw If the nodal connectivity includes an invalid id.
2206 DataArrayInt *MEDCoupling1DGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception)
2209 int nbOfNodes=getNumberOfNodes();
2210 int nbOfCells=getNumberOfCells();//checkCoherency
2211 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2212 ret->alloc(nbOfNodes,1);
2213 int *traducer=ret->getPointer();
2214 std::fill(traducer,traducer+nbOfNodes,-1);
2215 const int *conn=_conn->begin(),*conni(_conn_indx->begin());
2216 for(int i=0;i<nbOfCells;i++,conni++)
2218 int nbNodesPerCell=conni[1]-conni[0];
2219 for(int j=0;j<nbNodesPerCell;j++)
2221 int nodeId=conn[conni[0]+j];
2222 if(nodeId==-1) continue;
2223 if(nodeId>=0 && nodeId<nbOfNodes)
2227 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << nodeId << " not in [0," << nbOfNodes << ") !";
2228 throw INTERP_KERNEL::Exception(oss.str().c_str());
2232 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
2233 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
2238 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
2239 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
2240 * This method is a generalization of shiftNodeNumbersInConn().
2241 * \warning This method performs no check of validity of new ids. **Use it with care !**
2242 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
2243 * this->getNumberOfNodes(), in "Old to New" mode.
2244 * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
2245 * \throw If the nodal connectivity of cells is not defined.
2247 void MEDCoupling1DGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
2249 getNumberOfCells();//only to check that all is well defined.
2251 int nbElemsIn=getNumberOfNodes();
2252 int nbOfTuples=_conn->getNumberOfTuples();
2253 int *pt=_conn->getPointer();
2254 for(int i=0;i<nbOfTuples;i++,pt++)
2256 if(*pt==-1) continue;
2257 if(*pt>=0 && *pt<nbElemsIn)
2258 *pt=newNodeNumbersO2N[*pt];
2261 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
2262 throw INTERP_KERNEL::Exception(oss.str().c_str());
2265 _conn->declareAsNew();
2271 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
2272 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
2273 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
2274 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
2276 * \param [in] begin input start of array of node ids.
2277 * \param [in] end input end of array of node ids.
2278 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
2279 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
2281 void MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
2283 int nbOfCells=getNumberOfCells();
2284 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
2286 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
2287 std::vector<bool> fastFinder(sz,false);
2288 for(const int *work=begin;work!=end;work++)
2289 if(*work>=0 && *work<sz)
2290 fastFinder[*work]=true;
2291 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2292 for(int i=0;i<nbOfCells;i++,conni++)
2294 int ref=0,nbOfHit=0;
2295 int nbNodesPerCell=conni[1]-conni[0];
2296 if(nbNodesPerCell>=0)
2298 for(int j=0;j<nbNodesPerCell;j++)
2300 int nodeId=conn[conni[0]+j];
2304 if(fastFinder[nodeId])
2311 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !";
2312 throw INTERP_KERNEL::Exception(oss.str().c_str());
2314 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
2315 cellIdsKept->pushBackSilent(i);
2317 cellIdsKeptArr=cellIdsKept.retn();
2320 void MEDCoupling1DGTUMesh::allocateCells(int nbOfCells) throw(INTERP_KERNEL::Exception)
2323 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !");
2324 _conn=DataArrayInt::New();
2325 _conn->reserve(nbOfCells*3);
2326 _conn_indx=DataArrayInt::New();
2327 _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0);
2332 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
2334 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
2335 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
2336 * \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
2337 * attached to \a this.
2338 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
2340 void MEDCoupling1DGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) throw(INTERP_KERNEL::Exception)
2342 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
2343 DataArrayInt *c(_conn),*c2(_conn_indx);
2347 if(pos==c->getNumberOfTuples())
2349 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
2350 c2->pushBackSilent(pos+sz);
2354 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !";
2355 throw INTERP_KERNEL::Exception(oss.str().c_str());
2359 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !");
2362 void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex) throw(INTERP_KERNEL::Exception)
2365 nodalConn->incrRef();
2368 nodalConnIndex->incrRef();
2369 _conn_indx=nodalConnIndex;
2374 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
2376 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivity() const throw(INTERP_KERNEL::Exception)
2378 const DataArrayInt *ret(_conn);
2379 return const_cast<DataArrayInt *>(ret);
2383 * \return DataArrayInt * - the internal reference to the nodal connectivity index. The caller is not reponsible to deallocate it.
2385 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const throw(INTERP_KERNEL::Exception)
2387 const DataArrayInt *ret(_conn_indx);
2388 return const_cast<DataArrayInt *>(ret);
2392 * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here".
2393 * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity).
2394 * 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.
2396 * 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.
2398 * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal
2399 * connectivity arrays are different (false)
2400 * \return a new object to be managed by the caller.
2402 * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked
2404 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const throw(INTERP_KERNEL::Exception)
2406 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2407 DataArrayInt *nc=0,*nci=0;
2408 isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci);
2409 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ncs(nc),ncis(nci);
2410 ret->_conn=ncs; ret->_conn_indx=ncis;
2411 ret->setCoords(getCoords());
2416 * This method allows to compute, if needed, the packed nodal connectivity pair.
2417 * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges convered by nodal connectivity index array.
2418 * 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.
2420 * 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)
2421 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
2423 * 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
2426 * This method return 3 elements.
2427 * \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
2428 * this pointer can be seen as a new object, that is to managed by the caller.
2429 * \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
2430 * this pointer can be seen as a new object, that is to managed by the caller.
2431 * \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
2432 * output parameters are newly created objects.
2434 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
2436 bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const throw(INTERP_KERNEL::Exception)
2438 if(isPacked())//performs the checkCoherency
2440 const DataArrayInt *c0(_conn),*c1(_conn_indx);
2441 nodalConn=const_cast<DataArrayInt *>(c0); nodalConnIndx=const_cast<DataArrayInt *>(c1);
2442 nodalConn->incrRef(); nodalConnIndx->incrRef();
2445 int bg=_conn_indx->front(),end=_conn_indx->back();
2446 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nc(_conn->selectByTupleId2(bg,end,1));
2447 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nci(_conn_indx->deepCpy());
2448 nci->applyLin(1,-bg);
2449 nodalConn=nc.retn(); nodalConnIndx=nci.retn();
2454 * 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)
2455 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
2456 * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned.
2457 * \return bool - true if \a this looks packed, false is not.
2459 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
2461 bool MEDCoupling1DGTUMesh::isPacked() const throw(INTERP_KERNEL::Exception)
2464 return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples();
2467 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2) throw(INTERP_KERNEL::Exception)
2469 std::vector<const MEDCoupling1DGTUMesh *> tmp(2);
2470 tmp[0]=const_cast<MEDCoupling1DGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1DGTUMesh *>(mesh2);
2471 return Merge1DGTUMeshes(tmp);
2474 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
2476 std::size_t sz=a.size();
2478 return Merge1DGTUMeshesLL(a);
2479 for(std::size_t ii=0;ii<sz;ii++)
2482 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::Merge1DGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
2483 throw INTERP_KERNEL::Exception(oss.str().c_str());
2485 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
2486 for(std::size_t ii=0;ii<sz;ii++)
2487 if(&(a[ii]->getCellModel())!=cm)
2488 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !");
2489 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > bb(sz);
2490 std::vector< const MEDCoupling1DGTUMesh * > aa(sz);
2492 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
2494 const MEDCoupling1DGTUMesh *cur=a[i];
2495 const DataArrayDouble *coo=cur->getCoords();
2497 spaceDim=coo->getNumberOfComponents();
2500 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !");
2501 for(std::size_t i=0;i<sz;i++)
2503 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
2506 return Merge1DGTUMeshesLL(aa);
2510 * \throw If presence of a null instance in the input vector \a a.
2511 * \throw If a is empty
2513 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
2516 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !");
2517 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
2519 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !");
2520 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
2521 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
2522 int nbOfCells=(*it)->getNumberOfCells();
2523 const DataArrayDouble *coords=(*it)->getCoords();
2524 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
2526 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
2527 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
2529 for(int i=1;it!=a.end();i++,it++)
2532 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !");
2533 if(cm!=&((*it)->getCellModel()))
2534 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
2535 (*it)->getNumberOfCells();//to check that all is OK
2536 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
2537 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
2538 if(coords!=(*it)->getCoords())
2539 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !");
2541 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
2542 ret->setCoords(coords);
2543 ret->_conn=DataArrayInt::Aggregate(ncs);
2544 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
2549 * 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)
2551 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
2554 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : input array must be NON EMPTY !");
2555 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
2556 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
2557 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
2558 std::vector<int> nbNodesPerElt(a.size());
2559 int nbOfCells=(*it)->getNumberOfCells();
2561 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
2562 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
2564 int prevNbOfNodes=(*it)->getNumberOfNodes();
2565 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
2567 for(int i=1;it!=a.end();i++,it++)
2569 if(cm!=&((*it)->getCellModel()))
2570 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
2571 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
2572 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
2573 nbOfCells+=(*it)->getNumberOfCells();
2574 nbNodesPerElt[i]=nbNodesPerElt[i-1]+prevNbOfNodes;
2575 prevNbOfNodes=(*it)->getNumberOfNodes();
2577 std::vector<const MEDCouplingPointSet *> aps(a.size());
2578 std::copy(a.begin(),a.end(),aps.begin());
2579 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
2580 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
2581 ret->setCoords(pts);
2582 ret->_conn=AggregateNodalConnAndShiftNodeIds(ncs,nbNodesPerElt);
2583 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
2587 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception)
2589 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2590 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1,tmp2;
2591 const DataArrayInt *nodalConn(_conn),*nodalConnI(_conn_indx);
2594 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
2602 tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
2606 ret->_conn_indx=tmp2;
2610 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
2611 ret->setCoords(coords);
2614 ret->setCoords(_coords);
2619 * This method performs an aggregation of \a nodalConns (as DataArrayInt::Aggregate does) but in addition of that a shift is applied on the
2620 * values contained in \a nodalConns using corresponding offset specified in input \a offsetInNodeIdsPerElt.
2621 * But it also manage the values -1, that have a semantic in MEDCoupling1DGTUMesh class (separator for polyhedron).
2623 * \param [in] nodalConns - a list of nodal connectivity arrays same size than \a offsetInNodeIdsPerElt.
2624 * \param [in] offsetInNodeIdsPerElt - a list of offsets to apply.
2625 * \return DataArrayInt * - A new object (to be managed by the caller) that is the result of the aggregation.
2626 * \throw If \a nodalConns or \a offsetInNodeIdsPerElt are empty.
2627 * \throw If \a nodalConns and \a offsetInNodeIdsPerElt have not the same size.
2628 * \throw If presence of null pointer in \a nodalConns.
2629 * \throw If presence of not allocated or array with not exactly one component in \a nodalConns.
2631 DataArrayInt *MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds(const std::vector<const DataArrayInt *>& nodalConns, const std::vector<int>& offsetInNodeIdsPerElt) throw(INTERP_KERNEL::Exception)
2633 std::size_t sz1(nodalConns.size()),sz2(offsetInNodeIdsPerElt.size());
2635 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : input vectors do not have the same size !");
2637 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : empty vectors in input !");
2639 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++)
2642 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of null pointer in input vector !");
2643 if(!(*it)->isAllocated())
2644 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of non allocated array in input vector !");
2645 if((*it)->getNumberOfComponents()!=1)
2646 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of array with not exactly one component !");
2647 nbOfTuples+=(*it)->getNumberOfTuples();
2649 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
2650 int *pt=ret->getPointer();
2652 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++,i++)
2654 int curNbt=(*it)->getNumberOfTuples();
2655 const int *inPt=(*it)->begin();
2656 int offset=offsetInNodeIdsPerElt[i];
2657 for(int j=0;j<curNbt;j++,pt++)
2668 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception)
2671 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh is null !");
2672 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
2674 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh must have exactly one geometric type !");
2675 int geoType((int)*gts.begin());
2676 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(m->getName().c_str(),*gts.begin()));
2677 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription().c_str());
2678 int nbCells(m->getNumberOfCells());
2679 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
2680 conn->alloc(m->getMeshLength()-nbCells,1); connI->alloc(nbCells+1,1);
2681 int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
2682 const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
2683 for(int i=0;i<nbCells;i++,ciin++,ci++)
2685 if(cin[ciin[0]]==geoType)
2687 if(ciin[1]-ciin[0]>=1)
2689 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
2690 ci[1]=ci[0]+ciin[1]-ciin[0]-1;
2694 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 !";
2695 throw INTERP_KERNEL::Exception(oss.str().c_str());
2700 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 !";
2701 throw INTERP_KERNEL::Exception(oss.str().c_str());
2704 ret->setNodalConnectivity(conn,connI);