1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (CEA/DEN)
21 #include "MEDCoupling1GTUMesh.hxx"
22 #include "MEDCouplingUMesh.hxx"
23 #include "MEDCouplingFieldDouble.hxx"
25 #include "SplitterTetra.hxx"
27 using namespace ParaMEDMEM;
29 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh()
33 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):_cm(&cm)
38 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const MEDCoupling1GTUMesh& other, bool recDeepCpy):MEDCouplingPointSet(other,recDeepCpy),_cm(other._cm)
42 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
44 if(type==INTERP_KERNEL::NORM_ERROR)
45 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
46 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
48 return MEDCoupling1SGTUMesh::New(name,type);
50 return MEDCoupling1DGTUMesh::New(name,type);
53 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception)
56 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh is null !");
57 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
59 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh must have exactly one geometric type !");
60 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*gts.begin());
62 return MEDCoupling1SGTUMesh::New(m);
64 return MEDCoupling1DGTUMesh::New(m);
67 const INTERP_KERNEL::CellModel& MEDCoupling1GTUMesh::getCellModel() const throw(INTERP_KERNEL::Exception)
72 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getCellModelEnum() const throw(INTERP_KERNEL::Exception)
74 return _cm->getEnum();
77 int MEDCoupling1GTUMesh::getMeshDimension() const
79 return (int)_cm->getDimension();
83 * This method returns a newly allocated array containing cell ids (ascendingly sorted) whose geometric type are equal to type.
84 * This method does not throw exception if geometric type \a type is not in \a this.
85 * This method throws an INTERP_KERNEL::Exception if meshdimension of \b this is not equal to those of \b type.
86 * The coordinates array is not considered here.
88 * \param [in] type the geometric type
89 * \return cell ids in this having geometric type \a type.
91 DataArrayInt *MEDCoupling1GTUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception)
93 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
94 if(type==getCellModelEnum())
95 ret->alloc(getNumberOfCells(),1);
103 * Returns nb of cells having the geometric type \a type. No throw if no cells in \a this has the geometric type \a type.
105 int MEDCoupling1GTUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
107 return type==getCellModelEnum()?getNumberOfCells():0;
111 * Returns a type of a cell by its id.
112 * \param [in] cellId - the id of the cell of interest.
113 * \return INTERP_KERNEL::NormalizedCellType - enumeration item describing the cell type.
114 * \throw If \a cellId is invalid. Valid range is [0, \a this->getNumberOfCells() ).
116 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getTypeOfCell(int cellId) const
118 if(cellId>=0 && cellId<getNumberOfCells())
119 return getCellModelEnum();
120 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::getTypeOfCell : Requesting type of cell #" << cellId << " but it should be in [0," << getNumberOfCells() << ") !";
121 throw INTERP_KERNEL::Exception(oss.str().c_str());
125 * Returns a set of all cell types available in \a this mesh.
126 * \return std::set<INTERP_KERNEL::NormalizedCellType> - the set of cell types.
127 * \warning this method does not throw any exception even if \a this is not defined.
129 std::set<INTERP_KERNEL::NormalizedCellType> MEDCoupling1GTUMesh::getAllGeoTypes() const
131 std::set<INTERP_KERNEL::NormalizedCellType> ret;
132 ret.insert(getCellModelEnum());
137 * This method expects that \a this is sorted by types. If not an exception will be thrown.
138 * This method returns in the same format as code (see MEDCouplingUMesh::checkTypeConsistencyAndContig or MEDCouplingUMesh::splitProfilePerType) how
139 * \a this is composed in cell types.
140 * The returned array is of size 3*n where n is the number of different types present in \a this.
141 * For every k in [0,n] ret[3*k+2]==-1 because it has no sense here.
142 * This parameter is kept only for compatibility with other methode listed above.
144 std::vector<int> MEDCoupling1GTUMesh::getDistributionOfTypes() const throw(INTERP_KERNEL::Exception)
146 std::vector<int> ret(3);
147 ret[0]=(int)getCellModelEnum(); ret[1]=getNumberOfCells(); ret[2]=-1;
152 * This method is the opposite of MEDCouplingUMesh::checkTypeConsistencyAndContig method. Given a list of cells in \a profile it returns a list of sub-profiles sorted by geo type.
153 * The result is put in the array \a idsPerType. In the returned parameter \a code, foreach i \a code[3*i+2] refers (if different from -1) to a location into the \a idsPerType.
154 * This method has 1 input \a profile and 3 outputs \a code \a idsInPflPerType and \a idsPerType.
156 * \param [out] code is a vector of size 3*n where n is the number of different geometric type in \a this \b reduced to the profile \a profile. \a code has exactly the same semantic than in MEDCouplingUMesh::checkTypeConsistencyAndContig method.
157 * \param [out] idsInPflPerType is a vector of size of different geometric type in the subpart defined by \a profile of \a this ( equal to \a code.size()/3). For each i,
158 * \a idsInPflPerType[i] stores the tuple ids in \a profile that correspond to the geometric type code[3*i+0]
159 * \param [out] idsPerType is a vector of size of different sub profiles needed to be defined to represent the profile \a profile for a given geometric type.
160 * This vector can be empty in case of all geometric type cells are fully covered in ascending in the given input \a profile.
162 * \warning for performance reasons no deep copy will be performed, if \a profile can been used as this in output parameters \a idsInPflPerType and \a idsPerType.
164 * \throw if \a profile has not exactly one component. It throws too, if \a profile contains some values not in [0,getNumberOfCells()) or if \a this is not fully defined
167 * - Before \a this has 3 cells \a profile contains [0,1,2]
168 * - After \a code contains [NORM_...,nbCells,-1], \a idsInPflPerType [[0,1,2]] and \a idsPerType is empty <br>
171 * - Before \a this has 3 cells \a profile contains [1,2]
172 * - After \a code contains [NORM_...,nbCells,0], \a idsInPflPerType [[0,1]] and \a idsPerType is [[1,2]] <br>
175 void MEDCoupling1GTUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
178 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile is NULL !");
179 if(profile->getNumberOfComponents()!=1)
180 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile should have exactly one component !");
181 int nbTuples=profile->getNumberOfTuples();
182 int nbOfCells=getNumberOfCells();
183 code.resize(3); idsInPflPerType.resize(1);
184 code[0]=(int)getCellModelEnum(); code[1]=nbTuples;
185 idsInPflPerType.resize(1);
186 if(profile->isIdentity() && nbTuples==nbOfCells)
189 idsInPflPerType[0]=const_cast<DataArrayInt *>(profile); idsInPflPerType[0]->incrRef();
194 profile->checkAllIdsInRange(0,nbOfCells);
195 idsPerType.resize(1);
196 idsPerType[0]=const_cast<DataArrayInt *>(profile); idsPerType[0]->incrRef();
197 idsInPflPerType[0]=DataArrayInt::Range(0,nbTuples,1);
201 * This method tries to minimize at most the number of deep copy.
202 * So if \a idsPerType is not empty it can be returned directly (without copy, but with ref count incremented) in return.
204 * \sa MEDCouplingUMesh::checkTypeConsistencyAndContig
206 DataArrayInt *MEDCoupling1GTUMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
208 int nbOfCells=getNumberOfCells();
210 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : invalid input code should be exactly of size 3 !");
211 if(code[0]!=(int)getCellModelEnum())
213 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : Mismatch of geometric type ! Asking for " << code[0] << " whereas the geometric type is \a this is " << getCellModelEnum() << " (" << _cm->getRepr() << ") !";
214 throw INTERP_KERNEL::Exception(oss.str().c_str());
218 if(code[1]==nbOfCells)
222 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : mismatch between the number of cells in this (" << nbOfCells << ") and the number of non profile (" << code[1] << ") !";
223 throw INTERP_KERNEL::Exception(oss.str().c_str());
227 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : single geo type mesh ! 0 or -1 is expected at pos #2 of input code !");
228 if(idsPerType.size()!=1)
229 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input code points to DataArrayInt #0 whereas the size of idsPerType is not equal to 1 !");
230 const DataArrayInt *pfl=idsPerType[0];
232 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : the input code points to a NULL DataArrayInt at rank 0 !");
233 if(pfl->getNumberOfComponents()!=1)
234 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input profile should have exactly one component !");
235 pfl->checkAllIdsInRange(0,nbOfCells);
237 return const_cast<DataArrayInt *>(pfl);
240 void MEDCoupling1GTUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception)
242 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
243 m->writeVTKLL(ofs,cellData,pointData);
246 std::string MEDCoupling1GTUMesh::getVTKDataSetType() const throw(INTERP_KERNEL::Exception)
248 return std::string("UnstructuredGrid");
251 std::size_t MEDCoupling1GTUMesh::getHeapMemorySize() const
253 return MEDCouplingPointSet::getHeapMemorySize();
256 bool MEDCoupling1GTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
258 if(!MEDCouplingPointSet::isEqualIfNotWhy(other,prec,reason))
261 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualIfNotWhy : input other pointer is null !");
262 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
265 reason="mesh given in input is not castable in MEDCouplingSGTUMesh !";
270 reason="mismatch in geometric type !";
276 bool MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
278 if(!MEDCouplingPointSet::isEqualWithoutConsideringStr(other,prec))
281 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
282 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
290 void MEDCoupling1GTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
292 MEDCouplingPointSet::checkCoherency();
295 DataArrayDouble *MEDCoupling1GTUMesh::getBarycenterAndOwner() const
297 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
298 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=m->getBarycenterAndOwner();
302 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureField(bool isAbs) const
304 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
305 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureField(isAbs);
310 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureFieldOnNode(bool isAbs) const
312 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
313 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureFieldOnNode(isAbs);
321 int MEDCoupling1GTUMesh::getCellContainingPoint(const double *pos, double eps) const
323 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
324 return m->getCellContainingPoint(pos,eps);
327 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::buildOrthogonalField() const
329 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
330 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->buildOrthogonalField();
335 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const double *bbox, double eps) const
337 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
338 return m->getCellsInBoundingBox(bbox,eps);
341 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps)
343 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
344 return m->getCellsInBoundingBox(bbox,eps);
347 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const
349 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
350 return m->buildFacePartOfMySelfNode(start,end,fullyIn);
353 DataArrayInt *MEDCoupling1GTUMesh::findBoundaryNodes() const
355 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
356 return m->findBoundaryNodes();
359 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildBoundaryMesh(bool keepCoords) const
361 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
362 return m->buildBoundaryMesh(keepCoords);
365 void MEDCoupling1GTUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const throw(INTERP_KERNEL::Exception)
367 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
368 m->findCommonCells(compType,startCellId,commonCellsArr,commonCellsIArr);
371 int MEDCoupling1GTUMesh::getNodalConnectivityLength() const throw(INTERP_KERNEL::Exception)
373 const DataArrayInt *c1(getNodalConnectivity());
375 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : no connectivity set !");
376 if(c1->getNumberOfComponents()!=1)
377 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array set must have exactly one component !");
378 if(!c1->isAllocated())
379 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array must be allocated !");
380 return c1->getNumberOfTuples();
384 * This method aggregates all the meshes in \a parts to put them in a single unstructured mesh (those returned).
385 * The order of cells is the returned instance is those in the order of instances in \a parts.
387 * \param [in] parts - all not null parts of single geo type meshes to be aggreagated having the same mesh dimension and same coordinates.
388 * \return MEDCouplingUMesh * - new object to be dealt by the caller.
390 * \throw If one element is null in \a parts.
391 * \throw If not all the parts do not have the same mesh dimension.
392 * \throw If not all the parts do not share the same coordinates.
393 * \throw If not all the parts have their connectivity set properly.
394 * \throw If \a parts is empty.
396 MEDCouplingUMesh *MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh(const std::vector< const MEDCoupling1GTUMesh *>& parts) throw(INTERP_KERNEL::Exception)
399 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : input parts vector is empty !");
400 const MEDCoupling1GTUMesh *firstPart(parts[0]);
402 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : the first instance in input parts is null !");
403 const DataArrayDouble *coords(firstPart->getCoords());
404 int meshDim(firstPart->getMeshDimension());
405 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret(MEDCouplingUMesh::New(firstPart->getName().c_str(),meshDim)); ret->setDescription(firstPart->getDescription().c_str());
406 ret->setCoords(coords);
407 int nbOfCells(0),connSize(0);
408 for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
411 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of null pointer in input vector !");
412 if((*it)->getMeshDimension()!=meshDim)
413 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances in input vector must have same mesh dimension !");
414 if((*it)->getCoords()!=coords)
415 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances must share the same coordinates pointer !");
416 nbOfCells+=(*it)->getNumberOfCells();
417 connSize+=(*it)->getNodalConnectivityLength();
419 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
420 connI->alloc(nbOfCells+1,1); conn->alloc(connSize+nbOfCells,1);
421 int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
422 for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
424 int curNbCells((*it)->getNumberOfCells());
425 int geoType((int)(*it)->getCellModelEnum());
426 const int *cinPtr((*it)->getNodalConnectivity()->begin());
427 const MEDCoupling1SGTUMesh *ps(dynamic_cast<const MEDCoupling1SGTUMesh *>(*it));
428 const MEDCoupling1DGTUMesh *pd(dynamic_cast<const MEDCoupling1DGTUMesh *>(*it));
431 int nNodesPerCell(ps->getNumberOfNodesPerCell());
432 for(int i=0;i<curNbCells;i++,ci++,cinPtr+=nNodesPerCell)
435 c=std::copy(cinPtr,cinPtr+nNodesPerCell,c);
436 ci[1]=ci[0]+nNodesPerCell+1;
441 const int *ciinPtr(pd->getNodalConnectivityIndex()->begin());
442 for(int i=0;i<curNbCells;i++,ci++,ciinPtr++)
445 c=std::copy(cinPtr+ciinPtr[0],cinPtr+ciinPtr[1],c);
446 ci[1]=ci[0]+ciinPtr[1]-ciinPtr[0]+1;
450 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of instance which type is not in [MEDCoupling1SGTUMesh,MEDCoupling1DGTUMesh] !");
452 ret->setConnectivity(conn,connI,true);
458 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const MEDCoupling1SGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
462 const DataArrayInt *c(other._conn);
468 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
472 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh()
476 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New()
478 return new MEDCoupling1SGTUMesh;
481 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
483 if(type==INTERP_KERNEL::NORM_ERROR)
484 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
485 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
488 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New : the input geometric type " << cm.getRepr() << " is dynamic ! Only static types are allowed here !";
489 throw INTERP_KERNEL::Exception(oss.str().c_str());
491 return new MEDCoupling1SGTUMesh(name,cm);
494 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception)
497 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh is null !");
498 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
500 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh must have exactly one geometric type !");
501 int geoType((int)*gts.begin());
502 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(m->getName().c_str(),*gts.begin()));
503 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription().c_str());
504 int nbCells(m->getNumberOfCells());
505 int nbOfNodesPerCell(ret->getNumberOfNodesPerCell());
506 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()); conn->alloc(nbCells*nbOfNodesPerCell,1);
507 int *c(conn->getPointer());
508 const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
509 for(int i=0;i<nbCells;i++,ciin++)
511 if(cin[ciin[0]]==geoType)
513 if(ciin[1]-ciin[0]==nbOfNodesPerCell+1)
514 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
517 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m) : something is wrong in the input mesh at cell #" << i << " ! The size of cell is not those expected (" << nbOfNodesPerCell << ") !";
518 throw INTERP_KERNEL::Exception(oss.str().c_str());
523 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m) : something is wrong in the input mesh at cell #" << i << " ! The geometric type is not those expected !";
524 throw INTERP_KERNEL::Exception(oss.str().c_str());
527 ret->setNodalConnectivity(conn);
531 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::clone(bool recDeepCpy) const
533 return new MEDCoupling1SGTUMesh(*this,recDeepCpy);
537 * This method behaves mostly like MEDCoupling1SGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
538 * The coordinates are shared between \a this and the returned instance.
540 * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
541 * \sa MEDCoupling1SGTUMesh::deepCpy
543 MEDCouplingPointSet *MEDCoupling1SGTUMesh::deepCpyConnectivityOnly() const throw(INTERP_KERNEL::Exception)
546 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(clone(false));
547 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy());
548 ret->setNodalConnectivity(c);
552 void MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception)
555 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
556 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
558 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1SGTUMesh instance !");
559 setNodalConnectivity(otherC->getNodalConnectivity());
562 void MEDCoupling1SGTUMesh::updateTime() const
564 MEDCoupling1GTUMesh::updateTime();
565 const DataArrayInt *c(_conn);
570 std::size_t MEDCoupling1SGTUMesh::getHeapMemorySize() const
573 const DataArrayInt *c(_conn);
575 ret+=c->getHeapMemorySize();
576 return MEDCoupling1GTUMesh::getHeapMemorySize()+ret;
579 MEDCouplingMesh *MEDCoupling1SGTUMesh::deepCpy() const
584 bool MEDCoupling1SGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
587 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualIfNotWhy : input other pointer is null !");
588 std::ostringstream oss; oss.precision(15);
589 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
592 reason="mesh given in input is not castable in MEDCoupling1SGTUMesh !";
595 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
597 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
602 reason="in connectivity of single static geometric type exactly one among this and other is null !";
605 if(!c1->isEqualIfNotWhy(*c2,reason))
607 reason.insert(0,"Nodal connectivity DataArrayInt differ : ");
613 bool MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
616 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
617 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
620 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
622 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
627 if(!c1->isEqualWithoutConsideringStr(*c2))
632 void MEDCoupling1SGTUMesh::checkCoherencyOfConnectivity() const throw(INTERP_KERNEL::Exception)
634 const DataArrayInt *c1(_conn);
637 if(c1->getNumberOfComponents()!=1)
638 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
639 if(c1->getInfoOnComponent(0)!="")
640 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
641 c1->checkAllocated();
644 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
647 void MEDCoupling1SGTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
649 MEDCouplingPointSet::checkCoherency();
650 checkCoherencyOfConnectivity();
653 void MEDCoupling1SGTUMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
656 const DataArrayInt *c1(_conn);
657 int nbOfTuples=c1->getNumberOfTuples();
658 int nbOfNodesPerCell=(int)_cm->getNumberOfNodes();
659 if(nbOfTuples%nbOfNodesPerCell!=0)
661 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::checkCoherency1 : the nb of tuples in conn is " << nbOfTuples << " and number of nodes per cell is " << nbOfNodesPerCell << ". But " << nbOfTuples << "%" << nbOfNodesPerCell << " !=0 !";
662 throw INTERP_KERNEL::Exception(oss.str().c_str());
664 int nbOfNodes=getNumberOfNodes();
665 int nbOfCells=nbOfTuples/nbOfNodesPerCell;
666 const int *w(c1->begin());
667 for(int i=0;i<nbOfCells;i++)
668 for(int j=0;j<nbOfNodesPerCell;j++,w++)
670 if(*w<0 || *w>=nbOfNodes)
672 std::ostringstream oss; oss << "At node #" << j << " of cell #" << i << ", is equal to " << *w << " must be in [0," << nbOfNodes << ") !";
673 throw INTERP_KERNEL::Exception(oss.str().c_str());
678 void MEDCoupling1SGTUMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
680 checkCoherency1(eps);
683 int MEDCoupling1SGTUMesh::getNumberOfCells() const
685 int nbOfTuples=getNodalConnectivityLength();
686 int nbOfNodesPerCell=getNumberOfNodesPerCell();
687 if(nbOfTuples%nbOfNodesPerCell!=0)
689 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh:getNumberOfCells: : the nb of tuples in conn is " << nbOfTuples << " and number of nodes per cell is " << nbOfNodesPerCell << ". But " << nbOfTuples << "%" << nbOfNodesPerCell << " !=0 !";
690 throw INTERP_KERNEL::Exception(oss.str().c_str());
692 return nbOfTuples/nbOfNodesPerCell;
695 int MEDCoupling1SGTUMesh::getNumberOfNodesInCell(int cellId) const throw(INTERP_KERNEL::Exception)
697 return getNumberOfNodesPerCell();
700 int MEDCoupling1SGTUMesh::getNumberOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
702 checkNonDynamicGeoType();
703 return (int)_cm->getNumberOfNodes();
706 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
708 checkNonDynamicGeoType();
709 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
710 ret->alloc(getNumberOfCells(),1);
711 ret->fillWithValue((int)_cm->getNumberOfNodes());
715 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception)
717 checkNonDynamicGeoType();
718 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
719 ret->alloc(getNumberOfCells(),1);
720 ret->fillWithValue((int)_cm->getNumberOfSons());
724 DataArrayInt *MEDCoupling1SGTUMesh::computeEffectiveNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
726 checkNonDynamicGeoType();
727 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
728 int nbCells(getNumberOfCells());
729 ret->alloc(nbCells,1);
730 int *retPtr(ret->getPointer());
731 int nbNodesPerCell(getNumberOfNodesPerCell());
732 const int *conn(_conn->begin());
733 for(int i=0;i<nbCells;i++,conn+=nbNodesPerCell,retPtr++)
735 std::set<int> s(conn,conn+nbNodesPerCell);
736 *retPtr=(int)s.size();
741 void MEDCoupling1SGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
743 int sz=getNumberOfNodesPerCell();
745 if(cellId>=0 && cellId<getNumberOfCells())
746 std::copy(_conn->begin()+cellId*sz,_conn->begin()+(cellId+1)*sz,conn.begin());
749 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << getNumberOfCells() << ") !";
750 throw INTERP_KERNEL::Exception(oss.str().c_str());
754 void MEDCoupling1SGTUMesh::checkNonDynamicGeoType() const throw(INTERP_KERNEL::Exception)
757 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkNonDynamicGeoType : internal error ! the internal geo type is dynamic ! should be static !");
760 std::string MEDCoupling1SGTUMesh::simpleRepr() const
762 static const char msg0[]="No coordinates specified !";
763 std::ostringstream ret;
764 ret << "Single static geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
765 ret << "Description of mesh : \"" << getDescription() << "\"\n";
767 double tt=getTime(tmpp1,tmpp2);
768 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
769 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
770 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
773 const int spaceDim=getSpaceDimension();
774 ret << spaceDim << "\nInfo attached on space dimension : ";
775 for(int i=0;i<spaceDim;i++)
776 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
781 ret << "Number of nodes : ";
783 ret << getNumberOfNodes() << "\n";
786 ret << "Number of cells : ";
787 if((const DataArrayInt *)_conn)
789 if(_conn->isAllocated())
791 if(_conn->getNumberOfComponents()==1)
792 ret << getNumberOfCells() << "\n";
794 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
797 ret << "Nodal connectivity array specified but not allocated !" << "\n";
800 ret << "No connectivity specified !" << "\n";
801 ret << "Cell type : " << _cm->getRepr() << "\n";
805 std::string MEDCoupling1SGTUMesh::advancedRepr() const
807 std::ostringstream ret;
809 ret << "\nCoordinates array : \n___________________\n\n";
811 _coords->reprWithoutNameStream(ret);
813 ret << "No array set !\n";
814 ret << "\n\nConnectivity array : \n____________________\n\n";
816 if((const DataArrayInt *)_conn)
818 if(_conn->isAllocated())
820 if(_conn->getNumberOfComponents()==1)
822 int nbOfCells=getNumberOfCells();
823 int sz=getNumberOfNodesPerCell();
824 const int *connPtr=_conn->begin();
825 for(int i=0;i<nbOfCells;i++,connPtr+=sz)
827 ret << "Cell #" << i << " : ";
828 std::copy(connPtr,connPtr+sz,std::ostream_iterator<int>(ret," "));
833 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
836 ret << "Nodal connectivity array specified but not allocated !" << "\n";
839 ret << "No connectivity specified !" << "\n";
843 DataArrayDouble *MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
845 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
846 int spaceDim=getSpaceDimension();
847 int nbOfCells=getNumberOfCells();//checkCoherency()
848 int nbOfNodes=getNumberOfNodes();
849 ret->alloc(nbOfCells,spaceDim);
850 double *ptToFill=ret->getPointer();
851 const double *coor=_coords->begin();
852 const int *nodal=_conn->begin();
853 int sz=getNumberOfNodesPerCell();
854 double coeff=1./(double)sz;
855 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim)
857 std::fill(ptToFill,ptToFill+spaceDim,0.);
858 for(int j=0;j<sz;j++,nodal++)
859 if(*nodal>=0 && *nodal<nbOfNodes)
860 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
863 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
864 throw INTERP_KERNEL::Exception(oss.str().c_str());
866 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),coeff));
871 void MEDCoupling1SGTUMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
873 int nbCells=getNumberOfCells();
874 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
875 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
877 o2n=o2n->checkAndPreparePermutation();
879 const int *conn=_conn->begin();
880 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o=o2n->invertArrayO2N2N2O(nbCells);
881 const int *n2oPtr=n2o->begin();
882 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
883 newConn->alloc(_conn->getNumberOfTuples(),1);
884 newConn->copyStringInfoFrom(*_conn);
885 int sz=getNumberOfNodesPerCell();
887 int *newC=newConn->getPointer();
888 for(int i=0;i<nbCells;i++,newC+=sz)
891 std::copy(conn+pos*sz,conn+(pos+1)*sz,newC);
897 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
898 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
899 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
900 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
902 * \param [in] begin input start of array of node ids.
903 * \param [in] end input end of array of node ids.
904 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
905 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
907 void MEDCoupling1SGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
909 int nbOfCells=getNumberOfCells();
910 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
912 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
913 std::vector<bool> fastFinder(sz,false);
914 for(const int *work=begin;work!=end;work++)
915 if(*work>=0 && *work<sz)
916 fastFinder[*work]=true;
917 const int *conn=_conn->begin();
918 int nbNodesPerCell=getNumberOfNodesPerCell();
919 for(int i=0;i<nbOfCells;i++,conn+=nbNodesPerCell)
922 for(int j=0;j<nbNodesPerCell;j++)
926 if(fastFinder[conn[j]])
929 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
930 cellIdsKept->pushBackSilent(i);
932 cellIdsKeptArr=cellIdsKept.retn();
935 MEDCouplingMesh *MEDCoupling1SGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
937 if(other->getType()!=SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED)
938 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single static geo type each other !");
939 const MEDCoupling1SGTUMesh *otherC=static_cast<const MEDCoupling1SGTUMesh *>(other);
940 return Merge1SGTUMeshes(this,otherC);
943 MEDCouplingUMesh *MEDCoupling1SGTUMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
945 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName().c_str(),getMeshDimension());
946 ret->setCoords(getCoords());
947 const int *nodalConn=_conn->begin();
948 int nbCells=getNumberOfCells();
949 int nbNodesPerCell=getNumberOfNodesPerCell();
950 int geoType=(int)getCellModelEnum();
951 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells*(nbNodesPerCell+1),1);
952 int *cPtr=c->getPointer();
953 for(int i=0;i<nbCells;i++,nodalConn+=nbNodesPerCell)
956 cPtr=std::copy(nodalConn,nodalConn+nbNodesPerCell,cPtr);
958 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::Range(0,(nbCells+1)*(nbNodesPerCell+1),nbNodesPerCell+1);
959 ret->setConnectivity(c,cI,true);
963 DataArrayInt *MEDCoupling1SGTUMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
968 return simplexizePol0();
970 return simplexizePol1();
971 case (int) INTERP_KERNEL::PLANAR_FACE_5:
972 return simplexizePlanarFace5();
973 case (int) INTERP_KERNEL::PLANAR_FACE_6:
974 return simplexizePlanarFace6();
976 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::simplexize : unrecognized policy ! Must be :\n - 0 or 1 (only available for meshdim=2) \n - PLANAR_FACE_5, PLANAR_FACE_6 (only for meshdim=3)");
982 struct MEDCouplingAccVisit
984 MEDCouplingAccVisit():_new_nb_of_nodes(0) { }
985 int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; }
986 int _new_nb_of_nodes;
992 * Finds nodes not used in any cell and returns an array giving a new id to every node
993 * by excluding the unused nodes, for which the array holds -1. The result array is
994 * a mapping in "Old to New" mode.
995 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
996 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
997 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
998 * if the node is unused or a new id else. The caller is to delete this
999 * array using decrRef() as it is no more needed.
1000 * \throw If the coordinates array is not set.
1001 * \throw If the nodal connectivity of cells is not defined.
1002 * \throw If the nodal connectivity includes an invalid id.
1004 DataArrayInt *MEDCoupling1SGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception)
1007 int nbOfNodes=getNumberOfNodes();
1008 int nbOfCells=getNumberOfCells();
1009 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1010 ret->alloc(nbOfNodes,1);
1011 int *traducer=ret->getPointer();
1012 std::fill(traducer,traducer+nbOfNodes,-1);
1013 const int *conn=_conn->begin();
1014 int nbNodesPerCell=getNumberOfNodesPerCell();
1015 for(int i=0;i<nbOfCells;i++)
1016 for(int j=0;j<nbNodesPerCell;j++,conn++)
1017 if(*conn>=0 && *conn<nbOfNodes)
1021 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << conn[j] << " not in [0," << nbOfNodes << ") !";
1022 throw INTERP_KERNEL::Exception(oss.str().c_str());
1024 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
1025 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
1030 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
1031 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
1032 * This method is a generalization of shiftNodeNumbersInConn().
1033 * \warning This method performs no check of validity of new ids. **Use it with care !**
1034 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
1035 * this->getNumberOfNodes(), in "Old to New" mode.
1036 * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
1037 * \throw If the nodal connectivity of cells is not defined.
1039 void MEDCoupling1SGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
1041 getNumberOfCells();//only to check that all is well defined.
1042 _conn->transformWithIndArr(newNodeNumbersO2N,newNodeNumbersO2N+getNumberOfNodes());
1046 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2) throw(INTERP_KERNEL::Exception)
1048 std::vector<const MEDCoupling1SGTUMesh *> tmp(2);
1049 tmp[0]=const_cast<MEDCoupling1SGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1SGTUMesh *>(mesh2);
1050 return Merge1SGTUMeshes(tmp);
1053 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
1055 std::size_t sz=a.size();
1057 return Merge1SGTUMeshesLL(a);
1058 for(std::size_t ii=0;ii<sz;ii++)
1061 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::Merge1SGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
1062 throw INTERP_KERNEL::Exception(oss.str().c_str());
1064 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
1065 for(std::size_t ii=0;ii<sz;ii++)
1066 if(&(a[ii]->getCellModel())!=cm)
1067 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : all items must have the same geo type !");
1068 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> > bb(sz);
1069 std::vector< const MEDCoupling1SGTUMesh * > aa(sz);
1071 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
1073 const MEDCoupling1SGTUMesh *cur=a[i];
1074 const DataArrayDouble *coo=cur->getCoords();
1076 spaceDim=coo->getNumberOfComponents();
1079 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : no spaceDim specified ! unable to perform merge !");
1080 for(std::size_t i=0;i<sz;i++)
1082 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
1085 return Merge1SGTUMeshesLL(aa);
1089 * \throw If presence of a null instance in the input vector \a a.
1090 * \throw If a is empty
1092 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
1095 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : input array must be NON EMPTY !");
1096 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1098 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : null instance in the first element of input vector !");
1099 std::vector<const DataArrayInt *> ncs(a.size());
1100 int nbOfCells=(*it)->getNumberOfCells();
1101 const DataArrayDouble *coords=(*it)->getCoords();
1102 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1103 int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
1104 ncs[0]=(*it)->getNodalConnectivity();
1106 for(int i=1;it!=a.end();i++,it++)
1109 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : presence of a null instance in the input vector !");
1110 if(cm!=&((*it)->getCellModel()))
1111 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1112 (*it)->getNumberOfCells();//to check that all is OK
1113 ncs[i]=(*it)->getNodalConnectivity();
1114 if(coords!=(*it)->getCoords())
1115 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : not lying on same coords !");
1117 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1118 ret->setCoords(coords);
1119 ret->_conn=DataArrayInt::Aggregate(ncs);
1124 * Assume that all instances in \a a are non null. If null it leads to a crash. That's why this method is assigned to be low level (LL)
1126 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
1129 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : input array must be NON EMPTY !");
1130 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1131 int nbOfCells=(*it)->getNumberOfCells();
1132 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1133 int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
1135 for(;it!=a.end();it++)
1137 if(cm!=&((*it)->getCellModel()))
1138 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1139 nbOfCells+=(*it)->getNumberOfCells();
1141 std::vector<const MEDCouplingPointSet *> aps(a.size());
1142 std::copy(a.begin(),a.end(),aps.begin());
1143 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
1144 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1145 ret->setCoords(pts);
1146 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New();
1147 c->alloc(nbOfCells*nbNodesPerCell,1);
1148 int *cPtr=c->getPointer();
1150 for(it=a.begin();it!=a.end();it++)
1152 int curConnLgth=(*it)->getNodalConnectivityLength();
1153 const int *curC=(*it)->_conn->begin();
1154 cPtr=std::transform(curC,curC+curConnLgth,cPtr,std::bind2nd(std::plus<int>(),offset));
1155 offset+=(*it)->getNumberOfNodes();
1158 ret->setNodalConnectivity(c);
1162 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
1164 int ncell=getNumberOfCells();
1165 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName().c_str(),*_cm));
1166 ret->setCoords(_coords);
1167 std::size_t nbOfElemsRet=std::distance(begin,end);
1168 const int *inConn=_conn->getConstPointer();
1169 int sz=getNumberOfNodesPerCell();
1170 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1171 int *connPtr=connRet->getPointer();
1172 for(const int *work=begin;work!=end;work++,connPtr+=sz)
1174 if(*work>=0 && *work<ncell)
1175 std::copy(inConn+(work[0])*sz,inConn+(work[0]+1)*sz,connPtr);
1178 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !";
1179 throw INTERP_KERNEL::Exception(oss.str().c_str());
1183 ret->copyTinyInfoFrom(this);
1187 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
1189 int ncell=getNumberOfCells();
1190 int nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : ");
1191 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName().c_str(),*_cm));
1192 ret->setCoords(_coords);
1193 const int *inConn=_conn->getConstPointer();
1194 int sz=getNumberOfNodesPerCell();
1195 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1196 int *connPtr=connRet->getPointer();
1198 for(int i=0;i<nbOfElemsRet;i++,connPtr+=sz,curId+=step)
1200 if(curId>=0 && curId<ncell)
1201 std::copy(inConn+curId*sz,inConn+(curId+1)*sz,connPtr);
1204 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : On pos #" << i << " input cell id =" << curId << " should be in [0," << ncell << ") !";
1205 throw INTERP_KERNEL::Exception(oss.str().c_str());
1209 ret->copyTinyInfoFrom(this);
1213 void MEDCoupling1SGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const throw(INTERP_KERNEL::Exception)
1215 int sz((int)nodeIdsInUse.size());
1216 int nbCells(getNumberOfCells());
1217 int nbOfNodesPerCell(getNumberOfNodesPerCell());
1218 const int *w(_conn->begin());
1219 for(int i=0;i<nbCells;i++)
1220 for(int j=0;j<nbOfNodesPerCell;j++,w++)
1223 nodeIdsInUse[*w]=true;
1226 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeNodeIdsAlg : At cell #" << i << " presence of node id #" << *w << " should be in [0," << sz << ") !";
1227 throw INTERP_KERNEL::Exception(oss.str().c_str());
1232 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception)
1234 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName().c_str(),*_cm));
1235 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1;
1236 const DataArrayInt *nodalConn(_conn);
1239 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
1246 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
1247 ret->setCoords(coords);
1250 ret->setCoords(_coords);
1254 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol0() throw(INTERP_KERNEL::Exception)
1256 int nbOfCells=getNumberOfCells();
1257 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1258 return DataArrayInt::Range(0,nbOfCells,1);
1259 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1260 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1261 const int *c(_conn->begin());
1262 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1263 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1265 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[2];
1266 newConnPtr[3]=c[0]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1267 retPtr[0]=i; retPtr[1]=i;
1270 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1275 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol1() throw(INTERP_KERNEL::Exception)
1277 int nbOfCells=getNumberOfCells();
1278 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1279 return DataArrayInt::Range(0,nbOfCells,1);
1280 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1281 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1282 const int *c(_conn->begin());
1283 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1284 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1286 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[3];
1287 newConnPtr[3]=c[1]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1288 retPtr[0]=i; retPtr[1]=i;
1291 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1296 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace5() throw(INTERP_KERNEL::Exception)
1298 int nbOfCells=getNumberOfCells();
1299 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1300 return DataArrayInt::Range(0,nbOfCells,1);
1301 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(5*4*nbOfCells,1);
1302 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(5*nbOfCells,1);
1303 const int *c(_conn->begin());
1304 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1305 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=20,retPtr+=5)
1307 for(int j=0;j<20;j++)
1308 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_5_WO[j]];
1309 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i;
1312 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1317 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace6() throw(INTERP_KERNEL::Exception)
1319 int nbOfCells=getNumberOfCells();
1320 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1321 return DataArrayInt::Range(0,nbOfCells,1);
1322 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(6*4*nbOfCells,1);
1323 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(6*nbOfCells,1);
1324 const int *c(_conn->begin());
1325 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1326 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=24,retPtr+=6)
1328 for(int j=0;j<24;j++)
1329 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_6_WO[j]];
1330 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i; retPtr[5]=i;
1333 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1338 void MEDCoupling1SGTUMesh::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1340 stream << "MEDCoupling1SGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
1341 stream << " Mesh dimension : " << getMeshDimension() << ".";
1343 { stream << " No coordinates set !"; return ; }
1344 if(!_coords->isAllocated())
1345 { stream << " Coordinates set but not allocated !"; return ; }
1346 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
1347 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
1348 if(!(const DataArrayInt *)_conn)
1349 { stream << std::endl << "Nodal connectivity NOT set !"; return ; }
1350 if(_conn->isAllocated())
1352 if(_conn->getNumberOfComponents()==1)
1353 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
1357 void MEDCoupling1SGTUMesh::checkFullyDefined() const throw(INTERP_KERNEL::Exception)
1359 if(!((const DataArrayInt *)_conn) || !((const DataArrayDouble *)_coords))
1360 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFullyDefined : part of this is not fully defined.");
1364 * First step of unserialization process.
1366 bool MEDCoupling1SGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
1368 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEmptyMesh : not implemented yet !");
1371 void MEDCoupling1SGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
1374 double time=getTime(it,order);
1375 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
1377 littleStrings.push_back(getName());
1378 littleStrings.push_back(getDescription());
1379 littleStrings.push_back(getTimeUnit());
1381 std::vector<std::string> littleStrings2,littleStrings3;
1382 if((const DataArrayDouble *)_coords)
1383 _coords->getTinySerializationStrInformation(littleStrings2);
1384 if((const DataArrayInt *)_conn)
1385 _conn->getTinySerializationStrInformation(littleStrings3);
1386 int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size());
1387 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
1388 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
1390 tinyInfo.push_back(getCellModelEnum());
1391 tinyInfo.push_back(it);
1392 tinyInfo.push_back(order);
1393 std::vector<int> tinyInfo2,tinyInfo3;
1394 if((const DataArrayDouble *)_coords)
1395 _coords->getTinySerializationIntInformation(tinyInfo2);
1396 if((const DataArrayInt *)_conn)
1397 _conn->getTinySerializationIntInformation(tinyInfo3);
1398 int sz2((int)tinyInfo2.size()),sz3((int)tinyInfo3.size());
1399 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3);
1400 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1401 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
1403 tinyInfoD.push_back(time);
1406 void MEDCoupling1SGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
1408 std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+tinyInfo[5]);
1409 std::vector<int> tinyInfo1(tinyInfo.begin()+7+tinyInfo[5],tinyInfo.begin()+7+tinyInfo[5]+tinyInfo[6]);
1410 a1->resizeForUnserialization(tinyInfo1);
1411 a2->resizeForUnserialization(tinyInfo2);
1414 void MEDCoupling1SGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
1417 if((const DataArrayInt *)_conn)
1418 if(_conn->isAllocated())
1419 sz=_conn->getNbOfElems();
1420 a1=DataArrayInt::New();
1422 if(sz!=0 && (const DataArrayInt *)_conn)
1423 std::copy(_conn->begin(),_conn->end(),a1->getPointer());
1425 if((const DataArrayDouble *)_coords)
1426 if(_coords->isAllocated())
1427 sz=_coords->getNbOfElems();
1428 a2=DataArrayDouble::New();
1430 if(sz!=0 && (const DataArrayDouble *)_coords)
1431 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
1434 void MEDCoupling1SGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
1435 const std::vector<std::string>& littleStrings)
1437 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
1438 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
1439 setName(littleStrings[0].c_str());
1440 setDescription(littleStrings[1].c_str());
1441 setTimeUnit(littleStrings[2].c_str());
1442 setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
1443 int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]);
1445 _coords=DataArrayDouble::New();
1446 std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+sz2);
1447 _coords->resizeForUnserialization(tinyInfo2);
1448 std::copy(a2->begin(),a2->end(),_coords->getPointer());
1449 _conn=DataArrayInt::New();
1450 std::vector<int> tinyInfo3(tinyInfo.begin()+7+sz2,tinyInfo.begin()+7+sz2+sz3);
1451 _conn->resizeForUnserialization(tinyInfo3);
1452 std::copy(a1->begin(),a1->end(),_conn->getPointer());
1453 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
1454 _coords->finishUnserialization(tinyInfo2,littleStrings2);
1455 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
1456 _conn->finishUnserialization(tinyInfo3,littleStrings3);
1460 * Checks if \a this and \a other meshes are geometrically equivalent with high
1461 * probability, else an exception is thrown. The meshes are considered equivalent if
1462 * (1) meshes contain the same number of nodes and the same number of elements of the
1463 * same types (2) three cells of the two meshes (first, last and middle) are based
1464 * on coincident nodes (with a specified precision).
1465 * \param [in] other - the mesh to compare with.
1466 * \param [in] prec - the precision used to compare nodes of the two meshes.
1467 * \throw If the two meshes do not match.
1469 void MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception)
1471 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1472 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1474 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single static geometric type !");
1475 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1479 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1480 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1481 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1482 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1483 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1484 if(c1->getHashCode()!=c2->getHashCode())
1485 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1488 MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
1491 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
1492 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1494 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
1495 std::vector<const MEDCoupling1SGTUMesh *> ms(2);
1498 return Merge1SGTUMeshesOnSameCoords(ms);
1501 void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception)
1503 checkFullyDefined();
1504 int nbOfNodes=getNumberOfNodes();
1505 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
1506 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
1507 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
1508 const int *conn=_conn->begin();
1509 int nbOfCells=getNumberOfCells();
1510 int nbOfEltsInRevNodal=0;
1511 int nbOfNodesPerCell=getNumberOfNodesPerCell();
1512 for(int eltId=0;eltId<nbOfCells;eltId++)
1514 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1516 if(conn[0]>=0 && conn[0]<nbOfNodes)
1518 nbOfEltsInRevNodal++;
1519 revNodalIndxPtr[conn[0]+1]++;
1523 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
1524 throw INTERP_KERNEL::Exception(oss.str().c_str());
1528 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
1529 conn=_conn->begin();
1530 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
1531 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
1532 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
1533 for(int eltId=0;eltId<nbOfCells;eltId++)
1535 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1537 *std::find_if(revNodalPtr+revNodalIndxPtr[*conn],revNodalPtr+revNodalIndxPtr[*conn+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
1543 * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null.
1545 void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn) throw(INTERP_KERNEL::Exception)
1548 nodalConn->incrRef();
1554 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
1556 DataArrayInt *MEDCoupling1SGTUMesh::getNodalConnectivity() const throw(INTERP_KERNEL::Exception)
1558 const DataArrayInt *ret(_conn);
1559 return const_cast<DataArrayInt *>(ret);
1563 * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted,
1564 * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter.
1565 * If a nodal connectivity previouly existed before the call of this method, it will be reset.
1567 * \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain.
1569 void MEDCoupling1SGTUMesh::allocateCells(int nbOfCells) throw(INTERP_KERNEL::Exception)
1572 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !");
1573 _conn=DataArrayInt::New();
1574 _conn->reserve(getNumberOfNodesPerCell()*nbOfCells);
1579 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
1581 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
1582 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
1583 * \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
1584 * attached to \a this.
1585 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
1587 void MEDCoupling1SGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) throw(INTERP_KERNEL::Exception)
1589 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
1590 int ref=getNumberOfNodesPerCell();
1593 DataArrayInt *c(_conn);
1595 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
1597 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !");
1601 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this (";
1602 oss << ref << ") !";
1603 throw INTERP_KERNEL::Exception(oss.str().c_str());
1608 * This method builds the dual mesh of \a this and returns it.
1610 * \return MEDCoupling1SGTUMesh * - newly object created to be managed by the caller.
1611 * \throw If \a this is not a mesh containing only simplex cells.
1612 * \throw If \a this is not correctly allocated (coordinates and connectivities have to be correctly set !).
1613 * \throw If at least one node in \a this is orphan (without any simplex cell lying on it !)
1615 MEDCoupling1GTUMesh *MEDCoupling1SGTUMesh::computeDualMesh() const throw(INTERP_KERNEL::Exception)
1617 const INTERP_KERNEL::CellModel& cm(getCellModel());
1619 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : this mesh is not a simplex mesh ! Please invoke simplexize of tetrahedrize on this before calling this method !");
1620 switch(getMeshDimension())
1623 return computeDualMesh3D();
1625 return computeDualMesh2D();
1627 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : meshdimension must be in [2,3] !");
1631 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh3D() const throw(INTERP_KERNEL::Exception)
1633 static const int DUAL_TETRA_0[36]={
1634 4,1,0, 6,0,3, 7,3,1,
1635 4,0,1, 5,2,0, 8,1,2,
1636 6,3,0, 5,0,2, 9,2,3,
1639 static const int DUAL_TETRA_1[36]={
1640 8,4,10, 11,5,8, 10,7,11,
1641 9,4,8, 8,5,12, 12,6,9,
1642 10,4,9, 9,6,13, 13,7,10,
1643 12,5,11, 13,6,12, 11,7,13
1645 static const int FACEID_NOT_SH_NODE[4]={2,3,1,0};
1646 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TETRA4)
1647 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh3D : only TETRA4 supported !");
1648 checkFullyDefined();
1649 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured());
1650 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1651 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1652 const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1653 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d1Arr(DataArrayInt::New()),di1Arr(DataArrayInt::New()),rd1Arr(DataArrayInt::New()),rdi1Arr(DataArrayInt::New());
1654 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->explode3DMeshTo1D(d1Arr,di1Arr,rd1Arr,rdi1Arr));
1655 const int *d1(d1Arr->begin());
1656 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1657 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> faces(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
1658 const int *d2(d2Arr->begin()),*rd2(rd2Arr->begin()),*rdi2(rdi2Arr->begin());
1659 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),facesBaryArr(faces->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
1660 const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+faces->getNumberOfCells()),offset1(offset0+edges->getNumberOfCells());
1662 std::vector<const DataArrayDouble *> v(4); v[0]=getCoords(); v[1]=facesBaryArr; v[2]=edgesBaryArr; v[3]=baryArr;
1663 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0; facesBaryArr=0;
1664 std::string name("DualOf_"); name+=getName();
1665 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name.c_str(),INTERP_KERNEL::NORM_POLYHED)); ret->setCoords(zeArr);
1666 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1667 for(int i=0;i<nbOfNodes;i++,revNodI++)
1669 int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1670 if(nbOfCellsSharingNode==0)
1672 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh3D : Node #" << i << " is orphan !";
1673 throw INTERP_KERNEL::Exception(oss.str().c_str());
1675 for(int j=0;j<nbOfCellsSharingNode;j++)
1677 int curCellId(revNod[revNodI[0]+j]);
1678 const int *connOfCurCell(nodal+4*curCellId);
1679 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1680 if(j!=0) cArr->pushBackSilent(-1);
1683 tmp[0]=d1[6*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+0]-4]+offset0; tmp[1]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+1]]+nbOfNodes;
1684 tmp[2]=curCellId+offset1; tmp[3]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+2]]+nbOfNodes;
1686 tmp[5]=d1[6*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+3]-4]+offset0; tmp[6]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+4]]+nbOfNodes;
1687 tmp[7]=curCellId+offset1; tmp[8]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+5]]+nbOfNodes;
1689 tmp[10]=d1[6*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+6]-4]+offset0; tmp[11]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+7]]+nbOfNodes;
1690 tmp[12]=curCellId+offset1; tmp[13]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+8]]+nbOfNodes;
1691 cArr->insertAtTheEnd(tmp,tmp+14);
1693 for(int k=0;k<4;k++)
1695 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1697 const int *faceId(d2+4*curCellId+k);
1698 if(rdi2[*faceId+1]-rdi2[*faceId]==1)
1700 int tmp2[5]; tmp2[0]=-1; tmp2[1]=i;
1701 tmp2[2]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+0]-8]+offset0;
1702 tmp2[3]=d2[4*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+1]-4]+nbOfNodes;
1703 tmp2[4]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+2]-8]+offset0;
1704 cArr->insertAtTheEnd(tmp2,tmp2+5);
1710 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
1712 ret->setNodalConnectivity(cArr,ciArr);
1716 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh2D() const throw(INTERP_KERNEL::Exception)
1718 static const int DUAL_TRI_0[6]={0,2, 1,0, 2,1};
1719 static const int DUAL_TRI_1[6]={-3,+5, +3,-4, +4,-5};
1720 static const int FACEID_NOT_SH_NODE[3]={1,2,0};
1721 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TRI3)
1722 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh2D : only TRI3 supported !");
1723 checkFullyDefined();
1724 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured());
1725 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1726 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1727 const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1728 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1729 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
1730 const int *d2(d2Arr->begin()),*rd2(rd2Arr->begin()),*rdi2(rdi2Arr->begin());
1731 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
1732 const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+edges->getNumberOfCells());
1734 std::vector<const DataArrayDouble *> v(3); v[0]=getCoords(); v[1]=edgesBaryArr; v[2]=baryArr;
1735 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0;
1736 std::string name("DualOf_"); name+=getName();
1737 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name.c_str(),INTERP_KERNEL::NORM_POLYGON)); ret->setCoords(zeArr);
1738 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1739 for(int i=0;i<nbOfNodes;i++,revNodI++)
1741 int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1742 if(nbOfCellsSharingNode==0)
1744 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh2D : Node #" << i << " is orphan !";
1745 throw INTERP_KERNEL::Exception(oss.str().c_str());
1747 std::vector< std::vector<int> > polyg;
1748 for(int j=0;j<nbOfCellsSharingNode;j++)
1750 int curCellId(revNod[revNodI[0]+j]);
1751 const int *connOfCurCell(nodal+3*curCellId);
1752 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1753 std::vector<int> locV(3);
1754 locV[0]=d2[3*curCellId+DUAL_TRI_0[2*nodePosInCurCell+0]]+nbOfNodes; locV[1]=curCellId+offset0; locV[2]=d2[3*curCellId+DUAL_TRI_0[2*nodePosInCurCell+1]]+nbOfNodes;
1755 polyg.push_back(locV);
1757 for(int k=0;k<3;k++)
1759 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1761 const int *edgeId(d2+3*curCellId+k);
1762 if(rdi2[*edgeId+1]-rdi2[*edgeId]==1)
1764 std::vector<int> locV2(2);
1765 int zeLocEdgeIdRel(DUAL_TRI_1[2*nodePosInCurCell+kk]);
1766 if(zeLocEdgeIdRel>0)
1767 { locV2[0]=d2[3*curCellId+zeLocEdgeIdRel-3]+nbOfNodes; locV2[1]=i; }
1769 { locV2[0]=i; locV2[1]=d2[3*curCellId-zeLocEdgeIdRel-3]+nbOfNodes; }
1770 polyg.push_back(locV2);
1776 std::vector<int> zePolyg(MEDCoupling1DGTUMesh::BuildAPolygonFromParts(polyg));
1777 cArr->insertAtTheEnd(zePolyg.begin(),zePolyg.end());
1778 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
1780 ret->setNodalConnectivity(cArr,ciArr);
1786 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New()
1788 return new MEDCoupling1DGTUMesh;
1791 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
1793 if(type==INTERP_KERNEL::NORM_ERROR)
1794 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
1795 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
1798 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !";
1799 throw INTERP_KERNEL::Exception(oss.str().c_str());
1801 return new MEDCoupling1DGTUMesh(name,cm);
1804 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh()
1808 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
1812 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
1816 const DataArrayInt *c(other._conn);
1821 _conn_indx=c->deepCpy();
1825 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const
1827 return new MEDCoupling1DGTUMesh(*this,recDeepCpy);
1831 * This method behaves mostly like MEDCoupling1DGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
1832 * The coordinates are shared between \a this and the returned instance.
1834 * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
1835 * \sa MEDCoupling1DGTUMesh::deepCpy
1837 MEDCouplingPointSet *MEDCoupling1DGTUMesh::deepCpyConnectivityOnly() const throw(INTERP_KERNEL::Exception)
1840 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(clone(false));
1841 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy()),ci(_conn_indx->deepCpy());
1842 ret->setNodalConnectivity(c,ci);
1846 void MEDCoupling1DGTUMesh::updateTime() const
1848 MEDCoupling1GTUMesh::updateTime();
1849 const DataArrayInt *c(_conn);
1857 std::size_t MEDCoupling1DGTUMesh::getHeapMemorySize() const
1860 const DataArrayInt *c(_conn);
1862 ret+=c->getHeapMemorySize();
1865 ret+=c->getHeapMemorySize();
1866 return MEDCoupling1GTUMesh::getHeapMemorySize()+ret;
1869 MEDCouplingMesh *MEDCoupling1DGTUMesh::deepCpy() const
1874 bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
1877 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !");
1878 std::ostringstream oss; oss.precision(15);
1879 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1882 reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !";
1885 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
1887 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1892 reason="in connectivity of single dynamic geometric type exactly one among this and other is null !";
1895 if(!c1->isEqualIfNotWhy(*c2,reason))
1897 reason.insert(0,"Nodal connectivity DataArrayInt differs : ");
1900 c1=_conn_indx; c2=otherC->_conn_indx;
1905 reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !";
1908 if(!c1->isEqualIfNotWhy(*c2,reason))
1910 reason.insert(0,"Nodal connectivity index DataArrayInt differs : ");
1916 bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
1919 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
1920 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1923 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
1925 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1930 if(!c1->isEqualWithoutConsideringStr(*c2))
1933 c1=_conn_indx; c2=otherC->_conn_indx;
1938 if(!c1->isEqualWithoutConsideringStr(*c2))
1944 * Checks if \a this and \a other meshes are geometrically equivalent with high
1945 * probability, else an exception is thrown. The meshes are considered equivalent if
1946 * (1) meshes contain the same number of nodes and the same number of elements of the
1947 * same types (2) three cells of the two meshes (first, last and middle) are based
1948 * on coincident nodes (with a specified precision).
1949 * \param [in] other - the mesh to compare with.
1950 * \param [in] prec - the precision used to compare nodes of the two meshes.
1951 * \throw If the two meshes do not match.
1953 void MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception)
1955 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1956 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1958 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single dynamic geometric type !");
1959 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1963 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1964 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1965 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1966 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1967 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1968 if(c1->getHashCode()!=c2->getHashCode())
1969 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1971 c1=_conn_indx; c2=otherC->_conn_indx;
1975 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !");
1976 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1977 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !");
1978 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1979 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !");
1980 if(c1->getHashCode()!=c2->getHashCode())
1981 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs");
1985 void MEDCoupling1DGTUMesh::checkCoherencyOfConnectivity() const throw(INTERP_KERNEL::Exception)
1987 const DataArrayInt *c1(_conn);
1990 if(c1->getNumberOfComponents()!=1)
1991 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
1992 if(c1->getInfoOnComponent(0)!="")
1993 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
1994 c1->checkAllocated();
1997 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
1999 int sz2=_conn->getNumberOfTuples();
2003 if(c1->getNumberOfComponents()!=1)
2004 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
2005 c1->checkAllocated();
2006 if(c1->getNumberOfTuples()<1)
2007 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !");
2008 if(c1->getInfoOnComponent(0)!="")
2009 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
2010 int f=c1->front(),ll=c1->back();
2013 std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !";
2014 throw INTERP_KERNEL::Exception(oss.str().c_str());
2018 std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !";
2019 throw INTERP_KERNEL::Exception(oss.str().c_str());
2023 std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !";
2024 throw INTERP_KERNEL::Exception(oss.str().c_str());
2028 throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !");
2029 int szOfC1Exp=_conn_indx->back();
2032 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() << " !";
2033 throw INTERP_KERNEL::Exception(oss.str().c_str());
2038 * 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.
2039 * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one.
2040 * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array.
2042 void MEDCoupling1DGTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
2044 MEDCouplingPointSet::checkCoherency();
2045 checkCoherencyOfConnectivity();
2048 void MEDCoupling1DGTUMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
2051 const DataArrayInt *c1(_conn),*c2(_conn_indx);
2052 if(!c2->isMonotonic(true))
2053 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkCoherency1 : the nodal connectivity index is expected to be increasing monotinic !");
2055 int nbOfTuples=c1->getNumberOfTuples();
2056 int nbOfNodes=getNumberOfNodes();
2057 const int *w(c1->begin());
2058 for(int i=0;i<nbOfTuples;i++,w++)
2060 if(*w==-1) continue;
2061 if(*w<0 || *w>=nbOfNodes)
2063 std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !";
2064 throw INTERP_KERNEL::Exception(oss.str().c_str());
2069 void MEDCoupling1DGTUMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
2071 checkCoherency1(eps);
2074 int MEDCoupling1DGTUMesh::getNumberOfCells() const
2076 checkCoherencyOfConnectivity();//do not remove
2077 return _conn_indx->getNumberOfTuples()-1;
2081 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2082 * For each cell in \b this the number of nodes constituting cell is computed.
2083 * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned.
2084 * So for pohyhedrons some nodes can be counted several times in the returned result.
2086 * \return a newly allocated array
2088 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
2091 _conn_indx->checkMonotonic(true);
2092 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2093 return _conn_indx->deltaShiftIndex();
2095 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2096 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2097 ret->alloc(nbOfCells,1);
2098 int *retPtr=ret->getPointer();
2099 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2100 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2101 *retPtr=ci[1]-ci[0]-std::count(c+ci[0],c+ci[1],-1);
2106 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2107 * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed.
2109 * \return a newly allocated array
2111 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception)
2114 _conn_indx->checkMonotonic(true);
2115 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG)
2116 return _conn_indx->deltaShiftIndex();
2117 if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG)
2119 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=_conn_indx->deltaShiftIndex();
2120 ret->applyDivideBy(2);
2124 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2125 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2126 ret->alloc(nbOfCells,1);
2127 int *retPtr=ret->getPointer();
2128 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2129 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2130 *retPtr=std::count(c+ci[0],c+ci[1],-1)+1;
2135 * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell,
2136 * will be counted only once here whereas it will be counted several times in MEDCoupling1DGTUMesh::computeNbOfNodesPerCell method.
2138 * \return DataArrayInt * - new object to be deallocated by the caller.
2139 * \sa MEDCoupling1DGTUMesh::computeNbOfNodesPerCell
2141 DataArrayInt *MEDCoupling1DGTUMesh::computeEffectiveNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
2144 _conn_indx->checkMonotonic(true);
2145 int nbOfCells(_conn_indx->getNumberOfTuples()-1);
2146 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2147 ret->alloc(nbOfCells,1);
2148 int *retPtr(ret->getPointer());
2149 const int *ci(_conn_indx->begin()),*c(_conn->begin());
2150 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2152 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2154 std::set<int> s(c+ci[0],c+ci[1]);
2155 *retPtr=(int)s.size();
2160 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2162 std::set<int> s(c+ci[0],c+ci[1]); s.erase(-1);
2163 *retPtr=(int)s.size();
2169 void MEDCoupling1DGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
2171 int nbOfCells(getNumberOfCells());//performs checks
2172 if(cellId>=0 && cellId<nbOfCells)
2174 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2175 int nbOfNodes=stp-strt;
2177 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !");
2178 conn.resize(nbOfNodes);
2179 std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin());
2183 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2184 throw INTERP_KERNEL::Exception(oss.str().c_str());
2188 int MEDCoupling1DGTUMesh::getNumberOfNodesInCell(int cellId) const throw(INTERP_KERNEL::Exception)
2190 int nbOfCells(getNumberOfCells());//performs checks
2191 if(cellId>=0 && cellId<nbOfCells)
2193 const int *conn(_conn->begin());
2194 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2195 return stp-strt-std::count(conn+strt,conn+stp,-1);
2199 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNumberOfNodesInCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2200 throw INTERP_KERNEL::Exception(oss.str().c_str());
2204 std::string MEDCoupling1DGTUMesh::simpleRepr() const
2206 static const char msg0[]="No coordinates specified !";
2207 std::ostringstream ret;
2208 ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
2209 ret << "Description of mesh : \"" << getDescription() << "\"\n";
2211 double tt=getTime(tmpp1,tmpp2);
2212 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
2213 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
2214 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
2217 const int spaceDim=getSpaceDimension();
2218 ret << spaceDim << "\nInfo attached on space dimension : ";
2219 for(int i=0;i<spaceDim;i++)
2220 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
2224 ret << msg0 << "\n";
2225 ret << "Number of nodes : ";
2227 ret << getNumberOfNodes() << "\n";
2229 ret << msg0 << "\n";
2230 ret << "Number of cells : ";
2232 try { checkCoherency(); } catch(INTERP_KERNEL::Exception& e)
2234 ret << "Nodal connectivity arrays are not set or badly set !\n";
2238 ret << getNumberOfCells() << "\n";
2239 ret << "Cell type : " << _cm->getRepr() << "\n";
2243 std::string MEDCoupling1DGTUMesh::advancedRepr() const
2245 std::ostringstream ret;
2246 ret << simpleRepr();
2247 ret << "\nCoordinates array : \n___________________\n\n";
2249 _coords->reprWithoutNameStream(ret);
2251 ret << "No array set !\n";
2252 ret << "\n\nNodal Connectivity : \n____________________\n\n";
2255 try { checkCoherency1(); } catch(INTERP_KERNEL::Exception& e)
2257 ret << "Nodal connectivity arrays are not set or badly set !\n";
2262 int nbOfCells=getNumberOfCells();
2263 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2264 for(int i=0;i<nbOfCells;i++,ci++)
2266 ret << "Cell #" << i << " : ";
2267 std::copy(c+ci[0],c+ci[1],std::ostream_iterator<int>(ret," "));
2273 DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
2275 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
2276 int spaceDim=getSpaceDimension();
2277 int nbOfCells=getNumberOfCells();//checkCoherency()
2278 int nbOfNodes=getNumberOfNodes();
2279 ret->alloc(nbOfCells,spaceDim);
2280 double *ptToFill=ret->getPointer();
2281 const double *coor=_coords->begin();
2282 const int *nodal=_conn->begin(),*nodali=_conn_indx->begin();
2284 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2286 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2288 std::fill(ptToFill,ptToFill+spaceDim,0.);
2289 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2291 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2293 if(*nodal>=0 && *nodal<nbOfNodes)
2294 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2297 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2298 throw INTERP_KERNEL::Exception(oss.str().c_str());
2300 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(nodali[1]-nodali[0])));
2305 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !";
2306 throw INTERP_KERNEL::Exception(oss.str().c_str());
2312 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2314 std::fill(ptToFill,ptToFill+spaceDim,0.);
2315 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2318 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2320 if(*nodal==-1) continue;
2321 if(*nodal>=0 && *nodal<nbOfNodes)
2323 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2328 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2329 throw INTERP_KERNEL::Exception(oss.str().c_str());
2333 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./nbOfNod));
2336 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !";
2337 throw INTERP_KERNEL::Exception(oss.str().c_str());
2342 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : at cell #" << i << " the nodal index array is invalid !";
2343 throw INTERP_KERNEL::Exception(oss.str().c_str());
2350 void MEDCoupling1DGTUMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
2352 int nbCells=getNumberOfCells();
2353 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
2354 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
2356 o2n=o2n->checkAndPreparePermutation();
2358 const int *o2nPtr=o2n->getPointer();
2359 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2360 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
2361 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
2362 newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1);
2363 newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx);
2365 int *newC=newConn->getPointer(),*newCI=newConnI->getPointer();
2366 for(int i=0;i<nbCells;i++)
2368 int newPos=o2nPtr[i];
2369 int sz=conni[i+1]-conni[i];
2374 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !";
2375 throw INTERP_KERNEL::Exception(oss.str().c_str());
2378 newConnI->computeOffsets2(); newCI=newConnI->getPointer();
2380 for(int i=0;i<nbCells;i++,conni++)
2382 int sz=conni[1]-conni[0];
2384 std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]);
2387 _conn_indx=newConnI;
2390 MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
2392 if(other->getType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED)
2393 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !");
2394 const MEDCoupling1DGTUMesh *otherC=static_cast<const MEDCoupling1DGTUMesh *>(other);
2395 return Merge1DGTUMeshes(this,otherC);
2398 MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
2400 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName().c_str(),getMeshDimension());
2401 ret->setCoords(getCoords());
2402 const int *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin();
2403 int nbCells=getNumberOfCells();//checkCoherency
2404 int geoType=(int)getCellModelEnum();
2405 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1);
2406 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::New(); cI->alloc(nbCells+1);
2407 int *cPtr=c->getPointer(),*ciPtr=cI->getPointer();
2409 for(int i=0;i<nbCells;i++,ciPtr++)
2411 int sz=nodalConnI[i+1]-nodalConnI[i];
2415 cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr);
2416 ciPtr[1]=ciPtr[0]+sz+1;
2420 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !";
2421 throw INTERP_KERNEL::Exception(oss.str().c_str());
2424 ret->setConnectivity(c,cI,true);
2429 * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes
2431 DataArrayInt *MEDCoupling1DGTUMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
2433 int nbOfCells=getNumberOfCells();
2434 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2435 ret->alloc(nbOfCells,1);
2440 void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
2442 stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
2443 stream << " Mesh dimension : " << getMeshDimension() << ".";
2445 { stream << " No coordinates set !"; return ; }
2446 if(!_coords->isAllocated())
2447 { stream << " Coordinates set but not allocated !"; return ; }
2448 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
2449 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
2451 try { checkCoherency(); } catch(INTERP_KERNEL::Exception& e)
2453 stream << std::endl << "Nodal connectivity NOT set properly !\n";
2457 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
2460 void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception)
2463 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
2464 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2466 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !");
2467 setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex());
2470 MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
2473 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
2474 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2476 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
2477 std::vector<const MEDCoupling1DGTUMesh *> ms(2);
2480 return Merge1DGTUMeshesOnSameCoords(ms);
2483 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
2486 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2487 ret->setCoords(_coords);
2488 DataArrayInt *c=0,*ci=0;
2489 MEDCouplingUMesh::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci);
2490 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2491 ret->setNodalConnectivity(c,ci);
2495 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
2498 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2499 ret->setCoords(_coords);
2500 DataArrayInt *c=0,*ci=0;
2501 MEDCouplingUMesh::ExtractFromIndexedArrays2(start,end,step,_conn,_conn_indx,c,ci);
2502 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2503 ret->setNodalConnectivity(c,ci);
2507 void MEDCoupling1DGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const throw(INTERP_KERNEL::Exception)
2509 int sz((int)nodeIdsInUse.size());
2510 int nbCells(getNumberOfCells());
2511 const int *w(_conn->begin()),*wi(_conn_indx->begin());
2512 for(int i=0;i<nbCells;i++,wi++)
2513 for(const int *pt=w+wi[0];pt!=w+wi[1];pt++)
2516 if(*pt>=0 && *pt<sz)
2517 nodeIdsInUse[*pt]=true;
2520 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeNodeIdsAlg : At cell #" << i << " presence of node id #" << *pt << " should be in [0," << sz << ") !";
2521 throw INTERP_KERNEL::Exception(oss.str().c_str());
2526 void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception)
2528 checkFullyDefined();
2529 int nbOfNodes=getNumberOfNodes();
2530 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
2531 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
2532 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
2533 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2534 int nbOfCells=getNumberOfCells();
2535 int nbOfEltsInRevNodal=0;
2536 for(int eltId=0;eltId<nbOfCells;eltId++)
2538 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2539 if(nbOfNodesPerCell>=0)
2541 for(int j=0;j<nbOfNodesPerCell;j++)
2543 int nodeId=conn[conni[eltId]+j];
2544 if(nodeId==-1) continue;
2545 if(nodeId>=0 && nodeId<nbOfNodes)
2547 nbOfEltsInRevNodal++;
2548 revNodalIndxPtr[nodeId+1]++;
2552 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
2553 throw INTERP_KERNEL::Exception(oss.str().c_str());
2559 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << "nodal connectivity is invalid !";
2560 throw INTERP_KERNEL::Exception(oss.str().c_str());
2563 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
2564 conn=_conn->begin();
2565 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
2566 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
2567 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
2568 for(int eltId=0;eltId<nbOfCells;eltId++)
2570 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2571 for(int j=0;j<nbOfNodesPerCell;j++)
2573 int nodeId=conn[conni[eltId]+j];
2575 *std::find_if(revNodalPtr+revNodalIndxPtr[nodeId],revNodalPtr+revNodalIndxPtr[nodeId+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
2580 void MEDCoupling1DGTUMesh::checkFullyDefined() const throw(INTERP_KERNEL::Exception)
2582 if(!((const DataArrayInt *)_conn) || !((const DataArrayInt *)_conn_indx) || !((const DataArrayDouble *)_coords))
2583 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined.");
2586 bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
2588 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !");
2591 void MEDCoupling1DGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
2594 double time=getTime(it,order);
2595 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
2597 littleStrings.push_back(getName());
2598 littleStrings.push_back(getDescription());
2599 littleStrings.push_back(getTimeUnit());
2601 std::vector<std::string> littleStrings2,littleStrings3,littleStrings4;
2602 if((const DataArrayDouble *)_coords)
2603 _coords->getTinySerializationStrInformation(littleStrings2);
2604 if((const DataArrayInt *)_conn)
2605 _conn->getTinySerializationStrInformation(littleStrings3);
2606 if((const DataArrayInt *)_conn_indx)
2607 _conn_indx->getTinySerializationStrInformation(littleStrings4);
2608 int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size()),sz2((int)littleStrings4.size());
2609 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
2610 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
2611 littleStrings.insert(littleStrings.end(),littleStrings4.begin(),littleStrings4.end());
2613 tinyInfo.push_back(getCellModelEnum());
2614 tinyInfo.push_back(it);
2615 tinyInfo.push_back(order);
2616 std::vector<int> tinyInfo2,tinyInfo3,tinyInfo4;
2617 if((const DataArrayDouble *)_coords)
2618 _coords->getTinySerializationIntInformation(tinyInfo2);
2619 if((const DataArrayInt *)_conn)
2620 _conn->getTinySerializationIntInformation(tinyInfo3);
2621 if((const DataArrayInt *)_conn_indx)
2622 _conn_indx->getTinySerializationIntInformation(tinyInfo4);
2623 int sz3((int)tinyInfo2.size()),sz4((int)tinyInfo3.size()),sz5((int)tinyInfo4.size());
2624 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3); tinyInfo.push_back(sz4); tinyInfo.push_back(sz5);
2625 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
2626 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
2627 tinyInfo.insert(tinyInfo.end(),tinyInfo4.begin(),tinyInfo4.end());
2629 tinyInfoD.push_back(time);
2632 void MEDCoupling1DGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
2634 std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+tinyInfo[6]);
2635 std::vector<int> tinyInfo1(tinyInfo.begin()+9+tinyInfo[6],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]);
2636 std::vector<int> tinyInfo12(tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]+tinyInfo[8]);
2637 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(DataArrayInt::New()); p1->resizeForUnserialization(tinyInfo1);
2638 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(DataArrayInt::New()); p2->resizeForUnserialization(tinyInfo12);
2639 std::vector<const DataArrayInt *> v(2); v[0]=p1; v[1]=p2;
2640 p2=DataArrayInt::Aggregate(v);
2641 a2->resizeForUnserialization(tinyInfo2);
2642 a1->alloc(p2->getNbOfElems(),1);
2645 void MEDCoupling1DGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
2648 if((const DataArrayInt *)_conn)
2649 if(_conn->isAllocated())
2650 sz=_conn->getNbOfElems();
2651 if((const DataArrayInt *)_conn_indx)
2652 if(_conn_indx->isAllocated())
2653 sz+=_conn_indx->getNbOfElems();
2654 a1=DataArrayInt::New();
2656 int *work(a1->getPointer());
2657 if(sz!=0 && (const DataArrayInt *)_conn)
2658 work=std::copy(_conn->begin(),_conn->end(),a1->getPointer());
2659 if(sz!=0 && (const DataArrayInt *)_conn_indx)
2660 std::copy(_conn_indx->begin(),_conn_indx->end(),work);
2662 if((const DataArrayDouble *)_coords)
2663 if(_coords->isAllocated())
2664 sz=_coords->getNbOfElems();
2665 a2=DataArrayDouble::New();
2667 if(sz!=0 && (const DataArrayDouble *)_coords)
2668 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
2671 void MEDCoupling1DGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
2672 const std::vector<std::string>& littleStrings)
2674 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
2675 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
2676 setName(littleStrings[0].c_str());
2677 setDescription(littleStrings[1].c_str());
2678 setTimeUnit(littleStrings[2].c_str());
2679 setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
2680 int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]),sz4(tinyInfo[7]),sz5(tinyInfo[8]);
2682 _coords=DataArrayDouble::New();
2683 std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+sz3);
2684 _coords->resizeForUnserialization(tinyInfo2);
2685 std::copy(a2->begin(),a2->end(),_coords->getPointer());
2686 _conn=DataArrayInt::New();
2687 std::vector<int> tinyInfo3(tinyInfo.begin()+9+sz3,tinyInfo.begin()+9+sz3+sz4);
2688 _conn->resizeForUnserialization(tinyInfo3);
2689 std::copy(a1->begin(),a1->begin()+_conn->getNbOfElems(),_conn->getPointer());
2690 _conn_indx=DataArrayInt::New();
2691 std::vector<int> tinyInfo4(tinyInfo.begin()+9+sz3+sz4,tinyInfo.begin()+9+sz3+sz4+sz5);
2692 _conn_indx->resizeForUnserialization(tinyInfo4);
2693 std::copy(a1->begin()+_conn->getNbOfElems(),a1->end(),_conn_indx->getPointer());
2694 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
2695 _coords->finishUnserialization(tinyInfo2,littleStrings2);
2696 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
2697 _conn->finishUnserialization(tinyInfo3,littleStrings3);
2698 std::vector<std::string> littleStrings4(littleStrings.begin()+3+sz0+sz1,littleStrings.begin()+3+sz0+sz1+sz2);
2699 _conn_indx->finishUnserialization(tinyInfo4,littleStrings4);
2703 * Finds nodes not used in any cell and returns an array giving a new id to every node
2704 * by excluding the unused nodes, for which the array holds -1. The result array is
2705 * a mapping in "Old to New" mode.
2706 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
2707 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
2708 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
2709 * if the node is unused or a new id else. The caller is to delete this
2710 * array using decrRef() as it is no more needed.
2711 * \throw If the coordinates array is not set.
2712 * \throw If the nodal connectivity of cells is not defined.
2713 * \throw If the nodal connectivity includes an invalid id.
2715 DataArrayInt *MEDCoupling1DGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception)
2718 int nbOfNodes=getNumberOfNodes();
2719 int nbOfCells=getNumberOfCells();//checkCoherency
2720 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2721 ret->alloc(nbOfNodes,1);
2722 int *traducer=ret->getPointer();
2723 std::fill(traducer,traducer+nbOfNodes,-1);
2724 const int *conn=_conn->begin(),*conni(_conn_indx->begin());
2725 for(int i=0;i<nbOfCells;i++,conni++)
2727 int nbNodesPerCell=conni[1]-conni[0];
2728 for(int j=0;j<nbNodesPerCell;j++)
2730 int nodeId=conn[conni[0]+j];
2731 if(nodeId==-1) continue;
2732 if(nodeId>=0 && nodeId<nbOfNodes)
2736 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << nodeId << " not in [0," << nbOfNodes << ") !";
2737 throw INTERP_KERNEL::Exception(oss.str().c_str());
2741 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
2742 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
2747 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
2748 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
2749 * This method is a generalization of shiftNodeNumbersInConn().
2750 * \warning This method performs no check of validity of new ids. **Use it with care !**
2751 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
2752 * this->getNumberOfNodes(), in "Old to New" mode.
2753 * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
2754 * \throw If the nodal connectivity of cells is not defined.
2756 void MEDCoupling1DGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
2758 getNumberOfCells();//only to check that all is well defined.
2760 int nbElemsIn=getNumberOfNodes();
2761 int nbOfTuples=_conn->getNumberOfTuples();
2762 int *pt=_conn->getPointer();
2763 for(int i=0;i<nbOfTuples;i++,pt++)
2765 if(*pt==-1) continue;
2766 if(*pt>=0 && *pt<nbElemsIn)
2767 *pt=newNodeNumbersO2N[*pt];
2770 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
2771 throw INTERP_KERNEL::Exception(oss.str().c_str());
2774 _conn->declareAsNew();
2780 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
2781 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
2782 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
2783 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
2785 * \param [in] begin input start of array of node ids.
2786 * \param [in] end input end of array of node ids.
2787 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
2788 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
2790 void MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
2792 int nbOfCells=getNumberOfCells();
2793 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
2795 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
2796 std::vector<bool> fastFinder(sz,false);
2797 for(const int *work=begin;work!=end;work++)
2798 if(*work>=0 && *work<sz)
2799 fastFinder[*work]=true;
2800 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2801 for(int i=0;i<nbOfCells;i++,conni++)
2803 int ref=0,nbOfHit=0;
2804 int nbNodesPerCell=conni[1]-conni[0];
2805 if(nbNodesPerCell>=0)
2807 for(int j=0;j<nbNodesPerCell;j++)
2809 int nodeId=conn[conni[0]+j];
2813 if(fastFinder[nodeId])
2820 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !";
2821 throw INTERP_KERNEL::Exception(oss.str().c_str());
2823 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
2824 cellIdsKept->pushBackSilent(i);
2826 cellIdsKeptArr=cellIdsKept.retn();
2829 void MEDCoupling1DGTUMesh::allocateCells(int nbOfCells) throw(INTERP_KERNEL::Exception)
2832 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !");
2833 _conn=DataArrayInt::New();
2834 _conn->reserve(nbOfCells*3);
2835 _conn_indx=DataArrayInt::New();
2836 _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0);
2841 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
2843 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
2844 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
2845 * \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
2846 * attached to \a this.
2847 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
2849 void MEDCoupling1DGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) throw(INTERP_KERNEL::Exception)
2851 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
2852 DataArrayInt *c(_conn),*c2(_conn_indx);
2856 if(pos==c->getNumberOfTuples())
2858 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
2859 c2->pushBackSilent(pos+sz);
2863 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !";
2864 throw INTERP_KERNEL::Exception(oss.str().c_str());
2868 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !");
2871 void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex) throw(INTERP_KERNEL::Exception)
2874 nodalConn->incrRef();
2877 nodalConnIndex->incrRef();
2878 _conn_indx=nodalConnIndex;
2883 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
2885 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivity() const throw(INTERP_KERNEL::Exception)
2887 const DataArrayInt *ret(_conn);
2888 return const_cast<DataArrayInt *>(ret);
2892 * \return DataArrayInt * - the internal reference to the nodal connectivity index. The caller is not reponsible to deallocate it.
2894 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const throw(INTERP_KERNEL::Exception)
2896 const DataArrayInt *ret(_conn_indx);
2897 return const_cast<DataArrayInt *>(ret);
2901 * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here".
2902 * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity).
2903 * 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.
2905 * 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.
2907 * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal
2908 * connectivity arrays are different (false)
2909 * \return a new object to be managed by the caller.
2911 * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked
2913 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const throw(INTERP_KERNEL::Exception)
2915 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2916 DataArrayInt *nc=0,*nci=0;
2917 isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci);
2918 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ncs(nc),ncis(nci);
2919 ret->_conn=ncs; ret->_conn_indx=ncis;
2920 ret->setCoords(getCoords());
2925 * This method allows to compute, if needed, the packed nodal connectivity pair.
2926 * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges convered by nodal connectivity index array.
2927 * 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.
2929 * 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)
2930 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
2932 * 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
2935 * This method return 3 elements.
2936 * \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
2937 * this pointer can be seen as a new object, that is to managed by the caller.
2938 * \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
2939 * this pointer can be seen as a new object, that is to managed by the caller.
2940 * \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
2941 * output parameters are newly created objects.
2943 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
2945 bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const throw(INTERP_KERNEL::Exception)
2947 if(isPacked())//performs the checkCoherency
2949 const DataArrayInt *c0(_conn),*c1(_conn_indx);
2950 nodalConn=const_cast<DataArrayInt *>(c0); nodalConnIndx=const_cast<DataArrayInt *>(c1);
2951 nodalConn->incrRef(); nodalConnIndx->incrRef();
2954 int bg=_conn_indx->front(),end=_conn_indx->back();
2955 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nc(_conn->selectByTupleId2(bg,end,1));
2956 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nci(_conn_indx->deepCpy());
2957 nci->applyLin(1,-bg);
2958 nodalConn=nc.retn(); nodalConnIndx=nci.retn();
2963 * 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)
2964 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
2965 * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned.
2966 * \return bool - true if \a this looks packed, false is not.
2968 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
2970 bool MEDCoupling1DGTUMesh::isPacked() const throw(INTERP_KERNEL::Exception)
2973 return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples();
2976 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2) throw(INTERP_KERNEL::Exception)
2978 std::vector<const MEDCoupling1DGTUMesh *> tmp(2);
2979 tmp[0]=const_cast<MEDCoupling1DGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1DGTUMesh *>(mesh2);
2980 return Merge1DGTUMeshes(tmp);
2983 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
2985 std::size_t sz=a.size();
2987 return Merge1DGTUMeshesLL(a);
2988 for(std::size_t ii=0;ii<sz;ii++)
2991 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::Merge1DGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
2992 throw INTERP_KERNEL::Exception(oss.str().c_str());
2994 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
2995 for(std::size_t ii=0;ii<sz;ii++)
2996 if(&(a[ii]->getCellModel())!=cm)
2997 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !");
2998 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > bb(sz);
2999 std::vector< const MEDCoupling1DGTUMesh * > aa(sz);
3001 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
3003 const MEDCoupling1DGTUMesh *cur=a[i];
3004 const DataArrayDouble *coo=cur->getCoords();
3006 spaceDim=coo->getNumberOfComponents();
3009 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !");
3010 for(std::size_t i=0;i<sz;i++)
3012 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
3015 return Merge1DGTUMeshesLL(aa);
3019 * \throw If presence of a null instance in the input vector \a a.
3020 * \throw If a is empty
3022 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
3025 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !");
3026 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3028 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !");
3029 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
3030 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3031 int nbOfCells=(*it)->getNumberOfCells();
3032 const DataArrayDouble *coords=(*it)->getCoords();
3033 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3035 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3036 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3038 for(int i=1;it!=a.end();i++,it++)
3041 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !");
3042 if(cm!=&((*it)->getCellModel()))
3043 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3044 (*it)->getNumberOfCells();//to check that all is OK
3045 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3046 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3047 if(coords!=(*it)->getCoords())
3048 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !");
3050 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3051 ret->setCoords(coords);
3052 ret->_conn=DataArrayInt::Aggregate(ncs);
3053 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3058 * 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)
3060 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
3063 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : input array must be NON EMPTY !");
3064 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
3065 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3066 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3067 std::vector<int> nbNodesPerElt(a.size());
3068 int nbOfCells=(*it)->getNumberOfCells();
3070 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3071 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3073 int prevNbOfNodes=(*it)->getNumberOfNodes();
3074 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3076 for(int i=1;it!=a.end();i++,it++)
3078 if(cm!=&((*it)->getCellModel()))
3079 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3080 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3081 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3082 nbOfCells+=(*it)->getNumberOfCells();
3083 nbNodesPerElt[i]=nbNodesPerElt[i-1]+prevNbOfNodes;
3084 prevNbOfNodes=(*it)->getNumberOfNodes();
3086 std::vector<const MEDCouplingPointSet *> aps(a.size());
3087 std::copy(a.begin(),a.end(),aps.begin());
3088 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
3089 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3090 ret->setCoords(pts);
3091 ret->_conn=AggregateNodalConnAndShiftNodeIds(ncs,nbNodesPerElt);
3092 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3096 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception)
3098 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
3099 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1,tmp2;
3100 const DataArrayInt *nodalConn(_conn),*nodalConnI(_conn_indx);
3103 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
3111 tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
3115 ret->_conn_indx=tmp2;
3119 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
3120 ret->setCoords(coords);
3123 ret->setCoords(_coords);
3127 std::vector<int> MEDCoupling1DGTUMesh::BuildAPolygonFromParts(const std::vector< std::vector<int> >& parts) throw(INTERP_KERNEL::Exception)
3129 std::vector<int> ret;
3132 ret.insert(ret.end(),parts[0].begin(),parts[0].end());
3133 int ref(ret.back());
3134 std::size_t sz(parts.size()),nbh(1);
3135 std::vector<bool> b(sz,true); b[0]=false;
3139 for(;i<sz;i++) if(b[i] && parts[i].front()==ref) { ret.insert(ret.end(),parts[i].begin()+1,parts[i].end()); nbh++; break; }
3143 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::BuildAPolygonFromParts : the input vector is not a part of a single polygon !");
3145 if(ret.back()==ret.front())
3151 * This method performs an aggregation of \a nodalConns (as DataArrayInt::Aggregate does) but in addition of that a shift is applied on the
3152 * values contained in \a nodalConns using corresponding offset specified in input \a offsetInNodeIdsPerElt.
3153 * But it also manage the values -1, that have a semantic in MEDCoupling1DGTUMesh class (separator for polyhedron).
3155 * \param [in] nodalConns - a list of nodal connectivity arrays same size than \a offsetInNodeIdsPerElt.
3156 * \param [in] offsetInNodeIdsPerElt - a list of offsets to apply.
3157 * \return DataArrayInt * - A new object (to be managed by the caller) that is the result of the aggregation.
3158 * \throw If \a nodalConns or \a offsetInNodeIdsPerElt are empty.
3159 * \throw If \a nodalConns and \a offsetInNodeIdsPerElt have not the same size.
3160 * \throw If presence of null pointer in \a nodalConns.
3161 * \throw If presence of not allocated or array with not exactly one component in \a nodalConns.
3163 DataArrayInt *MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds(const std::vector<const DataArrayInt *>& nodalConns, const std::vector<int>& offsetInNodeIdsPerElt) throw(INTERP_KERNEL::Exception)
3165 std::size_t sz1(nodalConns.size()),sz2(offsetInNodeIdsPerElt.size());
3167 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : input vectors do not have the same size !");
3169 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : empty vectors in input !");
3171 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++)
3174 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of null pointer in input vector !");
3175 if(!(*it)->isAllocated())
3176 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of non allocated array in input vector !");
3177 if((*it)->getNumberOfComponents()!=1)
3178 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of array with not exactly one component !");
3179 nbOfTuples+=(*it)->getNumberOfTuples();
3181 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
3182 int *pt=ret->getPointer();
3184 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++,i++)
3186 int curNbt=(*it)->getNumberOfTuples();
3187 const int *inPt=(*it)->begin();
3188 int offset=offsetInNodeIdsPerElt[i];
3189 for(int j=0;j<curNbt;j++,pt++)
3200 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception)
3203 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh is null !");
3204 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
3206 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh must have exactly one geometric type !");
3207 int geoType((int)*gts.begin());
3208 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(m->getName().c_str(),*gts.begin()));
3209 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription().c_str());
3210 int nbCells(m->getNumberOfCells());
3211 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
3212 conn->alloc(m->getMeshLength()-nbCells,1); connI->alloc(nbCells+1,1);
3213 int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
3214 const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
3215 for(int i=0;i<nbCells;i++,ciin++,ci++)
3217 if(cin[ciin[0]]==geoType)
3219 if(ciin[1]-ciin[0]>=1)
3221 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
3222 ci[1]=ci[0]+ciin[1]-ciin[0]-1;
3226 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 !";
3227 throw INTERP_KERNEL::Exception(oss.str().c_str());
3232 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 !";
3233 throw INTERP_KERNEL::Exception(oss.str().c_str());
3236 ret->setNodalConnectivity(conn,connI);