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, DataArrayByte *byteData) const throw(INTERP_KERNEL::Exception)
242 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
243 m->writeVTKLL(ofs,cellData,pointData,byteData);
246 std::string MEDCoupling1GTUMesh::getVTKDataSetType() const throw(INTERP_KERNEL::Exception)
248 return std::string("UnstructuredGrid");
251 std::size_t MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren() const
253 return MEDCouplingPointSet::getHeapMemorySizeWithoutChildren();
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::getHeapMemorySizeWithoutChildren() const
572 return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren();
575 std::vector<RefCountObject *> MEDCoupling1SGTUMesh::getDirectChildren() const
577 std::vector<RefCountObject *> ret(MEDCoupling1GTUMesh::getDirectChildren());
578 const DataArrayInt *c(_conn);
580 ret.push_back(const_cast<DataArrayInt *>(c));
584 MEDCouplingMesh *MEDCoupling1SGTUMesh::deepCpy() const
589 bool MEDCoupling1SGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
592 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualIfNotWhy : input other pointer is null !");
593 std::ostringstream oss; oss.precision(15);
594 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
597 reason="mesh given in input is not castable in MEDCoupling1SGTUMesh !";
600 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
602 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
607 reason="in connectivity of single static geometric type exactly one among this and other is null !";
610 if(!c1->isEqualIfNotWhy(*c2,reason))
612 reason.insert(0,"Nodal connectivity DataArrayInt differ : ");
618 bool MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
621 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
622 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
625 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
627 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
632 if(!c1->isEqualWithoutConsideringStr(*c2))
637 void MEDCoupling1SGTUMesh::checkCoherencyOfConnectivity() const throw(INTERP_KERNEL::Exception)
639 const DataArrayInt *c1(_conn);
642 if(c1->getNumberOfComponents()!=1)
643 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
644 if(c1->getInfoOnComponent(0)!="")
645 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
646 c1->checkAllocated();
649 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
652 void MEDCoupling1SGTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
654 MEDCouplingPointSet::checkCoherency();
655 checkCoherencyOfConnectivity();
658 void MEDCoupling1SGTUMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
661 const DataArrayInt *c1(_conn);
662 int nbOfTuples=c1->getNumberOfTuples();
663 int nbOfNodesPerCell=(int)_cm->getNumberOfNodes();
664 if(nbOfTuples%nbOfNodesPerCell!=0)
666 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 !";
667 throw INTERP_KERNEL::Exception(oss.str().c_str());
669 int nbOfNodes=getNumberOfNodes();
670 int nbOfCells=nbOfTuples/nbOfNodesPerCell;
671 const int *w(c1->begin());
672 for(int i=0;i<nbOfCells;i++)
673 for(int j=0;j<nbOfNodesPerCell;j++,w++)
675 if(*w<0 || *w>=nbOfNodes)
677 std::ostringstream oss; oss << "At node #" << j << " of cell #" << i << ", is equal to " << *w << " must be in [0," << nbOfNodes << ") !";
678 throw INTERP_KERNEL::Exception(oss.str().c_str());
683 void MEDCoupling1SGTUMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
685 checkCoherency1(eps);
688 int MEDCoupling1SGTUMesh::getNumberOfCells() const
690 int nbOfTuples=getNodalConnectivityLength();
691 int nbOfNodesPerCell=getNumberOfNodesPerCell();
692 if(nbOfTuples%nbOfNodesPerCell!=0)
694 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 !";
695 throw INTERP_KERNEL::Exception(oss.str().c_str());
697 return nbOfTuples/nbOfNodesPerCell;
700 int MEDCoupling1SGTUMesh::getNumberOfNodesInCell(int cellId) const throw(INTERP_KERNEL::Exception)
702 return getNumberOfNodesPerCell();
705 int MEDCoupling1SGTUMesh::getNumberOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
707 checkNonDynamicGeoType();
708 return (int)_cm->getNumberOfNodes();
711 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
713 checkNonDynamicGeoType();
714 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
715 ret->alloc(getNumberOfCells(),1);
716 ret->fillWithValue((int)_cm->getNumberOfNodes());
720 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception)
722 checkNonDynamicGeoType();
723 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
724 ret->alloc(getNumberOfCells(),1);
725 ret->fillWithValue((int)_cm->getNumberOfSons());
729 DataArrayInt *MEDCoupling1SGTUMesh::computeEffectiveNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
731 checkNonDynamicGeoType();
732 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
733 int nbCells(getNumberOfCells());
734 ret->alloc(nbCells,1);
735 int *retPtr(ret->getPointer());
736 int nbNodesPerCell(getNumberOfNodesPerCell());
737 const int *conn(_conn->begin());
738 for(int i=0;i<nbCells;i++,conn+=nbNodesPerCell,retPtr++)
740 std::set<int> s(conn,conn+nbNodesPerCell);
741 *retPtr=(int)s.size();
746 void MEDCoupling1SGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
748 int sz=getNumberOfNodesPerCell();
750 if(cellId>=0 && cellId<getNumberOfCells())
751 std::copy(_conn->begin()+cellId*sz,_conn->begin()+(cellId+1)*sz,conn.begin());
754 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << getNumberOfCells() << ") !";
755 throw INTERP_KERNEL::Exception(oss.str().c_str());
759 void MEDCoupling1SGTUMesh::checkNonDynamicGeoType() const throw(INTERP_KERNEL::Exception)
762 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkNonDynamicGeoType : internal error ! the internal geo type is dynamic ! should be static !");
765 std::string MEDCoupling1SGTUMesh::simpleRepr() const
767 static const char msg0[]="No coordinates specified !";
768 std::ostringstream ret;
769 ret << "Single static geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
770 ret << "Description of mesh : \"" << getDescription() << "\"\n";
772 double tt=getTime(tmpp1,tmpp2);
773 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
774 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
775 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
778 const int spaceDim=getSpaceDimension();
779 ret << spaceDim << "\nInfo attached on space dimension : ";
780 for(int i=0;i<spaceDim;i++)
781 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
786 ret << "Number of nodes : ";
788 ret << getNumberOfNodes() << "\n";
791 ret << "Number of cells : ";
792 if((const DataArrayInt *)_conn)
794 if(_conn->isAllocated())
796 if(_conn->getNumberOfComponents()==1)
797 ret << getNumberOfCells() << "\n";
799 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
802 ret << "Nodal connectivity array specified but not allocated !" << "\n";
805 ret << "No connectivity specified !" << "\n";
806 ret << "Cell type : " << _cm->getRepr() << "\n";
810 std::string MEDCoupling1SGTUMesh::advancedRepr() const
812 std::ostringstream ret;
814 ret << "\nCoordinates array : \n___________________\n\n";
816 _coords->reprWithoutNameStream(ret);
818 ret << "No array set !\n";
819 ret << "\n\nConnectivity array : \n____________________\n\n";
821 if((const DataArrayInt *)_conn)
823 if(_conn->isAllocated())
825 if(_conn->getNumberOfComponents()==1)
827 int nbOfCells=getNumberOfCells();
828 int sz=getNumberOfNodesPerCell();
829 const int *connPtr=_conn->begin();
830 for(int i=0;i<nbOfCells;i++,connPtr+=sz)
832 ret << "Cell #" << i << " : ";
833 std::copy(connPtr,connPtr+sz,std::ostream_iterator<int>(ret," "));
838 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
841 ret << "Nodal connectivity array specified but not allocated !" << "\n";
844 ret << "No connectivity specified !" << "\n";
848 DataArrayDouble *MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
850 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
851 int spaceDim=getSpaceDimension();
852 int nbOfCells=getNumberOfCells();//checkCoherency()
853 int nbOfNodes=getNumberOfNodes();
854 ret->alloc(nbOfCells,spaceDim);
855 double *ptToFill=ret->getPointer();
856 const double *coor=_coords->begin();
857 const int *nodal=_conn->begin();
858 int sz=getNumberOfNodesPerCell();
859 double coeff=1./(double)sz;
860 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim)
862 std::fill(ptToFill,ptToFill+spaceDim,0.);
863 for(int j=0;j<sz;j++,nodal++)
864 if(*nodal>=0 && *nodal<nbOfNodes)
865 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
868 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
869 throw INTERP_KERNEL::Exception(oss.str().c_str());
871 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),coeff));
876 void MEDCoupling1SGTUMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
878 int nbCells=getNumberOfCells();
879 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
880 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
882 o2n=o2n->checkAndPreparePermutation();
884 const int *conn=_conn->begin();
885 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o=o2n->invertArrayO2N2N2O(nbCells);
886 const int *n2oPtr=n2o->begin();
887 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
888 newConn->alloc(_conn->getNumberOfTuples(),1);
889 newConn->copyStringInfoFrom(*_conn);
890 int sz=getNumberOfNodesPerCell();
892 int *newC=newConn->getPointer();
893 for(int i=0;i<nbCells;i++,newC+=sz)
896 std::copy(conn+pos*sz,conn+(pos+1)*sz,newC);
902 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
903 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
904 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
905 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
907 * \param [in] begin input start of array of node ids.
908 * \param [in] end input end of array of node ids.
909 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
910 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
912 void MEDCoupling1SGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
914 int nbOfCells=getNumberOfCells();
915 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
917 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
918 std::vector<bool> fastFinder(sz,false);
919 for(const int *work=begin;work!=end;work++)
920 if(*work>=0 && *work<sz)
921 fastFinder[*work]=true;
922 const int *conn=_conn->begin();
923 int nbNodesPerCell=getNumberOfNodesPerCell();
924 for(int i=0;i<nbOfCells;i++,conn+=nbNodesPerCell)
927 for(int j=0;j<nbNodesPerCell;j++)
931 if(fastFinder[conn[j]])
934 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
935 cellIdsKept->pushBackSilent(i);
937 cellIdsKeptArr=cellIdsKept.retn();
940 MEDCouplingMesh *MEDCoupling1SGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
942 if(other->getType()!=SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED)
943 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single static geo type each other !");
944 const MEDCoupling1SGTUMesh *otherC=static_cast<const MEDCoupling1SGTUMesh *>(other);
945 return Merge1SGTUMeshes(this,otherC);
948 MEDCouplingUMesh *MEDCoupling1SGTUMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
950 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName().c_str(),getMeshDimension());
951 ret->setCoords(getCoords());
952 const int *nodalConn=_conn->begin();
953 int nbCells=getNumberOfCells();
954 int nbNodesPerCell=getNumberOfNodesPerCell();
955 int geoType=(int)getCellModelEnum();
956 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells*(nbNodesPerCell+1),1);
957 int *cPtr=c->getPointer();
958 for(int i=0;i<nbCells;i++,nodalConn+=nbNodesPerCell)
961 cPtr=std::copy(nodalConn,nodalConn+nbNodesPerCell,cPtr);
963 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::Range(0,(nbCells+1)*(nbNodesPerCell+1),nbNodesPerCell+1);
964 ret->setConnectivity(c,cI,true);
968 DataArrayInt *MEDCoupling1SGTUMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
973 return simplexizePol0();
975 return simplexizePol1();
976 case (int) INTERP_KERNEL::PLANAR_FACE_5:
977 return simplexizePlanarFace5();
978 case (int) INTERP_KERNEL::PLANAR_FACE_6:
979 return simplexizePlanarFace6();
981 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)");
987 struct MEDCouplingAccVisit
989 MEDCouplingAccVisit():_new_nb_of_nodes(0) { }
990 int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; }
991 int _new_nb_of_nodes;
997 * Finds nodes not used in any cell and returns an array giving a new id to every node
998 * by excluding the unused nodes, for which the array holds -1. The result array is
999 * a mapping in "Old to New" mode.
1000 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
1001 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
1002 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
1003 * if the node is unused or a new id else. The caller is to delete this
1004 * array using decrRef() as it is no more needed.
1005 * \throw If the coordinates array is not set.
1006 * \throw If the nodal connectivity of cells is not defined.
1007 * \throw If the nodal connectivity includes an invalid id.
1009 DataArrayInt *MEDCoupling1SGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception)
1012 int nbOfNodes=getNumberOfNodes();
1013 int nbOfCells=getNumberOfCells();
1014 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1015 ret->alloc(nbOfNodes,1);
1016 int *traducer=ret->getPointer();
1017 std::fill(traducer,traducer+nbOfNodes,-1);
1018 const int *conn=_conn->begin();
1019 int nbNodesPerCell=getNumberOfNodesPerCell();
1020 for(int i=0;i<nbOfCells;i++)
1021 for(int j=0;j<nbNodesPerCell;j++,conn++)
1022 if(*conn>=0 && *conn<nbOfNodes)
1026 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << conn[j] << " not in [0," << nbOfNodes << ") !";
1027 throw INTERP_KERNEL::Exception(oss.str().c_str());
1029 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
1030 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
1035 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
1036 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
1037 * This method is a generalization of shiftNodeNumbersInConn().
1038 * \warning This method performs no check of validity of new ids. **Use it with care !**
1039 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
1040 * this->getNumberOfNodes(), in "Old to New" mode.
1041 * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
1042 * \throw If the nodal connectivity of cells is not defined.
1044 void MEDCoupling1SGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
1046 getNumberOfCells();//only to check that all is well defined.
1047 _conn->transformWithIndArr(newNodeNumbersO2N,newNodeNumbersO2N+getNumberOfNodes());
1051 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2) throw(INTERP_KERNEL::Exception)
1053 std::vector<const MEDCoupling1SGTUMesh *> tmp(2);
1054 tmp[0]=const_cast<MEDCoupling1SGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1SGTUMesh *>(mesh2);
1055 return Merge1SGTUMeshes(tmp);
1058 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
1060 std::size_t sz=a.size();
1062 return Merge1SGTUMeshesLL(a);
1063 for(std::size_t ii=0;ii<sz;ii++)
1066 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::Merge1SGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
1067 throw INTERP_KERNEL::Exception(oss.str().c_str());
1069 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
1070 for(std::size_t ii=0;ii<sz;ii++)
1071 if(&(a[ii]->getCellModel())!=cm)
1072 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : all items must have the same geo type !");
1073 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> > bb(sz);
1074 std::vector< const MEDCoupling1SGTUMesh * > aa(sz);
1076 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
1078 const MEDCoupling1SGTUMesh *cur=a[i];
1079 const DataArrayDouble *coo=cur->getCoords();
1081 spaceDim=coo->getNumberOfComponents();
1084 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : no spaceDim specified ! unable to perform merge !");
1085 for(std::size_t i=0;i<sz;i++)
1087 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
1090 return Merge1SGTUMeshesLL(aa);
1094 * \throw If presence of a null instance in the input vector \a a.
1095 * \throw If a is empty
1097 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
1100 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : input array must be NON EMPTY !");
1101 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1103 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : null instance in the first element of input vector !");
1104 std::vector<const DataArrayInt *> ncs(a.size());
1105 int nbOfCells=(*it)->getNumberOfCells();
1106 const DataArrayDouble *coords=(*it)->getCoords();
1107 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1108 int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
1109 ncs[0]=(*it)->getNodalConnectivity();
1111 for(int i=1;it!=a.end();i++,it++)
1114 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : presence of a null instance in the input vector !");
1115 if(cm!=&((*it)->getCellModel()))
1116 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1117 (*it)->getNumberOfCells();//to check that all is OK
1118 ncs[i]=(*it)->getNodalConnectivity();
1119 if(coords!=(*it)->getCoords())
1120 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : not lying on same coords !");
1122 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1123 ret->setCoords(coords);
1124 ret->_conn=DataArrayInt::Aggregate(ncs);
1129 * 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)
1131 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
1134 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : input array must be NON EMPTY !");
1135 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1136 int nbOfCells=(*it)->getNumberOfCells();
1137 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1138 int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
1140 for(;it!=a.end();it++)
1142 if(cm!=&((*it)->getCellModel()))
1143 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1144 nbOfCells+=(*it)->getNumberOfCells();
1146 std::vector<const MEDCouplingPointSet *> aps(a.size());
1147 std::copy(a.begin(),a.end(),aps.begin());
1148 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
1149 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1150 ret->setCoords(pts);
1151 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New();
1152 c->alloc(nbOfCells*nbNodesPerCell,1);
1153 int *cPtr=c->getPointer();
1155 for(it=a.begin();it!=a.end();it++)
1157 int curConnLgth=(*it)->getNodalConnectivityLength();
1158 const int *curC=(*it)->_conn->begin();
1159 cPtr=std::transform(curC,curC+curConnLgth,cPtr,std::bind2nd(std::plus<int>(),offset));
1160 offset+=(*it)->getNumberOfNodes();
1163 ret->setNodalConnectivity(c);
1167 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
1169 int ncell=getNumberOfCells();
1170 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName().c_str(),*_cm));
1171 ret->setCoords(_coords);
1172 std::size_t nbOfElemsRet=std::distance(begin,end);
1173 const int *inConn=_conn->getConstPointer();
1174 int sz=getNumberOfNodesPerCell();
1175 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1176 int *connPtr=connRet->getPointer();
1177 for(const int *work=begin;work!=end;work++,connPtr+=sz)
1179 if(*work>=0 && *work<ncell)
1180 std::copy(inConn+(work[0])*sz,inConn+(work[0]+1)*sz,connPtr);
1183 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !";
1184 throw INTERP_KERNEL::Exception(oss.str().c_str());
1188 ret->copyTinyInfoFrom(this);
1192 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
1194 int ncell=getNumberOfCells();
1195 int nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : ");
1196 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName().c_str(),*_cm));
1197 ret->setCoords(_coords);
1198 const int *inConn=_conn->getConstPointer();
1199 int sz=getNumberOfNodesPerCell();
1200 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1201 int *connPtr=connRet->getPointer();
1203 for(int i=0;i<nbOfElemsRet;i++,connPtr+=sz,curId+=step)
1205 if(curId>=0 && curId<ncell)
1206 std::copy(inConn+curId*sz,inConn+(curId+1)*sz,connPtr);
1209 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : On pos #" << i << " input cell id =" << curId << " should be in [0," << ncell << ") !";
1210 throw INTERP_KERNEL::Exception(oss.str().c_str());
1214 ret->copyTinyInfoFrom(this);
1218 void MEDCoupling1SGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const throw(INTERP_KERNEL::Exception)
1220 int sz((int)nodeIdsInUse.size());
1221 int nbCells(getNumberOfCells());
1222 int nbOfNodesPerCell(getNumberOfNodesPerCell());
1223 const int *w(_conn->begin());
1224 for(int i=0;i<nbCells;i++)
1225 for(int j=0;j<nbOfNodesPerCell;j++,w++)
1228 nodeIdsInUse[*w]=true;
1231 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeNodeIdsAlg : At cell #" << i << " presence of node id #" << *w << " should be in [0," << sz << ") !";
1232 throw INTERP_KERNEL::Exception(oss.str().c_str());
1237 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception)
1239 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName().c_str(),*_cm));
1240 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1;
1241 const DataArrayInt *nodalConn(_conn);
1244 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
1251 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
1252 ret->setCoords(coords);
1255 ret->setCoords(_coords);
1259 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol0() throw(INTERP_KERNEL::Exception)
1261 int nbOfCells=getNumberOfCells();
1262 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1263 return DataArrayInt::Range(0,nbOfCells,1);
1264 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1265 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1266 const int *c(_conn->begin());
1267 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1268 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1270 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[2];
1271 newConnPtr[3]=c[0]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1272 retPtr[0]=i; retPtr[1]=i;
1275 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1280 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol1() throw(INTERP_KERNEL::Exception)
1282 int nbOfCells=getNumberOfCells();
1283 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1284 return DataArrayInt::Range(0,nbOfCells,1);
1285 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1286 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1287 const int *c(_conn->begin());
1288 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1289 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1291 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[3];
1292 newConnPtr[3]=c[1]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1293 retPtr[0]=i; retPtr[1]=i;
1296 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1301 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace5() throw(INTERP_KERNEL::Exception)
1303 int nbOfCells=getNumberOfCells();
1304 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1305 return DataArrayInt::Range(0,nbOfCells,1);
1306 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(5*4*nbOfCells,1);
1307 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(5*nbOfCells,1);
1308 const int *c(_conn->begin());
1309 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1310 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=20,retPtr+=5)
1312 for(int j=0;j<20;j++)
1313 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_5_WO[j]];
1314 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i;
1317 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1322 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace6() throw(INTERP_KERNEL::Exception)
1324 int nbOfCells=getNumberOfCells();
1325 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1326 return DataArrayInt::Range(0,nbOfCells,1);
1327 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(6*4*nbOfCells,1);
1328 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(6*nbOfCells,1);
1329 const int *c(_conn->begin());
1330 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1331 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=24,retPtr+=6)
1333 for(int j=0;j<24;j++)
1334 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_6_WO[j]];
1335 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i; retPtr[5]=i;
1338 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1343 void MEDCoupling1SGTUMesh::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1345 stream << "MEDCoupling1SGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
1346 stream << " Mesh dimension : " << getMeshDimension() << ".";
1348 { stream << " No coordinates set !"; return ; }
1349 if(!_coords->isAllocated())
1350 { stream << " Coordinates set but not allocated !"; return ; }
1351 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
1352 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
1353 if(!(const DataArrayInt *)_conn)
1354 { stream << std::endl << "Nodal connectivity NOT set !"; return ; }
1355 if(_conn->isAllocated())
1357 if(_conn->getNumberOfComponents()==1)
1358 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
1362 void MEDCoupling1SGTUMesh::checkFullyDefined() const throw(INTERP_KERNEL::Exception)
1364 if(!((const DataArrayInt *)_conn) || !((const DataArrayDouble *)_coords))
1365 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFullyDefined : part of this is not fully defined.");
1369 * First step of unserialization process.
1371 bool MEDCoupling1SGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
1373 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEmptyMesh : not implemented yet !");
1376 void MEDCoupling1SGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
1379 double time=getTime(it,order);
1380 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
1382 littleStrings.push_back(getName());
1383 littleStrings.push_back(getDescription());
1384 littleStrings.push_back(getTimeUnit());
1386 std::vector<std::string> littleStrings2,littleStrings3;
1387 if((const DataArrayDouble *)_coords)
1388 _coords->getTinySerializationStrInformation(littleStrings2);
1389 if((const DataArrayInt *)_conn)
1390 _conn->getTinySerializationStrInformation(littleStrings3);
1391 int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size());
1392 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
1393 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
1395 tinyInfo.push_back(getCellModelEnum());
1396 tinyInfo.push_back(it);
1397 tinyInfo.push_back(order);
1398 std::vector<int> tinyInfo2,tinyInfo3;
1399 if((const DataArrayDouble *)_coords)
1400 _coords->getTinySerializationIntInformation(tinyInfo2);
1401 if((const DataArrayInt *)_conn)
1402 _conn->getTinySerializationIntInformation(tinyInfo3);
1403 int sz2((int)tinyInfo2.size()),sz3((int)tinyInfo3.size());
1404 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3);
1405 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1406 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
1408 tinyInfoD.push_back(time);
1411 void MEDCoupling1SGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
1413 std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+tinyInfo[5]);
1414 std::vector<int> tinyInfo1(tinyInfo.begin()+7+tinyInfo[5],tinyInfo.begin()+7+tinyInfo[5]+tinyInfo[6]);
1415 a1->resizeForUnserialization(tinyInfo1);
1416 a2->resizeForUnserialization(tinyInfo2);
1419 void MEDCoupling1SGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
1422 if((const DataArrayInt *)_conn)
1423 if(_conn->isAllocated())
1424 sz=_conn->getNbOfElems();
1425 a1=DataArrayInt::New();
1427 if(sz!=0 && (const DataArrayInt *)_conn)
1428 std::copy(_conn->begin(),_conn->end(),a1->getPointer());
1430 if((const DataArrayDouble *)_coords)
1431 if(_coords->isAllocated())
1432 sz=_coords->getNbOfElems();
1433 a2=DataArrayDouble::New();
1435 if(sz!=0 && (const DataArrayDouble *)_coords)
1436 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
1439 void MEDCoupling1SGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
1440 const std::vector<std::string>& littleStrings)
1442 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
1443 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
1444 setName(littleStrings[0].c_str());
1445 setDescription(littleStrings[1].c_str());
1446 setTimeUnit(littleStrings[2].c_str());
1447 setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
1448 int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]);
1450 _coords=DataArrayDouble::New();
1451 std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+sz2);
1452 _coords->resizeForUnserialization(tinyInfo2);
1453 std::copy(a2->begin(),a2->end(),_coords->getPointer());
1454 _conn=DataArrayInt::New();
1455 std::vector<int> tinyInfo3(tinyInfo.begin()+7+sz2,tinyInfo.begin()+7+sz2+sz3);
1456 _conn->resizeForUnserialization(tinyInfo3);
1457 std::copy(a1->begin(),a1->end(),_conn->getPointer());
1458 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
1459 _coords->finishUnserialization(tinyInfo2,littleStrings2);
1460 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
1461 _conn->finishUnserialization(tinyInfo3,littleStrings3);
1465 * Checks if \a this and \a other meshes are geometrically equivalent with high
1466 * probability, else an exception is thrown. The meshes are considered equivalent if
1467 * (1) meshes contain the same number of nodes and the same number of elements of the
1468 * same types (2) three cells of the two meshes (first, last and middle) are based
1469 * on coincident nodes (with a specified precision).
1470 * \param [in] other - the mesh to compare with.
1471 * \param [in] prec - the precision used to compare nodes of the two meshes.
1472 * \throw If the two meshes do not match.
1474 void MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception)
1476 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1477 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1479 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single static geometric type !");
1480 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1484 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1485 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1486 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1487 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1488 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1489 if(c1->getHashCode()!=c2->getHashCode())
1490 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1493 MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
1496 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
1497 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1499 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
1500 std::vector<const MEDCoupling1SGTUMesh *> ms(2);
1503 return Merge1SGTUMeshesOnSameCoords(ms);
1506 void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception)
1508 checkFullyDefined();
1509 int nbOfNodes=getNumberOfNodes();
1510 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
1511 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
1512 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
1513 const int *conn=_conn->begin();
1514 int nbOfCells=getNumberOfCells();
1515 int nbOfEltsInRevNodal=0;
1516 int nbOfNodesPerCell=getNumberOfNodesPerCell();
1517 for(int eltId=0;eltId<nbOfCells;eltId++)
1519 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1521 if(conn[0]>=0 && conn[0]<nbOfNodes)
1523 nbOfEltsInRevNodal++;
1524 revNodalIndxPtr[conn[0]+1]++;
1528 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
1529 throw INTERP_KERNEL::Exception(oss.str().c_str());
1533 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
1534 conn=_conn->begin();
1535 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
1536 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
1537 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
1538 for(int eltId=0;eltId<nbOfCells;eltId++)
1540 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1542 *std::find_if(revNodalPtr+revNodalIndxPtr[*conn],revNodalPtr+revNodalIndxPtr[*conn+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
1548 * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null.
1550 void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn) throw(INTERP_KERNEL::Exception)
1553 nodalConn->incrRef();
1559 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
1561 DataArrayInt *MEDCoupling1SGTUMesh::getNodalConnectivity() const throw(INTERP_KERNEL::Exception)
1563 const DataArrayInt *ret(_conn);
1564 return const_cast<DataArrayInt *>(ret);
1568 * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted,
1569 * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter.
1570 * If a nodal connectivity previouly existed before the call of this method, it will be reset.
1572 * \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain.
1574 void MEDCoupling1SGTUMesh::allocateCells(int nbOfCells) throw(INTERP_KERNEL::Exception)
1577 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !");
1578 _conn=DataArrayInt::New();
1579 _conn->reserve(getNumberOfNodesPerCell()*nbOfCells);
1584 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
1586 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
1587 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
1588 * \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
1589 * attached to \a this.
1590 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
1592 void MEDCoupling1SGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) throw(INTERP_KERNEL::Exception)
1594 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
1595 int ref=getNumberOfNodesPerCell();
1598 DataArrayInt *c(_conn);
1600 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
1602 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !");
1606 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this (";
1607 oss << ref << ") !";
1608 throw INTERP_KERNEL::Exception(oss.str().c_str());
1613 * This method builds the dual mesh of \a this and returns it.
1615 * \return MEDCoupling1SGTUMesh * - newly object created to be managed by the caller.
1616 * \throw If \a this is not a mesh containing only simplex cells.
1617 * \throw If \a this is not correctly allocated (coordinates and connectivities have to be correctly set !).
1618 * \throw If at least one node in \a this is orphan (without any simplex cell lying on it !)
1620 MEDCoupling1GTUMesh *MEDCoupling1SGTUMesh::computeDualMesh() const throw(INTERP_KERNEL::Exception)
1622 const INTERP_KERNEL::CellModel& cm(getCellModel());
1624 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : this mesh is not a simplex mesh ! Please invoke simplexize of tetrahedrize on this before calling this method !");
1625 switch(getMeshDimension())
1628 return computeDualMesh3D();
1630 return computeDualMesh2D();
1632 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : meshdimension must be in [2,3] !");
1636 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh3D() const throw(INTERP_KERNEL::Exception)
1638 static const int DUAL_TETRA_0[36]={
1639 4,1,0, 6,0,3, 7,3,1,
1640 4,0,1, 5,2,0, 8,1,2,
1641 6,3,0, 5,0,2, 9,2,3,
1644 static const int DUAL_TETRA_1[36]={
1645 8,4,10, 11,5,8, 10,7,11,
1646 9,4,8, 8,5,12, 12,6,9,
1647 10,4,9, 9,6,13, 13,7,10,
1648 12,5,11, 13,6,12, 11,7,13
1650 static const int FACEID_NOT_SH_NODE[4]={2,3,1,0};
1651 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TETRA4)
1652 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh3D : only TETRA4 supported !");
1653 checkFullyDefined();
1654 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured());
1655 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1656 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1657 const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1658 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d1Arr(DataArrayInt::New()),di1Arr(DataArrayInt::New()),rd1Arr(DataArrayInt::New()),rdi1Arr(DataArrayInt::New());
1659 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->explode3DMeshTo1D(d1Arr,di1Arr,rd1Arr,rdi1Arr));
1660 const int *d1(d1Arr->begin());
1661 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1662 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> faces(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
1663 const int *d2(d2Arr->begin()),*rd2(rd2Arr->begin()),*rdi2(rdi2Arr->begin());
1664 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),facesBaryArr(faces->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
1665 const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+faces->getNumberOfCells()),offset1(offset0+edges->getNumberOfCells());
1667 std::vector<const DataArrayDouble *> v(4); v[0]=getCoords(); v[1]=facesBaryArr; v[2]=edgesBaryArr; v[3]=baryArr;
1668 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0; facesBaryArr=0;
1669 std::string name("DualOf_"); name+=getName();
1670 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name.c_str(),INTERP_KERNEL::NORM_POLYHED)); ret->setCoords(zeArr);
1671 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1672 for(int i=0;i<nbOfNodes;i++,revNodI++)
1674 int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1675 if(nbOfCellsSharingNode==0)
1677 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh3D : Node #" << i << " is orphan !";
1678 throw INTERP_KERNEL::Exception(oss.str().c_str());
1680 for(int j=0;j<nbOfCellsSharingNode;j++)
1682 int curCellId(revNod[revNodI[0]+j]);
1683 const int *connOfCurCell(nodal+4*curCellId);
1684 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1685 if(j!=0) cArr->pushBackSilent(-1);
1688 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;
1689 tmp[2]=curCellId+offset1; tmp[3]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+2]]+nbOfNodes;
1691 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;
1692 tmp[7]=curCellId+offset1; tmp[8]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+5]]+nbOfNodes;
1694 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;
1695 tmp[12]=curCellId+offset1; tmp[13]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+8]]+nbOfNodes;
1696 cArr->insertAtTheEnd(tmp,tmp+14);
1698 for(int k=0;k<4;k++)
1700 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1702 const int *faceId(d2+4*curCellId+k);
1703 if(rdi2[*faceId+1]-rdi2[*faceId]==1)
1705 int tmp2[5]; tmp2[0]=-1; tmp2[1]=i;
1706 tmp2[2]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+0]-8]+offset0;
1707 tmp2[3]=d2[4*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+1]-4]+nbOfNodes;
1708 tmp2[4]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+2]-8]+offset0;
1709 cArr->insertAtTheEnd(tmp2,tmp2+5);
1715 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
1717 ret->setNodalConnectivity(cArr,ciArr);
1721 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh2D() const throw(INTERP_KERNEL::Exception)
1723 static const int DUAL_TRI_0[6]={0,2, 1,0, 2,1};
1724 static const int DUAL_TRI_1[6]={-3,+5, +3,-4, +4,-5};
1725 static const int FACEID_NOT_SH_NODE[3]={1,2,0};
1726 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TRI3)
1727 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh2D : only TRI3 supported !");
1728 checkFullyDefined();
1729 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured());
1730 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1731 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1732 const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1733 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1734 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
1735 const int *d2(d2Arr->begin()),*rd2(rd2Arr->begin()),*rdi2(rdi2Arr->begin());
1736 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
1737 const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+edges->getNumberOfCells());
1739 std::vector<const DataArrayDouble *> v(3); v[0]=getCoords(); v[1]=edgesBaryArr; v[2]=baryArr;
1740 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0;
1741 std::string name("DualOf_"); name+=getName();
1742 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name.c_str(),INTERP_KERNEL::NORM_POLYGON)); ret->setCoords(zeArr);
1743 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1744 for(int i=0;i<nbOfNodes;i++,revNodI++)
1746 int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1747 if(nbOfCellsSharingNode==0)
1749 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh2D : Node #" << i << " is orphan !";
1750 throw INTERP_KERNEL::Exception(oss.str().c_str());
1752 std::vector< std::vector<int> > polyg;
1753 for(int j=0;j<nbOfCellsSharingNode;j++)
1755 int curCellId(revNod[revNodI[0]+j]);
1756 const int *connOfCurCell(nodal+3*curCellId);
1757 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1758 std::vector<int> locV(3);
1759 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;
1760 polyg.push_back(locV);
1762 for(int k=0;k<3;k++)
1764 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1766 const int *edgeId(d2+3*curCellId+k);
1767 if(rdi2[*edgeId+1]-rdi2[*edgeId]==1)
1769 std::vector<int> locV2(2);
1770 int zeLocEdgeIdRel(DUAL_TRI_1[2*nodePosInCurCell+kk]);
1771 if(zeLocEdgeIdRel>0)
1772 { locV2[0]=d2[3*curCellId+zeLocEdgeIdRel-3]+nbOfNodes; locV2[1]=i; }
1774 { locV2[0]=i; locV2[1]=d2[3*curCellId-zeLocEdgeIdRel-3]+nbOfNodes; }
1775 polyg.push_back(locV2);
1781 std::vector<int> zePolyg(MEDCoupling1DGTUMesh::BuildAPolygonFromParts(polyg));
1782 cArr->insertAtTheEnd(zePolyg.begin(),zePolyg.end());
1783 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
1785 ret->setNodalConnectivity(cArr,ciArr);
1790 * This method aggregate the bbox of each cell and put it into bbox
1792 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
1794 * \throw If \a this is not fully set (coordinates and connectivity).
1795 * \throw If a cell in \a this has no valid nodeId.
1797 DataArrayDouble *MEDCoupling1SGTUMesh::getBoundingBoxForBBTree() const
1799 int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()),nbOfNodesPerCell(getNumberOfNodesPerCell());
1800 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
1801 double *bbox(ret->getPointer());
1802 for(int i=0;i<nbOfCells*spaceDim;i++)
1804 bbox[2*i]=std::numeric_limits<double>::max();
1805 bbox[2*i+1]=-std::numeric_limits<double>::max();
1807 const double *coordsPtr(_coords->getConstPointer());
1808 const int *conn(_conn->getConstPointer());
1809 for(int i=0;i<nbOfCells;i++)
1812 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1815 if(nodeId>=0 && nodeId<nbOfNodes)
1817 for(int k=0;k<spaceDim;k++)
1819 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
1820 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
1827 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
1828 throw INTERP_KERNEL::Exception(oss.str().c_str());
1836 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New()
1838 return new MEDCoupling1DGTUMesh;
1841 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
1843 if(type==INTERP_KERNEL::NORM_ERROR)
1844 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
1845 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
1848 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !";
1849 throw INTERP_KERNEL::Exception(oss.str().c_str());
1851 return new MEDCoupling1DGTUMesh(name,cm);
1854 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh()
1858 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
1862 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
1866 const DataArrayInt *c(other._conn);
1871 _conn_indx=c->deepCpy();
1875 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const
1877 return new MEDCoupling1DGTUMesh(*this,recDeepCpy);
1881 * This method behaves mostly like MEDCoupling1DGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
1882 * The coordinates are shared between \a this and the returned instance.
1884 * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
1885 * \sa MEDCoupling1DGTUMesh::deepCpy
1887 MEDCouplingPointSet *MEDCoupling1DGTUMesh::deepCpyConnectivityOnly() const throw(INTERP_KERNEL::Exception)
1890 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(clone(false));
1891 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy()),ci(_conn_indx->deepCpy());
1892 ret->setNodalConnectivity(c,ci);
1896 void MEDCoupling1DGTUMesh::updateTime() const
1898 MEDCoupling1GTUMesh::updateTime();
1899 const DataArrayInt *c(_conn);
1907 std::size_t MEDCoupling1DGTUMesh::getHeapMemorySizeWithoutChildren() const
1909 return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren();
1912 std::vector<RefCountObject *> MEDCoupling1DGTUMesh::getDirectChildren() const
1914 std::vector<RefCountObject *> ret(MEDCoupling1GTUMesh::getDirectChildren());
1915 const DataArrayInt *c(_conn);
1917 ret.push_back(const_cast<DataArrayInt *>(c));
1920 ret.push_back(const_cast<DataArrayInt *>(c));
1924 MEDCouplingMesh *MEDCoupling1DGTUMesh::deepCpy() const
1929 bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
1932 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !");
1933 std::ostringstream oss; oss.precision(15);
1934 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1937 reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !";
1940 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
1942 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1947 reason="in connectivity of single dynamic geometric type exactly one among this and other is null !";
1950 if(!c1->isEqualIfNotWhy(*c2,reason))
1952 reason.insert(0,"Nodal connectivity DataArrayInt differs : ");
1955 c1=_conn_indx; c2=otherC->_conn_indx;
1960 reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !";
1963 if(!c1->isEqualIfNotWhy(*c2,reason))
1965 reason.insert(0,"Nodal connectivity index DataArrayInt differs : ");
1971 bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
1974 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
1975 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1978 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
1980 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1985 if(!c1->isEqualWithoutConsideringStr(*c2))
1988 c1=_conn_indx; c2=otherC->_conn_indx;
1993 if(!c1->isEqualWithoutConsideringStr(*c2))
1999 * Checks if \a this and \a other meshes are geometrically equivalent with high
2000 * probability, else an exception is thrown. The meshes are considered equivalent if
2001 * (1) meshes contain the same number of nodes and the same number of elements of the
2002 * same types (2) three cells of the two meshes (first, last and middle) are based
2003 * on coincident nodes (with a specified precision).
2004 * \param [in] other - the mesh to compare with.
2005 * \param [in] prec - the precision used to compare nodes of the two meshes.
2006 * \throw If the two meshes do not match.
2008 void MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception)
2010 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
2011 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2013 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single dynamic geometric type !");
2014 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2018 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
2019 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2020 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
2021 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2022 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
2023 if(c1->getHashCode()!=c2->getHashCode())
2024 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs");
2026 c1=_conn_indx; c2=otherC->_conn_indx;
2030 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !");
2031 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2032 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !");
2033 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2034 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !");
2035 if(c1->getHashCode()!=c2->getHashCode())
2036 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs");
2040 void MEDCoupling1DGTUMesh::checkCoherencyOfConnectivity() const throw(INTERP_KERNEL::Exception)
2042 const DataArrayInt *c1(_conn);
2045 if(c1->getNumberOfComponents()!=1)
2046 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
2047 if(c1->getInfoOnComponent(0)!="")
2048 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
2049 c1->checkAllocated();
2052 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
2054 int sz2=_conn->getNumberOfTuples();
2058 if(c1->getNumberOfComponents()!=1)
2059 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
2060 c1->checkAllocated();
2061 if(c1->getNumberOfTuples()<1)
2062 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !");
2063 if(c1->getInfoOnComponent(0)!="")
2064 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
2065 int f=c1->front(),ll=c1->back();
2068 std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !";
2069 throw INTERP_KERNEL::Exception(oss.str().c_str());
2073 std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !";
2074 throw INTERP_KERNEL::Exception(oss.str().c_str());
2078 std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !";
2079 throw INTERP_KERNEL::Exception(oss.str().c_str());
2083 throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !");
2084 int szOfC1Exp=_conn_indx->back();
2087 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() << " !";
2088 throw INTERP_KERNEL::Exception(oss.str().c_str());
2093 * 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.
2094 * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one.
2095 * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array.
2097 void MEDCoupling1DGTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
2099 MEDCouplingPointSet::checkCoherency();
2100 checkCoherencyOfConnectivity();
2103 void MEDCoupling1DGTUMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
2106 const DataArrayInt *c1(_conn),*c2(_conn_indx);
2107 if(!c2->isMonotonic(true))
2108 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkCoherency1 : the nodal connectivity index is expected to be increasing monotinic !");
2110 int nbOfTuples=c1->getNumberOfTuples();
2111 int nbOfNodes=getNumberOfNodes();
2112 const int *w(c1->begin());
2113 for(int i=0;i<nbOfTuples;i++,w++)
2115 if(*w==-1) continue;
2116 if(*w<0 || *w>=nbOfNodes)
2118 std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !";
2119 throw INTERP_KERNEL::Exception(oss.str().c_str());
2124 void MEDCoupling1DGTUMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
2126 checkCoherency1(eps);
2129 int MEDCoupling1DGTUMesh::getNumberOfCells() const
2131 checkCoherencyOfConnectivity();//do not remove
2132 return _conn_indx->getNumberOfTuples()-1;
2136 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2137 * For each cell in \b this the number of nodes constituting cell is computed.
2138 * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned.
2139 * So for pohyhedrons some nodes can be counted several times in the returned result.
2141 * \return a newly allocated array
2143 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
2146 _conn_indx->checkMonotonic(true);
2147 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2148 return _conn_indx->deltaShiftIndex();
2150 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2151 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2152 ret->alloc(nbOfCells,1);
2153 int *retPtr=ret->getPointer();
2154 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2155 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2156 *retPtr=ci[1]-ci[0]-std::count(c+ci[0],c+ci[1],-1);
2161 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2162 * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed.
2164 * \return a newly allocated array
2166 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception)
2169 _conn_indx->checkMonotonic(true);
2170 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG)
2171 return _conn_indx->deltaShiftIndex();
2172 if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG)
2174 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=_conn_indx->deltaShiftIndex();
2175 ret->applyDivideBy(2);
2179 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2180 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2181 ret->alloc(nbOfCells,1);
2182 int *retPtr=ret->getPointer();
2183 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2184 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2185 *retPtr=std::count(c+ci[0],c+ci[1],-1)+1;
2190 * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell,
2191 * will be counted only once here whereas it will be counted several times in MEDCoupling1DGTUMesh::computeNbOfNodesPerCell method.
2193 * \return DataArrayInt * - new object to be deallocated by the caller.
2194 * \sa MEDCoupling1DGTUMesh::computeNbOfNodesPerCell
2196 DataArrayInt *MEDCoupling1DGTUMesh::computeEffectiveNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
2199 _conn_indx->checkMonotonic(true);
2200 int nbOfCells(_conn_indx->getNumberOfTuples()-1);
2201 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2202 ret->alloc(nbOfCells,1);
2203 int *retPtr(ret->getPointer());
2204 const int *ci(_conn_indx->begin()),*c(_conn->begin());
2205 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2207 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2209 std::set<int> s(c+ci[0],c+ci[1]);
2210 *retPtr=(int)s.size();
2215 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2217 std::set<int> s(c+ci[0],c+ci[1]); s.erase(-1);
2218 *retPtr=(int)s.size();
2224 void MEDCoupling1DGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
2226 int nbOfCells(getNumberOfCells());//performs checks
2227 if(cellId>=0 && cellId<nbOfCells)
2229 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2230 int nbOfNodes=stp-strt;
2232 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !");
2233 conn.resize(nbOfNodes);
2234 std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin());
2238 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2239 throw INTERP_KERNEL::Exception(oss.str().c_str());
2243 int MEDCoupling1DGTUMesh::getNumberOfNodesInCell(int cellId) const throw(INTERP_KERNEL::Exception)
2245 int nbOfCells(getNumberOfCells());//performs checks
2246 if(cellId>=0 && cellId<nbOfCells)
2248 const int *conn(_conn->begin());
2249 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2250 return stp-strt-std::count(conn+strt,conn+stp,-1);
2254 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNumberOfNodesInCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2255 throw INTERP_KERNEL::Exception(oss.str().c_str());
2259 std::string MEDCoupling1DGTUMesh::simpleRepr() const
2261 static const char msg0[]="No coordinates specified !";
2262 std::ostringstream ret;
2263 ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
2264 ret << "Description of mesh : \"" << getDescription() << "\"\n";
2266 double tt=getTime(tmpp1,tmpp2);
2267 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
2268 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
2269 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
2272 const int spaceDim=getSpaceDimension();
2273 ret << spaceDim << "\nInfo attached on space dimension : ";
2274 for(int i=0;i<spaceDim;i++)
2275 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
2279 ret << msg0 << "\n";
2280 ret << "Number of nodes : ";
2282 ret << getNumberOfNodes() << "\n";
2284 ret << msg0 << "\n";
2285 ret << "Number of cells : ";
2287 try { checkCoherency(); } catch(INTERP_KERNEL::Exception& e)
2289 ret << "Nodal connectivity arrays are not set or badly set !\n";
2293 ret << getNumberOfCells() << "\n";
2294 ret << "Cell type : " << _cm->getRepr() << "\n";
2298 std::string MEDCoupling1DGTUMesh::advancedRepr() const
2300 std::ostringstream ret;
2301 ret << simpleRepr();
2302 ret << "\nCoordinates array : \n___________________\n\n";
2304 _coords->reprWithoutNameStream(ret);
2306 ret << "No array set !\n";
2307 ret << "\n\nNodal Connectivity : \n____________________\n\n";
2310 try { checkCoherency1(); } catch(INTERP_KERNEL::Exception& e)
2312 ret << "Nodal connectivity arrays are not set or badly set !\n";
2317 int nbOfCells=getNumberOfCells();
2318 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2319 for(int i=0;i<nbOfCells;i++,ci++)
2321 ret << "Cell #" << i << " : ";
2322 std::copy(c+ci[0],c+ci[1],std::ostream_iterator<int>(ret," "));
2328 DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
2330 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
2331 int spaceDim=getSpaceDimension();
2332 int nbOfCells=getNumberOfCells();//checkCoherency()
2333 int nbOfNodes=getNumberOfNodes();
2334 ret->alloc(nbOfCells,spaceDim);
2335 double *ptToFill=ret->getPointer();
2336 const double *coor=_coords->begin();
2337 const int *nodal=_conn->begin(),*nodali=_conn_indx->begin();
2339 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2341 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2343 std::fill(ptToFill,ptToFill+spaceDim,0.);
2344 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2346 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2348 if(*nodal>=0 && *nodal<nbOfNodes)
2349 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2352 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2353 throw INTERP_KERNEL::Exception(oss.str().c_str());
2355 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(nodali[1]-nodali[0])));
2360 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !";
2361 throw INTERP_KERNEL::Exception(oss.str().c_str());
2367 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2369 std::fill(ptToFill,ptToFill+spaceDim,0.);
2370 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2373 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2375 if(*nodal==-1) continue;
2376 if(*nodal>=0 && *nodal<nbOfNodes)
2378 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2383 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2384 throw INTERP_KERNEL::Exception(oss.str().c_str());
2388 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./nbOfNod));
2391 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !";
2392 throw INTERP_KERNEL::Exception(oss.str().c_str());
2397 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : at cell #" << i << " the nodal index array is invalid !";
2398 throw INTERP_KERNEL::Exception(oss.str().c_str());
2405 void MEDCoupling1DGTUMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
2407 int nbCells=getNumberOfCells();
2408 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
2409 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
2411 o2n=o2n->checkAndPreparePermutation();
2413 const int *o2nPtr=o2n->getPointer();
2414 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2415 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
2416 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
2417 newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1);
2418 newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx);
2420 int *newC=newConn->getPointer(),*newCI=newConnI->getPointer();
2421 for(int i=0;i<nbCells;i++)
2423 int newPos=o2nPtr[i];
2424 int sz=conni[i+1]-conni[i];
2429 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !";
2430 throw INTERP_KERNEL::Exception(oss.str().c_str());
2433 newConnI->computeOffsets2(); newCI=newConnI->getPointer();
2435 for(int i=0;i<nbCells;i++,conni++)
2437 int sz=conni[1]-conni[0];
2439 std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]);
2442 _conn_indx=newConnI;
2445 MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
2447 if(other->getType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED)
2448 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !");
2449 const MEDCoupling1DGTUMesh *otherC=static_cast<const MEDCoupling1DGTUMesh *>(other);
2450 return Merge1DGTUMeshes(this,otherC);
2453 MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
2455 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName().c_str(),getMeshDimension());
2456 ret->setCoords(getCoords());
2457 const int *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin();
2458 int nbCells=getNumberOfCells();//checkCoherency
2459 int geoType=(int)getCellModelEnum();
2460 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1);
2461 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::New(); cI->alloc(nbCells+1);
2462 int *cPtr=c->getPointer(),*ciPtr=cI->getPointer();
2464 for(int i=0;i<nbCells;i++,ciPtr++)
2466 int sz=nodalConnI[i+1]-nodalConnI[i];
2470 cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr);
2471 ciPtr[1]=ciPtr[0]+sz+1;
2475 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !";
2476 throw INTERP_KERNEL::Exception(oss.str().c_str());
2479 ret->setConnectivity(c,cI,true);
2484 * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes
2486 DataArrayInt *MEDCoupling1DGTUMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
2488 int nbOfCells=getNumberOfCells();
2489 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2490 ret->alloc(nbOfCells,1);
2495 void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
2497 stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
2498 stream << " Mesh dimension : " << getMeshDimension() << ".";
2500 { stream << " No coordinates set !"; return ; }
2501 if(!_coords->isAllocated())
2502 { stream << " Coordinates set but not allocated !"; return ; }
2503 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
2504 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
2506 try { checkCoherency(); } catch(INTERP_KERNEL::Exception& e)
2508 stream << std::endl << "Nodal connectivity NOT set properly !\n";
2512 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
2515 void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception)
2518 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
2519 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2521 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !");
2522 setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex());
2525 MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
2528 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
2529 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2531 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
2532 std::vector<const MEDCoupling1DGTUMesh *> ms(2);
2535 return Merge1DGTUMeshesOnSameCoords(ms);
2538 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
2541 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2542 ret->setCoords(_coords);
2543 DataArrayInt *c=0,*ci=0;
2544 MEDCouplingUMesh::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci);
2545 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2546 ret->setNodalConnectivity(c,ci);
2550 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
2553 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2554 ret->setCoords(_coords);
2555 DataArrayInt *c=0,*ci=0;
2556 MEDCouplingUMesh::ExtractFromIndexedArrays2(start,end,step,_conn,_conn_indx,c,ci);
2557 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2558 ret->setNodalConnectivity(c,ci);
2562 void MEDCoupling1DGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const throw(INTERP_KERNEL::Exception)
2564 int sz((int)nodeIdsInUse.size());
2565 int nbCells(getNumberOfCells());
2566 const int *w(_conn->begin()),*wi(_conn_indx->begin());
2567 for(int i=0;i<nbCells;i++,wi++)
2568 for(const int *pt=w+wi[0];pt!=w+wi[1];pt++)
2571 if(*pt>=0 && *pt<sz)
2572 nodeIdsInUse[*pt]=true;
2575 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeNodeIdsAlg : At cell #" << i << " presence of node id #" << *pt << " should be in [0," << sz << ") !";
2576 throw INTERP_KERNEL::Exception(oss.str().c_str());
2581 void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception)
2583 checkFullyDefined();
2584 int nbOfNodes=getNumberOfNodes();
2585 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
2586 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
2587 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
2588 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2589 int nbOfCells=getNumberOfCells();
2590 int nbOfEltsInRevNodal=0;
2591 for(int eltId=0;eltId<nbOfCells;eltId++)
2593 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2594 if(nbOfNodesPerCell>=0)
2596 for(int j=0;j<nbOfNodesPerCell;j++)
2598 int nodeId=conn[conni[eltId]+j];
2599 if(nodeId==-1) continue;
2600 if(nodeId>=0 && nodeId<nbOfNodes)
2602 nbOfEltsInRevNodal++;
2603 revNodalIndxPtr[nodeId+1]++;
2607 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
2608 throw INTERP_KERNEL::Exception(oss.str().c_str());
2614 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << "nodal connectivity is invalid !";
2615 throw INTERP_KERNEL::Exception(oss.str().c_str());
2618 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
2619 conn=_conn->begin();
2620 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
2621 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
2622 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
2623 for(int eltId=0;eltId<nbOfCells;eltId++)
2625 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2626 for(int j=0;j<nbOfNodesPerCell;j++)
2628 int nodeId=conn[conni[eltId]+j];
2630 *std::find_if(revNodalPtr+revNodalIndxPtr[nodeId],revNodalPtr+revNodalIndxPtr[nodeId+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
2635 void MEDCoupling1DGTUMesh::checkFullyDefined() const throw(INTERP_KERNEL::Exception)
2637 if(!((const DataArrayInt *)_conn) || !((const DataArrayInt *)_conn_indx) || !((const DataArrayDouble *)_coords))
2638 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined.");
2641 bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
2643 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !");
2646 void MEDCoupling1DGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
2649 double time=getTime(it,order);
2650 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
2652 littleStrings.push_back(getName());
2653 littleStrings.push_back(getDescription());
2654 littleStrings.push_back(getTimeUnit());
2656 std::vector<std::string> littleStrings2,littleStrings3,littleStrings4;
2657 if((const DataArrayDouble *)_coords)
2658 _coords->getTinySerializationStrInformation(littleStrings2);
2659 if((const DataArrayInt *)_conn)
2660 _conn->getTinySerializationStrInformation(littleStrings3);
2661 if((const DataArrayInt *)_conn_indx)
2662 _conn_indx->getTinySerializationStrInformation(littleStrings4);
2663 int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size()),sz2((int)littleStrings4.size());
2664 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
2665 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
2666 littleStrings.insert(littleStrings.end(),littleStrings4.begin(),littleStrings4.end());
2668 tinyInfo.push_back(getCellModelEnum());
2669 tinyInfo.push_back(it);
2670 tinyInfo.push_back(order);
2671 std::vector<int> tinyInfo2,tinyInfo3,tinyInfo4;
2672 if((const DataArrayDouble *)_coords)
2673 _coords->getTinySerializationIntInformation(tinyInfo2);
2674 if((const DataArrayInt *)_conn)
2675 _conn->getTinySerializationIntInformation(tinyInfo3);
2676 if((const DataArrayInt *)_conn_indx)
2677 _conn_indx->getTinySerializationIntInformation(tinyInfo4);
2678 int sz3((int)tinyInfo2.size()),sz4((int)tinyInfo3.size()),sz5((int)tinyInfo4.size());
2679 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3); tinyInfo.push_back(sz4); tinyInfo.push_back(sz5);
2680 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
2681 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
2682 tinyInfo.insert(tinyInfo.end(),tinyInfo4.begin(),tinyInfo4.end());
2684 tinyInfoD.push_back(time);
2687 void MEDCoupling1DGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
2689 std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+tinyInfo[6]);
2690 std::vector<int> tinyInfo1(tinyInfo.begin()+9+tinyInfo[6],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]);
2691 std::vector<int> tinyInfo12(tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]+tinyInfo[8]);
2692 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(DataArrayInt::New()); p1->resizeForUnserialization(tinyInfo1);
2693 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(DataArrayInt::New()); p2->resizeForUnserialization(tinyInfo12);
2694 std::vector<const DataArrayInt *> v(2); v[0]=p1; v[1]=p2;
2695 p2=DataArrayInt::Aggregate(v);
2696 a2->resizeForUnserialization(tinyInfo2);
2697 a1->alloc(p2->getNbOfElems(),1);
2700 void MEDCoupling1DGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
2703 if((const DataArrayInt *)_conn)
2704 if(_conn->isAllocated())
2705 sz=_conn->getNbOfElems();
2706 if((const DataArrayInt *)_conn_indx)
2707 if(_conn_indx->isAllocated())
2708 sz+=_conn_indx->getNbOfElems();
2709 a1=DataArrayInt::New();
2711 int *work(a1->getPointer());
2712 if(sz!=0 && (const DataArrayInt *)_conn)
2713 work=std::copy(_conn->begin(),_conn->end(),a1->getPointer());
2714 if(sz!=0 && (const DataArrayInt *)_conn_indx)
2715 std::copy(_conn_indx->begin(),_conn_indx->end(),work);
2717 if((const DataArrayDouble *)_coords)
2718 if(_coords->isAllocated())
2719 sz=_coords->getNbOfElems();
2720 a2=DataArrayDouble::New();
2722 if(sz!=0 && (const DataArrayDouble *)_coords)
2723 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
2726 void MEDCoupling1DGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
2727 const std::vector<std::string>& littleStrings)
2729 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
2730 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
2731 setName(littleStrings[0].c_str());
2732 setDescription(littleStrings[1].c_str());
2733 setTimeUnit(littleStrings[2].c_str());
2734 setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
2735 int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]),sz4(tinyInfo[7]),sz5(tinyInfo[8]);
2737 _coords=DataArrayDouble::New();
2738 std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+sz3);
2739 _coords->resizeForUnserialization(tinyInfo2);
2740 std::copy(a2->begin(),a2->end(),_coords->getPointer());
2741 _conn=DataArrayInt::New();
2742 std::vector<int> tinyInfo3(tinyInfo.begin()+9+sz3,tinyInfo.begin()+9+sz3+sz4);
2743 _conn->resizeForUnserialization(tinyInfo3);
2744 std::copy(a1->begin(),a1->begin()+_conn->getNbOfElems(),_conn->getPointer());
2745 _conn_indx=DataArrayInt::New();
2746 std::vector<int> tinyInfo4(tinyInfo.begin()+9+sz3+sz4,tinyInfo.begin()+9+sz3+sz4+sz5);
2747 _conn_indx->resizeForUnserialization(tinyInfo4);
2748 std::copy(a1->begin()+_conn->getNbOfElems(),a1->end(),_conn_indx->getPointer());
2749 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
2750 _coords->finishUnserialization(tinyInfo2,littleStrings2);
2751 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
2752 _conn->finishUnserialization(tinyInfo3,littleStrings3);
2753 std::vector<std::string> littleStrings4(littleStrings.begin()+3+sz0+sz1,littleStrings.begin()+3+sz0+sz1+sz2);
2754 _conn_indx->finishUnserialization(tinyInfo4,littleStrings4);
2758 * Finds nodes not used in any cell and returns an array giving a new id to every node
2759 * by excluding the unused nodes, for which the array holds -1. The result array is
2760 * a mapping in "Old to New" mode.
2761 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
2762 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
2763 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
2764 * if the node is unused or a new id else. The caller is to delete this
2765 * array using decrRef() as it is no more needed.
2766 * \throw If the coordinates array is not set.
2767 * \throw If the nodal connectivity of cells is not defined.
2768 * \throw If the nodal connectivity includes an invalid id.
2770 DataArrayInt *MEDCoupling1DGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception)
2773 int nbOfNodes=getNumberOfNodes();
2774 int nbOfCells=getNumberOfCells();//checkCoherency
2775 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2776 ret->alloc(nbOfNodes,1);
2777 int *traducer=ret->getPointer();
2778 std::fill(traducer,traducer+nbOfNodes,-1);
2779 const int *conn=_conn->begin(),*conni(_conn_indx->begin());
2780 for(int i=0;i<nbOfCells;i++,conni++)
2782 int nbNodesPerCell=conni[1]-conni[0];
2783 for(int j=0;j<nbNodesPerCell;j++)
2785 int nodeId=conn[conni[0]+j];
2786 if(nodeId==-1) continue;
2787 if(nodeId>=0 && nodeId<nbOfNodes)
2791 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << nodeId << " not in [0," << nbOfNodes << ") !";
2792 throw INTERP_KERNEL::Exception(oss.str().c_str());
2796 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
2797 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
2802 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
2803 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
2804 * This method is a generalization of shiftNodeNumbersInConn().
2805 * \warning This method performs no check of validity of new ids. **Use it with care !**
2806 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
2807 * this->getNumberOfNodes(), in "Old to New" mode.
2808 * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
2809 * \throw If the nodal connectivity of cells is not defined.
2811 void MEDCoupling1DGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
2813 getNumberOfCells();//only to check that all is well defined.
2815 int nbElemsIn=getNumberOfNodes();
2816 int nbOfTuples=_conn->getNumberOfTuples();
2817 int *pt=_conn->getPointer();
2818 for(int i=0;i<nbOfTuples;i++,pt++)
2820 if(*pt==-1) continue;
2821 if(*pt>=0 && *pt<nbElemsIn)
2822 *pt=newNodeNumbersO2N[*pt];
2825 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
2826 throw INTERP_KERNEL::Exception(oss.str().c_str());
2829 _conn->declareAsNew();
2835 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
2836 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
2837 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
2838 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
2840 * \param [in] begin input start of array of node ids.
2841 * \param [in] end input end of array of node ids.
2842 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
2843 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
2845 void MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
2847 int nbOfCells=getNumberOfCells();
2848 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
2850 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
2851 std::vector<bool> fastFinder(sz,false);
2852 for(const int *work=begin;work!=end;work++)
2853 if(*work>=0 && *work<sz)
2854 fastFinder[*work]=true;
2855 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2856 for(int i=0;i<nbOfCells;i++,conni++)
2858 int ref=0,nbOfHit=0;
2859 int nbNodesPerCell=conni[1]-conni[0];
2860 if(nbNodesPerCell>=0)
2862 for(int j=0;j<nbNodesPerCell;j++)
2864 int nodeId=conn[conni[0]+j];
2868 if(fastFinder[nodeId])
2875 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !";
2876 throw INTERP_KERNEL::Exception(oss.str().c_str());
2878 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
2879 cellIdsKept->pushBackSilent(i);
2881 cellIdsKeptArr=cellIdsKept.retn();
2884 void MEDCoupling1DGTUMesh::allocateCells(int nbOfCells) throw(INTERP_KERNEL::Exception)
2887 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !");
2888 _conn=DataArrayInt::New();
2889 _conn->reserve(nbOfCells*3);
2890 _conn_indx=DataArrayInt::New();
2891 _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0);
2896 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
2898 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
2899 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
2900 * \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
2901 * attached to \a this.
2902 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
2904 void MEDCoupling1DGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) throw(INTERP_KERNEL::Exception)
2906 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
2907 DataArrayInt *c(_conn),*c2(_conn_indx);
2911 if(pos==c->getNumberOfTuples())
2913 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
2914 c2->pushBackSilent(pos+sz);
2918 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !";
2919 throw INTERP_KERNEL::Exception(oss.str().c_str());
2923 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !");
2926 void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex) throw(INTERP_KERNEL::Exception)
2929 nodalConn->incrRef();
2932 nodalConnIndex->incrRef();
2933 _conn_indx=nodalConnIndex;
2938 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
2940 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivity() const throw(INTERP_KERNEL::Exception)
2942 const DataArrayInt *ret(_conn);
2943 return const_cast<DataArrayInt *>(ret);
2947 * \return DataArrayInt * - the internal reference to the nodal connectivity index. The caller is not reponsible to deallocate it.
2949 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const throw(INTERP_KERNEL::Exception)
2951 const DataArrayInt *ret(_conn_indx);
2952 return const_cast<DataArrayInt *>(ret);
2956 * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here".
2957 * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity).
2958 * 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.
2960 * 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.
2962 * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal
2963 * connectivity arrays are different (false)
2964 * \return a new object to be managed by the caller.
2966 * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked
2968 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const throw(INTERP_KERNEL::Exception)
2970 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2971 DataArrayInt *nc=0,*nci=0;
2972 isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci);
2973 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ncs(nc),ncis(nci);
2974 ret->_conn=ncs; ret->_conn_indx=ncis;
2975 ret->setCoords(getCoords());
2980 * This method allows to compute, if needed, the packed nodal connectivity pair.
2981 * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges convered by nodal connectivity index array.
2982 * 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.
2984 * 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)
2985 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
2987 * 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
2990 * This method return 3 elements.
2991 * \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
2992 * this pointer can be seen as a new object, that is to managed by the caller.
2993 * \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
2994 * this pointer can be seen as a new object, that is to managed by the caller.
2995 * \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
2996 * output parameters are newly created objects.
2998 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
3000 bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const throw(INTERP_KERNEL::Exception)
3002 if(isPacked())//performs the checkCoherency
3004 const DataArrayInt *c0(_conn),*c1(_conn_indx);
3005 nodalConn=const_cast<DataArrayInt *>(c0); nodalConnIndx=const_cast<DataArrayInt *>(c1);
3006 nodalConn->incrRef(); nodalConnIndx->incrRef();
3009 int bg=_conn_indx->front(),end=_conn_indx->back();
3010 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nc(_conn->selectByTupleId2(bg,end,1));
3011 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nci(_conn_indx->deepCpy());
3012 nci->applyLin(1,-bg);
3013 nodalConn=nc.retn(); nodalConnIndx=nci.retn();
3018 * 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)
3019 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3020 * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned.
3021 * \return bool - true if \a this looks packed, false is not.
3023 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
3025 bool MEDCoupling1DGTUMesh::isPacked() const throw(INTERP_KERNEL::Exception)
3028 return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples();
3031 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2) throw(INTERP_KERNEL::Exception)
3033 std::vector<const MEDCoupling1DGTUMesh *> tmp(2);
3034 tmp[0]=const_cast<MEDCoupling1DGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1DGTUMesh *>(mesh2);
3035 return Merge1DGTUMeshes(tmp);
3038 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
3040 std::size_t sz=a.size();
3042 return Merge1DGTUMeshesLL(a);
3043 for(std::size_t ii=0;ii<sz;ii++)
3046 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::Merge1DGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
3047 throw INTERP_KERNEL::Exception(oss.str().c_str());
3049 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
3050 for(std::size_t ii=0;ii<sz;ii++)
3051 if(&(a[ii]->getCellModel())!=cm)
3052 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !");
3053 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > bb(sz);
3054 std::vector< const MEDCoupling1DGTUMesh * > aa(sz);
3056 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
3058 const MEDCoupling1DGTUMesh *cur=a[i];
3059 const DataArrayDouble *coo=cur->getCoords();
3061 spaceDim=coo->getNumberOfComponents();
3064 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !");
3065 for(std::size_t i=0;i<sz;i++)
3067 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
3070 return Merge1DGTUMeshesLL(aa);
3074 * \throw If presence of a null instance in the input vector \a a.
3075 * \throw If a is empty
3077 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
3080 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !");
3081 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3083 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !");
3084 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
3085 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3086 int nbOfCells=(*it)->getNumberOfCells();
3087 const DataArrayDouble *coords=(*it)->getCoords();
3088 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3090 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3091 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3093 for(int i=1;it!=a.end();i++,it++)
3096 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !");
3097 if(cm!=&((*it)->getCellModel()))
3098 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3099 (*it)->getNumberOfCells();//to check that all is OK
3100 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3101 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3102 if(coords!=(*it)->getCoords())
3103 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !");
3105 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3106 ret->setCoords(coords);
3107 ret->_conn=DataArrayInt::Aggregate(ncs);
3108 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3113 * 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)
3115 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
3118 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : input array must be NON EMPTY !");
3119 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
3120 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3121 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3122 std::vector<int> nbNodesPerElt(a.size());
3123 int nbOfCells=(*it)->getNumberOfCells();
3125 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3126 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3128 int prevNbOfNodes=(*it)->getNumberOfNodes();
3129 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3131 for(int i=1;it!=a.end();i++,it++)
3133 if(cm!=&((*it)->getCellModel()))
3134 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3135 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3136 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3137 nbOfCells+=(*it)->getNumberOfCells();
3138 nbNodesPerElt[i]=nbNodesPerElt[i-1]+prevNbOfNodes;
3139 prevNbOfNodes=(*it)->getNumberOfNodes();
3141 std::vector<const MEDCouplingPointSet *> aps(a.size());
3142 std::copy(a.begin(),a.end(),aps.begin());
3143 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
3144 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3145 ret->setCoords(pts);
3146 ret->_conn=AggregateNodalConnAndShiftNodeIds(ncs,nbNodesPerElt);
3147 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3151 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception)
3153 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
3154 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1,tmp2;
3155 const DataArrayInt *nodalConn(_conn),*nodalConnI(_conn_indx);
3158 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
3166 tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
3170 ret->_conn_indx=tmp2;
3174 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
3175 ret->setCoords(coords);
3178 ret->setCoords(_coords);
3183 * This method aggregate the bbox of each cell and put it into bbox parameter.
3185 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
3187 * \throw If \a this is not fully set (coordinates and connectivity).
3188 * \throw If a cell in \a this has no valid nodeId.
3190 DataArrayDouble *MEDCoupling1DGTUMesh::getBoundingBoxForBBTree() const
3192 checkFullyDefined();
3193 int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes());
3194 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
3195 double *bbox(ret->getPointer());
3196 for(int i=0;i<nbOfCells*spaceDim;i++)
3198 bbox[2*i]=std::numeric_limits<double>::max();
3199 bbox[2*i+1]=-std::numeric_limits<double>::max();
3201 const double *coordsPtr(_coords->getConstPointer());
3202 const int *conn(_conn->getConstPointer()),*connI(_conn_indx->getConstPointer());
3203 for(int i=0;i<nbOfCells;i++)
3205 int offset=connI[i];
3206 int nbOfNodesForCell(connI[i+1]-offset),kk(0);
3207 for(int j=0;j<nbOfNodesForCell;j++)
3209 int nodeId=conn[offset+j];
3210 if(nodeId>=0 && nodeId<nbOfNodes)
3212 for(int k=0;k<spaceDim;k++)
3214 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
3215 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
3222 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
3223 throw INTERP_KERNEL::Exception(oss.str().c_str());
3229 std::vector<int> MEDCoupling1DGTUMesh::BuildAPolygonFromParts(const std::vector< std::vector<int> >& parts) throw(INTERP_KERNEL::Exception)
3231 std::vector<int> ret;
3234 ret.insert(ret.end(),parts[0].begin(),parts[0].end());
3235 int ref(ret.back());
3236 std::size_t sz(parts.size()),nbh(1);
3237 std::vector<bool> b(sz,true); b[0]=false;
3241 for(;i<sz;i++) if(b[i] && parts[i].front()==ref) { ret.insert(ret.end(),parts[i].begin()+1,parts[i].end()); nbh++; break; }
3245 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::BuildAPolygonFromParts : the input vector is not a part of a single polygon !");
3247 if(ret.back()==ret.front())
3253 * This method performs an aggregation of \a nodalConns (as DataArrayInt::Aggregate does) but in addition of that a shift is applied on the
3254 * values contained in \a nodalConns using corresponding offset specified in input \a offsetInNodeIdsPerElt.
3255 * But it also manage the values -1, that have a semantic in MEDCoupling1DGTUMesh class (separator for polyhedron).
3257 * \param [in] nodalConns - a list of nodal connectivity arrays same size than \a offsetInNodeIdsPerElt.
3258 * \param [in] offsetInNodeIdsPerElt - a list of offsets to apply.
3259 * \return DataArrayInt * - A new object (to be managed by the caller) that is the result of the aggregation.
3260 * \throw If \a nodalConns or \a offsetInNodeIdsPerElt are empty.
3261 * \throw If \a nodalConns and \a offsetInNodeIdsPerElt have not the same size.
3262 * \throw If presence of null pointer in \a nodalConns.
3263 * \throw If presence of not allocated or array with not exactly one component in \a nodalConns.
3265 DataArrayInt *MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds(const std::vector<const DataArrayInt *>& nodalConns, const std::vector<int>& offsetInNodeIdsPerElt) throw(INTERP_KERNEL::Exception)
3267 std::size_t sz1(nodalConns.size()),sz2(offsetInNodeIdsPerElt.size());
3269 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : input vectors do not have the same size !");
3271 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : empty vectors in input !");
3273 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++)
3276 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of null pointer in input vector !");
3277 if(!(*it)->isAllocated())
3278 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of non allocated array in input vector !");
3279 if((*it)->getNumberOfComponents()!=1)
3280 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of array with not exactly one component !");
3281 nbOfTuples+=(*it)->getNumberOfTuples();
3283 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
3284 int *pt=ret->getPointer();
3286 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++,i++)
3288 int curNbt=(*it)->getNumberOfTuples();
3289 const int *inPt=(*it)->begin();
3290 int offset=offsetInNodeIdsPerElt[i];
3291 for(int j=0;j<curNbt;j++,pt++)
3302 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception)
3305 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh is null !");
3306 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
3308 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh must have exactly one geometric type !");
3309 int geoType((int)*gts.begin());
3310 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(m->getName().c_str(),*gts.begin()));
3311 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription().c_str());
3312 int nbCells(m->getNumberOfCells());
3313 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
3314 conn->alloc(m->getMeshLength()-nbCells,1); connI->alloc(nbCells+1,1);
3315 int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
3316 const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
3317 for(int i=0;i<nbCells;i++,ciin++,ci++)
3319 if(cin[ciin[0]]==geoType)
3321 if(ciin[1]-ciin[0]>=1)
3323 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
3324 ci[1]=ci[0]+ciin[1]-ciin[0]-1;
3328 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 !";
3329 throw INTERP_KERNEL::Exception(oss.str().c_str());
3334 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 !";
3335 throw INTERP_KERNEL::Exception(oss.str().c_str());
3338 ret->setNodalConnectivity(conn,connI);