1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (CEA/DEN)
21 #include "MEDCoupling1GTUMesh.hxx"
22 #include "MEDCouplingUMesh.hxx"
23 #include "MEDCouplingFieldDouble.hxx"
25 #include "SplitterTetra.hxx"
27 using namespace ParaMEDMEM;
29 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh()
33 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):_cm(&cm)
38 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const MEDCoupling1GTUMesh& other, bool recDeepCpy):MEDCouplingPointSet(other,recDeepCpy),_cm(other._cm)
42 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
44 if(type==INTERP_KERNEL::NORM_ERROR)
45 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
46 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
48 return MEDCoupling1SGTUMesh::New(name,type);
50 return MEDCoupling1DGTUMesh::New(name,type);
53 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception)
56 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh is null !");
57 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
59 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh must have exactly one geometric type !");
60 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*gts.begin());
62 return MEDCoupling1SGTUMesh::New(m);
64 return MEDCoupling1DGTUMesh::New(m);
67 const INTERP_KERNEL::CellModel& MEDCoupling1GTUMesh::getCellModel() const throw(INTERP_KERNEL::Exception)
72 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getCellModelEnum() const throw(INTERP_KERNEL::Exception)
74 return _cm->getEnum();
77 int MEDCoupling1GTUMesh::getMeshDimension() const
79 return (int)_cm->getDimension();
83 * This method returns a newly allocated array containing cell ids (ascendingly sorted) whose geometric type are equal to type.
84 * This method does not throw exception if geometric type \a type is not in \a this.
85 * This method throws an INTERP_KERNEL::Exception if meshdimension of \b this is not equal to those of \b type.
86 * The coordinates array is not considered here.
88 * \param [in] type the geometric type
89 * \return cell ids in this having geometric type \a type.
91 DataArrayInt *MEDCoupling1GTUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception)
93 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
94 if(type==getCellModelEnum())
95 ret->alloc(getNumberOfCells(),1);
103 * Returns nb of cells having the geometric type \a type. No throw if no cells in \a this has the geometric type \a type.
105 int MEDCoupling1GTUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
107 return type==getCellModelEnum()?getNumberOfCells():0;
111 * Returns a type of a cell by its id.
112 * \param [in] cellId - the id of the cell of interest.
113 * \return INTERP_KERNEL::NormalizedCellType - enumeration item describing the cell type.
114 * \throw If \a cellId is invalid. Valid range is [0, \a this->getNumberOfCells() ).
116 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getTypeOfCell(int cellId) const
118 if(cellId>=0 && cellId<getNumberOfCells())
119 return getCellModelEnum();
120 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::getTypeOfCell : Requesting type of cell #" << cellId << " but it should be in [0," << getNumberOfCells() << ") !";
121 throw INTERP_KERNEL::Exception(oss.str().c_str());
125 * Returns a set of all cell types available in \a this mesh.
126 * \return std::set<INTERP_KERNEL::NormalizedCellType> - the set of cell types.
127 * \warning this method does not throw any exception even if \a this is not defined.
129 std::set<INTERP_KERNEL::NormalizedCellType> MEDCoupling1GTUMesh::getAllGeoTypes() const
131 std::set<INTERP_KERNEL::NormalizedCellType> ret;
132 ret.insert(getCellModelEnum());
137 * This method expects that \a this is sorted by types. If not an exception will be thrown.
138 * This method returns in the same format as code (see MEDCouplingUMesh::checkTypeConsistencyAndContig or MEDCouplingUMesh::splitProfilePerType) how
139 * \a this is composed in cell types.
140 * The returned array is of size 3*n where n is the number of different types present in \a this.
141 * For every k in [0,n] ret[3*k+2]==-1 because it has no sense here.
142 * This parameter is kept only for compatibility with other methode listed above.
144 std::vector<int> MEDCoupling1GTUMesh::getDistributionOfTypes() const throw(INTERP_KERNEL::Exception)
146 std::vector<int> ret(3);
147 ret[0]=(int)getCellModelEnum(); ret[1]=getNumberOfCells(); ret[2]=-1;
152 * This method is the opposite of MEDCouplingUMesh::checkTypeConsistencyAndContig method. Given a list of cells in \a profile it returns a list of sub-profiles sorted by geo type.
153 * The result is put in the array \a idsPerType. In the returned parameter \a code, foreach i \a code[3*i+2] refers (if different from -1) to a location into the \a idsPerType.
154 * This method has 1 input \a profile and 3 outputs \a code \a idsInPflPerType and \a idsPerType.
156 * \param [out] code is a vector of size 3*n where n is the number of different geometric type in \a this \b reduced to the profile \a profile. \a code has exactly the same semantic than in MEDCouplingUMesh::checkTypeConsistencyAndContig method.
157 * \param [out] idsInPflPerType is a vector of size of different geometric type in the subpart defined by \a profile of \a this ( equal to \a code.size()/3). For each i,
158 * \a idsInPflPerType[i] stores the tuple ids in \a profile that correspond to the geometric type code[3*i+0]
159 * \param [out] idsPerType is a vector of size of different sub profiles needed to be defined to represent the profile \a profile for a given geometric type.
160 * This vector can be empty in case of all geometric type cells are fully covered in ascending in the given input \a profile.
162 * \warning for performance reasons no deep copy will be performed, if \a profile can been used as this in output parameters \a idsInPflPerType and \a idsPerType.
164 * \throw if \a profile has not exactly one component. It throws too, if \a profile contains some values not in [0,getNumberOfCells()) or if \a this is not fully defined
167 * - Before \a this has 3 cells \a profile contains [0,1,2]
168 * - After \a code contains [NORM_...,nbCells,-1], \a idsInPflPerType [[0,1,2]] and \a idsPerType is empty <br>
171 * - Before \a this has 3 cells \a profile contains [1,2]
172 * - After \a code contains [NORM_...,nbCells,0], \a idsInPflPerType [[0,1]] and \a idsPerType is [[1,2]] <br>
175 void MEDCoupling1GTUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
178 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile is NULL !");
179 if(profile->getNumberOfComponents()!=1)
180 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile should have exactly one component !");
181 int nbTuples=profile->getNumberOfTuples();
182 int nbOfCells=getNumberOfCells();
183 code.resize(3); idsInPflPerType.resize(1);
184 code[0]=(int)getCellModelEnum(); code[1]=nbTuples;
185 idsInPflPerType.resize(1);
186 if(profile->isIdentity() && nbTuples==nbOfCells)
189 idsInPflPerType[0]=const_cast<DataArrayInt *>(profile); idsInPflPerType[0]->incrRef();
194 profile->checkAllIdsInRange(0,nbOfCells);
195 idsPerType.resize(1);
196 idsPerType[0]=const_cast<DataArrayInt *>(profile); idsPerType[0]->incrRef();
197 idsInPflPerType[0]=DataArrayInt::Range(0,nbTuples,1);
201 * This method tries to minimize at most the number of deep copy.
202 * So if \a idsPerType is not empty it can be returned directly (without copy, but with ref count incremented) in return.
204 * \sa MEDCouplingUMesh::checkTypeConsistencyAndContig
206 DataArrayInt *MEDCoupling1GTUMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
208 int nbOfCells=getNumberOfCells();
210 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : invalid input code should be exactly of size 3 !");
211 if(code[0]!=(int)getCellModelEnum())
213 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : Mismatch of geometric type ! Asking for " << code[0] << " whereas the geometric type is \a this is " << getCellModelEnum() << " (" << _cm->getRepr() << ") !";
214 throw INTERP_KERNEL::Exception(oss.str().c_str());
218 if(code[1]==nbOfCells)
222 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : mismatch between the number of cells in this (" << nbOfCells << ") and the number of non profile (" << code[1] << ") !";
223 throw INTERP_KERNEL::Exception(oss.str().c_str());
227 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : single geo type mesh ! 0 or -1 is expected at pos #2 of input code !");
228 if(idsPerType.size()!=1)
229 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input code points to DataArrayInt #0 whereas the size of idsPerType is not equal to 1 !");
230 const DataArrayInt *pfl=idsPerType[0];
232 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : the input code points to a NULL DataArrayInt at rank 0 !");
233 if(pfl->getNumberOfComponents()!=1)
234 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input profile should have exactly one component !");
235 pfl->checkAllIdsInRange(0,nbOfCells);
237 return const_cast<DataArrayInt *>(pfl);
240 void MEDCoupling1GTUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception)
242 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
243 m->writeVTKLL(ofs,cellData,pointData);
246 std::string MEDCoupling1GTUMesh::getVTKDataSetType() const throw(INTERP_KERNEL::Exception)
248 return std::string("UnstructuredGrid");
251 std::size_t MEDCoupling1GTUMesh::getHeapMemorySize() const
253 return MEDCouplingPointSet::getHeapMemorySize();
256 bool MEDCoupling1GTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
258 if(!MEDCouplingPointSet::isEqualIfNotWhy(other,prec,reason))
261 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualIfNotWhy : input other pointer is null !");
262 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
265 reason="mesh given in input is not castable in MEDCouplingSGTUMesh !";
270 reason="mismatch in geometric type !";
276 bool MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
278 if(!MEDCouplingPointSet::isEqualWithoutConsideringStr(other,prec))
281 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
282 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
290 void MEDCoupling1GTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
292 MEDCouplingPointSet::checkCoherency();
295 DataArrayDouble *MEDCoupling1GTUMesh::getBarycenterAndOwner() const
297 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
298 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=m->getBarycenterAndOwner();
302 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureField(bool isAbs) const
304 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
305 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureField(isAbs);
310 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureFieldOnNode(bool isAbs) const
312 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
313 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureFieldOnNode(isAbs);
321 int MEDCoupling1GTUMesh::getCellContainingPoint(const double *pos, double eps) const
323 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
324 return m->getCellContainingPoint(pos,eps);
327 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::buildOrthogonalField() const
329 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
330 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->buildOrthogonalField();
335 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const double *bbox, double eps) const
337 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
338 return m->getCellsInBoundingBox(bbox,eps);
341 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps)
343 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
344 return m->getCellsInBoundingBox(bbox,eps);
347 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const
349 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
350 return m->buildFacePartOfMySelfNode(start,end,fullyIn);
353 DataArrayInt *MEDCoupling1GTUMesh::findBoundaryNodes() const
355 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
356 return m->findBoundaryNodes();
359 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildBoundaryMesh(bool keepCoords) const
361 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
362 return m->buildBoundaryMesh(keepCoords);
365 void MEDCoupling1GTUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const throw(INTERP_KERNEL::Exception)
367 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
368 m->findCommonCells(compType,startCellId,commonCellsArr,commonCellsIArr);
371 int MEDCoupling1GTUMesh::getNodalConnectivityLength() const throw(INTERP_KERNEL::Exception)
373 const DataArrayInt *c1(getNodalConnectivity());
375 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : no connectivity set !");
376 if(c1->getNumberOfComponents()!=1)
377 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array set must have exactly one component !");
378 if(!c1->isAllocated())
379 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array must be allocated !");
380 return c1->getNumberOfTuples();
384 * This method aggregates all the meshes in \a parts to put them in a single unstructured mesh (those returned).
385 * The order of cells is the returned instance is those in the order of instances in \a parts.
387 * \param [in] parts - all not null parts of single geo type meshes to be aggreagated having the same mesh dimension and same coordinates.
388 * \return MEDCouplingUMesh * - new object to be dealt by the caller.
390 * \throw If one element is null in \a parts.
391 * \throw If not all the parts do not have the same mesh dimension.
392 * \throw If not all the parts do not share the same coordinates.
393 * \throw If not all the parts have their connectivity set properly.
394 * \throw If \a parts is empty.
396 MEDCouplingUMesh *MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh(const std::vector< const MEDCoupling1GTUMesh *>& parts) throw(INTERP_KERNEL::Exception)
399 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : input parts vector is empty !");
400 const MEDCoupling1GTUMesh *firstPart(parts[0]);
402 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : the first instance in input parts is null !");
403 const DataArrayDouble *coords(firstPart->getCoords());
404 int meshDim(firstPart->getMeshDimension());
405 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret(MEDCouplingUMesh::New(firstPart->getName().c_str(),meshDim)); ret->setDescription(firstPart->getDescription().c_str());
406 ret->setCoords(coords);
407 int nbOfCells(0),connSize(0);
408 for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
411 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of null pointer in input vector !");
412 if((*it)->getMeshDimension()!=meshDim)
413 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances in input vector must have same mesh dimension !");
414 if((*it)->getCoords()!=coords)
415 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances must share the same coordinates pointer !");
416 nbOfCells+=(*it)->getNumberOfCells();
417 connSize+=(*it)->getNodalConnectivityLength();
419 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
420 connI->alloc(nbOfCells+1,1); conn->alloc(connSize+nbOfCells,1);
421 int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
422 for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
424 int curNbCells((*it)->getNumberOfCells());
425 int geoType((int)(*it)->getCellModelEnum());
426 const int *cinPtr((*it)->getNodalConnectivity()->begin());
427 const MEDCoupling1SGTUMesh *ps(dynamic_cast<const MEDCoupling1SGTUMesh *>(*it));
428 const MEDCoupling1DGTUMesh *pd(dynamic_cast<const MEDCoupling1DGTUMesh *>(*it));
431 int nNodesPerCell(ps->getNumberOfNodesPerCell());
432 for(int i=0;i<curNbCells;i++,ci++,cinPtr+=nNodesPerCell)
435 c=std::copy(cinPtr,cinPtr+nNodesPerCell,c);
436 ci[1]=ci[0]+nNodesPerCell+1;
441 const int *ciinPtr(pd->getNodalConnectivityIndex()->begin());
442 for(int i=0;i<curNbCells;i++,ci++,ciinPtr++)
445 c=std::copy(cinPtr+ciinPtr[0],cinPtr+ciinPtr[1],c);
446 ci[1]=ci[0]+ciinPtr[1]-ciinPtr[0]+1;
450 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of instance which type is not in [MEDCoupling1SGTUMesh,MEDCoupling1DGTUMesh] !");
452 ret->setConnectivity(conn,connI,true);
458 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const MEDCoupling1SGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
462 const DataArrayInt *c(other._conn);
468 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
472 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh()
476 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New()
478 return new MEDCoupling1SGTUMesh;
481 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
483 if(type==INTERP_KERNEL::NORM_ERROR)
484 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
485 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
488 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New : the input geometric type " << cm.getRepr() << " is dynamic ! Only static types are allowed here !";
489 throw INTERP_KERNEL::Exception(oss.str().c_str());
491 return new MEDCoupling1SGTUMesh(name,cm);
494 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception)
497 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh is null !");
498 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
500 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh must have exactly one geometric type !");
501 int geoType((int)*gts.begin());
502 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(m->getName().c_str(),*gts.begin()));
503 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription().c_str());
504 int nbCells(m->getNumberOfCells());
505 int nbOfNodesPerCell(ret->getNumberOfNodesPerCell());
506 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()); conn->alloc(nbCells*nbOfNodesPerCell,1);
507 int *c(conn->getPointer());
508 const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
509 for(int i=0;i<nbCells;i++,ciin++)
511 if(cin[ciin[0]]==geoType)
513 if(ciin[1]-ciin[0]==nbOfNodesPerCell+1)
514 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
517 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m) : something is wrong in the input mesh at cell #" << i << " ! The size of cell is not those expected (" << nbOfNodesPerCell << ") !";
518 throw INTERP_KERNEL::Exception(oss.str().c_str());
523 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m) : something is wrong in the input mesh at cell #" << i << " ! The geometric type is not those expected !";
524 throw INTERP_KERNEL::Exception(oss.str().c_str());
527 ret->setNodalConnectivity(conn);
531 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::clone(bool recDeepCpy) const
533 return new MEDCoupling1SGTUMesh(*this,recDeepCpy);
537 * This method behaves mostly like MEDCoupling1SGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
538 * The coordinates are shared between \a this and the returned instance.
540 * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
541 * \sa MEDCoupling1SGTUMesh::deepCpy
543 MEDCouplingPointSet *MEDCoupling1SGTUMesh::deepCpyConnectivityOnly() const throw(INTERP_KERNEL::Exception)
546 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(clone(false));
547 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy());
548 ret->setNodalConnectivity(c);
552 void MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception)
555 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
556 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
558 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1SGTUMesh instance !");
559 setNodalConnectivity(otherC->getNodalConnectivity());
562 void MEDCoupling1SGTUMesh::updateTime() const
564 MEDCoupling1GTUMesh::updateTime();
565 const DataArrayInt *c(_conn);
570 std::size_t MEDCoupling1SGTUMesh::getHeapMemorySize() const
573 const DataArrayInt *c(_conn);
575 ret+=c->getHeapMemorySize();
576 return MEDCoupling1GTUMesh::getHeapMemorySize()+ret;
579 MEDCouplingMesh *MEDCoupling1SGTUMesh::deepCpy() const
584 bool MEDCoupling1SGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
587 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualIfNotWhy : input other pointer is null !");
588 std::ostringstream oss; oss.precision(15);
589 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
592 reason="mesh given in input is not castable in MEDCoupling1SGTUMesh !";
595 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
597 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
602 reason="in connectivity of single static geometric type exactly one among this and other is null !";
605 if(!c1->isEqualIfNotWhy(*c2,reason))
607 reason.insert(0,"Nodal connectivity DataArrayInt differ : ");
613 bool MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
616 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
617 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
620 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
622 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
627 if(!c1->isEqualWithoutConsideringStr(*c2))
632 void MEDCoupling1SGTUMesh::checkCoherencyOfConnectivity() const throw(INTERP_KERNEL::Exception)
634 const DataArrayInt *c1(_conn);
637 if(c1->getNumberOfComponents()!=1)
638 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
639 if(c1->getInfoOnComponent(0)!="")
640 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
641 c1->checkAllocated();
644 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
647 void MEDCoupling1SGTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
649 MEDCouplingPointSet::checkCoherency();
650 checkCoherencyOfConnectivity();
653 void MEDCoupling1SGTUMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
656 const DataArrayInt *c1(_conn);
657 int nbOfTuples=c1->getNumberOfTuples();
658 int nbOfNodesPerCell=(int)_cm->getNumberOfNodes();
659 if(nbOfTuples%nbOfNodesPerCell!=0)
661 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::checkCoherency1 : the nb of tuples in conn is " << nbOfTuples << " and number of nodes per cell is " << nbOfNodesPerCell << ". But " << nbOfTuples << "%" << nbOfNodesPerCell << " !=0 !";
662 throw INTERP_KERNEL::Exception(oss.str().c_str());
664 int nbOfNodes=getNumberOfNodes();
665 int nbOfCells=nbOfTuples/nbOfNodesPerCell;
666 const int *w(c1->begin());
667 for(int i=0;i<nbOfCells;i++)
668 for(int j=0;j<nbOfNodesPerCell;j++,w++)
670 if(*w<0 || *w>=nbOfNodes)
672 std::ostringstream oss; oss << "At node #" << j << " of cell #" << i << ", is equal to " << *w << " must be in [0," << nbOfNodes << ") !";
673 throw INTERP_KERNEL::Exception(oss.str().c_str());
678 void MEDCoupling1SGTUMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
680 checkCoherency1(eps);
683 int MEDCoupling1SGTUMesh::getNumberOfCells() const
685 int nbOfTuples=getNodalConnectivityLength();
686 int nbOfNodesPerCell=getNumberOfNodesPerCell();
687 if(nbOfTuples%nbOfNodesPerCell!=0)
689 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh:getNumberOfCells: : the nb of tuples in conn is " << nbOfTuples << " and number of nodes per cell is " << nbOfNodesPerCell << ". But " << nbOfTuples << "%" << nbOfNodesPerCell << " !=0 !";
690 throw INTERP_KERNEL::Exception(oss.str().c_str());
692 return nbOfTuples/nbOfNodesPerCell;
695 int MEDCoupling1SGTUMesh::getNumberOfNodesInCell(int cellId) const throw(INTERP_KERNEL::Exception)
697 return getNumberOfNodesPerCell();
700 int MEDCoupling1SGTUMesh::getNumberOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
702 checkNonDynamicGeoType();
703 return (int)_cm->getNumberOfNodes();
706 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
708 checkNonDynamicGeoType();
709 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
710 ret->alloc(getNumberOfCells(),1);
711 ret->fillWithValue((int)_cm->getNumberOfNodes());
715 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception)
717 checkNonDynamicGeoType();
718 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
719 ret->alloc(getNumberOfCells(),1);
720 ret->fillWithValue((int)_cm->getNumberOfSons());
724 DataArrayInt *MEDCoupling1SGTUMesh::computeEffectiveNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
726 checkNonDynamicGeoType();
727 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
728 int nbCells(getNumberOfCells());
729 ret->alloc(nbCells,1);
730 int *retPtr(ret->getPointer());
731 int nbNodesPerCell(getNumberOfNodesPerCell());
732 const int *conn(_conn->begin());
733 for(int i=0;i<nbCells;i++,conn+=nbNodesPerCell,retPtr++)
735 std::set<int> s(conn,conn+nbNodesPerCell);
736 *retPtr=(int)s.size();
741 void MEDCoupling1SGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
743 int sz=getNumberOfNodesPerCell();
745 if(cellId>=0 && cellId<getNumberOfCells())
746 std::copy(_conn->begin()+cellId*sz,_conn->begin()+(cellId+1)*sz,conn.begin());
749 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << getNumberOfCells() << ") !";
750 throw INTERP_KERNEL::Exception(oss.str().c_str());
754 void MEDCoupling1SGTUMesh::checkNonDynamicGeoType() const throw(INTERP_KERNEL::Exception)
757 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkNonDynamicGeoType : internal error ! the internal geo type is dynamic ! should be static !");
760 std::string MEDCoupling1SGTUMesh::simpleRepr() const
762 static const char msg0[]="No coordinates specified !";
763 std::ostringstream ret;
764 ret << "Single static geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
765 ret << "Description of mesh : \"" << getDescription() << "\"\n";
767 double tt=getTime(tmpp1,tmpp2);
768 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
769 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
770 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
773 const int spaceDim=getSpaceDimension();
774 ret << spaceDim << "\nInfo attached on space dimension : ";
775 for(int i=0;i<spaceDim;i++)
776 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
781 ret << "Number of nodes : ";
783 ret << getNumberOfNodes() << "\n";
786 ret << "Number of cells : ";
787 if((const DataArrayInt *)_conn)
789 if(_conn->isAllocated())
791 if(_conn->getNumberOfComponents()==1)
792 ret << getNumberOfCells() << "\n";
794 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
797 ret << "Nodal connectivity array specified but not allocated !" << "\n";
800 ret << "No connectivity specified !" << "\n";
801 ret << "Cell type : " << _cm->getRepr() << "\n";
805 std::string MEDCoupling1SGTUMesh::advancedRepr() const
807 std::ostringstream ret;
809 ret << "\nCoordinates array : \n___________________\n\n";
811 _coords->reprWithoutNameStream(ret);
813 ret << "No array set !\n";
814 ret << "\n\nConnectivity array : \n____________________\n\n";
816 if((const DataArrayInt *)_conn)
818 if(_conn->isAllocated())
820 if(_conn->getNumberOfComponents()==1)
822 int nbOfCells=getNumberOfCells();
823 int sz=getNumberOfNodesPerCell();
824 const int *connPtr=_conn->begin();
825 for(int i=0;i<nbOfCells;i++,connPtr+=sz)
827 ret << "Cell #" << i << " : ";
828 std::copy(connPtr,connPtr+sz,std::ostream_iterator<int>(ret," "));
833 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
836 ret << "Nodal connectivity array specified but not allocated !" << "\n";
839 ret << "No connectivity specified !" << "\n";
843 DataArrayDouble *MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
845 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
846 int spaceDim=getSpaceDimension();
847 int nbOfCells=getNumberOfCells();//checkCoherency()
848 int nbOfNodes=getNumberOfNodes();
849 ret->alloc(nbOfCells,spaceDim);
850 double *ptToFill=ret->getPointer();
851 const double *coor=_coords->begin();
852 const int *nodal=_conn->begin();
853 int sz=getNumberOfNodesPerCell();
854 double coeff=1./(double)sz;
855 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim)
857 std::fill(ptToFill,ptToFill+spaceDim,0.);
858 for(int j=0;j<sz;j++,nodal++)
859 if(*nodal>=0 && *nodal<nbOfNodes)
860 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
863 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
864 throw INTERP_KERNEL::Exception(oss.str().c_str());
866 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),coeff));
871 void MEDCoupling1SGTUMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
873 int nbCells=getNumberOfCells();
874 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
875 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
877 o2n=o2n->checkAndPreparePermutation();
879 const int *conn=_conn->begin();
880 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o=o2n->invertArrayO2N2N2O(nbCells);
881 const int *n2oPtr=n2o->begin();
882 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
883 newConn->alloc(_conn->getNumberOfTuples(),1);
884 newConn->copyStringInfoFrom(*_conn);
885 int sz=getNumberOfNodesPerCell();
887 int *newC=newConn->getPointer();
888 for(int i=0;i<nbCells;i++,newC+=sz)
891 std::copy(conn+pos*sz,conn+(pos+1)*sz,newC);
897 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
898 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
899 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
900 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
902 * \param [in] begin input start of array of node ids.
903 * \param [in] end input end of array of node ids.
904 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
905 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
907 void MEDCoupling1SGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
909 int nbOfCells=getNumberOfCells();
910 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
912 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
913 std::vector<bool> fastFinder(sz,false);
914 for(const int *work=begin;work!=end;work++)
915 if(*work>=0 && *work<sz)
916 fastFinder[*work]=true;
917 const int *conn=_conn->begin();
918 int nbNodesPerCell=getNumberOfNodesPerCell();
919 for(int i=0;i<nbOfCells;i++,conn+=nbNodesPerCell)
922 for(int j=0;j<nbNodesPerCell;j++)
926 if(fastFinder[conn[j]])
929 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
930 cellIdsKept->pushBackSilent(i);
932 cellIdsKeptArr=cellIdsKept.retn();
935 MEDCouplingMesh *MEDCoupling1SGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
937 if(other->getType()!=SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED)
938 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single static geo type each other !");
939 const MEDCoupling1SGTUMesh *otherC=static_cast<const MEDCoupling1SGTUMesh *>(other);
940 return Merge1SGTUMeshes(this,otherC);
943 MEDCouplingUMesh *MEDCoupling1SGTUMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
945 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName().c_str(),getMeshDimension());
946 ret->setCoords(getCoords());
947 const int *nodalConn=_conn->begin();
948 int nbCells=getNumberOfCells();
949 int nbNodesPerCell=getNumberOfNodesPerCell();
950 int geoType=(int)getCellModelEnum();
951 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells*(nbNodesPerCell+1),1);
952 int *cPtr=c->getPointer();
953 for(int i=0;i<nbCells;i++,nodalConn+=nbNodesPerCell)
956 cPtr=std::copy(nodalConn,nodalConn+nbNodesPerCell,cPtr);
958 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::Range(0,(nbCells+1)*(nbNodesPerCell+1),nbNodesPerCell+1);
959 ret->setConnectivity(c,cI,true);
963 DataArrayInt *MEDCoupling1SGTUMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
968 return simplexizePol0();
970 return simplexizePol1();
971 case (int) INTERP_KERNEL::PLANAR_FACE_5:
972 return simplexizePlanarFace5();
973 case (int) INTERP_KERNEL::PLANAR_FACE_6:
974 return simplexizePlanarFace6();
976 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::simplexize : unrecognized policy ! Must be :\n - 0 or 1 (only available for meshdim=2) \n - PLANAR_FACE_5, PLANAR_FACE_6 (only for meshdim=3)");
982 struct MEDCouplingAccVisit
984 MEDCouplingAccVisit():_new_nb_of_nodes(0) { }
985 int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; }
986 int _new_nb_of_nodes;
992 * Finds nodes not used in any cell and returns an array giving a new id to every node
993 * by excluding the unused nodes, for which the array holds -1. The result array is
994 * a mapping in "Old to New" mode.
995 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
996 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
997 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
998 * if the node is unused or a new id else. The caller is to delete this
999 * array using decrRef() as it is no more needed.
1000 * \throw If the coordinates array is not set.
1001 * \throw If the nodal connectivity of cells is not defined.
1002 * \throw If the nodal connectivity includes an invalid id.
1004 DataArrayInt *MEDCoupling1SGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception)
1007 int nbOfNodes=getNumberOfNodes();
1008 int nbOfCells=getNumberOfCells();
1009 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1010 ret->alloc(nbOfNodes,1);
1011 int *traducer=ret->getPointer();
1012 std::fill(traducer,traducer+nbOfNodes,-1);
1013 const int *conn=_conn->begin();
1014 int nbNodesPerCell=getNumberOfNodesPerCell();
1015 for(int i=0;i<nbOfCells;i++)
1016 for(int j=0;j<nbNodesPerCell;j++,conn++)
1017 if(*conn>=0 && *conn<nbOfNodes)
1021 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << conn[j] << " not in [0," << nbOfNodes << ") !";
1022 throw INTERP_KERNEL::Exception(oss.str().c_str());
1024 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
1025 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
1030 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
1031 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
1032 * This method is a generalization of shiftNodeNumbersInConn().
1033 * \warning This method performs no check of validity of new ids. **Use it with care !**
1034 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
1035 * this->getNumberOfNodes(), in "Old to New" mode.
1036 * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
1037 * \throw If the nodal connectivity of cells is not defined.
1039 void MEDCoupling1SGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
1041 getNumberOfCells();//only to check that all is well defined.
1042 _conn->transformWithIndArr(newNodeNumbersO2N,newNodeNumbersO2N+getNumberOfNodes());
1046 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2) throw(INTERP_KERNEL::Exception)
1048 std::vector<const MEDCoupling1SGTUMesh *> tmp(2);
1049 tmp[0]=const_cast<MEDCoupling1SGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1SGTUMesh *>(mesh2);
1050 return Merge1SGTUMeshes(tmp);
1053 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
1055 std::size_t sz=a.size();
1057 return Merge1SGTUMeshesLL(a);
1058 for(std::size_t ii=0;ii<sz;ii++)
1061 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::Merge1SGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
1062 throw INTERP_KERNEL::Exception(oss.str().c_str());
1064 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
1065 for(std::size_t ii=0;ii<sz;ii++)
1066 if(&(a[ii]->getCellModel())!=cm)
1067 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : all items must have the same geo type !");
1068 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> > bb(sz);
1069 std::vector< const MEDCoupling1SGTUMesh * > aa(sz);
1071 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
1073 const MEDCoupling1SGTUMesh *cur=a[i];
1074 const DataArrayDouble *coo=cur->getCoords();
1076 spaceDim=coo->getNumberOfComponents();
1079 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : no spaceDim specified ! unable to perform merge !");
1080 for(std::size_t i=0;i<sz;i++)
1082 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
1085 return Merge1SGTUMeshesLL(aa);
1089 * \throw If presence of a null instance in the input vector \a a.
1090 * \throw If a is empty
1092 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
1095 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : input array must be NON EMPTY !");
1096 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1098 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : null instance in the first element of input vector !");
1099 std::vector<const DataArrayInt *> ncs(a.size());
1100 int nbOfCells=(*it)->getNumberOfCells();
1101 const DataArrayDouble *coords=(*it)->getCoords();
1102 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1103 int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
1104 ncs[0]=(*it)->getNodalConnectivity();
1106 for(int i=1;it!=a.end();i++,it++)
1109 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : presence of a null instance in the input vector !");
1110 if(cm!=&((*it)->getCellModel()))
1111 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1112 (*it)->getNumberOfCells();//to check that all is OK
1113 ncs[i]=(*it)->getNodalConnectivity();
1114 if(coords!=(*it)->getCoords())
1115 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : not lying on same coords !");
1117 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1118 ret->setCoords(coords);
1119 ret->_conn=DataArrayInt::Aggregate(ncs);
1124 * Assume that all instances in \a a are non null. If null it leads to a crash. That's why this method is assigned to be low level (LL)
1126 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
1129 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : input array must be NON EMPTY !");
1130 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1131 int nbOfCells=(*it)->getNumberOfCells();
1132 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1133 int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
1135 for(;it!=a.end();it++)
1137 if(cm!=&((*it)->getCellModel()))
1138 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1139 nbOfCells+=(*it)->getNumberOfCells();
1141 std::vector<const MEDCouplingPointSet *> aps(a.size());
1142 std::copy(a.begin(),a.end(),aps.begin());
1143 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
1144 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1145 ret->setCoords(pts);
1146 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New();
1147 c->alloc(nbOfCells*nbNodesPerCell,1);
1148 int *cPtr=c->getPointer();
1150 for(it=a.begin();it!=a.end();it++)
1152 int curConnLgth=(*it)->getNodalConnectivityLength();
1153 const int *curC=(*it)->_conn->begin();
1154 cPtr=std::transform(curC,curC+curConnLgth,cPtr,std::bind2nd(std::plus<int>(),offset));
1155 offset+=(*it)->getNumberOfNodes();
1158 ret->setNodalConnectivity(c);
1162 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
1164 int ncell=getNumberOfCells();
1165 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName().c_str(),*_cm));
1166 ret->setCoords(_coords);
1167 std::size_t nbOfElemsRet=std::distance(begin,end);
1168 const int *inConn=_conn->getConstPointer();
1169 int sz=getNumberOfNodesPerCell();
1170 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1171 int *connPtr=connRet->getPointer();
1172 for(const int *work=begin;work!=end;work++,connPtr+=sz)
1174 if(*work>=0 && *work<ncell)
1175 std::copy(inConn+(work[0])*sz,inConn+(work[0]+1)*sz,connPtr);
1178 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !";
1179 throw INTERP_KERNEL::Exception(oss.str().c_str());
1183 ret->copyTinyInfoFrom(this);
1187 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
1189 int ncell=getNumberOfCells();
1190 int nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : ");
1191 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName().c_str(),*_cm));
1192 ret->setCoords(_coords);
1193 const int *inConn=_conn->getConstPointer();
1194 int sz=getNumberOfNodesPerCell();
1195 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1196 int *connPtr=connRet->getPointer();
1198 for(int i=0;i<nbOfElemsRet;i++,connPtr+=sz,curId+=step)
1200 if(curId>=0 && curId<ncell)
1201 std::copy(inConn+curId*sz,inConn+(curId+1)*sz,connPtr);
1204 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : On pos #" << i << " input cell id =" << curId << " should be in [0," << ncell << ") !";
1205 throw INTERP_KERNEL::Exception(oss.str().c_str());
1209 ret->copyTinyInfoFrom(this);
1213 void MEDCoupling1SGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const throw(INTERP_KERNEL::Exception)
1215 int sz((int)nodeIdsInUse.size());
1216 int nbCells(getNumberOfCells());
1217 int nbOfNodesPerCell(getNumberOfNodesPerCell());
1218 const int *w(_conn->begin());
1219 for(int i=0;i<nbCells;i++)
1220 for(int j=0;j<nbOfNodesPerCell;j++,w++)
1223 nodeIdsInUse[*w]=true;
1226 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeNodeIdsAlg : At cell #" << i << " presence of node id #" << *w << " should be in [0," << sz << ") !";
1227 throw INTERP_KERNEL::Exception(oss.str().c_str());
1232 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception)
1234 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName().c_str(),*_cm));
1235 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1;
1236 const DataArrayInt *nodalConn(_conn);
1239 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
1246 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
1247 ret->setCoords(coords);
1250 ret->setCoords(_coords);
1254 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol0() throw(INTERP_KERNEL::Exception)
1256 int nbOfCells=getNumberOfCells();
1257 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1258 return DataArrayInt::Range(0,nbOfCells,1);
1259 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1260 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1261 const int *c(_conn->begin());
1262 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1263 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1265 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[2];
1266 newConnPtr[3]=c[0]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1267 retPtr[0]=i; retPtr[1]=i;
1270 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1275 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol1() throw(INTERP_KERNEL::Exception)
1277 int nbOfCells=getNumberOfCells();
1278 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1279 return DataArrayInt::Range(0,nbOfCells,1);
1280 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1281 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1282 const int *c(_conn->begin());
1283 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1284 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1286 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[3];
1287 newConnPtr[3]=c[1]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1288 retPtr[0]=i; retPtr[1]=i;
1291 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1296 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace5() throw(INTERP_KERNEL::Exception)
1298 int nbOfCells=getNumberOfCells();
1299 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1300 return DataArrayInt::Range(0,nbOfCells,1);
1301 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(5*4*nbOfCells,1);
1302 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(5*nbOfCells,1);
1303 const int *c(_conn->begin());
1304 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1305 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=20,retPtr+=5)
1307 for(int j=0;j<20;j++)
1308 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_5_WO[j]];
1309 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i;
1312 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1317 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace6() throw(INTERP_KERNEL::Exception)
1319 int nbOfCells=getNumberOfCells();
1320 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1321 return DataArrayInt::Range(0,nbOfCells,1);
1322 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(6*4*nbOfCells,1);
1323 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(6*nbOfCells,1);
1324 const int *c(_conn->begin());
1325 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1326 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=24,retPtr+=6)
1328 for(int j=0;j<24;j++)
1329 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_6_WO[j]];
1330 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i; retPtr[5]=i;
1333 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1338 void MEDCoupling1SGTUMesh::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1340 stream << "MEDCoupling1SGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
1341 stream << " Mesh dimension : " << getMeshDimension() << ".";
1343 { stream << " No coordinates set !"; return ; }
1344 if(!_coords->isAllocated())
1345 { stream << " Coordinates set but not allocated !"; return ; }
1346 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
1347 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
1348 if(!(const DataArrayInt *)_conn)
1349 { stream << std::endl << "Nodal connectivity NOT set !"; return ; }
1350 if(_conn->isAllocated())
1352 if(_conn->getNumberOfComponents()==1)
1353 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
1357 void MEDCoupling1SGTUMesh::checkFullyDefined() const throw(INTERP_KERNEL::Exception)
1359 if(!((const DataArrayInt *)_conn) || !((const DataArrayDouble *)_coords))
1360 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFullyDefined : part of this is not fully defined.");
1364 * First step of unserialization process.
1366 bool MEDCoupling1SGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
1368 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEmptyMesh : not implemented yet !");
1371 void MEDCoupling1SGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
1374 double time=getTime(it,order);
1375 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
1377 littleStrings.push_back(getName());
1378 littleStrings.push_back(getDescription());
1379 littleStrings.push_back(getTimeUnit());
1381 std::vector<std::string> littleStrings2,littleStrings3;
1382 if((const DataArrayDouble *)_coords)
1383 _coords->getTinySerializationStrInformation(littleStrings2);
1384 if((const DataArrayInt *)_conn)
1385 _conn->getTinySerializationStrInformation(littleStrings3);
1386 int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size());
1387 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
1388 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
1390 tinyInfo.push_back(getCellModelEnum());
1391 tinyInfo.push_back(it);
1392 tinyInfo.push_back(order);
1393 std::vector<int> tinyInfo2,tinyInfo3;
1394 if((const DataArrayDouble *)_coords)
1395 _coords->getTinySerializationIntInformation(tinyInfo2);
1396 if((const DataArrayInt *)_conn)
1397 _conn->getTinySerializationIntInformation(tinyInfo3);
1398 int sz2((int)tinyInfo2.size()),sz3((int)tinyInfo3.size());
1399 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3);
1400 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1401 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
1403 tinyInfoD.push_back(time);
1406 void MEDCoupling1SGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
1408 std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+tinyInfo[5]);
1409 std::vector<int> tinyInfo1(tinyInfo.begin()+7+tinyInfo[5],tinyInfo.begin()+7+tinyInfo[5]+tinyInfo[6]);
1410 a1->resizeForUnserialization(tinyInfo1);
1411 a2->resizeForUnserialization(tinyInfo2);
1414 void MEDCoupling1SGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
1417 if((const DataArrayInt *)_conn)
1418 if(_conn->isAllocated())
1419 sz=_conn->getNbOfElems();
1420 a1=DataArrayInt::New();
1422 if(sz!=0 && (const DataArrayInt *)_conn)
1423 std::copy(_conn->begin(),_conn->end(),a1->getPointer());
1425 if((const DataArrayDouble *)_coords)
1426 if(_coords->isAllocated())
1427 sz=_coords->getNbOfElems();
1428 a2=DataArrayDouble::New();
1430 if(sz!=0 && (const DataArrayDouble *)_coords)
1431 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
1434 void MEDCoupling1SGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
1435 const std::vector<std::string>& littleStrings)
1437 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
1438 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
1439 setName(littleStrings[0].c_str());
1440 setDescription(littleStrings[1].c_str());
1441 setTimeUnit(littleStrings[2].c_str());
1442 setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
1443 int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]);
1445 _coords=DataArrayDouble::New();
1446 std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+sz2);
1447 _coords->resizeForUnserialization(tinyInfo2);
1448 std::copy(a2->begin(),a2->end(),_coords->getPointer());
1449 _conn=DataArrayInt::New();
1450 std::vector<int> tinyInfo3(tinyInfo.begin()+7+sz2,tinyInfo.begin()+7+sz2+sz3);
1451 _conn->resizeForUnserialization(tinyInfo3);
1452 std::copy(a1->begin(),a1->end(),_conn->getPointer());
1453 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
1454 _coords->finishUnserialization(tinyInfo2,littleStrings2);
1455 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
1456 _conn->finishUnserialization(tinyInfo3,littleStrings3);
1460 * Checks if \a this and \a other meshes are geometrically equivalent with high
1461 * probability, else an exception is thrown. The meshes are considered equivalent if
1462 * (1) meshes contain the same number of nodes and the same number of elements of the
1463 * same types (2) three cells of the two meshes (first, last and middle) are based
1464 * on coincident nodes (with a specified precision).
1465 * \param [in] other - the mesh to compare with.
1466 * \param [in] prec - the precision used to compare nodes of the two meshes.
1467 * \throw If the two meshes do not match.
1469 void MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception)
1471 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1472 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1474 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single static geometric type !");
1475 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1479 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1480 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1481 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1482 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1483 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1484 if(c1->getHashCode()!=c2->getHashCode())
1485 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1488 MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
1491 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
1492 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1494 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
1495 std::vector<const MEDCoupling1SGTUMesh *> ms(2);
1498 return Merge1SGTUMeshesOnSameCoords(ms);
1501 void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception)
1503 checkFullyDefined();
1504 int nbOfNodes=getNumberOfNodes();
1505 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
1506 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
1507 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
1508 const int *conn=_conn->begin();
1509 int nbOfCells=getNumberOfCells();
1510 int nbOfEltsInRevNodal=0;
1511 int nbOfNodesPerCell=getNumberOfNodesPerCell();
1512 for(int eltId=0;eltId<nbOfCells;eltId++)
1514 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1516 if(conn[0]>=0 && conn[0]<nbOfNodes)
1518 nbOfEltsInRevNodal++;
1519 revNodalIndxPtr[conn[0]+1]++;
1523 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
1524 throw INTERP_KERNEL::Exception(oss.str().c_str());
1528 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
1529 conn=_conn->begin();
1530 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
1531 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
1532 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
1533 for(int eltId=0;eltId<nbOfCells;eltId++)
1535 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1537 *std::find_if(revNodalPtr+revNodalIndxPtr[*conn],revNodalPtr+revNodalIndxPtr[*conn+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
1543 * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null.
1545 void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn) throw(INTERP_KERNEL::Exception)
1548 nodalConn->incrRef();
1554 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
1556 DataArrayInt *MEDCoupling1SGTUMesh::getNodalConnectivity() const throw(INTERP_KERNEL::Exception)
1558 const DataArrayInt *ret(_conn);
1559 return const_cast<DataArrayInt *>(ret);
1563 * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted,
1564 * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter.
1565 * If a nodal connectivity previouly existed before the call of this method, it will be reset.
1567 * \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain.
1569 void MEDCoupling1SGTUMesh::allocateCells(int nbOfCells) throw(INTERP_KERNEL::Exception)
1572 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !");
1573 _conn=DataArrayInt::New();
1574 _conn->reserve(getNumberOfNodesPerCell()*nbOfCells);
1579 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
1581 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
1582 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
1583 * \throw If the length of the input nodal connectivity array of the cell to add is not equal to number of nodes per cell relative to the unique geometric type
1584 * attached to \a this.
1585 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
1587 void MEDCoupling1SGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) throw(INTERP_KERNEL::Exception)
1589 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
1590 int ref=getNumberOfNodesPerCell();
1593 DataArrayInt *c(_conn);
1595 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
1597 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !");
1601 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this (";
1602 oss << ref << ") !";
1603 throw INTERP_KERNEL::Exception(oss.str().c_str());
1608 * This method builds the dual mesh of \a this and returns it.
1610 * \return MEDCoupling1SGTUMesh * - newly object created to be managed by the caller.
1611 * \throw If \a this is not a mesh containing only simplex cells.
1612 * \throw If \a this is not correctly allocated (coordinates and connectivities have to be correctly set !).
1613 * \throw If at least one node in \a this is orphan (without any simplex cell lying on it !)
1615 MEDCoupling1GTUMesh *MEDCoupling1SGTUMesh::computeDualMesh() const throw(INTERP_KERNEL::Exception)
1617 const INTERP_KERNEL::CellModel& cm(getCellModel());
1619 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : this mesh is not a simplex mesh ! Please invoke simplexize of tetrahedrize on this before calling this method !");
1620 switch(getMeshDimension())
1623 return computeDualMesh3D();
1625 return computeDualMesh2D();
1627 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : meshdimension must be in [2,3] !");
1631 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh3D() const throw(INTERP_KERNEL::Exception)
1633 static const int DUAL_TETRA_0[36]={
1634 4,1,0, 6,0,3, 7,3,1,
1635 4,0,1, 5,2,0, 8,1,2,
1636 6,3,0, 5,0,2, 9,2,3,
1639 static const int DUAL_TETRA_1[36]={
1640 8,4,10, 11,5,8, 10,7,11,
1641 9,4,8, 8,5,12, 12,6,9,
1642 10,4,9, 9,6,13, 13,7,10,
1643 12,5,11, 13,6,12, 11,7,13
1645 static const int FACEID_NOT_SH_NODE[4]={2,3,1,0};
1646 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TETRA4)
1647 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh3D : only TETRA4 supported !");
1648 checkFullyDefined();
1649 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured());
1650 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1651 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1652 const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1653 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d1Arr(DataArrayInt::New()),di1Arr(DataArrayInt::New()),rd1Arr(DataArrayInt::New()),rdi1Arr(DataArrayInt::New());
1654 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->explode3DMeshTo1D(d1Arr,di1Arr,rd1Arr,rdi1Arr));
1655 const int *d1(d1Arr->begin());
1656 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1657 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> faces(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
1658 const int *d2(d2Arr->begin()),*rd2(rd2Arr->begin()),*rdi2(rdi2Arr->begin());
1659 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),facesBaryArr(faces->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
1660 const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+faces->getNumberOfCells()),offset1(offset0+edges->getNumberOfCells());
1662 std::vector<const DataArrayDouble *> v(4); v[0]=getCoords(); v[1]=facesBaryArr; v[2]=edgesBaryArr; v[3]=baryArr;
1663 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0; facesBaryArr=0;
1664 std::string name("DualOf_"); name+=getName();
1665 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name.c_str(),INTERP_KERNEL::NORM_POLYHED)); ret->setCoords(zeArr);
1666 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1667 for(int i=0;i<nbOfNodes;i++,revNodI++)
1669 int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1670 if(nbOfCellsSharingNode==0)
1672 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh3D : Node #" << i << " is orphan !";
1673 throw INTERP_KERNEL::Exception(oss.str().c_str());
1675 for(int j=0;j<nbOfCellsSharingNode;j++)
1677 int curCellId(revNod[revNodI[0]+j]);
1678 const int *connOfCurCell(nodal+4*curCellId);
1679 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1680 if(j!=0) cArr->pushBackSilent(-1);
1683 tmp[0]=d1[6*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+0]-4]+offset0; tmp[1]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+1]]+nbOfNodes;
1684 tmp[2]=curCellId+offset1; tmp[3]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+2]]+nbOfNodes;
1686 tmp[5]=d1[6*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+3]-4]+offset0; tmp[6]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+4]]+nbOfNodes;
1687 tmp[7]=curCellId+offset1; tmp[8]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+5]]+nbOfNodes;
1689 tmp[10]=d1[6*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+6]-4]+offset0; tmp[11]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+7]]+nbOfNodes;
1690 tmp[12]=curCellId+offset1; tmp[13]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+8]]+nbOfNodes;
1691 cArr->insertAtTheEnd(tmp,tmp+14);
1693 for(int k=0;k<4;k++)
1695 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1697 const int *faceId(d2+4*curCellId+k);
1698 if(rdi2[*faceId+1]-rdi2[*faceId]==1)
1700 int tmp2[5]; tmp2[0]=-1; tmp2[1]=i;
1701 tmp2[2]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+0]-8]+offset0;
1702 tmp2[3]=d2[4*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+1]-4]+nbOfNodes;
1703 tmp2[4]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+2]-8]+offset0;
1704 cArr->insertAtTheEnd(tmp2,tmp2+5);
1710 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
1712 ret->setNodalConnectivity(cArr,ciArr);
1716 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh2D() const throw(INTERP_KERNEL::Exception)
1718 static const int DUAL_TRI_0[6]={0,2, 1,0, 2,1};
1719 static const int DUAL_TRI_1[6]={-3,+5, +3,-4, +4,-5};
1720 static const int FACEID_NOT_SH_NODE[3]={1,2,0};
1721 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TRI3)
1722 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh2D : only TRI3 supported !");
1723 checkFullyDefined();
1724 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured());
1725 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1726 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1727 const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1728 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1729 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
1730 const int *d2(d2Arr->begin()),*rd2(rd2Arr->begin()),*rdi2(rdi2Arr->begin());
1731 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
1732 const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+edges->getNumberOfCells());
1734 std::vector<const DataArrayDouble *> v(3); v[0]=getCoords(); v[1]=edgesBaryArr; v[2]=baryArr;
1735 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0;
1736 std::string name("DualOf_"); name+=getName();
1737 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name.c_str(),INTERP_KERNEL::NORM_POLYGON)); ret->setCoords(zeArr);
1738 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1739 for(int i=0;i<nbOfNodes;i++,revNodI++)
1741 int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1742 if(nbOfCellsSharingNode==0)
1744 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh2D : Node #" << i << " is orphan !";
1745 throw INTERP_KERNEL::Exception(oss.str().c_str());
1747 std::vector< std::vector<int> > polyg;
1748 for(int j=0;j<nbOfCellsSharingNode;j++)
1750 int curCellId(revNod[revNodI[0]+j]);
1751 const int *connOfCurCell(nodal+3*curCellId);
1752 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1753 std::vector<int> locV(3);
1754 locV[0]=d2[3*curCellId+DUAL_TRI_0[2*nodePosInCurCell+0]]+nbOfNodes; locV[1]=curCellId+offset0; locV[2]=d2[3*curCellId+DUAL_TRI_0[2*nodePosInCurCell+1]]+nbOfNodes;
1755 polyg.push_back(locV);
1757 for(int k=0;k<3;k++)
1759 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1761 const int *edgeId(d2+3*curCellId+k);
1762 if(rdi2[*edgeId+1]-rdi2[*edgeId]==1)
1764 std::vector<int> locV2(2);
1765 int zeLocEdgeIdRel(DUAL_TRI_1[2*nodePosInCurCell+kk]);
1766 if(zeLocEdgeIdRel>0)
1767 { locV2[0]=d2[3*curCellId+zeLocEdgeIdRel-3]+nbOfNodes; locV2[1]=i; }
1769 { locV2[0]=i; locV2[1]=d2[3*curCellId-zeLocEdgeIdRel-3]+nbOfNodes; }
1770 polyg.push_back(locV2);
1776 std::vector<int> zePolyg(MEDCoupling1DGTUMesh::BuildAPolygonFromParts(polyg));
1777 cArr->insertAtTheEnd(zePolyg.begin(),zePolyg.end());
1778 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
1780 ret->setNodalConnectivity(cArr,ciArr);
1785 * This method aggregate the bbox of each cell and put it into bbox
1787 * \return DataArrayDouble * - having \a this number of cells tuples and 2*spacedim components.
1789 * \throw If \a this is not fully set (coordinates and connectivity).
1790 * \throw If a cell in \a this has no valid nodeId.
1792 DataArrayDouble *MEDCoupling1SGTUMesh::getBoundingBoxForBBTree() const
1794 int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()),nbOfNodesPerCell(getNumberOfNodesPerCell());
1795 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
1796 double *bbox(ret->getPointer());
1797 for(int i=0;i<nbOfCells*spaceDim;i++)
1799 bbox[2*i]=std::numeric_limits<double>::max();
1800 bbox[2*i+1]=-std::numeric_limits<double>::max();
1802 const double *coordsPtr(_coords->getConstPointer());
1803 const int *conn(_conn->getConstPointer());
1804 for(int i=0;i<nbOfCells;i++)
1806 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1808 int nodeId(*conn),kk(0);
1809 if(nodeId>=0 && nodeId<nbOfNodes)
1811 for(int k=0;k<spaceDim;k++)
1813 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
1814 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
1820 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
1821 throw INTERP_KERNEL::Exception(oss.str().c_str());
1830 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New()
1832 return new MEDCoupling1DGTUMesh;
1835 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
1837 if(type==INTERP_KERNEL::NORM_ERROR)
1838 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
1839 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
1842 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !";
1843 throw INTERP_KERNEL::Exception(oss.str().c_str());
1845 return new MEDCoupling1DGTUMesh(name,cm);
1848 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh()
1852 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
1856 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
1860 const DataArrayInt *c(other._conn);
1865 _conn_indx=c->deepCpy();
1869 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const
1871 return new MEDCoupling1DGTUMesh(*this,recDeepCpy);
1875 * This method behaves mostly like MEDCoupling1DGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
1876 * The coordinates are shared between \a this and the returned instance.
1878 * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
1879 * \sa MEDCoupling1DGTUMesh::deepCpy
1881 MEDCouplingPointSet *MEDCoupling1DGTUMesh::deepCpyConnectivityOnly() const throw(INTERP_KERNEL::Exception)
1884 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(clone(false));
1885 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy()),ci(_conn_indx->deepCpy());
1886 ret->setNodalConnectivity(c,ci);
1890 void MEDCoupling1DGTUMesh::updateTime() const
1892 MEDCoupling1GTUMesh::updateTime();
1893 const DataArrayInt *c(_conn);
1901 std::size_t MEDCoupling1DGTUMesh::getHeapMemorySize() const
1904 const DataArrayInt *c(_conn);
1906 ret+=c->getHeapMemorySize();
1909 ret+=c->getHeapMemorySize();
1910 return MEDCoupling1GTUMesh::getHeapMemorySize()+ret;
1913 MEDCouplingMesh *MEDCoupling1DGTUMesh::deepCpy() const
1918 bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
1921 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !");
1922 std::ostringstream oss; oss.precision(15);
1923 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1926 reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !";
1929 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
1931 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1936 reason="in connectivity of single dynamic geometric type exactly one among this and other is null !";
1939 if(!c1->isEqualIfNotWhy(*c2,reason))
1941 reason.insert(0,"Nodal connectivity DataArrayInt differs : ");
1944 c1=_conn_indx; c2=otherC->_conn_indx;
1949 reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !";
1952 if(!c1->isEqualIfNotWhy(*c2,reason))
1954 reason.insert(0,"Nodal connectivity index DataArrayInt differs : ");
1960 bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
1963 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
1964 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1967 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
1969 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1974 if(!c1->isEqualWithoutConsideringStr(*c2))
1977 c1=_conn_indx; c2=otherC->_conn_indx;
1982 if(!c1->isEqualWithoutConsideringStr(*c2))
1988 * Checks if \a this and \a other meshes are geometrically equivalent with high
1989 * probability, else an exception is thrown. The meshes are considered equivalent if
1990 * (1) meshes contain the same number of nodes and the same number of elements of the
1991 * same types (2) three cells of the two meshes (first, last and middle) are based
1992 * on coincident nodes (with a specified precision).
1993 * \param [in] other - the mesh to compare with.
1994 * \param [in] prec - the precision used to compare nodes of the two meshes.
1995 * \throw If the two meshes do not match.
1997 void MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception)
1999 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
2000 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2002 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single dynamic geometric type !");
2003 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2007 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
2008 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2009 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
2010 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2011 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
2012 if(c1->getHashCode()!=c2->getHashCode())
2013 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs");
2015 c1=_conn_indx; c2=otherC->_conn_indx;
2019 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !");
2020 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2021 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !");
2022 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2023 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !");
2024 if(c1->getHashCode()!=c2->getHashCode())
2025 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs");
2029 void MEDCoupling1DGTUMesh::checkCoherencyOfConnectivity() const throw(INTERP_KERNEL::Exception)
2031 const DataArrayInt *c1(_conn);
2034 if(c1->getNumberOfComponents()!=1)
2035 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
2036 if(c1->getInfoOnComponent(0)!="")
2037 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
2038 c1->checkAllocated();
2041 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
2043 int sz2=_conn->getNumberOfTuples();
2047 if(c1->getNumberOfComponents()!=1)
2048 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
2049 c1->checkAllocated();
2050 if(c1->getNumberOfTuples()<1)
2051 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !");
2052 if(c1->getInfoOnComponent(0)!="")
2053 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
2054 int f=c1->front(),ll=c1->back();
2057 std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !";
2058 throw INTERP_KERNEL::Exception(oss.str().c_str());
2062 std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !";
2063 throw INTERP_KERNEL::Exception(oss.str().c_str());
2067 std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !";
2068 throw INTERP_KERNEL::Exception(oss.str().c_str());
2072 throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !");
2073 int szOfC1Exp=_conn_indx->back();
2076 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() << " !";
2077 throw INTERP_KERNEL::Exception(oss.str().c_str());
2082 * 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.
2083 * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one.
2084 * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array.
2086 void MEDCoupling1DGTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
2088 MEDCouplingPointSet::checkCoherency();
2089 checkCoherencyOfConnectivity();
2092 void MEDCoupling1DGTUMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
2095 const DataArrayInt *c1(_conn),*c2(_conn_indx);
2096 if(!c2->isMonotonic(true))
2097 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkCoherency1 : the nodal connectivity index is expected to be increasing monotinic !");
2099 int nbOfTuples=c1->getNumberOfTuples();
2100 int nbOfNodes=getNumberOfNodes();
2101 const int *w(c1->begin());
2102 for(int i=0;i<nbOfTuples;i++,w++)
2104 if(*w==-1) continue;
2105 if(*w<0 || *w>=nbOfNodes)
2107 std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !";
2108 throw INTERP_KERNEL::Exception(oss.str().c_str());
2113 void MEDCoupling1DGTUMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
2115 checkCoherency1(eps);
2118 int MEDCoupling1DGTUMesh::getNumberOfCells() const
2120 checkCoherencyOfConnectivity();//do not remove
2121 return _conn_indx->getNumberOfTuples()-1;
2125 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2126 * For each cell in \b this the number of nodes constituting cell is computed.
2127 * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned.
2128 * So for pohyhedrons some nodes can be counted several times in the returned result.
2130 * \return a newly allocated array
2132 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
2135 _conn_indx->checkMonotonic(true);
2136 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2137 return _conn_indx->deltaShiftIndex();
2139 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2140 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2141 ret->alloc(nbOfCells,1);
2142 int *retPtr=ret->getPointer();
2143 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2144 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2145 *retPtr=ci[1]-ci[0]-std::count(c+ci[0],c+ci[1],-1);
2150 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2151 * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed.
2153 * \return a newly allocated array
2155 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception)
2158 _conn_indx->checkMonotonic(true);
2159 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG)
2160 return _conn_indx->deltaShiftIndex();
2161 if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG)
2163 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=_conn_indx->deltaShiftIndex();
2164 ret->applyDivideBy(2);
2168 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2169 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2170 ret->alloc(nbOfCells,1);
2171 int *retPtr=ret->getPointer();
2172 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2173 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2174 *retPtr=std::count(c+ci[0],c+ci[1],-1)+1;
2179 * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell,
2180 * will be counted only once here whereas it will be counted several times in MEDCoupling1DGTUMesh::computeNbOfNodesPerCell method.
2182 * \return DataArrayInt * - new object to be deallocated by the caller.
2183 * \sa MEDCoupling1DGTUMesh::computeNbOfNodesPerCell
2185 DataArrayInt *MEDCoupling1DGTUMesh::computeEffectiveNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
2188 _conn_indx->checkMonotonic(true);
2189 int nbOfCells(_conn_indx->getNumberOfTuples()-1);
2190 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2191 ret->alloc(nbOfCells,1);
2192 int *retPtr(ret->getPointer());
2193 const int *ci(_conn_indx->begin()),*c(_conn->begin());
2194 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2196 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2198 std::set<int> s(c+ci[0],c+ci[1]);
2199 *retPtr=(int)s.size();
2204 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2206 std::set<int> s(c+ci[0],c+ci[1]); s.erase(-1);
2207 *retPtr=(int)s.size();
2213 void MEDCoupling1DGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
2215 int nbOfCells(getNumberOfCells());//performs checks
2216 if(cellId>=0 && cellId<nbOfCells)
2218 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2219 int nbOfNodes=stp-strt;
2221 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !");
2222 conn.resize(nbOfNodes);
2223 std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin());
2227 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2228 throw INTERP_KERNEL::Exception(oss.str().c_str());
2232 int MEDCoupling1DGTUMesh::getNumberOfNodesInCell(int cellId) const throw(INTERP_KERNEL::Exception)
2234 int nbOfCells(getNumberOfCells());//performs checks
2235 if(cellId>=0 && cellId<nbOfCells)
2237 const int *conn(_conn->begin());
2238 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2239 return stp-strt-std::count(conn+strt,conn+stp,-1);
2243 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNumberOfNodesInCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2244 throw INTERP_KERNEL::Exception(oss.str().c_str());
2248 std::string MEDCoupling1DGTUMesh::simpleRepr() const
2250 static const char msg0[]="No coordinates specified !";
2251 std::ostringstream ret;
2252 ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
2253 ret << "Description of mesh : \"" << getDescription() << "\"\n";
2255 double tt=getTime(tmpp1,tmpp2);
2256 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
2257 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
2258 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
2261 const int spaceDim=getSpaceDimension();
2262 ret << spaceDim << "\nInfo attached on space dimension : ";
2263 for(int i=0;i<spaceDim;i++)
2264 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
2268 ret << msg0 << "\n";
2269 ret << "Number of nodes : ";
2271 ret << getNumberOfNodes() << "\n";
2273 ret << msg0 << "\n";
2274 ret << "Number of cells : ";
2276 try { checkCoherency(); } catch(INTERP_KERNEL::Exception& e)
2278 ret << "Nodal connectivity arrays are not set or badly set !\n";
2282 ret << getNumberOfCells() << "\n";
2283 ret << "Cell type : " << _cm->getRepr() << "\n";
2287 std::string MEDCoupling1DGTUMesh::advancedRepr() const
2289 std::ostringstream ret;
2290 ret << simpleRepr();
2291 ret << "\nCoordinates array : \n___________________\n\n";
2293 _coords->reprWithoutNameStream(ret);
2295 ret << "No array set !\n";
2296 ret << "\n\nNodal Connectivity : \n____________________\n\n";
2299 try { checkCoherency1(); } catch(INTERP_KERNEL::Exception& e)
2301 ret << "Nodal connectivity arrays are not set or badly set !\n";
2306 int nbOfCells=getNumberOfCells();
2307 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2308 for(int i=0;i<nbOfCells;i++,ci++)
2310 ret << "Cell #" << i << " : ";
2311 std::copy(c+ci[0],c+ci[1],std::ostream_iterator<int>(ret," "));
2317 DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
2319 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
2320 int spaceDim=getSpaceDimension();
2321 int nbOfCells=getNumberOfCells();//checkCoherency()
2322 int nbOfNodes=getNumberOfNodes();
2323 ret->alloc(nbOfCells,spaceDim);
2324 double *ptToFill=ret->getPointer();
2325 const double *coor=_coords->begin();
2326 const int *nodal=_conn->begin(),*nodali=_conn_indx->begin();
2328 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2330 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2332 std::fill(ptToFill,ptToFill+spaceDim,0.);
2333 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2335 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2337 if(*nodal>=0 && *nodal<nbOfNodes)
2338 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2341 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2342 throw INTERP_KERNEL::Exception(oss.str().c_str());
2344 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(nodali[1]-nodali[0])));
2349 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !";
2350 throw INTERP_KERNEL::Exception(oss.str().c_str());
2356 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2358 std::fill(ptToFill,ptToFill+spaceDim,0.);
2359 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2362 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2364 if(*nodal==-1) continue;
2365 if(*nodal>=0 && *nodal<nbOfNodes)
2367 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2372 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2373 throw INTERP_KERNEL::Exception(oss.str().c_str());
2377 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./nbOfNod));
2380 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !";
2381 throw INTERP_KERNEL::Exception(oss.str().c_str());
2386 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : at cell #" << i << " the nodal index array is invalid !";
2387 throw INTERP_KERNEL::Exception(oss.str().c_str());
2394 void MEDCoupling1DGTUMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
2396 int nbCells=getNumberOfCells();
2397 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
2398 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
2400 o2n=o2n->checkAndPreparePermutation();
2402 const int *o2nPtr=o2n->getPointer();
2403 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2404 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
2405 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
2406 newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1);
2407 newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx);
2409 int *newC=newConn->getPointer(),*newCI=newConnI->getPointer();
2410 for(int i=0;i<nbCells;i++)
2412 int newPos=o2nPtr[i];
2413 int sz=conni[i+1]-conni[i];
2418 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !";
2419 throw INTERP_KERNEL::Exception(oss.str().c_str());
2422 newConnI->computeOffsets2(); newCI=newConnI->getPointer();
2424 for(int i=0;i<nbCells;i++,conni++)
2426 int sz=conni[1]-conni[0];
2428 std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]);
2431 _conn_indx=newConnI;
2434 MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
2436 if(other->getType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED)
2437 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !");
2438 const MEDCoupling1DGTUMesh *otherC=static_cast<const MEDCoupling1DGTUMesh *>(other);
2439 return Merge1DGTUMeshes(this,otherC);
2442 MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
2444 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName().c_str(),getMeshDimension());
2445 ret->setCoords(getCoords());
2446 const int *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin();
2447 int nbCells=getNumberOfCells();//checkCoherency
2448 int geoType=(int)getCellModelEnum();
2449 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1);
2450 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::New(); cI->alloc(nbCells+1);
2451 int *cPtr=c->getPointer(),*ciPtr=cI->getPointer();
2453 for(int i=0;i<nbCells;i++,ciPtr++)
2455 int sz=nodalConnI[i+1]-nodalConnI[i];
2459 cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr);
2460 ciPtr[1]=ciPtr[0]+sz+1;
2464 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !";
2465 throw INTERP_KERNEL::Exception(oss.str().c_str());
2468 ret->setConnectivity(c,cI,true);
2473 * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes
2475 DataArrayInt *MEDCoupling1DGTUMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
2477 int nbOfCells=getNumberOfCells();
2478 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2479 ret->alloc(nbOfCells,1);
2484 void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
2486 stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
2487 stream << " Mesh dimension : " << getMeshDimension() << ".";
2489 { stream << " No coordinates set !"; return ; }
2490 if(!_coords->isAllocated())
2491 { stream << " Coordinates set but not allocated !"; return ; }
2492 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
2493 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
2495 try { checkCoherency(); } catch(INTERP_KERNEL::Exception& e)
2497 stream << std::endl << "Nodal connectivity NOT set properly !\n";
2501 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
2504 void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception)
2507 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
2508 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2510 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !");
2511 setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex());
2514 MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
2517 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
2518 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2520 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
2521 std::vector<const MEDCoupling1DGTUMesh *> ms(2);
2524 return Merge1DGTUMeshesOnSameCoords(ms);
2527 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
2530 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2531 ret->setCoords(_coords);
2532 DataArrayInt *c=0,*ci=0;
2533 MEDCouplingUMesh::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci);
2534 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2535 ret->setNodalConnectivity(c,ci);
2539 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
2542 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2543 ret->setCoords(_coords);
2544 DataArrayInt *c=0,*ci=0;
2545 MEDCouplingUMesh::ExtractFromIndexedArrays2(start,end,step,_conn,_conn_indx,c,ci);
2546 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2547 ret->setNodalConnectivity(c,ci);
2551 void MEDCoupling1DGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const throw(INTERP_KERNEL::Exception)
2553 int sz((int)nodeIdsInUse.size());
2554 int nbCells(getNumberOfCells());
2555 const int *w(_conn->begin()),*wi(_conn_indx->begin());
2556 for(int i=0;i<nbCells;i++,wi++)
2557 for(const int *pt=w+wi[0];pt!=w+wi[1];pt++)
2560 if(*pt>=0 && *pt<sz)
2561 nodeIdsInUse[*pt]=true;
2564 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeNodeIdsAlg : At cell #" << i << " presence of node id #" << *pt << " should be in [0," << sz << ") !";
2565 throw INTERP_KERNEL::Exception(oss.str().c_str());
2570 void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception)
2572 checkFullyDefined();
2573 int nbOfNodes=getNumberOfNodes();
2574 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
2575 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
2576 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
2577 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2578 int nbOfCells=getNumberOfCells();
2579 int nbOfEltsInRevNodal=0;
2580 for(int eltId=0;eltId<nbOfCells;eltId++)
2582 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2583 if(nbOfNodesPerCell>=0)
2585 for(int j=0;j<nbOfNodesPerCell;j++)
2587 int nodeId=conn[conni[eltId]+j];
2588 if(nodeId==-1) continue;
2589 if(nodeId>=0 && nodeId<nbOfNodes)
2591 nbOfEltsInRevNodal++;
2592 revNodalIndxPtr[nodeId+1]++;
2596 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
2597 throw INTERP_KERNEL::Exception(oss.str().c_str());
2603 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << "nodal connectivity is invalid !";
2604 throw INTERP_KERNEL::Exception(oss.str().c_str());
2607 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
2608 conn=_conn->begin();
2609 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
2610 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
2611 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
2612 for(int eltId=0;eltId<nbOfCells;eltId++)
2614 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2615 for(int j=0;j<nbOfNodesPerCell;j++)
2617 int nodeId=conn[conni[eltId]+j];
2619 *std::find_if(revNodalPtr+revNodalIndxPtr[nodeId],revNodalPtr+revNodalIndxPtr[nodeId+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
2624 void MEDCoupling1DGTUMesh::checkFullyDefined() const throw(INTERP_KERNEL::Exception)
2626 if(!((const DataArrayInt *)_conn) || !((const DataArrayInt *)_conn_indx) || !((const DataArrayDouble *)_coords))
2627 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined.");
2630 bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
2632 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !");
2635 void MEDCoupling1DGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
2638 double time=getTime(it,order);
2639 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
2641 littleStrings.push_back(getName());
2642 littleStrings.push_back(getDescription());
2643 littleStrings.push_back(getTimeUnit());
2645 std::vector<std::string> littleStrings2,littleStrings3,littleStrings4;
2646 if((const DataArrayDouble *)_coords)
2647 _coords->getTinySerializationStrInformation(littleStrings2);
2648 if((const DataArrayInt *)_conn)
2649 _conn->getTinySerializationStrInformation(littleStrings3);
2650 if((const DataArrayInt *)_conn_indx)
2651 _conn_indx->getTinySerializationStrInformation(littleStrings4);
2652 int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size()),sz2((int)littleStrings4.size());
2653 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
2654 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
2655 littleStrings.insert(littleStrings.end(),littleStrings4.begin(),littleStrings4.end());
2657 tinyInfo.push_back(getCellModelEnum());
2658 tinyInfo.push_back(it);
2659 tinyInfo.push_back(order);
2660 std::vector<int> tinyInfo2,tinyInfo3,tinyInfo4;
2661 if((const DataArrayDouble *)_coords)
2662 _coords->getTinySerializationIntInformation(tinyInfo2);
2663 if((const DataArrayInt *)_conn)
2664 _conn->getTinySerializationIntInformation(tinyInfo3);
2665 if((const DataArrayInt *)_conn_indx)
2666 _conn_indx->getTinySerializationIntInformation(tinyInfo4);
2667 int sz3((int)tinyInfo2.size()),sz4((int)tinyInfo3.size()),sz5((int)tinyInfo4.size());
2668 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3); tinyInfo.push_back(sz4); tinyInfo.push_back(sz5);
2669 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
2670 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
2671 tinyInfo.insert(tinyInfo.end(),tinyInfo4.begin(),tinyInfo4.end());
2673 tinyInfoD.push_back(time);
2676 void MEDCoupling1DGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
2678 std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+tinyInfo[6]);
2679 std::vector<int> tinyInfo1(tinyInfo.begin()+9+tinyInfo[6],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]);
2680 std::vector<int> tinyInfo12(tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]+tinyInfo[8]);
2681 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(DataArrayInt::New()); p1->resizeForUnserialization(tinyInfo1);
2682 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(DataArrayInt::New()); p2->resizeForUnserialization(tinyInfo12);
2683 std::vector<const DataArrayInt *> v(2); v[0]=p1; v[1]=p2;
2684 p2=DataArrayInt::Aggregate(v);
2685 a2->resizeForUnserialization(tinyInfo2);
2686 a1->alloc(p2->getNbOfElems(),1);
2689 void MEDCoupling1DGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
2692 if((const DataArrayInt *)_conn)
2693 if(_conn->isAllocated())
2694 sz=_conn->getNbOfElems();
2695 if((const DataArrayInt *)_conn_indx)
2696 if(_conn_indx->isAllocated())
2697 sz+=_conn_indx->getNbOfElems();
2698 a1=DataArrayInt::New();
2700 int *work(a1->getPointer());
2701 if(sz!=0 && (const DataArrayInt *)_conn)
2702 work=std::copy(_conn->begin(),_conn->end(),a1->getPointer());
2703 if(sz!=0 && (const DataArrayInt *)_conn_indx)
2704 std::copy(_conn_indx->begin(),_conn_indx->end(),work);
2706 if((const DataArrayDouble *)_coords)
2707 if(_coords->isAllocated())
2708 sz=_coords->getNbOfElems();
2709 a2=DataArrayDouble::New();
2711 if(sz!=0 && (const DataArrayDouble *)_coords)
2712 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
2715 void MEDCoupling1DGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
2716 const std::vector<std::string>& littleStrings)
2718 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
2719 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
2720 setName(littleStrings[0].c_str());
2721 setDescription(littleStrings[1].c_str());
2722 setTimeUnit(littleStrings[2].c_str());
2723 setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
2724 int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]),sz4(tinyInfo[7]),sz5(tinyInfo[8]);
2726 _coords=DataArrayDouble::New();
2727 std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+sz3);
2728 _coords->resizeForUnserialization(tinyInfo2);
2729 std::copy(a2->begin(),a2->end(),_coords->getPointer());
2730 _conn=DataArrayInt::New();
2731 std::vector<int> tinyInfo3(tinyInfo.begin()+9+sz3,tinyInfo.begin()+9+sz3+sz4);
2732 _conn->resizeForUnserialization(tinyInfo3);
2733 std::copy(a1->begin(),a1->begin()+_conn->getNbOfElems(),_conn->getPointer());
2734 _conn_indx=DataArrayInt::New();
2735 std::vector<int> tinyInfo4(tinyInfo.begin()+9+sz3+sz4,tinyInfo.begin()+9+sz3+sz4+sz5);
2736 _conn_indx->resizeForUnserialization(tinyInfo4);
2737 std::copy(a1->begin()+_conn->getNbOfElems(),a1->end(),_conn_indx->getPointer());
2738 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
2739 _coords->finishUnserialization(tinyInfo2,littleStrings2);
2740 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
2741 _conn->finishUnserialization(tinyInfo3,littleStrings3);
2742 std::vector<std::string> littleStrings4(littleStrings.begin()+3+sz0+sz1,littleStrings.begin()+3+sz0+sz1+sz2);
2743 _conn_indx->finishUnserialization(tinyInfo4,littleStrings4);
2747 * Finds nodes not used in any cell and returns an array giving a new id to every node
2748 * by excluding the unused nodes, for which the array holds -1. The result array is
2749 * a mapping in "Old to New" mode.
2750 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
2751 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
2752 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
2753 * if the node is unused or a new id else. The caller is to delete this
2754 * array using decrRef() as it is no more needed.
2755 * \throw If the coordinates array is not set.
2756 * \throw If the nodal connectivity of cells is not defined.
2757 * \throw If the nodal connectivity includes an invalid id.
2759 DataArrayInt *MEDCoupling1DGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception)
2762 int nbOfNodes=getNumberOfNodes();
2763 int nbOfCells=getNumberOfCells();//checkCoherency
2764 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2765 ret->alloc(nbOfNodes,1);
2766 int *traducer=ret->getPointer();
2767 std::fill(traducer,traducer+nbOfNodes,-1);
2768 const int *conn=_conn->begin(),*conni(_conn_indx->begin());
2769 for(int i=0;i<nbOfCells;i++,conni++)
2771 int nbNodesPerCell=conni[1]-conni[0];
2772 for(int j=0;j<nbNodesPerCell;j++)
2774 int nodeId=conn[conni[0]+j];
2775 if(nodeId==-1) continue;
2776 if(nodeId>=0 && nodeId<nbOfNodes)
2780 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << nodeId << " not in [0," << nbOfNodes << ") !";
2781 throw INTERP_KERNEL::Exception(oss.str().c_str());
2785 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
2786 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
2791 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
2792 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
2793 * This method is a generalization of shiftNodeNumbersInConn().
2794 * \warning This method performs no check of validity of new ids. **Use it with care !**
2795 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
2796 * this->getNumberOfNodes(), in "Old to New" mode.
2797 * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
2798 * \throw If the nodal connectivity of cells is not defined.
2800 void MEDCoupling1DGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
2802 getNumberOfCells();//only to check that all is well defined.
2804 int nbElemsIn=getNumberOfNodes();
2805 int nbOfTuples=_conn->getNumberOfTuples();
2806 int *pt=_conn->getPointer();
2807 for(int i=0;i<nbOfTuples;i++,pt++)
2809 if(*pt==-1) continue;
2810 if(*pt>=0 && *pt<nbElemsIn)
2811 *pt=newNodeNumbersO2N[*pt];
2814 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
2815 throw INTERP_KERNEL::Exception(oss.str().c_str());
2818 _conn->declareAsNew();
2824 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
2825 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
2826 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
2827 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
2829 * \param [in] begin input start of array of node ids.
2830 * \param [in] end input end of array of node ids.
2831 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
2832 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
2834 void MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
2836 int nbOfCells=getNumberOfCells();
2837 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
2839 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
2840 std::vector<bool> fastFinder(sz,false);
2841 for(const int *work=begin;work!=end;work++)
2842 if(*work>=0 && *work<sz)
2843 fastFinder[*work]=true;
2844 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2845 for(int i=0;i<nbOfCells;i++,conni++)
2847 int ref=0,nbOfHit=0;
2848 int nbNodesPerCell=conni[1]-conni[0];
2849 if(nbNodesPerCell>=0)
2851 for(int j=0;j<nbNodesPerCell;j++)
2853 int nodeId=conn[conni[0]+j];
2857 if(fastFinder[nodeId])
2864 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !";
2865 throw INTERP_KERNEL::Exception(oss.str().c_str());
2867 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
2868 cellIdsKept->pushBackSilent(i);
2870 cellIdsKeptArr=cellIdsKept.retn();
2873 void MEDCoupling1DGTUMesh::allocateCells(int nbOfCells) throw(INTERP_KERNEL::Exception)
2876 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !");
2877 _conn=DataArrayInt::New();
2878 _conn->reserve(nbOfCells*3);
2879 _conn_indx=DataArrayInt::New();
2880 _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0);
2885 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
2887 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
2888 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
2889 * \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
2890 * attached to \a this.
2891 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
2893 void MEDCoupling1DGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) throw(INTERP_KERNEL::Exception)
2895 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
2896 DataArrayInt *c(_conn),*c2(_conn_indx);
2900 if(pos==c->getNumberOfTuples())
2902 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
2903 c2->pushBackSilent(pos+sz);
2907 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !";
2908 throw INTERP_KERNEL::Exception(oss.str().c_str());
2912 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !");
2915 void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex) throw(INTERP_KERNEL::Exception)
2918 nodalConn->incrRef();
2921 nodalConnIndex->incrRef();
2922 _conn_indx=nodalConnIndex;
2927 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
2929 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivity() const throw(INTERP_KERNEL::Exception)
2931 const DataArrayInt *ret(_conn);
2932 return const_cast<DataArrayInt *>(ret);
2936 * \return DataArrayInt * - the internal reference to the nodal connectivity index. The caller is not reponsible to deallocate it.
2938 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const throw(INTERP_KERNEL::Exception)
2940 const DataArrayInt *ret(_conn_indx);
2941 return const_cast<DataArrayInt *>(ret);
2945 * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here".
2946 * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity).
2947 * 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.
2949 * 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.
2951 * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal
2952 * connectivity arrays are different (false)
2953 * \return a new object to be managed by the caller.
2955 * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked
2957 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const throw(INTERP_KERNEL::Exception)
2959 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2960 DataArrayInt *nc=0,*nci=0;
2961 isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci);
2962 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ncs(nc),ncis(nci);
2963 ret->_conn=ncs; ret->_conn_indx=ncis;
2964 ret->setCoords(getCoords());
2969 * This method allows to compute, if needed, the packed nodal connectivity pair.
2970 * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges convered by nodal connectivity index array.
2971 * 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.
2973 * 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)
2974 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
2976 * 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
2979 * This method return 3 elements.
2980 * \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
2981 * this pointer can be seen as a new object, that is to managed by the caller.
2982 * \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
2983 * this pointer can be seen as a new object, that is to managed by the caller.
2984 * \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
2985 * output parameters are newly created objects.
2987 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
2989 bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const throw(INTERP_KERNEL::Exception)
2991 if(isPacked())//performs the checkCoherency
2993 const DataArrayInt *c0(_conn),*c1(_conn_indx);
2994 nodalConn=const_cast<DataArrayInt *>(c0); nodalConnIndx=const_cast<DataArrayInt *>(c1);
2995 nodalConn->incrRef(); nodalConnIndx->incrRef();
2998 int bg=_conn_indx->front(),end=_conn_indx->back();
2999 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nc(_conn->selectByTupleId2(bg,end,1));
3000 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nci(_conn_indx->deepCpy());
3001 nci->applyLin(1,-bg);
3002 nodalConn=nc.retn(); nodalConnIndx=nci.retn();
3007 * 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)
3008 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3009 * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned.
3010 * \return bool - true if \a this looks packed, false is not.
3012 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
3014 bool MEDCoupling1DGTUMesh::isPacked() const throw(INTERP_KERNEL::Exception)
3017 return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples();
3020 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2) throw(INTERP_KERNEL::Exception)
3022 std::vector<const MEDCoupling1DGTUMesh *> tmp(2);
3023 tmp[0]=const_cast<MEDCoupling1DGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1DGTUMesh *>(mesh2);
3024 return Merge1DGTUMeshes(tmp);
3027 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
3029 std::size_t sz=a.size();
3031 return Merge1DGTUMeshesLL(a);
3032 for(std::size_t ii=0;ii<sz;ii++)
3035 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::Merge1DGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
3036 throw INTERP_KERNEL::Exception(oss.str().c_str());
3038 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
3039 for(std::size_t ii=0;ii<sz;ii++)
3040 if(&(a[ii]->getCellModel())!=cm)
3041 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !");
3042 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > bb(sz);
3043 std::vector< const MEDCoupling1DGTUMesh * > aa(sz);
3045 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
3047 const MEDCoupling1DGTUMesh *cur=a[i];
3048 const DataArrayDouble *coo=cur->getCoords();
3050 spaceDim=coo->getNumberOfComponents();
3053 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !");
3054 for(std::size_t i=0;i<sz;i++)
3056 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
3059 return Merge1DGTUMeshesLL(aa);
3063 * \throw If presence of a null instance in the input vector \a a.
3064 * \throw If a is empty
3066 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
3069 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !");
3070 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3072 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !");
3073 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
3074 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3075 int nbOfCells=(*it)->getNumberOfCells();
3076 const DataArrayDouble *coords=(*it)->getCoords();
3077 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3079 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3080 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3082 for(int i=1;it!=a.end();i++,it++)
3085 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !");
3086 if(cm!=&((*it)->getCellModel()))
3087 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3088 (*it)->getNumberOfCells();//to check that all is OK
3089 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3090 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3091 if(coords!=(*it)->getCoords())
3092 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !");
3094 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3095 ret->setCoords(coords);
3096 ret->_conn=DataArrayInt::Aggregate(ncs);
3097 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3102 * 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)
3104 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
3107 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : input array must be NON EMPTY !");
3108 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
3109 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3110 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3111 std::vector<int> nbNodesPerElt(a.size());
3112 int nbOfCells=(*it)->getNumberOfCells();
3114 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3115 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3117 int prevNbOfNodes=(*it)->getNumberOfNodes();
3118 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3120 for(int i=1;it!=a.end();i++,it++)
3122 if(cm!=&((*it)->getCellModel()))
3123 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3124 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3125 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3126 nbOfCells+=(*it)->getNumberOfCells();
3127 nbNodesPerElt[i]=nbNodesPerElt[i-1]+prevNbOfNodes;
3128 prevNbOfNodes=(*it)->getNumberOfNodes();
3130 std::vector<const MEDCouplingPointSet *> aps(a.size());
3131 std::copy(a.begin(),a.end(),aps.begin());
3132 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
3133 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3134 ret->setCoords(pts);
3135 ret->_conn=AggregateNodalConnAndShiftNodeIds(ncs,nbNodesPerElt);
3136 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3140 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception)
3142 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
3143 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1,tmp2;
3144 const DataArrayInt *nodalConn(_conn),*nodalConnI(_conn_indx);
3147 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
3155 tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
3159 ret->_conn_indx=tmp2;
3163 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
3164 ret->setCoords(coords);
3167 ret->setCoords(_coords);
3172 * This method aggregate the bbox of each cell and put it into bbox parameter.
3174 * \return DataArrayDouble * - having \a this number of cells tuples and 2*spacedim components.
3176 * \throw If \a this is not fully set (coordinates and connectivity).
3177 * \throw If a cell in \a this has no valid nodeId.
3179 DataArrayDouble *MEDCoupling1DGTUMesh::getBoundingBoxForBBTree() const
3181 checkFullyDefined();
3182 int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes());
3183 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
3184 double *bbox(ret->getPointer());
3185 for(int i=0;i<nbOfCells*spaceDim;i++)
3187 bbox[2*i]=std::numeric_limits<double>::max();
3188 bbox[2*i+1]=-std::numeric_limits<double>::max();
3190 const double *coordsPtr(_coords->getConstPointer());
3191 const int *conn(_conn->getConstPointer()),*connI(_conn_indx->getConstPointer());
3192 for(int i=0;i<nbOfCells;i++)
3194 int offset=connI[i];
3195 int nbOfNodesForCell=connI[i+1]-offset;
3196 for(int j=0;j<nbOfNodesForCell;j++)
3198 int nodeId=conn[offset+j];
3200 if(nodeId>=0 && nodeId<nbOfNodes)
3202 for(int k=0;k<spaceDim;k++)
3204 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
3205 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
3211 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
3212 throw INTERP_KERNEL::Exception(oss.str().c_str());
3219 std::vector<int> MEDCoupling1DGTUMesh::BuildAPolygonFromParts(const std::vector< std::vector<int> >& parts) throw(INTERP_KERNEL::Exception)
3221 std::vector<int> ret;
3224 ret.insert(ret.end(),parts[0].begin(),parts[0].end());
3225 int ref(ret.back());
3226 std::size_t sz(parts.size()),nbh(1);
3227 std::vector<bool> b(sz,true); b[0]=false;
3231 for(;i<sz;i++) if(b[i] && parts[i].front()==ref) { ret.insert(ret.end(),parts[i].begin()+1,parts[i].end()); nbh++; break; }
3235 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::BuildAPolygonFromParts : the input vector is not a part of a single polygon !");
3237 if(ret.back()==ret.front())
3243 * This method performs an aggregation of \a nodalConns (as DataArrayInt::Aggregate does) but in addition of that a shift is applied on the
3244 * values contained in \a nodalConns using corresponding offset specified in input \a offsetInNodeIdsPerElt.
3245 * But it also manage the values -1, that have a semantic in MEDCoupling1DGTUMesh class (separator for polyhedron).
3247 * \param [in] nodalConns - a list of nodal connectivity arrays same size than \a offsetInNodeIdsPerElt.
3248 * \param [in] offsetInNodeIdsPerElt - a list of offsets to apply.
3249 * \return DataArrayInt * - A new object (to be managed by the caller) that is the result of the aggregation.
3250 * \throw If \a nodalConns or \a offsetInNodeIdsPerElt are empty.
3251 * \throw If \a nodalConns and \a offsetInNodeIdsPerElt have not the same size.
3252 * \throw If presence of null pointer in \a nodalConns.
3253 * \throw If presence of not allocated or array with not exactly one component in \a nodalConns.
3255 DataArrayInt *MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds(const std::vector<const DataArrayInt *>& nodalConns, const std::vector<int>& offsetInNodeIdsPerElt) throw(INTERP_KERNEL::Exception)
3257 std::size_t sz1(nodalConns.size()),sz2(offsetInNodeIdsPerElt.size());
3259 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : input vectors do not have the same size !");
3261 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : empty vectors in input !");
3263 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++)
3266 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of null pointer in input vector !");
3267 if(!(*it)->isAllocated())
3268 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of non allocated array in input vector !");
3269 if((*it)->getNumberOfComponents()!=1)
3270 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of array with not exactly one component !");
3271 nbOfTuples+=(*it)->getNumberOfTuples();
3273 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
3274 int *pt=ret->getPointer();
3276 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++,i++)
3278 int curNbt=(*it)->getNumberOfTuples();
3279 const int *inPt=(*it)->begin();
3280 int offset=offsetInNodeIdsPerElt[i];
3281 for(int j=0;j<curNbt;j++,pt++)
3292 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception)
3295 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh is null !");
3296 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
3298 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh must have exactly one geometric type !");
3299 int geoType((int)*gts.begin());
3300 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(m->getName().c_str(),*gts.begin()));
3301 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription().c_str());
3302 int nbCells(m->getNumberOfCells());
3303 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
3304 conn->alloc(m->getMeshLength()-nbCells,1); connI->alloc(nbCells+1,1);
3305 int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
3306 const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
3307 for(int i=0;i<nbCells;i++,ciin++,ci++)
3309 if(cin[ciin[0]]==geoType)
3311 if(ciin[1]-ciin[0]>=1)
3313 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
3314 ci[1]=ci[0]+ciin[1]-ciin[0]-1;
3318 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 !";
3319 throw INTERP_KERNEL::Exception(oss.str().c_str());
3324 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 !";
3325 throw INTERP_KERNEL::Exception(oss.str().c_str());
3328 ret->setNodalConnectivity(conn,connI);