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 * - newly created object (to be managed by the caller) \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++)
1807 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1810 if(nodeId>=0 && nodeId<nbOfNodes)
1812 for(int k=0;k<spaceDim;k++)
1814 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
1815 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
1822 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
1823 throw INTERP_KERNEL::Exception(oss.str().c_str());
1831 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New()
1833 return new MEDCoupling1DGTUMesh;
1836 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
1838 if(type==INTERP_KERNEL::NORM_ERROR)
1839 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
1840 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
1843 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !";
1844 throw INTERP_KERNEL::Exception(oss.str().c_str());
1846 return new MEDCoupling1DGTUMesh(name,cm);
1849 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh()
1853 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
1857 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
1861 const DataArrayInt *c(other._conn);
1866 _conn_indx=c->deepCpy();
1870 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const
1872 return new MEDCoupling1DGTUMesh(*this,recDeepCpy);
1876 * This method behaves mostly like MEDCoupling1DGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
1877 * The coordinates are shared between \a this and the returned instance.
1879 * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
1880 * \sa MEDCoupling1DGTUMesh::deepCpy
1882 MEDCouplingPointSet *MEDCoupling1DGTUMesh::deepCpyConnectivityOnly() const throw(INTERP_KERNEL::Exception)
1885 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(clone(false));
1886 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy()),ci(_conn_indx->deepCpy());
1887 ret->setNodalConnectivity(c,ci);
1891 void MEDCoupling1DGTUMesh::updateTime() const
1893 MEDCoupling1GTUMesh::updateTime();
1894 const DataArrayInt *c(_conn);
1902 std::size_t MEDCoupling1DGTUMesh::getHeapMemorySize() const
1905 const DataArrayInt *c(_conn);
1907 ret+=c->getHeapMemorySize();
1910 ret+=c->getHeapMemorySize();
1911 return MEDCoupling1GTUMesh::getHeapMemorySize()+ret;
1914 MEDCouplingMesh *MEDCoupling1DGTUMesh::deepCpy() const
1919 bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
1922 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !");
1923 std::ostringstream oss; oss.precision(15);
1924 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1927 reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !";
1930 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
1932 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1937 reason="in connectivity of single dynamic geometric type exactly one among this and other is null !";
1940 if(!c1->isEqualIfNotWhy(*c2,reason))
1942 reason.insert(0,"Nodal connectivity DataArrayInt differs : ");
1945 c1=_conn_indx; c2=otherC->_conn_indx;
1950 reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !";
1953 if(!c1->isEqualIfNotWhy(*c2,reason))
1955 reason.insert(0,"Nodal connectivity index DataArrayInt differs : ");
1961 bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
1964 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
1965 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1968 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
1970 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1975 if(!c1->isEqualWithoutConsideringStr(*c2))
1978 c1=_conn_indx; c2=otherC->_conn_indx;
1983 if(!c1->isEqualWithoutConsideringStr(*c2))
1989 * Checks if \a this and \a other meshes are geometrically equivalent with high
1990 * probability, else an exception is thrown. The meshes are considered equivalent if
1991 * (1) meshes contain the same number of nodes and the same number of elements of the
1992 * same types (2) three cells of the two meshes (first, last and middle) are based
1993 * on coincident nodes (with a specified precision).
1994 * \param [in] other - the mesh to compare with.
1995 * \param [in] prec - the precision used to compare nodes of the two meshes.
1996 * \throw If the two meshes do not match.
1998 void MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception)
2000 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
2001 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2003 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single dynamic geometric type !");
2004 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2008 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
2009 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2010 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
2011 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2012 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
2013 if(c1->getHashCode()!=c2->getHashCode())
2014 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs");
2016 c1=_conn_indx; c2=otherC->_conn_indx;
2020 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !");
2021 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2022 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !");
2023 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2024 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !");
2025 if(c1->getHashCode()!=c2->getHashCode())
2026 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs");
2030 void MEDCoupling1DGTUMesh::checkCoherencyOfConnectivity() const throw(INTERP_KERNEL::Exception)
2032 const DataArrayInt *c1(_conn);
2035 if(c1->getNumberOfComponents()!=1)
2036 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
2037 if(c1->getInfoOnComponent(0)!="")
2038 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
2039 c1->checkAllocated();
2042 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
2044 int sz2=_conn->getNumberOfTuples();
2048 if(c1->getNumberOfComponents()!=1)
2049 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
2050 c1->checkAllocated();
2051 if(c1->getNumberOfTuples()<1)
2052 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !");
2053 if(c1->getInfoOnComponent(0)!="")
2054 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
2055 int f=c1->front(),ll=c1->back();
2058 std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !";
2059 throw INTERP_KERNEL::Exception(oss.str().c_str());
2063 std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !";
2064 throw INTERP_KERNEL::Exception(oss.str().c_str());
2068 std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !";
2069 throw INTERP_KERNEL::Exception(oss.str().c_str());
2073 throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !");
2074 int szOfC1Exp=_conn_indx->back();
2077 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() << " !";
2078 throw INTERP_KERNEL::Exception(oss.str().c_str());
2083 * 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.
2084 * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one.
2085 * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array.
2087 void MEDCoupling1DGTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
2089 MEDCouplingPointSet::checkCoherency();
2090 checkCoherencyOfConnectivity();
2093 void MEDCoupling1DGTUMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
2096 const DataArrayInt *c1(_conn),*c2(_conn_indx);
2097 if(!c2->isMonotonic(true))
2098 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkCoherency1 : the nodal connectivity index is expected to be increasing monotinic !");
2100 int nbOfTuples=c1->getNumberOfTuples();
2101 int nbOfNodes=getNumberOfNodes();
2102 const int *w(c1->begin());
2103 for(int i=0;i<nbOfTuples;i++,w++)
2105 if(*w==-1) continue;
2106 if(*w<0 || *w>=nbOfNodes)
2108 std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !";
2109 throw INTERP_KERNEL::Exception(oss.str().c_str());
2114 void MEDCoupling1DGTUMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
2116 checkCoherency1(eps);
2119 int MEDCoupling1DGTUMesh::getNumberOfCells() const
2121 checkCoherencyOfConnectivity();//do not remove
2122 return _conn_indx->getNumberOfTuples()-1;
2126 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2127 * For each cell in \b this the number of nodes constituting cell is computed.
2128 * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned.
2129 * So for pohyhedrons some nodes can be counted several times in the returned result.
2131 * \return a newly allocated array
2133 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
2136 _conn_indx->checkMonotonic(true);
2137 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2138 return _conn_indx->deltaShiftIndex();
2140 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2141 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2142 ret->alloc(nbOfCells,1);
2143 int *retPtr=ret->getPointer();
2144 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2145 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2146 *retPtr=ci[1]-ci[0]-std::count(c+ci[0],c+ci[1],-1);
2151 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2152 * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed.
2154 * \return a newly allocated array
2156 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception)
2159 _conn_indx->checkMonotonic(true);
2160 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG)
2161 return _conn_indx->deltaShiftIndex();
2162 if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG)
2164 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=_conn_indx->deltaShiftIndex();
2165 ret->applyDivideBy(2);
2169 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2170 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2171 ret->alloc(nbOfCells,1);
2172 int *retPtr=ret->getPointer();
2173 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2174 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2175 *retPtr=std::count(c+ci[0],c+ci[1],-1)+1;
2180 * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell,
2181 * will be counted only once here whereas it will be counted several times in MEDCoupling1DGTUMesh::computeNbOfNodesPerCell method.
2183 * \return DataArrayInt * - new object to be deallocated by the caller.
2184 * \sa MEDCoupling1DGTUMesh::computeNbOfNodesPerCell
2186 DataArrayInt *MEDCoupling1DGTUMesh::computeEffectiveNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
2189 _conn_indx->checkMonotonic(true);
2190 int nbOfCells(_conn_indx->getNumberOfTuples()-1);
2191 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2192 ret->alloc(nbOfCells,1);
2193 int *retPtr(ret->getPointer());
2194 const int *ci(_conn_indx->begin()),*c(_conn->begin());
2195 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2197 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2199 std::set<int> s(c+ci[0],c+ci[1]);
2200 *retPtr=(int)s.size();
2205 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2207 std::set<int> s(c+ci[0],c+ci[1]); s.erase(-1);
2208 *retPtr=(int)s.size();
2214 void MEDCoupling1DGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
2216 int nbOfCells(getNumberOfCells());//performs checks
2217 if(cellId>=0 && cellId<nbOfCells)
2219 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2220 int nbOfNodes=stp-strt;
2222 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !");
2223 conn.resize(nbOfNodes);
2224 std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin());
2228 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2229 throw INTERP_KERNEL::Exception(oss.str().c_str());
2233 int MEDCoupling1DGTUMesh::getNumberOfNodesInCell(int cellId) const throw(INTERP_KERNEL::Exception)
2235 int nbOfCells(getNumberOfCells());//performs checks
2236 if(cellId>=0 && cellId<nbOfCells)
2238 const int *conn(_conn->begin());
2239 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2240 return stp-strt-std::count(conn+strt,conn+stp,-1);
2244 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNumberOfNodesInCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2245 throw INTERP_KERNEL::Exception(oss.str().c_str());
2249 std::string MEDCoupling1DGTUMesh::simpleRepr() const
2251 static const char msg0[]="No coordinates specified !";
2252 std::ostringstream ret;
2253 ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
2254 ret << "Description of mesh : \"" << getDescription() << "\"\n";
2256 double tt=getTime(tmpp1,tmpp2);
2257 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
2258 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
2259 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
2262 const int spaceDim=getSpaceDimension();
2263 ret << spaceDim << "\nInfo attached on space dimension : ";
2264 for(int i=0;i<spaceDim;i++)
2265 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
2269 ret << msg0 << "\n";
2270 ret << "Number of nodes : ";
2272 ret << getNumberOfNodes() << "\n";
2274 ret << msg0 << "\n";
2275 ret << "Number of cells : ";
2277 try { checkCoherency(); } catch(INTERP_KERNEL::Exception& e)
2279 ret << "Nodal connectivity arrays are not set or badly set !\n";
2283 ret << getNumberOfCells() << "\n";
2284 ret << "Cell type : " << _cm->getRepr() << "\n";
2288 std::string MEDCoupling1DGTUMesh::advancedRepr() const
2290 std::ostringstream ret;
2291 ret << simpleRepr();
2292 ret << "\nCoordinates array : \n___________________\n\n";
2294 _coords->reprWithoutNameStream(ret);
2296 ret << "No array set !\n";
2297 ret << "\n\nNodal Connectivity : \n____________________\n\n";
2300 try { checkCoherency1(); } catch(INTERP_KERNEL::Exception& e)
2302 ret << "Nodal connectivity arrays are not set or badly set !\n";
2307 int nbOfCells=getNumberOfCells();
2308 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2309 for(int i=0;i<nbOfCells;i++,ci++)
2311 ret << "Cell #" << i << " : ";
2312 std::copy(c+ci[0],c+ci[1],std::ostream_iterator<int>(ret," "));
2318 DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
2320 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
2321 int spaceDim=getSpaceDimension();
2322 int nbOfCells=getNumberOfCells();//checkCoherency()
2323 int nbOfNodes=getNumberOfNodes();
2324 ret->alloc(nbOfCells,spaceDim);
2325 double *ptToFill=ret->getPointer();
2326 const double *coor=_coords->begin();
2327 const int *nodal=_conn->begin(),*nodali=_conn_indx->begin();
2329 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2331 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2333 std::fill(ptToFill,ptToFill+spaceDim,0.);
2334 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2336 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2338 if(*nodal>=0 && *nodal<nbOfNodes)
2339 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2342 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2343 throw INTERP_KERNEL::Exception(oss.str().c_str());
2345 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(nodali[1]-nodali[0])));
2350 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !";
2351 throw INTERP_KERNEL::Exception(oss.str().c_str());
2357 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2359 std::fill(ptToFill,ptToFill+spaceDim,0.);
2360 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2363 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2365 if(*nodal==-1) continue;
2366 if(*nodal>=0 && *nodal<nbOfNodes)
2368 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2373 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2374 throw INTERP_KERNEL::Exception(oss.str().c_str());
2378 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./nbOfNod));
2381 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !";
2382 throw INTERP_KERNEL::Exception(oss.str().c_str());
2387 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : at cell #" << i << " the nodal index array is invalid !";
2388 throw INTERP_KERNEL::Exception(oss.str().c_str());
2395 void MEDCoupling1DGTUMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
2397 int nbCells=getNumberOfCells();
2398 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
2399 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
2401 o2n=o2n->checkAndPreparePermutation();
2403 const int *o2nPtr=o2n->getPointer();
2404 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2405 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
2406 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
2407 newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1);
2408 newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx);
2410 int *newC=newConn->getPointer(),*newCI=newConnI->getPointer();
2411 for(int i=0;i<nbCells;i++)
2413 int newPos=o2nPtr[i];
2414 int sz=conni[i+1]-conni[i];
2419 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !";
2420 throw INTERP_KERNEL::Exception(oss.str().c_str());
2423 newConnI->computeOffsets2(); newCI=newConnI->getPointer();
2425 for(int i=0;i<nbCells;i++,conni++)
2427 int sz=conni[1]-conni[0];
2429 std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]);
2432 _conn_indx=newConnI;
2435 MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
2437 if(other->getType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED)
2438 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !");
2439 const MEDCoupling1DGTUMesh *otherC=static_cast<const MEDCoupling1DGTUMesh *>(other);
2440 return Merge1DGTUMeshes(this,otherC);
2443 MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
2445 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName().c_str(),getMeshDimension());
2446 ret->setCoords(getCoords());
2447 const int *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin();
2448 int nbCells=getNumberOfCells();//checkCoherency
2449 int geoType=(int)getCellModelEnum();
2450 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1);
2451 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::New(); cI->alloc(nbCells+1);
2452 int *cPtr=c->getPointer(),*ciPtr=cI->getPointer();
2454 for(int i=0;i<nbCells;i++,ciPtr++)
2456 int sz=nodalConnI[i+1]-nodalConnI[i];
2460 cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr);
2461 ciPtr[1]=ciPtr[0]+sz+1;
2465 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !";
2466 throw INTERP_KERNEL::Exception(oss.str().c_str());
2469 ret->setConnectivity(c,cI,true);
2474 * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes
2476 DataArrayInt *MEDCoupling1DGTUMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
2478 int nbOfCells=getNumberOfCells();
2479 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2480 ret->alloc(nbOfCells,1);
2485 void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
2487 stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
2488 stream << " Mesh dimension : " << getMeshDimension() << ".";
2490 { stream << " No coordinates set !"; return ; }
2491 if(!_coords->isAllocated())
2492 { stream << " Coordinates set but not allocated !"; return ; }
2493 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
2494 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
2496 try { checkCoherency(); } catch(INTERP_KERNEL::Exception& e)
2498 stream << std::endl << "Nodal connectivity NOT set properly !\n";
2502 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
2505 void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception)
2508 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
2509 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2511 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !");
2512 setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex());
2515 MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
2518 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
2519 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2521 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
2522 std::vector<const MEDCoupling1DGTUMesh *> ms(2);
2525 return Merge1DGTUMeshesOnSameCoords(ms);
2528 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
2531 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2532 ret->setCoords(_coords);
2533 DataArrayInt *c=0,*ci=0;
2534 MEDCouplingUMesh::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci);
2535 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2536 ret->setNodalConnectivity(c,ci);
2540 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
2543 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2544 ret->setCoords(_coords);
2545 DataArrayInt *c=0,*ci=0;
2546 MEDCouplingUMesh::ExtractFromIndexedArrays2(start,end,step,_conn,_conn_indx,c,ci);
2547 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2548 ret->setNodalConnectivity(c,ci);
2552 void MEDCoupling1DGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const throw(INTERP_KERNEL::Exception)
2554 int sz((int)nodeIdsInUse.size());
2555 int nbCells(getNumberOfCells());
2556 const int *w(_conn->begin()),*wi(_conn_indx->begin());
2557 for(int i=0;i<nbCells;i++,wi++)
2558 for(const int *pt=w+wi[0];pt!=w+wi[1];pt++)
2561 if(*pt>=0 && *pt<sz)
2562 nodeIdsInUse[*pt]=true;
2565 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeNodeIdsAlg : At cell #" << i << " presence of node id #" << *pt << " should be in [0," << sz << ") !";
2566 throw INTERP_KERNEL::Exception(oss.str().c_str());
2571 void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception)
2573 checkFullyDefined();
2574 int nbOfNodes=getNumberOfNodes();
2575 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
2576 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
2577 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
2578 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2579 int nbOfCells=getNumberOfCells();
2580 int nbOfEltsInRevNodal=0;
2581 for(int eltId=0;eltId<nbOfCells;eltId++)
2583 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2584 if(nbOfNodesPerCell>=0)
2586 for(int j=0;j<nbOfNodesPerCell;j++)
2588 int nodeId=conn[conni[eltId]+j];
2589 if(nodeId==-1) continue;
2590 if(nodeId>=0 && nodeId<nbOfNodes)
2592 nbOfEltsInRevNodal++;
2593 revNodalIndxPtr[nodeId+1]++;
2597 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
2598 throw INTERP_KERNEL::Exception(oss.str().c_str());
2604 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << "nodal connectivity is invalid !";
2605 throw INTERP_KERNEL::Exception(oss.str().c_str());
2608 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
2609 conn=_conn->begin();
2610 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
2611 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
2612 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
2613 for(int eltId=0;eltId<nbOfCells;eltId++)
2615 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2616 for(int j=0;j<nbOfNodesPerCell;j++)
2618 int nodeId=conn[conni[eltId]+j];
2620 *std::find_if(revNodalPtr+revNodalIndxPtr[nodeId],revNodalPtr+revNodalIndxPtr[nodeId+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
2625 void MEDCoupling1DGTUMesh::checkFullyDefined() const throw(INTERP_KERNEL::Exception)
2627 if(!((const DataArrayInt *)_conn) || !((const DataArrayInt *)_conn_indx) || !((const DataArrayDouble *)_coords))
2628 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined.");
2631 bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
2633 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !");
2636 void MEDCoupling1DGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
2639 double time=getTime(it,order);
2640 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
2642 littleStrings.push_back(getName());
2643 littleStrings.push_back(getDescription());
2644 littleStrings.push_back(getTimeUnit());
2646 std::vector<std::string> littleStrings2,littleStrings3,littleStrings4;
2647 if((const DataArrayDouble *)_coords)
2648 _coords->getTinySerializationStrInformation(littleStrings2);
2649 if((const DataArrayInt *)_conn)
2650 _conn->getTinySerializationStrInformation(littleStrings3);
2651 if((const DataArrayInt *)_conn_indx)
2652 _conn_indx->getTinySerializationStrInformation(littleStrings4);
2653 int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size()),sz2((int)littleStrings4.size());
2654 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
2655 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
2656 littleStrings.insert(littleStrings.end(),littleStrings4.begin(),littleStrings4.end());
2658 tinyInfo.push_back(getCellModelEnum());
2659 tinyInfo.push_back(it);
2660 tinyInfo.push_back(order);
2661 std::vector<int> tinyInfo2,tinyInfo3,tinyInfo4;
2662 if((const DataArrayDouble *)_coords)
2663 _coords->getTinySerializationIntInformation(tinyInfo2);
2664 if((const DataArrayInt *)_conn)
2665 _conn->getTinySerializationIntInformation(tinyInfo3);
2666 if((const DataArrayInt *)_conn_indx)
2667 _conn_indx->getTinySerializationIntInformation(tinyInfo4);
2668 int sz3((int)tinyInfo2.size()),sz4((int)tinyInfo3.size()),sz5((int)tinyInfo4.size());
2669 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3); tinyInfo.push_back(sz4); tinyInfo.push_back(sz5);
2670 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
2671 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
2672 tinyInfo.insert(tinyInfo.end(),tinyInfo4.begin(),tinyInfo4.end());
2674 tinyInfoD.push_back(time);
2677 void MEDCoupling1DGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
2679 std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+tinyInfo[6]);
2680 std::vector<int> tinyInfo1(tinyInfo.begin()+9+tinyInfo[6],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]);
2681 std::vector<int> tinyInfo12(tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]+tinyInfo[8]);
2682 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(DataArrayInt::New()); p1->resizeForUnserialization(tinyInfo1);
2683 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(DataArrayInt::New()); p2->resizeForUnserialization(tinyInfo12);
2684 std::vector<const DataArrayInt *> v(2); v[0]=p1; v[1]=p2;
2685 p2=DataArrayInt::Aggregate(v);
2686 a2->resizeForUnserialization(tinyInfo2);
2687 a1->alloc(p2->getNbOfElems(),1);
2690 void MEDCoupling1DGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
2693 if((const DataArrayInt *)_conn)
2694 if(_conn->isAllocated())
2695 sz=_conn->getNbOfElems();
2696 if((const DataArrayInt *)_conn_indx)
2697 if(_conn_indx->isAllocated())
2698 sz+=_conn_indx->getNbOfElems();
2699 a1=DataArrayInt::New();
2701 int *work(a1->getPointer());
2702 if(sz!=0 && (const DataArrayInt *)_conn)
2703 work=std::copy(_conn->begin(),_conn->end(),a1->getPointer());
2704 if(sz!=0 && (const DataArrayInt *)_conn_indx)
2705 std::copy(_conn_indx->begin(),_conn_indx->end(),work);
2707 if((const DataArrayDouble *)_coords)
2708 if(_coords->isAllocated())
2709 sz=_coords->getNbOfElems();
2710 a2=DataArrayDouble::New();
2712 if(sz!=0 && (const DataArrayDouble *)_coords)
2713 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
2716 void MEDCoupling1DGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
2717 const std::vector<std::string>& littleStrings)
2719 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
2720 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
2721 setName(littleStrings[0].c_str());
2722 setDescription(littleStrings[1].c_str());
2723 setTimeUnit(littleStrings[2].c_str());
2724 setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
2725 int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]),sz4(tinyInfo[7]),sz5(tinyInfo[8]);
2727 _coords=DataArrayDouble::New();
2728 std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+sz3);
2729 _coords->resizeForUnserialization(tinyInfo2);
2730 std::copy(a2->begin(),a2->end(),_coords->getPointer());
2731 _conn=DataArrayInt::New();
2732 std::vector<int> tinyInfo3(tinyInfo.begin()+9+sz3,tinyInfo.begin()+9+sz3+sz4);
2733 _conn->resizeForUnserialization(tinyInfo3);
2734 std::copy(a1->begin(),a1->begin()+_conn->getNbOfElems(),_conn->getPointer());
2735 _conn_indx=DataArrayInt::New();
2736 std::vector<int> tinyInfo4(tinyInfo.begin()+9+sz3+sz4,tinyInfo.begin()+9+sz3+sz4+sz5);
2737 _conn_indx->resizeForUnserialization(tinyInfo4);
2738 std::copy(a1->begin()+_conn->getNbOfElems(),a1->end(),_conn_indx->getPointer());
2739 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
2740 _coords->finishUnserialization(tinyInfo2,littleStrings2);
2741 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
2742 _conn->finishUnserialization(tinyInfo3,littleStrings3);
2743 std::vector<std::string> littleStrings4(littleStrings.begin()+3+sz0+sz1,littleStrings.begin()+3+sz0+sz1+sz2);
2744 _conn_indx->finishUnserialization(tinyInfo4,littleStrings4);
2748 * Finds nodes not used in any cell and returns an array giving a new id to every node
2749 * by excluding the unused nodes, for which the array holds -1. The result array is
2750 * a mapping in "Old to New" mode.
2751 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
2752 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
2753 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
2754 * if the node is unused or a new id else. The caller is to delete this
2755 * array using decrRef() as it is no more needed.
2756 * \throw If the coordinates array is not set.
2757 * \throw If the nodal connectivity of cells is not defined.
2758 * \throw If the nodal connectivity includes an invalid id.
2760 DataArrayInt *MEDCoupling1DGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception)
2763 int nbOfNodes=getNumberOfNodes();
2764 int nbOfCells=getNumberOfCells();//checkCoherency
2765 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2766 ret->alloc(nbOfNodes,1);
2767 int *traducer=ret->getPointer();
2768 std::fill(traducer,traducer+nbOfNodes,-1);
2769 const int *conn=_conn->begin(),*conni(_conn_indx->begin());
2770 for(int i=0;i<nbOfCells;i++,conni++)
2772 int nbNodesPerCell=conni[1]-conni[0];
2773 for(int j=0;j<nbNodesPerCell;j++)
2775 int nodeId=conn[conni[0]+j];
2776 if(nodeId==-1) continue;
2777 if(nodeId>=0 && nodeId<nbOfNodes)
2781 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << nodeId << " not in [0," << nbOfNodes << ") !";
2782 throw INTERP_KERNEL::Exception(oss.str().c_str());
2786 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
2787 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
2792 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
2793 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
2794 * This method is a generalization of shiftNodeNumbersInConn().
2795 * \warning This method performs no check of validity of new ids. **Use it with care !**
2796 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
2797 * this->getNumberOfNodes(), in "Old to New" mode.
2798 * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
2799 * \throw If the nodal connectivity of cells is not defined.
2801 void MEDCoupling1DGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
2803 getNumberOfCells();//only to check that all is well defined.
2805 int nbElemsIn=getNumberOfNodes();
2806 int nbOfTuples=_conn->getNumberOfTuples();
2807 int *pt=_conn->getPointer();
2808 for(int i=0;i<nbOfTuples;i++,pt++)
2810 if(*pt==-1) continue;
2811 if(*pt>=0 && *pt<nbElemsIn)
2812 *pt=newNodeNumbersO2N[*pt];
2815 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
2816 throw INTERP_KERNEL::Exception(oss.str().c_str());
2819 _conn->declareAsNew();
2825 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
2826 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
2827 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
2828 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
2830 * \param [in] begin input start of array of node ids.
2831 * \param [in] end input end of array of node ids.
2832 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
2833 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
2835 void MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
2837 int nbOfCells=getNumberOfCells();
2838 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
2840 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
2841 std::vector<bool> fastFinder(sz,false);
2842 for(const int *work=begin;work!=end;work++)
2843 if(*work>=0 && *work<sz)
2844 fastFinder[*work]=true;
2845 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2846 for(int i=0;i<nbOfCells;i++,conni++)
2848 int ref=0,nbOfHit=0;
2849 int nbNodesPerCell=conni[1]-conni[0];
2850 if(nbNodesPerCell>=0)
2852 for(int j=0;j<nbNodesPerCell;j++)
2854 int nodeId=conn[conni[0]+j];
2858 if(fastFinder[nodeId])
2865 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !";
2866 throw INTERP_KERNEL::Exception(oss.str().c_str());
2868 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
2869 cellIdsKept->pushBackSilent(i);
2871 cellIdsKeptArr=cellIdsKept.retn();
2874 void MEDCoupling1DGTUMesh::allocateCells(int nbOfCells) throw(INTERP_KERNEL::Exception)
2877 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !");
2878 _conn=DataArrayInt::New();
2879 _conn->reserve(nbOfCells*3);
2880 _conn_indx=DataArrayInt::New();
2881 _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0);
2886 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
2888 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
2889 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
2890 * \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
2891 * attached to \a this.
2892 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
2894 void MEDCoupling1DGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) throw(INTERP_KERNEL::Exception)
2896 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
2897 DataArrayInt *c(_conn),*c2(_conn_indx);
2901 if(pos==c->getNumberOfTuples())
2903 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
2904 c2->pushBackSilent(pos+sz);
2908 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !";
2909 throw INTERP_KERNEL::Exception(oss.str().c_str());
2913 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !");
2916 void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex) throw(INTERP_KERNEL::Exception)
2919 nodalConn->incrRef();
2922 nodalConnIndex->incrRef();
2923 _conn_indx=nodalConnIndex;
2928 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
2930 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivity() const throw(INTERP_KERNEL::Exception)
2932 const DataArrayInt *ret(_conn);
2933 return const_cast<DataArrayInt *>(ret);
2937 * \return DataArrayInt * - the internal reference to the nodal connectivity index. The caller is not reponsible to deallocate it.
2939 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const throw(INTERP_KERNEL::Exception)
2941 const DataArrayInt *ret(_conn_indx);
2942 return const_cast<DataArrayInt *>(ret);
2946 * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here".
2947 * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity).
2948 * 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.
2950 * 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.
2952 * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal
2953 * connectivity arrays are different (false)
2954 * \return a new object to be managed by the caller.
2956 * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked
2958 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const throw(INTERP_KERNEL::Exception)
2960 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2961 DataArrayInt *nc=0,*nci=0;
2962 isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci);
2963 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ncs(nc),ncis(nci);
2964 ret->_conn=ncs; ret->_conn_indx=ncis;
2965 ret->setCoords(getCoords());
2970 * This method allows to compute, if needed, the packed nodal connectivity pair.
2971 * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges convered by nodal connectivity index array.
2972 * 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.
2974 * 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)
2975 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
2977 * 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
2980 * This method return 3 elements.
2981 * \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
2982 * this pointer can be seen as a new object, that is to managed by the caller.
2983 * \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
2984 * this pointer can be seen as a new object, that is to managed by the caller.
2985 * \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
2986 * output parameters are newly created objects.
2988 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
2990 bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const throw(INTERP_KERNEL::Exception)
2992 if(isPacked())//performs the checkCoherency
2994 const DataArrayInt *c0(_conn),*c1(_conn_indx);
2995 nodalConn=const_cast<DataArrayInt *>(c0); nodalConnIndx=const_cast<DataArrayInt *>(c1);
2996 nodalConn->incrRef(); nodalConnIndx->incrRef();
2999 int bg=_conn_indx->front(),end=_conn_indx->back();
3000 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nc(_conn->selectByTupleId2(bg,end,1));
3001 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nci(_conn_indx->deepCpy());
3002 nci->applyLin(1,-bg);
3003 nodalConn=nc.retn(); nodalConnIndx=nci.retn();
3008 * 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)
3009 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3010 * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned.
3011 * \return bool - true if \a this looks packed, false is not.
3013 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
3015 bool MEDCoupling1DGTUMesh::isPacked() const throw(INTERP_KERNEL::Exception)
3018 return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples();
3021 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2) throw(INTERP_KERNEL::Exception)
3023 std::vector<const MEDCoupling1DGTUMesh *> tmp(2);
3024 tmp[0]=const_cast<MEDCoupling1DGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1DGTUMesh *>(mesh2);
3025 return Merge1DGTUMeshes(tmp);
3028 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
3030 std::size_t sz=a.size();
3032 return Merge1DGTUMeshesLL(a);
3033 for(std::size_t ii=0;ii<sz;ii++)
3036 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::Merge1DGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
3037 throw INTERP_KERNEL::Exception(oss.str().c_str());
3039 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
3040 for(std::size_t ii=0;ii<sz;ii++)
3041 if(&(a[ii]->getCellModel())!=cm)
3042 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !");
3043 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > bb(sz);
3044 std::vector< const MEDCoupling1DGTUMesh * > aa(sz);
3046 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
3048 const MEDCoupling1DGTUMesh *cur=a[i];
3049 const DataArrayDouble *coo=cur->getCoords();
3051 spaceDim=coo->getNumberOfComponents();
3054 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !");
3055 for(std::size_t i=0;i<sz;i++)
3057 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
3060 return Merge1DGTUMeshesLL(aa);
3064 * \throw If presence of a null instance in the input vector \a a.
3065 * \throw If a is empty
3067 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
3070 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !");
3071 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3073 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !");
3074 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
3075 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3076 int nbOfCells=(*it)->getNumberOfCells();
3077 const DataArrayDouble *coords=(*it)->getCoords();
3078 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3080 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3081 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3083 for(int i=1;it!=a.end();i++,it++)
3086 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !");
3087 if(cm!=&((*it)->getCellModel()))
3088 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3089 (*it)->getNumberOfCells();//to check that all is OK
3090 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3091 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3092 if(coords!=(*it)->getCoords())
3093 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !");
3095 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3096 ret->setCoords(coords);
3097 ret->_conn=DataArrayInt::Aggregate(ncs);
3098 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3103 * 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)
3105 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
3108 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : input array must be NON EMPTY !");
3109 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
3110 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3111 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3112 std::vector<int> nbNodesPerElt(a.size());
3113 int nbOfCells=(*it)->getNumberOfCells();
3115 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3116 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3118 int prevNbOfNodes=(*it)->getNumberOfNodes();
3119 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3121 for(int i=1;it!=a.end();i++,it++)
3123 if(cm!=&((*it)->getCellModel()))
3124 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3125 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3126 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3127 nbOfCells+=(*it)->getNumberOfCells();
3128 nbNodesPerElt[i]=nbNodesPerElt[i-1]+prevNbOfNodes;
3129 prevNbOfNodes=(*it)->getNumberOfNodes();
3131 std::vector<const MEDCouplingPointSet *> aps(a.size());
3132 std::copy(a.begin(),a.end(),aps.begin());
3133 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
3134 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3135 ret->setCoords(pts);
3136 ret->_conn=AggregateNodalConnAndShiftNodeIds(ncs,nbNodesPerElt);
3137 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3141 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception)
3143 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
3144 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1,tmp2;
3145 const DataArrayInt *nodalConn(_conn),*nodalConnI(_conn_indx);
3148 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
3156 tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
3160 ret->_conn_indx=tmp2;
3164 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
3165 ret->setCoords(coords);
3168 ret->setCoords(_coords);
3173 * This method aggregate the bbox of each cell and put it into bbox parameter.
3175 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
3177 * \throw If \a this is not fully set (coordinates and connectivity).
3178 * \throw If a cell in \a this has no valid nodeId.
3180 DataArrayDouble *MEDCoupling1DGTUMesh::getBoundingBoxForBBTree() const
3182 checkFullyDefined();
3183 int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes());
3184 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
3185 double *bbox(ret->getPointer());
3186 for(int i=0;i<nbOfCells*spaceDim;i++)
3188 bbox[2*i]=std::numeric_limits<double>::max();
3189 bbox[2*i+1]=-std::numeric_limits<double>::max();
3191 const double *coordsPtr(_coords->getConstPointer());
3192 const int *conn(_conn->getConstPointer()),*connI(_conn_indx->getConstPointer());
3193 for(int i=0;i<nbOfCells;i++)
3195 int offset=connI[i];
3196 int nbOfNodesForCell(connI[i+1]-offset),kk(0);
3197 for(int j=0;j<nbOfNodesForCell;j++)
3199 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]);
3212 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
3213 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);