1 // Copyright (C) 2007-2014 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, or (at your option) any later version.
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"
24 #include "MEDCouplingCMesh.hxx"
26 #include "SplitterTetra.hxx"
28 using namespace ParaMEDMEM;
30 const int MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[6]={0,1,2,4,3,5};
32 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh():_cm(0)
36 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):_cm(&cm)
41 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const MEDCoupling1GTUMesh& other, bool recDeepCpy):MEDCouplingPointSet(other,recDeepCpy),_cm(other._cm)
45 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
47 if(type==INTERP_KERNEL::NORM_ERROR)
48 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
49 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
51 return MEDCoupling1SGTUMesh::New(name,type);
53 return MEDCoupling1DGTUMesh::New(name,type);
56 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const MEDCouplingUMesh *m)
59 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh is null !");
60 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
62 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh must have exactly one geometric type !");
63 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*gts.begin());
65 return MEDCoupling1SGTUMesh::New(m);
67 return MEDCoupling1DGTUMesh::New(m);
70 const INTERP_KERNEL::CellModel& MEDCoupling1GTUMesh::getCellModel() const
75 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getCellModelEnum() const
77 return _cm->getEnum();
80 int MEDCoupling1GTUMesh::getMeshDimension() const
82 return (int)_cm->getDimension();
86 * This method returns a newly allocated array containing cell ids (ascendingly sorted) whose geometric type are equal to type.
87 * This method does not throw exception if geometric type \a type is not in \a this.
88 * This method throws an INTERP_KERNEL::Exception if meshdimension of \b this is not equal to those of \b type.
89 * The coordinates array is not considered here.
91 * \param [in] type the geometric type
92 * \return cell ids in this having geometric type \a type.
94 DataArrayInt *MEDCoupling1GTUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
96 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
97 if(type==getCellModelEnum())
98 ret->alloc(getNumberOfCells(),1);
106 * Returns nb of cells having the geometric type \a type. No throw if no cells in \a this has the geometric type \a type.
108 int MEDCoupling1GTUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
110 return type==getCellModelEnum()?getNumberOfCells():0;
114 * Returns a type of a cell by its id.
115 * \param [in] cellId - the id of the cell of interest.
116 * \return INTERP_KERNEL::NormalizedCellType - enumeration item describing the cell type.
117 * \throw If \a cellId is invalid. Valid range is [0, \a this->getNumberOfCells() ).
119 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getTypeOfCell(int cellId) const
121 if(cellId>=0 && cellId<getNumberOfCells())
122 return getCellModelEnum();
123 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::getTypeOfCell : Requesting type of cell #" << cellId << " but it should be in [0," << getNumberOfCells() << ") !";
124 throw INTERP_KERNEL::Exception(oss.str().c_str());
128 * Returns a set of all cell types available in \a this mesh.
129 * \return std::set<INTERP_KERNEL::NormalizedCellType> - the set of cell types.
130 * \warning this method does not throw any exception even if \a this is not defined.
132 std::set<INTERP_KERNEL::NormalizedCellType> MEDCoupling1GTUMesh::getAllGeoTypes() const
134 std::set<INTERP_KERNEL::NormalizedCellType> ret;
135 ret.insert(getCellModelEnum());
140 * This method expects that \a this is sorted by types. If not an exception will be thrown.
141 * This method returns in the same format as code (see MEDCouplingUMesh::checkTypeConsistencyAndContig or MEDCouplingUMesh::splitProfilePerType) how
142 * \a this is composed in cell types.
143 * The returned array is of size 3*n where n is the number of different types present in \a this.
144 * For every k in [0,n] ret[3*k+2]==-1 because it has no sense here.
145 * This parameter is kept only for compatibility with other methode listed above.
147 std::vector<int> MEDCoupling1GTUMesh::getDistributionOfTypes() const
149 std::vector<int> ret(3);
150 ret[0]=(int)getCellModelEnum(); ret[1]=getNumberOfCells(); ret[2]=-1;
155 * 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.
156 * 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.
157 * This method has 1 input \a profile and 3 outputs \a code \a idsInPflPerType and \a idsPerType.
159 * \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.
160 * \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,
161 * \a idsInPflPerType[i] stores the tuple ids in \a profile that correspond to the geometric type code[3*i+0]
162 * \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.
163 * This vector can be empty in case of all geometric type cells are fully covered in ascending in the given input \a profile.
165 * \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.
167 * \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
170 * - Before \a this has 3 cells \a profile contains [0,1,2]
171 * - After \a code contains [NORM_...,nbCells,-1], \a idsInPflPerType [[0,1,2]] and \a idsPerType is empty <br>
174 * - Before \a this has 3 cells \a profile contains [1,2]
175 * - After \a code contains [NORM_...,nbCells,0], \a idsInPflPerType [[0,1]] and \a idsPerType is [[1,2]] <br>
178 void MEDCoupling1GTUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const
181 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile is NULL !");
182 if(profile->getNumberOfComponents()!=1)
183 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile should have exactly one component !");
184 int nbTuples=profile->getNumberOfTuples();
185 int nbOfCells=getNumberOfCells();
186 code.resize(3); idsInPflPerType.resize(1);
187 code[0]=(int)getCellModelEnum(); code[1]=nbTuples;
188 idsInPflPerType.resize(1);
189 if(profile->isIdentity() && nbTuples==nbOfCells)
192 idsInPflPerType[0]=const_cast<DataArrayInt *>(profile); idsInPflPerType[0]->incrRef();
197 profile->checkAllIdsInRange(0,nbOfCells);
198 idsPerType.resize(1);
199 idsPerType[0]=const_cast<DataArrayInt *>(profile); idsPerType[0]->incrRef();
200 idsInPflPerType[0]=DataArrayInt::Range(0,nbTuples,1);
204 * This method tries to minimize at most the number of deep copy.
205 * So if \a idsPerType is not empty it can be returned directly (without copy, but with ref count incremented) in return.
207 * \sa MEDCouplingUMesh::checkTypeConsistencyAndContig
209 DataArrayInt *MEDCoupling1GTUMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const
211 int nbOfCells=getNumberOfCells();
213 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : invalid input code should be exactly of size 3 !");
214 if(code[0]!=(int)getCellModelEnum())
216 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() << ") !";
217 throw INTERP_KERNEL::Exception(oss.str().c_str());
221 if(code[1]==nbOfCells)
225 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : mismatch between the number of cells in this (" << nbOfCells << ") and the number of non profile (" << code[1] << ") !";
226 throw INTERP_KERNEL::Exception(oss.str().c_str());
230 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : single geo type mesh ! 0 or -1 is expected at pos #2 of input code !");
231 if(idsPerType.size()!=1)
232 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input code points to DataArrayInt #0 whereas the size of idsPerType is not equal to 1 !");
233 const DataArrayInt *pfl=idsPerType[0];
235 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : the input code points to a NULL DataArrayInt at rank 0 !");
236 if(pfl->getNumberOfComponents()!=1)
237 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input profile should have exactly one component !");
238 pfl->checkAllIdsInRange(0,nbOfCells);
240 return const_cast<DataArrayInt *>(pfl);
243 void MEDCoupling1GTUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const
245 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
246 m->writeVTKLL(ofs,cellData,pointData,byteData);
249 std::string MEDCoupling1GTUMesh::getVTKDataSetType() const
251 return std::string("UnstructuredGrid");
254 std::string MEDCoupling1GTUMesh::getVTKFileExtension() const
256 return std::string("vtu");
259 std::size_t MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren() const
261 return MEDCouplingPointSet::getHeapMemorySizeWithoutChildren();
264 bool MEDCoupling1GTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
266 if(!MEDCouplingPointSet::isEqualIfNotWhy(other,prec,reason))
269 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualIfNotWhy : input other pointer is null !");
270 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
273 reason="mesh given in input is not castable in MEDCouplingSGTUMesh !";
278 reason="mismatch in geometric type !";
284 bool MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
286 if(!MEDCouplingPointSet::isEqualWithoutConsideringStr(other,prec))
289 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
290 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
298 void MEDCoupling1GTUMesh::checkCoherency() const
300 MEDCouplingPointSet::checkCoherency();
303 DataArrayDouble *MEDCoupling1GTUMesh::getBarycenterAndOwner() const
305 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
306 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=m->getBarycenterAndOwner();
310 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureField(bool isAbs) const
312 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
313 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureField(isAbs);
318 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureFieldOnNode(bool isAbs) const
320 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
321 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureFieldOnNode(isAbs);
329 int MEDCoupling1GTUMesh::getCellContainingPoint(const double *pos, double eps) const
331 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
332 return m->getCellContainingPoint(pos,eps);
335 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::buildOrthogonalField() const
337 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
338 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->buildOrthogonalField();
343 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const double *bbox, double eps) const
345 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
346 return m->getCellsInBoundingBox(bbox,eps);
349 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps)
351 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
352 return m->getCellsInBoundingBox(bbox,eps);
355 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const
357 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
358 return m->buildFacePartOfMySelfNode(start,end,fullyIn);
361 DataArrayInt *MEDCoupling1GTUMesh::findBoundaryNodes() const
363 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
364 return m->findBoundaryNodes();
367 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildBoundaryMesh(bool keepCoords) const
369 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
370 return m->buildBoundaryMesh(keepCoords);
373 void MEDCoupling1GTUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const
375 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
376 m->findCommonCells(compType,startCellId,commonCellsArr,commonCellsIArr);
379 int MEDCoupling1GTUMesh::getNodalConnectivityLength() const
381 const DataArrayInt *c1(getNodalConnectivity());
383 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : no connectivity set !");
384 if(c1->getNumberOfComponents()!=1)
385 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array set must have exactly one component !");
386 if(!c1->isAllocated())
387 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array must be allocated !");
388 return c1->getNumberOfTuples();
392 * This method aggregates all the meshes in \a parts to put them in a single unstructured mesh (those returned).
393 * The order of cells is the returned instance is those in the order of instances in \a parts.
395 * \param [in] parts - all not null parts of single geo type meshes to be aggreagated having the same mesh dimension and same coordinates.
396 * \return MEDCouplingUMesh * - new object to be dealt by the caller.
398 * \throw If one element is null in \a parts.
399 * \throw If not all the parts do not have the same mesh dimension.
400 * \throw If not all the parts do not share the same coordinates.
401 * \throw If not all the parts have their connectivity set properly.
402 * \throw If \a parts is empty.
404 MEDCouplingUMesh *MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh(const std::vector< const MEDCoupling1GTUMesh *>& parts)
407 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : input parts vector is empty !");
408 const MEDCoupling1GTUMesh *firstPart(parts[0]);
410 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : the first instance in input parts is null !");
411 const DataArrayDouble *coords(firstPart->getCoords());
412 int meshDim(firstPart->getMeshDimension());
413 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret(MEDCouplingUMesh::New(firstPart->getName(),meshDim)); ret->setDescription(firstPart->getDescription());
414 ret->setCoords(coords);
415 int nbOfCells(0),connSize(0);
416 for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
419 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of null pointer in input vector !");
420 if((*it)->getMeshDimension()!=meshDim)
421 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances in input vector must have same mesh dimension !");
422 if((*it)->getCoords()!=coords)
423 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances must share the same coordinates pointer !");
424 nbOfCells+=(*it)->getNumberOfCells();
425 connSize+=(*it)->getNodalConnectivityLength();
427 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
428 connI->alloc(nbOfCells+1,1); conn->alloc(connSize+nbOfCells,1);
429 int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
430 for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
432 int curNbCells((*it)->getNumberOfCells());
433 int geoType((int)(*it)->getCellModelEnum());
434 const int *cinPtr((*it)->getNodalConnectivity()->begin());
435 const MEDCoupling1SGTUMesh *ps(dynamic_cast<const MEDCoupling1SGTUMesh *>(*it));
436 const MEDCoupling1DGTUMesh *pd(dynamic_cast<const MEDCoupling1DGTUMesh *>(*it));
439 int nNodesPerCell(ps->getNumberOfNodesPerCell());
440 for(int i=0;i<curNbCells;i++,ci++,cinPtr+=nNodesPerCell)
443 c=std::copy(cinPtr,cinPtr+nNodesPerCell,c);
444 ci[1]=ci[0]+nNodesPerCell+1;
449 const int *ciinPtr(pd->getNodalConnectivityIndex()->begin());
450 for(int i=0;i<curNbCells;i++,ci++,ciinPtr++)
453 c=std::copy(cinPtr+ciinPtr[0],cinPtr+ciinPtr[1],c);
454 ci[1]=ci[0]+ciinPtr[1]-ciinPtr[0]+1;
458 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of instance which type is not in [MEDCoupling1SGTUMesh,MEDCoupling1DGTUMesh] !");
460 ret->setConnectivity(conn,connI,true);
466 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const MEDCoupling1SGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
470 const DataArrayInt *c(other._conn);
476 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
480 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh()
484 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New()
486 return new MEDCoupling1SGTUMesh;
489 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
491 if(type==INTERP_KERNEL::NORM_ERROR)
492 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
493 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
496 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New : the input geometric type " << cm.getRepr() << " is dynamic ! Only static types are allowed here !";
497 throw INTERP_KERNEL::Exception(oss.str().c_str());
499 return new MEDCoupling1SGTUMesh(name,cm);
502 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m)
505 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh is null !");
506 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
508 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh must have exactly one geometric type !");
509 int geoType((int)*gts.begin());
510 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(m->getName(),*gts.begin()));
511 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription());
512 int nbCells(m->getNumberOfCells());
513 int nbOfNodesPerCell(ret->getNumberOfNodesPerCell());
514 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()); conn->alloc(nbCells*nbOfNodesPerCell,1);
515 int *c(conn->getPointer());
516 const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
517 for(int i=0;i<nbCells;i++,ciin++)
519 if(cin[ciin[0]]==geoType)
521 if(ciin[1]-ciin[0]==nbOfNodesPerCell+1)
522 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
525 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 << ") !";
526 throw INTERP_KERNEL::Exception(oss.str().c_str());
531 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 !";
532 throw INTERP_KERNEL::Exception(oss.str().c_str());
535 ret->setNodalConnectivity(conn);
537 { ret->copyTinyInfoFrom(m); }
538 catch(INTERP_KERNEL::Exception&) { }
542 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::clone(bool recDeepCpy) const
544 return new MEDCoupling1SGTUMesh(*this,recDeepCpy);
548 * This method behaves mostly like MEDCoupling1SGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
549 * The coordinates are shared between \a this and the returned instance.
551 * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
552 * \sa MEDCoupling1SGTUMesh::deepCpy
554 MEDCouplingPointSet *MEDCoupling1SGTUMesh::deepCpyConnectivityOnly() const
557 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(clone(false));
558 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy());
559 ret->setNodalConnectivity(c);
563 void MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
566 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
567 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
569 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1SGTUMesh instance !");
570 setNodalConnectivity(otherC->getNodalConnectivity());
573 void MEDCoupling1SGTUMesh::updateTime() const
575 MEDCoupling1GTUMesh::updateTime();
576 const DataArrayInt *c(_conn);
581 std::size_t MEDCoupling1SGTUMesh::getHeapMemorySizeWithoutChildren() const
583 return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren();
586 std::vector<const BigMemoryObject *> MEDCoupling1SGTUMesh::getDirectChildrenWithNull() const
588 std::vector<const BigMemoryObject *> ret(MEDCoupling1GTUMesh::getDirectChildrenWithNull());
589 ret.push_back((const DataArrayInt *)_conn);
593 MEDCouplingMesh *MEDCoupling1SGTUMesh::deepCpy() const
598 bool MEDCoupling1SGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
601 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualIfNotWhy : input other pointer is null !");
602 std::ostringstream oss; oss.precision(15);
603 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
606 reason="mesh given in input is not castable in MEDCoupling1SGTUMesh !";
609 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
611 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
616 reason="in connectivity of single static geometric type exactly one among this and other is null !";
619 if(!c1->isEqualIfNotWhy(*c2,reason))
621 reason.insert(0,"Nodal connectivity DataArrayInt differ : ");
627 bool MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
630 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
631 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
634 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
636 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
641 if(!c1->isEqualWithoutConsideringStr(*c2))
646 void MEDCoupling1SGTUMesh::checkCoherencyOfConnectivity() const
648 const DataArrayInt *c1(_conn);
651 if(c1->getNumberOfComponents()!=1)
652 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
653 if(c1->getInfoOnComponent(0)!="")
654 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
655 c1->checkAllocated();
658 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
661 void MEDCoupling1SGTUMesh::checkCoherency() const
663 MEDCouplingPointSet::checkCoherency();
664 checkCoherencyOfConnectivity();
667 void MEDCoupling1SGTUMesh::checkCoherency1(double eps) const
670 const DataArrayInt *c1(_conn);
671 int nbOfTuples=c1->getNumberOfTuples();
672 int nbOfNodesPerCell=(int)_cm->getNumberOfNodes();
673 if(nbOfTuples%nbOfNodesPerCell!=0)
675 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 !";
676 throw INTERP_KERNEL::Exception(oss.str().c_str());
678 int nbOfNodes=getNumberOfNodes();
679 int nbOfCells=nbOfTuples/nbOfNodesPerCell;
680 const int *w(c1->begin());
681 for(int i=0;i<nbOfCells;i++)
682 for(int j=0;j<nbOfNodesPerCell;j++,w++)
684 if(*w<0 || *w>=nbOfNodes)
686 std::ostringstream oss; oss << "At node #" << j << " of cell #" << i << ", is equal to " << *w << " must be in [0," << nbOfNodes << ") !";
687 throw INTERP_KERNEL::Exception(oss.str().c_str());
692 void MEDCoupling1SGTUMesh::checkCoherency2(double eps) const
694 checkCoherency1(eps);
697 int MEDCoupling1SGTUMesh::getNumberOfCells() const
699 int nbOfTuples=getNodalConnectivityLength();
700 int nbOfNodesPerCell=getNumberOfNodesPerCell();
701 if(nbOfTuples%nbOfNodesPerCell!=0)
703 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 !";
704 throw INTERP_KERNEL::Exception(oss.str().c_str());
706 return nbOfTuples/nbOfNodesPerCell;
709 int MEDCoupling1SGTUMesh::getNumberOfNodesInCell(int cellId) const
711 return getNumberOfNodesPerCell();
714 int MEDCoupling1SGTUMesh::getNumberOfNodesPerCell() const
716 checkNonDynamicGeoType();
717 return (int)_cm->getNumberOfNodes();
720 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfNodesPerCell() const
722 checkNonDynamicGeoType();
723 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
724 ret->alloc(getNumberOfCells(),1);
725 ret->fillWithValue((int)_cm->getNumberOfNodes());
729 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfFacesPerCell() const
731 checkNonDynamicGeoType();
732 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
733 ret->alloc(getNumberOfCells(),1);
734 ret->fillWithValue((int)_cm->getNumberOfSons());
738 DataArrayInt *MEDCoupling1SGTUMesh::computeEffectiveNbOfNodesPerCell() const
740 checkNonDynamicGeoType();
741 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
742 int nbCells(getNumberOfCells());
743 ret->alloc(nbCells,1);
744 int *retPtr(ret->getPointer());
745 int nbNodesPerCell(getNumberOfNodesPerCell());
746 const int *conn(_conn->begin());
747 for(int i=0;i<nbCells;i++,conn+=nbNodesPerCell,retPtr++)
749 std::set<int> s(conn,conn+nbNodesPerCell);
750 *retPtr=(int)s.size();
755 void MEDCoupling1SGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
757 int sz=getNumberOfNodesPerCell();
759 if(cellId>=0 && cellId<getNumberOfCells())
760 std::copy(_conn->begin()+cellId*sz,_conn->begin()+(cellId+1)*sz,conn.begin());
763 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << getNumberOfCells() << ") !";
764 throw INTERP_KERNEL::Exception(oss.str().c_str());
768 void MEDCoupling1SGTUMesh::checkNonDynamicGeoType() const
771 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkNonDynamicGeoType : internal error ! the internal geo type is dynamic ! should be static !");
774 std::string MEDCoupling1SGTUMesh::simpleRepr() const
776 static const char msg0[]="No coordinates specified !";
777 std::ostringstream ret;
778 ret << "Single static geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
779 ret << "Description of mesh : \"" << getDescription() << "\"\n";
781 double tt=getTime(tmpp1,tmpp2);
782 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
783 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
784 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
787 const int spaceDim=getSpaceDimension();
788 ret << spaceDim << "\nInfo attached on space dimension : ";
789 for(int i=0;i<spaceDim;i++)
790 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
795 ret << "Number of nodes : ";
797 ret << getNumberOfNodes() << "\n";
800 ret << "Number of cells : ";
801 if((const DataArrayInt *)_conn)
803 if(_conn->isAllocated())
805 if(_conn->getNumberOfComponents()==1)
806 ret << getNumberOfCells() << "\n";
808 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
811 ret << "Nodal connectivity array specified but not allocated !" << "\n";
814 ret << "No connectivity specified !" << "\n";
815 ret << "Cell type : " << _cm->getRepr() << "\n";
819 std::string MEDCoupling1SGTUMesh::advancedRepr() const
821 std::ostringstream ret;
823 ret << "\nCoordinates array : \n___________________\n\n";
825 _coords->reprWithoutNameStream(ret);
827 ret << "No array set !\n";
828 ret << "\n\nConnectivity array : \n____________________\n\n";
830 if((const DataArrayInt *)_conn)
832 if(_conn->isAllocated())
834 if(_conn->getNumberOfComponents()==1)
836 int nbOfCells=getNumberOfCells();
837 int sz=getNumberOfNodesPerCell();
838 const int *connPtr=_conn->begin();
839 for(int i=0;i<nbOfCells;i++,connPtr+=sz)
841 ret << "Cell #" << i << " : ";
842 std::copy(connPtr,connPtr+sz,std::ostream_iterator<int>(ret," "));
847 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
850 ret << "Nodal connectivity array specified but not allocated !" << "\n";
853 ret << "No connectivity specified !" << "\n";
857 DataArrayDouble *MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell() const
859 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
860 int spaceDim=getSpaceDimension();
861 int nbOfCells=getNumberOfCells();//checkCoherency()
862 int nbOfNodes=getNumberOfNodes();
863 ret->alloc(nbOfCells,spaceDim);
864 double *ptToFill=ret->getPointer();
865 const double *coor=_coords->begin();
866 const int *nodal=_conn->begin();
867 int sz=getNumberOfNodesPerCell();
868 double coeff=1./(double)sz;
869 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim)
871 std::fill(ptToFill,ptToFill+spaceDim,0.);
872 for(int j=0;j<sz;j++,nodal++)
873 if(*nodal>=0 && *nodal<nbOfNodes)
874 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
877 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
878 throw INTERP_KERNEL::Exception(oss.str().c_str());
880 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),coeff));
885 void MEDCoupling1SGTUMesh::renumberCells(const int *old2NewBg, bool check)
887 int nbCells=getNumberOfCells();
888 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
889 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
891 o2n=o2n->checkAndPreparePermutation();
893 const int *conn=_conn->begin();
894 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o=o2n->invertArrayO2N2N2O(nbCells);
895 const int *n2oPtr=n2o->begin();
896 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
897 newConn->alloc(_conn->getNumberOfTuples(),1);
898 newConn->copyStringInfoFrom(*_conn);
899 int sz=getNumberOfNodesPerCell();
901 int *newC=newConn->getPointer();
902 for(int i=0;i<nbCells;i++,newC+=sz)
905 std::copy(conn+pos*sz,conn+(pos+1)*sz,newC);
911 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
912 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
913 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
914 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
916 * \param [in] begin input start of array of node ids.
917 * \param [in] end input end of array of node ids.
918 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
919 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
921 void MEDCoupling1SGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
923 int nbOfCells=getNumberOfCells();
924 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
926 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
927 std::vector<bool> fastFinder(sz,false);
928 for(const int *work=begin;work!=end;work++)
929 if(*work>=0 && *work<sz)
930 fastFinder[*work]=true;
931 const int *conn=_conn->begin();
932 int nbNodesPerCell=getNumberOfNodesPerCell();
933 for(int i=0;i<nbOfCells;i++,conn+=nbNodesPerCell)
936 for(int j=0;j<nbNodesPerCell;j++)
940 if(fastFinder[conn[j]])
943 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
944 cellIdsKept->pushBackSilent(i);
946 cellIdsKeptArr=cellIdsKept.retn();
949 MEDCouplingMesh *MEDCoupling1SGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
951 if(other->getType()!=SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED)
952 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single static geo type each other !");
953 const MEDCoupling1SGTUMesh *otherC=static_cast<const MEDCoupling1SGTUMesh *>(other);
954 return Merge1SGTUMeshes(this,otherC);
957 MEDCouplingUMesh *MEDCoupling1SGTUMesh::buildUnstructured() const
959 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
960 ret->setCoords(getCoords());
961 const int *nodalConn=_conn->begin();
962 int nbCells=getNumberOfCells();
963 int nbNodesPerCell=getNumberOfNodesPerCell();
964 int geoType=(int)getCellModelEnum();
965 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells*(nbNodesPerCell+1),1);
966 int *cPtr=c->getPointer();
967 for(int i=0;i<nbCells;i++,nodalConn+=nbNodesPerCell)
970 cPtr=std::copy(nodalConn,nodalConn+nbNodesPerCell,cPtr);
972 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::Range(0,(nbCells+1)*(nbNodesPerCell+1),nbNodesPerCell+1);
973 ret->setConnectivity(c,cI,true);
975 { ret->copyTinyInfoFrom(this); }
976 catch(INTERP_KERNEL::Exception&) { }
980 DataArrayInt *MEDCoupling1SGTUMesh::simplexize(int policy)
985 return simplexizePol0();
987 return simplexizePol1();
988 case (int) INTERP_KERNEL::PLANAR_FACE_5:
989 return simplexizePlanarFace5();
990 case (int) INTERP_KERNEL::PLANAR_FACE_6:
991 return simplexizePlanarFace6();
993 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)");
999 struct MEDCouplingAccVisit
1001 MEDCouplingAccVisit():_new_nb_of_nodes(0) { }
1002 int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; }
1003 int _new_nb_of_nodes;
1009 * This method returns all node ids used in \b this. The data array returned has to be dealt by the caller.
1010 * The returned node ids are sortes ascendingly. This method is closed to MEDCoupling1SGTUMesh::getNodeIdsInUse except
1011 * the format of returned DataArrayInt instance.
1013 * \return a newly allocated DataArrayInt sorted ascendingly of fetched node ids.
1014 * \sa MEDCoupling1SGTUMesh::getNodeIdsInUse
1016 DataArrayInt *MEDCoupling1SGTUMesh::computeFetchedNodeIds() const
1018 checkCoherencyOfConnectivity();
1019 int nbNodes(getNumberOfNodes());
1020 std::vector<bool> fetchedNodes(nbNodes,false);
1021 computeNodeIdsAlg(fetchedNodes);
1022 int sz((int)std::count(fetchedNodes.begin(),fetchedNodes.end(),true));
1023 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
1024 int *retPtr(ret->getPointer());
1025 for(int i=0;i<nbNodes;i++)
1032 * Finds nodes not used in any cell and returns an array giving a new id to every node
1033 * by excluding the unused nodes, for which the array holds -1. The result array is
1034 * a mapping in "Old to New" mode.
1035 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
1036 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
1037 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
1038 * if the node is unused or a new id else. The caller is to delete this
1039 * array using decrRef() as it is no more needed.
1040 * \throw If the coordinates array is not set.
1041 * \throw If the nodal connectivity of cells is not defined.
1042 * \throw If the nodal connectivity includes an invalid id.
1043 * \sa MEDCoupling1SGTUMesh::computeFetchedNodeIds
1045 DataArrayInt *MEDCoupling1SGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
1048 int nbOfNodes=getNumberOfNodes();
1049 int nbOfCells=getNumberOfCells();
1050 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
1051 ret->alloc(nbOfNodes,1);
1052 int *traducer=ret->getPointer();
1053 std::fill(traducer,traducer+nbOfNodes,-1);
1054 const int *conn=_conn->begin();
1055 int nbNodesPerCell=getNumberOfNodesPerCell();
1056 for(int i=0;i<nbOfCells;i++)
1057 for(int j=0;j<nbNodesPerCell;j++,conn++)
1058 if(*conn>=0 && *conn<nbOfNodes)
1062 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << conn[j] << " not in [0," << nbOfNodes << ") !";
1063 throw INTERP_KERNEL::Exception(oss.str().c_str());
1065 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
1066 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
1071 * This method renumbers only nodal connectivity in \a this. The renumbering is only an offset applied. So this method is a specialization of
1072 * \a renumberNodesInConn. \b WARNING, this method does not check that the resulting node ids in the nodal connectivity is in a valid range !
1074 * \param [in] offset - specifies the offset to be applied on each element of connectivity.
1076 * \sa renumberNodesInConn
1078 void MEDCoupling1SGTUMesh::renumberNodesWithOffsetInConn(int offset)
1080 getNumberOfCells();//only to check that all is well defined.
1081 _conn->applyLin(1,offset);
1086 * Same than renumberNodesInConn(const int *) except that here the format of old-to-new traducer is using map instead
1087 * of array. This method is dedicated for renumbering from a big set of nodes the a tiny set of nodes which is the case during extraction
1090 void MEDCoupling1SGTUMesh::renumberNodesInConn(const INTERP_KERNEL::HashMap<int,int>& newNodeNumbersO2N)
1092 getNumberOfCells();//only to check that all is well defined.
1093 int *begPtr(_conn->getPointer());
1094 int nbElt(_conn->getNumberOfTuples());
1095 int *endPtr(begPtr+nbElt);
1096 for(int *it=begPtr;it!=endPtr;it++)
1098 INTERP_KERNEL::HashMap<int,int>::const_iterator it2(newNodeNumbersO2N.find(*it));
1099 if(it2!=newNodeNumbersO2N.end())
1105 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::renumberNodesInConn : At pos #" << std::distance(begPtr,it) << " of nodal connectivity value is " << *it << ". Not in map !";
1106 throw INTERP_KERNEL::Exception(oss.str().c_str());
1113 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
1114 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
1115 * This method is a generalization of shiftNodeNumbersInConn().
1116 * \warning This method performs no check of validity of new ids. **Use it with care !**
1117 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
1118 * this->getNumberOfNodes(), in "Old to New" mode.
1119 * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
1120 * \throw If the nodal connectivity of cells is not defined.
1122 void MEDCoupling1SGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
1124 getNumberOfCells();//only to check that all is well defined.
1125 _conn->transformWithIndArr(newNodeNumbersO2N,newNodeNumbersO2N+getNumberOfNodes());
1129 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2)
1131 std::vector<const MEDCoupling1SGTUMesh *> tmp(2);
1132 tmp[0]=const_cast<MEDCoupling1SGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1SGTUMesh *>(mesh2);
1133 return Merge1SGTUMeshes(tmp);
1136 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(std::vector<const MEDCoupling1SGTUMesh *>& a)
1138 std::size_t sz=a.size();
1140 return Merge1SGTUMeshesLL(a);
1141 for(std::size_t ii=0;ii<sz;ii++)
1144 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::Merge1SGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
1145 throw INTERP_KERNEL::Exception(oss.str().c_str());
1147 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
1148 for(std::size_t ii=0;ii<sz;ii++)
1149 if(&(a[ii]->getCellModel())!=cm)
1150 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : all items must have the same geo type !");
1151 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> > bb(sz);
1152 std::vector< const MEDCoupling1SGTUMesh * > aa(sz);
1154 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
1156 const MEDCoupling1SGTUMesh *cur=a[i];
1157 const DataArrayDouble *coo=cur->getCoords();
1159 spaceDim=coo->getNumberOfComponents();
1162 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : no spaceDim specified ! unable to perform merge !");
1163 for(std::size_t i=0;i<sz;i++)
1165 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
1168 return Merge1SGTUMeshesLL(aa);
1172 * \throw If presence of a null instance in the input vector \a a.
1173 * \throw If a is empty
1175 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::vector<const MEDCoupling1SGTUMesh *>& a)
1178 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : input array must be NON EMPTY !");
1179 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1181 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : null instance in the first element of input vector !");
1182 std::vector<const DataArrayInt *> ncs(a.size());
1183 (*it)->getNumberOfCells();//to check that all is OK
1184 const DataArrayDouble *coords=(*it)->getCoords();
1185 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1186 ncs[0]=(*it)->getNodalConnectivity();
1188 for(int i=1;it!=a.end();i++,it++)
1191 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : presence of a null instance in the input vector !");
1192 if(cm!=&((*it)->getCellModel()))
1193 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1194 (*it)->getNumberOfCells();//to check that all is OK
1195 ncs[i]=(*it)->getNodalConnectivity();
1196 if(coords!=(*it)->getCoords())
1197 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : not lying on same coords !");
1199 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1200 ret->setCoords(coords);
1201 ret->_conn=DataArrayInt::Aggregate(ncs);
1206 * 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)
1208 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector<const MEDCoupling1SGTUMesh *>& a)
1211 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : input array must be NON EMPTY !");
1212 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1213 int nbOfCells=(*it)->getNumberOfCells();
1214 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1215 int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
1217 for(;it!=a.end();it++)
1219 if(cm!=&((*it)->getCellModel()))
1220 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1221 nbOfCells+=(*it)->getNumberOfCells();
1223 std::vector<const MEDCouplingPointSet *> aps(a.size());
1224 std::copy(a.begin(),a.end(),aps.begin());
1225 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
1226 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1227 ret->setCoords(pts);
1228 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New();
1229 c->alloc(nbOfCells*nbNodesPerCell,1);
1230 int *cPtr=c->getPointer();
1232 for(it=a.begin();it!=a.end();it++)
1234 int curConnLgth=(*it)->getNodalConnectivityLength();
1235 const int *curC=(*it)->_conn->begin();
1236 cPtr=std::transform(curC,curC+curConnLgth,cPtr,std::bind2nd(std::plus<int>(),offset));
1237 offset+=(*it)->getNumberOfNodes();
1240 ret->setNodalConnectivity(c);
1244 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
1246 int ncell=getNumberOfCells();
1247 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1248 ret->setCoords(_coords);
1249 std::size_t nbOfElemsRet=std::distance(begin,end);
1250 const int *inConn=_conn->getConstPointer();
1251 int sz=getNumberOfNodesPerCell();
1252 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1253 int *connPtr=connRet->getPointer();
1254 for(const int *work=begin;work!=end;work++,connPtr+=sz)
1256 if(*work>=0 && *work<ncell)
1257 std::copy(inConn+(work[0])*sz,inConn+(work[0]+1)*sz,connPtr);
1260 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !";
1261 throw INTERP_KERNEL::Exception(oss.str().c_str());
1265 ret->copyTinyInfoFrom(this);
1269 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
1271 int ncell=getNumberOfCells();
1272 int nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : ");
1273 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1274 ret->setCoords(_coords);
1275 const int *inConn=_conn->getConstPointer();
1276 int sz=getNumberOfNodesPerCell();
1277 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1278 int *connPtr=connRet->getPointer();
1280 for(int i=0;i<nbOfElemsRet;i++,connPtr+=sz,curId+=step)
1282 if(curId>=0 && curId<ncell)
1283 std::copy(inConn+curId*sz,inConn+(curId+1)*sz,connPtr);
1286 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : On pos #" << i << " input cell id =" << curId << " should be in [0," << ncell << ") !";
1287 throw INTERP_KERNEL::Exception(oss.str().c_str());
1291 ret->copyTinyInfoFrom(this);
1295 void MEDCoupling1SGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
1297 int sz((int)nodeIdsInUse.size());
1298 for(const int *conn=_conn->begin();conn!=_conn->end();conn++)
1300 if(*conn>=0 && *conn<sz)
1301 nodeIdsInUse[*conn]=true;
1304 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeFetchedNodeIds : At pos #" << std::distance(_conn->begin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !";
1305 throw INTERP_KERNEL::Exception(oss.str().c_str());
1310 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(int spaceDim) const
1312 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1313 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1;
1314 const DataArrayInt *nodalConn(_conn);
1317 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
1324 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
1325 ret->setCoords(coords);
1328 ret->setCoords(_coords);
1332 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol0()
1334 int nbOfCells=getNumberOfCells();
1335 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1336 return DataArrayInt::Range(0,nbOfCells,1);
1337 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1338 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1339 const int *c(_conn->begin());
1340 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1341 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1343 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[2];
1344 newConnPtr[3]=c[0]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1345 retPtr[0]=i; retPtr[1]=i;
1348 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1353 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol1()
1355 int nbOfCells=getNumberOfCells();
1356 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1357 return DataArrayInt::Range(0,nbOfCells,1);
1358 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1359 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1360 const int *c(_conn->begin());
1361 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1362 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1364 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[3];
1365 newConnPtr[3]=c[1]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1366 retPtr[0]=i; retPtr[1]=i;
1369 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1374 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace5()
1376 int nbOfCells=getNumberOfCells();
1377 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1378 return DataArrayInt::Range(0,nbOfCells,1);
1379 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(5*4*nbOfCells,1);
1380 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(5*nbOfCells,1);
1381 const int *c(_conn->begin());
1382 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1383 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=20,retPtr+=5)
1385 for(int j=0;j<20;j++)
1386 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_5_WO[j]];
1387 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i;
1390 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1395 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace6()
1397 int nbOfCells=getNumberOfCells();
1398 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1399 return DataArrayInt::Range(0,nbOfCells,1);
1400 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(6*4*nbOfCells,1);
1401 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(6*nbOfCells,1);
1402 const int *c(_conn->begin());
1403 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1404 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=24,retPtr+=6)
1406 for(int j=0;j<24;j++)
1407 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_6_WO[j]];
1408 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i; retPtr[5]=i;
1411 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1416 void MEDCoupling1SGTUMesh::reprQuickOverview(std::ostream& stream) const
1418 stream << "MEDCoupling1SGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
1419 stream << " Mesh dimension : " << getMeshDimension() << ".";
1421 { stream << " No coordinates set !"; return ; }
1422 if(!_coords->isAllocated())
1423 { stream << " Coordinates set but not allocated !"; return ; }
1424 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
1425 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
1426 if(!(const DataArrayInt *)_conn)
1427 { stream << std::endl << "Nodal connectivity NOT set !"; return ; }
1428 if(_conn->isAllocated())
1430 if(_conn->getNumberOfComponents()==1)
1431 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
1435 void MEDCoupling1SGTUMesh::checkFullyDefined() const
1437 if(!((const DataArrayInt *)_conn) || !((const DataArrayDouble *)_coords))
1438 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFullyDefined : part of this is not fully defined.");
1442 * First step of unserialization process.
1444 bool MEDCoupling1SGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
1446 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEmptyMesh : not implemented yet !");
1449 void MEDCoupling1SGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
1452 double time=getTime(it,order);
1453 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
1455 littleStrings.push_back(getName());
1456 littleStrings.push_back(getDescription());
1457 littleStrings.push_back(getTimeUnit());
1459 std::vector<std::string> littleStrings2,littleStrings3;
1460 if((const DataArrayDouble *)_coords)
1461 _coords->getTinySerializationStrInformation(littleStrings2);
1462 if((const DataArrayInt *)_conn)
1463 _conn->getTinySerializationStrInformation(littleStrings3);
1464 int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size());
1465 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
1466 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
1468 tinyInfo.push_back(getCellModelEnum());
1469 tinyInfo.push_back(it);
1470 tinyInfo.push_back(order);
1471 std::vector<int> tinyInfo2,tinyInfo3;
1472 if((const DataArrayDouble *)_coords)
1473 _coords->getTinySerializationIntInformation(tinyInfo2);
1474 if((const DataArrayInt *)_conn)
1475 _conn->getTinySerializationIntInformation(tinyInfo3);
1476 int sz2((int)tinyInfo2.size()),sz3((int)tinyInfo3.size());
1477 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3);
1478 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1479 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
1481 tinyInfoD.push_back(time);
1484 void MEDCoupling1SGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
1486 std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+tinyInfo[5]);
1487 std::vector<int> tinyInfo1(tinyInfo.begin()+7+tinyInfo[5],tinyInfo.begin()+7+tinyInfo[5]+tinyInfo[6]);
1488 a1->resizeForUnserialization(tinyInfo1);
1489 a2->resizeForUnserialization(tinyInfo2);
1492 void MEDCoupling1SGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
1495 if((const DataArrayInt *)_conn)
1496 if(_conn->isAllocated())
1497 sz=_conn->getNbOfElems();
1498 a1=DataArrayInt::New();
1500 if(sz!=0 && (const DataArrayInt *)_conn)
1501 std::copy(_conn->begin(),_conn->end(),a1->getPointer());
1503 if((const DataArrayDouble *)_coords)
1504 if(_coords->isAllocated())
1505 sz=_coords->getNbOfElems();
1506 a2=DataArrayDouble::New();
1508 if(sz!=0 && (const DataArrayDouble *)_coords)
1509 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
1512 void MEDCoupling1SGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
1513 const std::vector<std::string>& littleStrings)
1515 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
1516 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
1517 setName(littleStrings[0]);
1518 setDescription(littleStrings[1]);
1519 setTimeUnit(littleStrings[2]);
1520 setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
1521 int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]);
1523 _coords=DataArrayDouble::New();
1524 std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+sz2);
1525 _coords->resizeForUnserialization(tinyInfo2);
1526 std::copy(a2->begin(),a2->end(),_coords->getPointer());
1527 _conn=DataArrayInt::New();
1528 std::vector<int> tinyInfo3(tinyInfo.begin()+7+sz2,tinyInfo.begin()+7+sz2+sz3);
1529 _conn->resizeForUnserialization(tinyInfo3);
1530 std::copy(a1->begin(),a1->end(),_conn->getPointer());
1531 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
1532 _coords->finishUnserialization(tinyInfo2,littleStrings2);
1533 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
1534 _conn->finishUnserialization(tinyInfo3,littleStrings3);
1538 * Checks if \a this and \a other meshes are geometrically equivalent with high
1539 * probability, else an exception is thrown. The meshes are considered equivalent if
1540 * (1) meshes contain the same number of nodes and the same number of elements of the
1541 * same types (2) three cells of the two meshes (first, last and middle) are based
1542 * on coincident nodes (with a specified precision).
1543 * \param [in] other - the mesh to compare with.
1544 * \param [in] prec - the precision used to compare nodes of the two meshes.
1545 * \throw If the two meshes do not match.
1547 void MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
1549 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1550 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1552 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single static geometric type !");
1553 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1557 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1558 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1559 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1560 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1561 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1562 if(c1->getHashCode()!=c2->getHashCode())
1563 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1566 MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
1569 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
1570 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1572 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
1573 std::vector<const MEDCoupling1SGTUMesh *> ms(2);
1576 return Merge1SGTUMeshesOnSameCoords(ms);
1579 void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const
1581 checkFullyDefined();
1582 int nbOfNodes=getNumberOfNodes();
1583 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
1584 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
1585 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
1586 const int *conn=_conn->begin();
1587 int nbOfCells=getNumberOfCells();
1588 int nbOfEltsInRevNodal=0;
1589 int nbOfNodesPerCell=getNumberOfNodesPerCell();
1590 for(int eltId=0;eltId<nbOfCells;eltId++)
1592 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1594 if(conn[0]>=0 && conn[0]<nbOfNodes)
1596 nbOfEltsInRevNodal++;
1597 revNodalIndxPtr[conn[0]+1]++;
1601 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
1602 throw INTERP_KERNEL::Exception(oss.str().c_str());
1606 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
1607 conn=_conn->begin();
1608 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
1609 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
1610 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
1611 for(int eltId=0;eltId<nbOfCells;eltId++)
1613 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1615 *std::find_if(revNodalPtr+revNodalIndxPtr[*conn],revNodalPtr+revNodalIndxPtr[*conn+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
1621 * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null.
1623 void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn)
1626 nodalConn->incrRef();
1632 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
1634 DataArrayInt *MEDCoupling1SGTUMesh::getNodalConnectivity() const
1636 const DataArrayInt *ret(_conn);
1637 return const_cast<DataArrayInt *>(ret);
1641 * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted,
1642 * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter.
1643 * If a nodal connectivity previouly existed before the call of this method, it will be reset.
1645 * \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain.
1647 void MEDCoupling1SGTUMesh::allocateCells(int nbOfCells)
1650 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !");
1651 _conn=DataArrayInt::New();
1652 _conn->reserve(getNumberOfNodesPerCell()*nbOfCells);
1657 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
1659 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
1660 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
1661 * \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
1662 * attached to \a this.
1663 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
1665 void MEDCoupling1SGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd)
1667 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
1668 int ref=getNumberOfNodesPerCell();
1671 DataArrayInt *c(_conn);
1673 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
1675 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !");
1679 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this (";
1680 oss << ref << ") !";
1681 throw INTERP_KERNEL::Exception(oss.str().c_str());
1686 * This method builds the dual mesh of \a this and returns it.
1688 * \return MEDCoupling1SGTUMesh * - newly object created to be managed by the caller.
1689 * \throw If \a this is not a mesh containing only simplex cells.
1690 * \throw If \a this is not correctly allocated (coordinates and connectivities have to be correctly set !).
1691 * \throw If at least one node in \a this is orphan (without any simplex cell lying on it !)
1693 MEDCoupling1GTUMesh *MEDCoupling1SGTUMesh::computeDualMesh() const
1695 const INTERP_KERNEL::CellModel& cm(getCellModel());
1697 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : this mesh is not a simplex mesh ! Please invoke simplexize of tetrahedrize on this before calling this method !");
1698 switch(getMeshDimension())
1701 return computeDualMesh3D();
1703 return computeDualMesh2D();
1705 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : meshdimension must be in [2,3] !");
1710 * This method explode each NORM_HEXA8 cells in \a this into 6 NORM_QUAD4 cells and put the result into the MEDCoupling1SGTUMesh returned instance.
1712 * \return MEDCoupling1SGTUMesh * - a newly allocated instances (to be managed by the caller) storing the result of the explosion.
1713 * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
1714 * \throw If \a this is not properly allocated.
1716 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4() const
1718 const INTERP_KERNEL::CellModel& cm(getCellModel());
1719 if(cm.getEnum()!=INTERP_KERNEL::NORM_HEXA8)
1720 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4 : this method can be applied only on HEXA8 mesh !");
1721 int nbHexa8(getNumberOfCells());
1722 const int *inConnPtr(getNodalConnectivity()->begin());
1723 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(getName(),INTERP_KERNEL::NORM_QUAD4));
1724 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()); c->alloc(nbHexa8*6*4,1);
1725 int *cPtr(c->getPointer());
1726 for(int i=0;i<nbHexa8;i++,inConnPtr+=8)
1728 for(int j=0;j<6;j++,cPtr+=4)
1729 cm.fillSonCellNodalConnectivity(j,inConnPtr,cPtr);
1731 ret->setCoords(getCoords());
1732 ret->setNodalConnectivity(c);
1737 * This method starts from an unstructured mesh that hides in reality a cartesian mesh.
1738 * If it is not the case, an exception will be thrown.
1739 * This method returns three objects : The cartesian mesh geometrically equivalent to \a this (within a precision of \a eps) and a permutation of cells
1740 * and a permutation of nodes.
1742 * - this[cellPerm[i]]=ret[i]
1744 * \param [out] cellPerm the permutation array of size \c this->getNumberOfCells()
1745 * \param [out] nodePerm the permutation array of size \c this->getNumberOfNodes()
1746 * \return MEDCouplingCMesh * - a newly allocated mesh that is the result of the structurization of \a this.
1748 MEDCouplingCMesh *MEDCoupling1SGTUMesh::structurizeMe(DataArrayInt *& cellPerm, DataArrayInt *& nodePerm, double eps) const
1751 int spaceDim(getSpaceDimension()),meshDim(getMeshDimension()),nbNodes(getNumberOfNodes());
1752 if(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim)!=getCellModelEnum())
1753 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::structurizeMe : the unique geo type in this is not compatible with the geometric type regarding mesh dimension !");
1754 MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> cm(MEDCouplingCMesh::New());
1755 for(int i=0;i<spaceDim;i++)
1757 std::vector<int> tmp(1,i);
1758 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> elt(static_cast<DataArrayDouble*>(getCoords()->keepSelectedComponents(tmp)));
1759 elt=elt->getDifferentValues(eps);
1761 cm->setCoordsAt(i,elt);
1763 if(nbNodes!=cm->getNumberOfNodes())
1764 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::structurizeMe : considering the number of nodes after split per components in space this can't be a cartesian mesh ! Maybe your epsilon parameter is invalid ?");
1766 { cm->copyTinyInfoFrom(this); }
1767 catch(INTERP_KERNEL::Exception&) { }
1768 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> um(cm->buildUnstructured()),self(buildUnstructured());
1769 self->checkGeoEquivalWith(um,12,eps,cellPerm,nodePerm);
1775 bool UpdateHexa8Cell(int validAxis, int neighId, const int *validConnQuad4NeighSide, int *allFacesNodalConn, int *myNeighbours)
1777 static const int TAB[48]={
1785 static const int TAB2[6]={0,0,3,3,3,3};
1786 if(myNeighbours[validAxis]==neighId && allFacesNodalConn[4*validAxis+0]==validConnQuad4NeighSide[TAB2[validAxis]])
1788 int oldAxis((int)std::distance(myNeighbours,std::find(myNeighbours,myNeighbours+6,neighId)));
1789 std::size_t pos(std::distance(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,std::find(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS+6,oldAxis)));
1790 std::size_t pos0(pos/2),pos1(pos%2);
1791 int oldAxisOpp(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[2*pos0+(pos1+1)%2]);
1792 int oldConn[8],myConn2[8]={-1,-1,-1,-1,-1,-1,-1,-1},myConn[8],edgeConn[2],allFacesTmp[24],neighTmp[6];
1793 oldConn[0]=allFacesNodalConn[0]; oldConn[1]=allFacesNodalConn[1]; oldConn[2]=allFacesNodalConn[2]; oldConn[3]=allFacesNodalConn[3];
1794 oldConn[4]=allFacesNodalConn[4]; oldConn[5]=allFacesNodalConn[7]; oldConn[6]=allFacesNodalConn[6]; oldConn[7]=allFacesNodalConn[5];
1795 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_HEXA8));
1796 for(int i=0;i<4;i++)
1797 myConn2[i]=validConnQuad4NeighSide[(4-i+TAB2[validAxis])%4];
1798 for(int i=0;i<4;i++)
1800 int nodeId(myConn2[i]);//the node id for which the opposite one will be found
1802 INTERP_KERNEL::NormalizedCellType typeOfSon;
1803 for(int j=0;j<12 && !found;j++)
1805 cm.fillSonEdgesNodalConnectivity3D(j,oldConn,-1,edgeConn,typeOfSon);
1806 if(edgeConn[0]==nodeId || edgeConn[1]==nodeId)
1808 if(std::find(allFacesNodalConn+4*oldAxisOpp,allFacesNodalConn+4*oldAxisOpp+4,edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0])!=allFacesNodalConn+4*oldAxisOpp+4)
1810 myConn2[i+4]=edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0];
1816 throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error !");
1818 const int *myTab(TAB+8*validAxis);
1819 for(int i=0;i<8;i++)
1820 myConn[i]=myConn2[myTab[i]];
1821 for(int i=0;i<6;i++)
1823 cm.fillSonCellNodalConnectivity(i,myConn,allFacesTmp+4*i);
1824 std::set<int> s(allFacesTmp+4*i,allFacesTmp+4*i+4);
1826 for(int j=0;j<6 && !found;j++)
1828 std::set<int> s1(allFacesNodalConn+4*j,allFacesNodalConn+4*j+4);
1831 neighTmp[i]=myNeighbours[j];
1836 throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error #2 !");
1838 std::copy(allFacesTmp,allFacesTmp+24,allFacesNodalConn);
1839 std::copy(neighTmp,neighTmp+6,myNeighbours);
1846 * This method expects the \a this contains NORM_HEXA8 cells only. This method will sort each cells in \a this so that their numbering was
1847 * homogeneous. If it succeeds the result of MEDCouplingUMesh::tetrahedrize will return a conform mesh.
1849 * \return DataArrayInt * - a newly allocated array (to be managed by the caller) containing renumbered cell ids.
1851 * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
1852 * \throw If \a this is not properly allocated.
1853 * \sa MEDCouplingUMesh::tetrahedrize, MEDCouplingUMesh::simplexize.
1855 DataArrayInt *MEDCoupling1SGTUMesh::sortHexa8EachOther()
1857 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> quads(explodeEachHexa8To6Quad4());//checks that only hexa8
1858 int nbHexa8(getNumberOfCells()),*cQuads(quads->getNodalConnectivity()->getPointer());
1859 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> neighOfQuads(DataArrayInt::New()); neighOfQuads->alloc(nbHexa8*6,1); neighOfQuads->fillWithValue(-1);
1860 int *ptNeigh(neighOfQuads->getPointer());
1861 {//neighOfQuads tells for each face of each Quad8 which cell (if!=-1) is connected to this face.
1862 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> quadsTmp(quads->buildUnstructured());
1863 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ccSafe,cciSafe;
1864 DataArrayInt *cc(0),*cci(0);
1865 quadsTmp->findCommonCells(3,0,cc,cci);
1866 ccSafe=cc; cciSafe=cci;
1867 const int *ccPtr(ccSafe->begin()),nbOfPair(cci->getNumberOfTuples()-1);
1868 for(int i=0;i<nbOfPair;i++)
1869 { ptNeigh[ccPtr[2*i+0]]=ccPtr[2*i+1]/6; ptNeigh[ccPtr[2*i+1]]=ccPtr[2*i+0]/6; }
1871 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
1872 std::vector<bool> fetched(nbHexa8,false);
1873 std::vector<bool>::iterator it(std::find(fetched.begin(),fetched.end(),false));
1874 while(it!=fetched.end())//it will turns as time as number of connected zones
1876 int cellId((int)std::distance(fetched.begin(),it));//it is the seed of the connected zone.
1877 std::set<int> s; s.insert(cellId);//s contains already organized.
1880 std::set<int> sNext;
1881 for(std::set<int>::const_iterator it0=s.begin();it0!=s.end();it0++)
1884 int *myNeighb(ptNeigh+6*(*it0));
1885 for(int i=0;i<6;i++)
1887 if(myNeighb[i]!=-1 && !fetched[myNeighb[i]])
1889 std::size_t pos(std::distance(HEXA8_FACE_PAIRS,std::find(HEXA8_FACE_PAIRS,HEXA8_FACE_PAIRS+6,i)));
1890 std::size_t pos0(pos/2),pos1(pos%2);
1891 if(!UpdateHexa8Cell(HEXA8_FACE_PAIRS[2*pos0+(pos1+1)%2],*it0,cQuads+6*4*(*it0)+4*i,cQuads+6*4*myNeighb[i],ptNeigh+6*myNeighb[i]))
1892 ret->pushBackSilent(myNeighb[i]);
1893 fetched[myNeighb[i]]=true;
1894 sNext.insert(myNeighb[i]);
1900 it=std::find(fetched.begin(),fetched.end(),false);
1904 int *conn(getNodalConnectivity()->getPointer());
1905 for(const int *pt=ret->begin();pt!=ret->end();pt++)
1908 conn[8*cellId+0]=cQuads[24*cellId+0]; conn[8*cellId+1]=cQuads[24*cellId+1]; conn[8*cellId+2]=cQuads[24*cellId+2]; conn[8*cellId+3]=cQuads[24*cellId+3];
1909 conn[8*cellId+4]=cQuads[24*cellId+4]; conn[8*cellId+5]=cQuads[24*cellId+7]; conn[8*cellId+6]=cQuads[24*cellId+6]; conn[8*cellId+7]=cQuads[24*cellId+5];
1916 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh3D() const
1918 static const int DUAL_TETRA_0[36]={
1919 4,1,0, 6,0,3, 7,3,1,
1920 4,0,1, 5,2,0, 8,1,2,
1921 6,3,0, 5,0,2, 9,2,3,
1924 static const int DUAL_TETRA_1[36]={
1925 8,4,10, 11,5,8, 10,7,11,
1926 9,4,8, 8,5,12, 12,6,9,
1927 10,4,9, 9,6,13, 13,7,10,
1928 12,5,11, 13,6,12, 11,7,13
1930 static const int FACEID_NOT_SH_NODE[4]={2,3,1,0};
1931 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TETRA4)
1932 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh3D : only TETRA4 supported !");
1933 checkFullyDefined();
1934 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured());
1935 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1936 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1937 const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1938 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d1Arr(DataArrayInt::New()),di1Arr(DataArrayInt::New()),rd1Arr(DataArrayInt::New()),rdi1Arr(DataArrayInt::New());
1939 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->explode3DMeshTo1D(d1Arr,di1Arr,rd1Arr,rdi1Arr));
1940 const int *d1(d1Arr->begin());
1941 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1942 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> faces(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
1943 const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
1944 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),facesBaryArr(faces->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
1945 const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+faces->getNumberOfCells()),offset1(offset0+edges->getNumberOfCells());
1947 std::vector<const DataArrayDouble *> v(4); v[0]=getCoords(); v[1]=facesBaryArr; v[2]=edgesBaryArr; v[3]=baryArr;
1948 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0; facesBaryArr=0;
1949 std::string name("DualOf_"); name+=getName();
1950 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYHED)); ret->setCoords(zeArr);
1951 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1952 for(int i=0;i<nbOfNodes;i++,revNodI++)
1954 int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1955 if(nbOfCellsSharingNode==0)
1957 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh3D : Node #" << i << " is orphan !";
1958 throw INTERP_KERNEL::Exception(oss.str().c_str());
1960 for(int j=0;j<nbOfCellsSharingNode;j++)
1962 int curCellId(revNod[revNodI[0]+j]);
1963 const int *connOfCurCell(nodal+4*curCellId);
1964 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1965 if(j!=0) cArr->pushBackSilent(-1);
1968 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;
1969 tmp[2]=curCellId+offset1; tmp[3]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+2]]+nbOfNodes;
1971 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;
1972 tmp[7]=curCellId+offset1; tmp[8]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+5]]+nbOfNodes;
1974 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;
1975 tmp[12]=curCellId+offset1; tmp[13]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+8]]+nbOfNodes;
1976 cArr->insertAtTheEnd(tmp,tmp+14);
1978 for(int k=0;k<4;k++)
1980 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1982 const int *faceId(d2+4*curCellId+k);
1983 if(rdi2[*faceId+1]-rdi2[*faceId]==1)
1985 int tmp2[5]; tmp2[0]=-1; tmp2[1]=i;
1986 tmp2[2]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+0]-8]+offset0;
1987 tmp2[3]=d2[4*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+1]-4]+nbOfNodes;
1988 tmp2[4]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+2]-8]+offset0;
1989 cArr->insertAtTheEnd(tmp2,tmp2+5);
1995 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
1997 ret->setNodalConnectivity(cArr,ciArr);
2001 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh2D() const
2003 static const int DUAL_TRI_0[6]={0,2, 1,0, 2,1};
2004 static const int DUAL_TRI_1[6]={-3,+5, +3,-4, +4,-5};
2005 static const int FACEID_NOT_SH_NODE[3]={1,2,0};
2006 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TRI3)
2007 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh2D : only TRI3 supported !");
2008 checkFullyDefined();
2009 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured());
2010 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
2011 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
2012 const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
2013 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
2014 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
2015 const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
2016 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
2017 const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+edges->getNumberOfCells());
2019 std::vector<const DataArrayDouble *> v(3); v[0]=getCoords(); v[1]=edgesBaryArr; v[2]=baryArr;
2020 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0;
2021 std::string name("DualOf_"); name+=getName();
2022 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYGON)); ret->setCoords(zeArr);
2023 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
2024 for(int i=0;i<nbOfNodes;i++,revNodI++)
2026 int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
2027 if(nbOfCellsSharingNode==0)
2029 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh2D : Node #" << i << " is orphan !";
2030 throw INTERP_KERNEL::Exception(oss.str().c_str());
2032 std::vector< std::vector<int> > polyg;
2033 for(int j=0;j<nbOfCellsSharingNode;j++)
2035 int curCellId(revNod[revNodI[0]+j]);
2036 const int *connOfCurCell(nodal+3*curCellId);
2037 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
2038 std::vector<int> locV(3);
2039 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;
2040 polyg.push_back(locV);
2042 for(int k=0;k<3;k++)
2044 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
2046 const int *edgeId(d2+3*curCellId+k);
2047 if(rdi2[*edgeId+1]-rdi2[*edgeId]==1)
2049 std::vector<int> locV2(2);
2050 int zeLocEdgeIdRel(DUAL_TRI_1[2*nodePosInCurCell+kk]);
2051 if(zeLocEdgeIdRel>0)
2052 { locV2[0]=d2[3*curCellId+zeLocEdgeIdRel-3]+nbOfNodes; locV2[1]=i; }
2054 { locV2[0]=i; locV2[1]=d2[3*curCellId-zeLocEdgeIdRel-3]+nbOfNodes; }
2055 polyg.push_back(locV2);
2061 std::vector<int> zePolyg(MEDCoupling1DGTUMesh::BuildAPolygonFromParts(polyg));
2062 cArr->insertAtTheEnd(zePolyg.begin(),zePolyg.end());
2063 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
2065 ret->setNodalConnectivity(cArr,ciArr);
2070 * This method aggregate the bbox of each cell and put it into bbox
2072 * \param [in] arcDetEps - a parameter specifying in case of 2D quadratic polygon cell the detection limit between linear and arc circle. (By default 1e-12)
2073 * For all other cases this input parameter is ignored.
2074 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
2076 * \throw If \a this is not fully set (coordinates and connectivity).
2077 * \throw If a cell in \a this has no valid nodeId.
2079 DataArrayDouble *MEDCoupling1SGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
2081 int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()),nbOfNodesPerCell(getNumberOfNodesPerCell());
2082 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
2083 double *bbox(ret->getPointer());
2084 for(int i=0;i<nbOfCells*spaceDim;i++)
2086 bbox[2*i]=std::numeric_limits<double>::max();
2087 bbox[2*i+1]=-std::numeric_limits<double>::max();
2089 const double *coordsPtr(_coords->getConstPointer());
2090 const int *conn(_conn->getConstPointer());
2091 for(int i=0;i<nbOfCells;i++)
2094 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
2097 if(nodeId>=0 && nodeId<nbOfNodes)
2099 for(int k=0;k<spaceDim;k++)
2101 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
2102 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
2109 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
2110 throw INTERP_KERNEL::Exception(oss.str().c_str());
2118 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New()
2120 return new MEDCoupling1DGTUMesh;
2123 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
2125 if(type==INTERP_KERNEL::NORM_ERROR)
2126 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
2127 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
2130 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !";
2131 throw INTERP_KERNEL::Exception(oss.str().c_str());
2133 return new MEDCoupling1DGTUMesh(name,cm);
2136 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh()
2140 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
2144 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
2148 const DataArrayInt *c(other._conn);
2153 _conn_indx=c->deepCpy();
2157 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const
2159 return new MEDCoupling1DGTUMesh(*this,recDeepCpy);
2163 * This method behaves mostly like MEDCoupling1DGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
2164 * The coordinates are shared between \a this and the returned instance.
2166 * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
2167 * \sa MEDCoupling1DGTUMesh::deepCpy
2169 MEDCouplingPointSet *MEDCoupling1DGTUMesh::deepCpyConnectivityOnly() const
2172 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(clone(false));
2173 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy()),ci(_conn_indx->deepCpy());
2174 ret->setNodalConnectivity(c,ci);
2178 void MEDCoupling1DGTUMesh::updateTime() const
2180 MEDCoupling1GTUMesh::updateTime();
2181 const DataArrayInt *c(_conn);
2189 std::size_t MEDCoupling1DGTUMesh::getHeapMemorySizeWithoutChildren() const
2191 return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren();
2194 std::vector<const BigMemoryObject *> MEDCoupling1DGTUMesh::getDirectChildrenWithNull() const
2196 std::vector<const BigMemoryObject *> ret(MEDCoupling1GTUMesh::getDirectChildrenWithNull());
2197 ret.push_back((const DataArrayInt *)_conn);
2198 ret.push_back((const DataArrayInt *)_conn_indx);
2202 MEDCouplingMesh *MEDCoupling1DGTUMesh::deepCpy() const
2207 bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
2210 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !");
2211 std::ostringstream oss; oss.precision(15);
2212 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2215 reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !";
2218 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
2220 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2225 reason="in connectivity of single dynamic geometric type exactly one among this and other is null !";
2228 if(!c1->isEqualIfNotWhy(*c2,reason))
2230 reason.insert(0,"Nodal connectivity DataArrayInt differs : ");
2233 c1=_conn_indx; c2=otherC->_conn_indx;
2238 reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !";
2241 if(!c1->isEqualIfNotWhy(*c2,reason))
2243 reason.insert(0,"Nodal connectivity index DataArrayInt differs : ");
2249 bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
2252 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
2253 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2256 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
2258 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2263 if(!c1->isEqualWithoutConsideringStr(*c2))
2266 c1=_conn_indx; c2=otherC->_conn_indx;
2271 if(!c1->isEqualWithoutConsideringStr(*c2))
2277 * Checks if \a this and \a other meshes are geometrically equivalent with high
2278 * probability, else an exception is thrown. The meshes are considered equivalent if
2279 * (1) meshes contain the same number of nodes and the same number of elements of the
2280 * same types (2) three cells of the two meshes (first, last and middle) are based
2281 * on coincident nodes (with a specified precision).
2282 * \param [in] other - the mesh to compare with.
2283 * \param [in] prec - the precision used to compare nodes of the two meshes.
2284 * \throw If the two meshes do not match.
2286 void MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
2288 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
2289 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2291 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single dynamic geometric type !");
2292 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2296 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
2297 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2298 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
2299 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2300 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
2301 if(c1->getHashCode()!=c2->getHashCode())
2302 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs");
2304 c1=_conn_indx; c2=otherC->_conn_indx;
2308 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !");
2309 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2310 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !");
2311 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2312 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !");
2313 if(c1->getHashCode()!=c2->getHashCode())
2314 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs");
2318 void MEDCoupling1DGTUMesh::checkCoherencyOfConnectivity() const
2320 const DataArrayInt *c1(_conn);
2323 if(c1->getNumberOfComponents()!=1)
2324 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
2325 if(c1->getInfoOnComponent(0)!="")
2326 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
2327 c1->checkAllocated();
2330 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
2332 int sz2=_conn->getNumberOfTuples();
2336 if(c1->getNumberOfComponents()!=1)
2337 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
2338 c1->checkAllocated();
2339 if(c1->getNumberOfTuples()<1)
2340 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !");
2341 if(c1->getInfoOnComponent(0)!="")
2342 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
2343 int f=c1->front(),ll=c1->back();
2346 std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !";
2347 throw INTERP_KERNEL::Exception(oss.str().c_str());
2351 std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !";
2352 throw INTERP_KERNEL::Exception(oss.str().c_str());
2356 std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !";
2357 throw INTERP_KERNEL::Exception(oss.str().c_str());
2361 throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !");
2362 int szOfC1Exp=_conn_indx->back();
2365 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() << " !";
2366 throw INTERP_KERNEL::Exception(oss.str().c_str());
2371 * 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.
2372 * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one.
2373 * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array.
2375 void MEDCoupling1DGTUMesh::checkCoherency() const
2377 MEDCouplingPointSet::checkCoherency();
2378 checkCoherencyOfConnectivity();
2381 void MEDCoupling1DGTUMesh::checkCoherency1(double eps) const
2384 const DataArrayInt *c1(_conn),*c2(_conn_indx);
2385 if(!c2->isMonotonic(true))
2386 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkCoherency1 : the nodal connectivity index is expected to be increasing monotinic !");
2388 int nbOfTuples=c1->getNumberOfTuples();
2389 int nbOfNodes=getNumberOfNodes();
2390 const int *w(c1->begin());
2391 for(int i=0;i<nbOfTuples;i++,w++)
2393 if(*w==-1) continue;
2394 if(*w<0 || *w>=nbOfNodes)
2396 std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !";
2397 throw INTERP_KERNEL::Exception(oss.str().c_str());
2402 void MEDCoupling1DGTUMesh::checkCoherency2(double eps) const
2404 checkCoherency1(eps);
2407 int MEDCoupling1DGTUMesh::getNumberOfCells() const
2409 checkCoherencyOfConnectivity();//do not remove
2410 return _conn_indx->getNumberOfTuples()-1;
2414 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2415 * For each cell in \b this the number of nodes constituting cell is computed.
2416 * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned.
2417 * So for pohyhedrons some nodes can be counted several times in the returned result.
2419 * \return a newly allocated array
2421 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const
2424 _conn_indx->checkMonotonic(true);
2425 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2426 return _conn_indx->deltaShiftIndex();
2428 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2429 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2430 ret->alloc(nbOfCells,1);
2431 int *retPtr=ret->getPointer();
2432 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2433 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2434 *retPtr=ci[1]-ci[0]-std::count(c+ci[0],c+ci[1],-1);
2439 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2440 * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed.
2442 * \return a newly allocated array
2444 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const
2447 _conn_indx->checkMonotonic(true);
2448 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG)
2449 return _conn_indx->deltaShiftIndex();
2450 if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG)
2452 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=_conn_indx->deltaShiftIndex();
2453 ret->applyDivideBy(2);
2457 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2458 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2459 ret->alloc(nbOfCells,1);
2460 int *retPtr=ret->getPointer();
2461 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2462 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2463 *retPtr=std::count(c+ci[0],c+ci[1],-1)+1;
2468 * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell,
2469 * will be counted only once here whereas it will be counted several times in MEDCoupling1DGTUMesh::computeNbOfNodesPerCell method.
2471 * \return DataArrayInt * - new object to be deallocated by the caller.
2472 * \sa MEDCoupling1DGTUMesh::computeNbOfNodesPerCell
2474 DataArrayInt *MEDCoupling1DGTUMesh::computeEffectiveNbOfNodesPerCell() const
2477 _conn_indx->checkMonotonic(true);
2478 int nbOfCells(_conn_indx->getNumberOfTuples()-1);
2479 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2480 ret->alloc(nbOfCells,1);
2481 int *retPtr(ret->getPointer());
2482 const int *ci(_conn_indx->begin()),*c(_conn->begin());
2483 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2485 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2487 std::set<int> s(c+ci[0],c+ci[1]);
2488 *retPtr=(int)s.size();
2493 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2495 std::set<int> s(c+ci[0],c+ci[1]); s.erase(-1);
2496 *retPtr=(int)s.size();
2502 void MEDCoupling1DGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
2504 int nbOfCells(getNumberOfCells());//performs checks
2505 if(cellId>=0 && cellId<nbOfCells)
2507 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2508 int nbOfNodes=stp-strt;
2510 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !");
2511 conn.resize(nbOfNodes);
2512 std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin());
2516 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2517 throw INTERP_KERNEL::Exception(oss.str().c_str());
2521 int MEDCoupling1DGTUMesh::getNumberOfNodesInCell(int cellId) const
2523 int nbOfCells(getNumberOfCells());//performs checks
2524 if(cellId>=0 && cellId<nbOfCells)
2526 const int *conn(_conn->begin());
2527 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2528 return stp-strt-std::count(conn+strt,conn+stp,-1);
2532 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNumberOfNodesInCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2533 throw INTERP_KERNEL::Exception(oss.str().c_str());
2537 std::string MEDCoupling1DGTUMesh::simpleRepr() const
2539 static const char msg0[]="No coordinates specified !";
2540 std::ostringstream ret;
2541 ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
2542 ret << "Description of mesh : \"" << getDescription() << "\"\n";
2544 double tt=getTime(tmpp1,tmpp2);
2545 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
2546 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
2547 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
2550 const int spaceDim=getSpaceDimension();
2551 ret << spaceDim << "\nInfo attached on space dimension : ";
2552 for(int i=0;i<spaceDim;i++)
2553 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
2557 ret << msg0 << "\n";
2558 ret << "Number of nodes : ";
2560 ret << getNumberOfNodes() << "\n";
2562 ret << msg0 << "\n";
2563 ret << "Number of cells : ";
2565 try { checkCoherency(); } catch(INTERP_KERNEL::Exception& /* e */)
2567 ret << "Nodal connectivity arrays are not set or badly set !\n";
2571 ret << getNumberOfCells() << "\n";
2572 ret << "Cell type : " << _cm->getRepr() << "\n";
2576 std::string MEDCoupling1DGTUMesh::advancedRepr() const
2578 std::ostringstream ret;
2579 ret << simpleRepr();
2580 ret << "\nCoordinates array : \n___________________\n\n";
2582 _coords->reprWithoutNameStream(ret);
2584 ret << "No array set !\n";
2585 ret << "\n\nNodal Connectivity : \n____________________\n\n";
2588 try { checkCoherency1(); } catch(INTERP_KERNEL::Exception& /* e */)
2590 ret << "Nodal connectivity arrays are not set or badly set !\n";
2595 int nbOfCells=getNumberOfCells();
2596 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2597 for(int i=0;i<nbOfCells;i++,ci++)
2599 ret << "Cell #" << i << " : ";
2600 std::copy(c+ci[0],c+ci[1],std::ostream_iterator<int>(ret," "));
2606 DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const
2608 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
2609 int spaceDim=getSpaceDimension();
2610 int nbOfCells=getNumberOfCells();//checkCoherency()
2611 int nbOfNodes=getNumberOfNodes();
2612 ret->alloc(nbOfCells,spaceDim);
2613 double *ptToFill=ret->getPointer();
2614 const double *coor=_coords->begin();
2615 const int *nodal=_conn->begin(),*nodali=_conn_indx->begin();
2617 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2619 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2621 std::fill(ptToFill,ptToFill+spaceDim,0.);
2622 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2624 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2626 if(*nodal>=0 && *nodal<nbOfNodes)
2627 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2630 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2631 throw INTERP_KERNEL::Exception(oss.str().c_str());
2633 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(nodali[1]-nodali[0])));
2638 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !";
2639 throw INTERP_KERNEL::Exception(oss.str().c_str());
2645 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2647 std::fill(ptToFill,ptToFill+spaceDim,0.);
2648 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2651 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2653 if(*nodal==-1) continue;
2654 if(*nodal>=0 && *nodal<nbOfNodes)
2656 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2661 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2662 throw INTERP_KERNEL::Exception(oss.str().c_str());
2666 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./nbOfNod));
2669 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !";
2670 throw INTERP_KERNEL::Exception(oss.str().c_str());
2675 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : at cell #" << i << " the nodal index array is invalid !";
2676 throw INTERP_KERNEL::Exception(oss.str().c_str());
2683 void MEDCoupling1DGTUMesh::renumberCells(const int *old2NewBg, bool check)
2685 int nbCells=getNumberOfCells();
2686 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
2687 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
2689 o2n=o2n->checkAndPreparePermutation();
2691 const int *o2nPtr=o2n->getPointer();
2692 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2693 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
2694 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
2695 newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1);
2696 newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx);
2698 int *newC=newConn->getPointer(),*newCI=newConnI->getPointer();
2699 for(int i=0;i<nbCells;i++)
2701 int newPos=o2nPtr[i];
2702 int sz=conni[i+1]-conni[i];
2707 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !";
2708 throw INTERP_KERNEL::Exception(oss.str().c_str());
2711 newConnI->computeOffsets2(); newCI=newConnI->getPointer();
2713 for(int i=0;i<nbCells;i++,conni++)
2716 std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]);
2719 _conn_indx=newConnI;
2722 MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
2724 if(other->getType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED)
2725 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !");
2726 const MEDCoupling1DGTUMesh *otherC=static_cast<const MEDCoupling1DGTUMesh *>(other);
2727 return Merge1DGTUMeshes(this,otherC);
2730 MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const
2732 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
2733 ret->setCoords(getCoords());
2734 const int *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin();
2735 int nbCells=getNumberOfCells();//checkCoherency
2736 int geoType=(int)getCellModelEnum();
2737 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1);
2738 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::New(); cI->alloc(nbCells+1);
2739 int *cPtr=c->getPointer(),*ciPtr=cI->getPointer();
2741 for(int i=0;i<nbCells;i++,ciPtr++)
2743 int sz=nodalConnI[i+1]-nodalConnI[i];
2747 cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr);
2748 ciPtr[1]=ciPtr[0]+sz+1;
2752 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !";
2753 throw INTERP_KERNEL::Exception(oss.str().c_str());
2756 ret->setConnectivity(c,cI,true);
2758 { ret->copyTinyInfoFrom(this); }
2759 catch(INTERP_KERNEL::Exception&) { }
2764 * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes
2766 DataArrayInt *MEDCoupling1DGTUMesh::simplexize(int policy)
2768 int nbOfCells=getNumberOfCells();
2769 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2770 ret->alloc(nbOfCells,1);
2775 void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const
2777 stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
2778 stream << " Mesh dimension : " << getMeshDimension() << ".";
2780 { stream << " No coordinates set !"; return ; }
2781 if(!_coords->isAllocated())
2782 { stream << " Coordinates set but not allocated !"; return ; }
2783 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
2784 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
2786 try { checkCoherency(); } catch(INTERP_KERNEL::Exception& /* e */)
2788 stream << std::endl << "Nodal connectivity NOT set properly !\n";
2792 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
2795 void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
2798 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
2799 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2801 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !");
2802 setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex());
2805 MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
2808 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
2809 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2811 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
2812 std::vector<const MEDCoupling1DGTUMesh *> ms(2);
2815 return Merge1DGTUMeshesOnSameCoords(ms);
2818 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
2821 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2822 ret->setCoords(_coords);
2823 DataArrayInt *c=0,*ci=0;
2824 MEDCouplingUMesh::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci);
2825 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2826 ret->setNodalConnectivity(c,ci);
2830 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
2833 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2834 ret->setCoords(_coords);
2835 DataArrayInt *c=0,*ci=0;
2836 MEDCouplingUMesh::ExtractFromIndexedArrays2(start,end,step,_conn,_conn_indx,c,ci);
2837 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2838 ret->setNodalConnectivity(c,ci);
2842 void MEDCoupling1DGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
2845 int sz((int)nodeIdsInUse.size());
2846 for(const int *conn=_conn->begin();conn!=_conn->end();conn++)
2848 if(*conn>=0 && *conn<sz)
2849 nodeIdsInUse[*conn]=true;
2854 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeNodeIdsAlg : At pos #" << std::distance(_conn->begin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !";
2855 throw INTERP_KERNEL::Exception(oss.str().c_str());
2861 void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const
2863 checkFullyDefined();
2864 int nbOfNodes=getNumberOfNodes();
2865 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
2866 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
2867 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
2868 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2869 int nbOfCells=getNumberOfCells();
2870 int nbOfEltsInRevNodal=0;
2871 for(int eltId=0;eltId<nbOfCells;eltId++)
2873 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2874 if(nbOfNodesPerCell>=0)
2876 for(int j=0;j<nbOfNodesPerCell;j++)
2878 int nodeId=conn[conni[eltId]+j];
2879 if(nodeId==-1) continue;
2880 if(nodeId>=0 && nodeId<nbOfNodes)
2882 nbOfEltsInRevNodal++;
2883 revNodalIndxPtr[nodeId+1]++;
2887 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
2888 throw INTERP_KERNEL::Exception(oss.str().c_str());
2894 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << "nodal connectivity is invalid !";
2895 throw INTERP_KERNEL::Exception(oss.str().c_str());
2898 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
2899 conn=_conn->begin();
2900 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
2901 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
2902 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
2903 for(int eltId=0;eltId<nbOfCells;eltId++)
2905 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2906 for(int j=0;j<nbOfNodesPerCell;j++)
2908 int nodeId=conn[conni[eltId]+j];
2910 *std::find_if(revNodalPtr+revNodalIndxPtr[nodeId],revNodalPtr+revNodalIndxPtr[nodeId+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
2915 void MEDCoupling1DGTUMesh::checkFullyDefined() const
2917 if(!((const DataArrayInt *)_conn) || !((const DataArrayInt *)_conn_indx) || !((const DataArrayDouble *)_coords))
2918 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined.");
2921 bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
2923 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !");
2926 void MEDCoupling1DGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
2929 double time=getTime(it,order);
2930 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
2932 littleStrings.push_back(getName());
2933 littleStrings.push_back(getDescription());
2934 littleStrings.push_back(getTimeUnit());
2936 std::vector<std::string> littleStrings2,littleStrings3,littleStrings4;
2937 if((const DataArrayDouble *)_coords)
2938 _coords->getTinySerializationStrInformation(littleStrings2);
2939 if((const DataArrayInt *)_conn)
2940 _conn->getTinySerializationStrInformation(littleStrings3);
2941 if((const DataArrayInt *)_conn_indx)
2942 _conn_indx->getTinySerializationStrInformation(littleStrings4);
2943 int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size()),sz2((int)littleStrings4.size());
2944 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
2945 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
2946 littleStrings.insert(littleStrings.end(),littleStrings4.begin(),littleStrings4.end());
2948 tinyInfo.push_back(getCellModelEnum());
2949 tinyInfo.push_back(it);
2950 tinyInfo.push_back(order);
2951 std::vector<int> tinyInfo2,tinyInfo3,tinyInfo4;
2952 if((const DataArrayDouble *)_coords)
2953 _coords->getTinySerializationIntInformation(tinyInfo2);
2954 if((const DataArrayInt *)_conn)
2955 _conn->getTinySerializationIntInformation(tinyInfo3);
2956 if((const DataArrayInt *)_conn_indx)
2957 _conn_indx->getTinySerializationIntInformation(tinyInfo4);
2958 int sz3((int)tinyInfo2.size()),sz4((int)tinyInfo3.size()),sz5((int)tinyInfo4.size());
2959 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3); tinyInfo.push_back(sz4); tinyInfo.push_back(sz5);
2960 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
2961 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
2962 tinyInfo.insert(tinyInfo.end(),tinyInfo4.begin(),tinyInfo4.end());
2964 tinyInfoD.push_back(time);
2967 void MEDCoupling1DGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
2969 std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+tinyInfo[6]);
2970 std::vector<int> tinyInfo1(tinyInfo.begin()+9+tinyInfo[6],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]);
2971 std::vector<int> tinyInfo12(tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]+tinyInfo[8]);
2972 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(DataArrayInt::New()); p1->resizeForUnserialization(tinyInfo1);
2973 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(DataArrayInt::New()); p2->resizeForUnserialization(tinyInfo12);
2974 std::vector<const DataArrayInt *> v(2); v[0]=p1; v[1]=p2;
2975 p2=DataArrayInt::Aggregate(v);
2976 a2->resizeForUnserialization(tinyInfo2);
2977 a1->alloc(p2->getNbOfElems(),1);
2980 void MEDCoupling1DGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
2983 if((const DataArrayInt *)_conn)
2984 if(_conn->isAllocated())
2985 sz=_conn->getNbOfElems();
2986 if((const DataArrayInt *)_conn_indx)
2987 if(_conn_indx->isAllocated())
2988 sz+=_conn_indx->getNbOfElems();
2989 a1=DataArrayInt::New();
2991 int *work(a1->getPointer());
2992 if(sz!=0 && (const DataArrayInt *)_conn)
2993 work=std::copy(_conn->begin(),_conn->end(),a1->getPointer());
2994 if(sz!=0 && (const DataArrayInt *)_conn_indx)
2995 std::copy(_conn_indx->begin(),_conn_indx->end(),work);
2997 if((const DataArrayDouble *)_coords)
2998 if(_coords->isAllocated())
2999 sz=_coords->getNbOfElems();
3000 a2=DataArrayDouble::New();
3002 if(sz!=0 && (const DataArrayDouble *)_coords)
3003 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
3006 void MEDCoupling1DGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
3007 const std::vector<std::string>& littleStrings)
3009 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
3010 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
3011 setName(littleStrings[0]);
3012 setDescription(littleStrings[1]);
3013 setTimeUnit(littleStrings[2]);
3014 setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
3015 int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]),sz4(tinyInfo[7]),sz5(tinyInfo[8]);
3017 _coords=DataArrayDouble::New();
3018 std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+sz3);
3019 _coords->resizeForUnserialization(tinyInfo2);
3020 std::copy(a2->begin(),a2->end(),_coords->getPointer());
3021 _conn=DataArrayInt::New();
3022 std::vector<int> tinyInfo3(tinyInfo.begin()+9+sz3,tinyInfo.begin()+9+sz3+sz4);
3023 _conn->resizeForUnserialization(tinyInfo3);
3024 std::copy(a1->begin(),a1->begin()+_conn->getNbOfElems(),_conn->getPointer());
3025 _conn_indx=DataArrayInt::New();
3026 std::vector<int> tinyInfo4(tinyInfo.begin()+9+sz3+sz4,tinyInfo.begin()+9+sz3+sz4+sz5);
3027 _conn_indx->resizeForUnserialization(tinyInfo4);
3028 std::copy(a1->begin()+_conn->getNbOfElems(),a1->end(),_conn_indx->getPointer());
3029 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
3030 _coords->finishUnserialization(tinyInfo2,littleStrings2);
3031 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
3032 _conn->finishUnserialization(tinyInfo3,littleStrings3);
3033 std::vector<std::string> littleStrings4(littleStrings.begin()+3+sz0+sz1,littleStrings.begin()+3+sz0+sz1+sz2);
3034 _conn_indx->finishUnserialization(tinyInfo4,littleStrings4);
3038 * Finds nodes not used in any cell and returns an array giving a new id to every node
3039 * by excluding the unused nodes, for which the array holds -1. The result array is
3040 * a mapping in "Old to New" mode.
3041 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
3042 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
3043 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
3044 * if the node is unused or a new id else. The caller is to delete this
3045 * array using decrRef() as it is no more needed.
3046 * \throw If the coordinates array is not set.
3047 * \throw If the nodal connectivity of cells is not defined.
3048 * \throw If the nodal connectivity includes an invalid id.
3049 * \sa MEDCoupling1DGTUMesh::computeFetchedNodeIds
3051 DataArrayInt *MEDCoupling1DGTUMesh::computeFetchedNodeIds() const
3054 int nbNodes(getNumberOfNodes());
3055 std::vector<bool> fetchedNodes(nbNodes,false);
3056 computeNodeIdsAlg(fetchedNodes);
3057 int sz((int)std::count(fetchedNodes.begin(),fetchedNodes.end(),true));
3058 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
3059 int *retPtr(ret->getPointer());
3060 for(int i=0;i<nbNodes;i++)
3067 * Finds nodes not used in any cell and returns an array giving a new id to every node
3068 * by excluding the unused nodes, for which the array holds -1. The result array is
3069 * a mapping in "Old to New" mode.
3070 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
3071 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
3072 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
3073 * if the node is unused or a new id else. The caller is to delete this
3074 * array using decrRef() as it is no more needed.
3075 * \throw If the coordinates array is not set.
3076 * \throw If the nodal connectivity of cells is not defined.
3077 * \throw If the nodal connectivity includes an invalid id.
3078 * \sa MEDCoupling1DGTUMesh::computeFetchedNodeIds
3080 DataArrayInt *MEDCoupling1DGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
3083 int nbOfNodes=getNumberOfNodes();
3084 int nbOfCells=getNumberOfCells();//checkCoherency
3085 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
3086 ret->alloc(nbOfNodes,1);
3087 int *traducer=ret->getPointer();
3088 std::fill(traducer,traducer+nbOfNodes,-1);
3089 const int *conn=_conn->begin(),*conni(_conn_indx->begin());
3090 for(int i=0;i<nbOfCells;i++,conni++)
3092 int nbNodesPerCell=conni[1]-conni[0];
3093 for(int j=0;j<nbNodesPerCell;j++)
3095 int nodeId=conn[conni[0]+j];
3096 if(nodeId==-1) continue;
3097 if(nodeId>=0 && nodeId<nbOfNodes)
3101 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << nodeId << " not in [0," << nbOfNodes << ") !";
3102 throw INTERP_KERNEL::Exception(oss.str().c_str());
3106 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
3107 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
3112 * This method renumbers only nodal connectivity in \a this. The renumbering is only an offset applied. So this method is a specialization of
3113 * \a renumberNodesInConn. \b WARNING, this method does not check that the resulting node ids in the nodal connectivity is in a valid range !
3115 * \param [in] offset - specifies the offset to be applied on each element of connectivity.
3117 * \sa renumberNodesInConn
3119 void MEDCoupling1DGTUMesh::renumberNodesWithOffsetInConn(int offset)
3121 getNumberOfCells();//only to check that all is well defined.
3123 int nbOfTuples(_conn->getNumberOfTuples());
3124 int *pt(_conn->getPointer());
3125 for(int i=0;i<nbOfTuples;i++,pt++)
3127 if(*pt==-1) continue;
3135 * Same than renumberNodesInConn(const int *) except that here the format of old-to-new traducer is using map instead
3136 * of array. This method is dedicated for renumbering from a big set of nodes the a tiny set of nodes which is the case during extraction
3139 void MEDCoupling1DGTUMesh::renumberNodesInConn(const INTERP_KERNEL::HashMap<int,int>& newNodeNumbersO2N)
3141 getNumberOfCells();//only to check that all is well defined.
3143 int nbElemsIn(getNumberOfNodes()),nbOfTuples(_conn->getNumberOfTuples());
3144 int *pt(_conn->getPointer());
3145 for(int i=0;i<nbOfTuples;i++,pt++)
3147 if(*pt==-1) continue;
3148 if(*pt>=0 && *pt<nbElemsIn)
3150 INTERP_KERNEL::HashMap<int,int>::const_iterator it(newNodeNumbersO2N.find(*pt));
3151 if(it!=newNodeNumbersO2N.end())
3155 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : At pos #" << i << " of connectivity, node id is " << *pt << ". Not in keys of input map !";
3156 throw INTERP_KERNEL::Exception(oss.str().c_str());
3161 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
3162 throw INTERP_KERNEL::Exception(oss.str().c_str());
3170 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
3171 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
3172 * This method is a generalization of shiftNodeNumbersInConn().
3173 * \warning This method performs no check of validity of new ids. **Use it with care !**
3174 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
3175 * this->getNumberOfNodes(), in "Old to New" mode.
3176 * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
3177 * \throw If the nodal connectivity of cells is not defined.
3179 void MEDCoupling1DGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
3181 getNumberOfCells();//only to check that all is well defined.
3183 int nbElemsIn(getNumberOfNodes()),nbOfTuples(_conn->getNumberOfTuples());
3184 int *pt(_conn->getPointer());
3185 for(int i=0;i<nbOfTuples;i++,pt++)
3187 if(*pt==-1) continue;
3188 if(*pt>=0 && *pt<nbElemsIn)
3189 *pt=newNodeNumbersO2N[*pt];
3192 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
3193 throw INTERP_KERNEL::Exception(oss.str().c_str());
3201 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
3202 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
3203 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
3204 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
3206 * \param [in] begin input start of array of node ids.
3207 * \param [in] end input end of array of node ids.
3208 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
3209 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
3211 void MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
3213 int nbOfCells=getNumberOfCells();
3214 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
3216 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
3217 std::vector<bool> fastFinder(sz,false);
3218 for(const int *work=begin;work!=end;work++)
3219 if(*work>=0 && *work<sz)
3220 fastFinder[*work]=true;
3221 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
3222 for(int i=0;i<nbOfCells;i++,conni++)
3224 int ref=0,nbOfHit=0;
3225 int nbNodesPerCell=conni[1]-conni[0];
3226 if(nbNodesPerCell>=0)
3228 for(int j=0;j<nbNodesPerCell;j++)
3230 int nodeId=conn[conni[0]+j];
3234 if(fastFinder[nodeId])
3241 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !";
3242 throw INTERP_KERNEL::Exception(oss.str().c_str());
3244 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
3245 cellIdsKept->pushBackSilent(i);
3247 cellIdsKeptArr=cellIdsKept.retn();
3250 void MEDCoupling1DGTUMesh::allocateCells(int nbOfCells)
3253 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !");
3254 _conn=DataArrayInt::New();
3255 _conn->reserve(nbOfCells*3);
3256 _conn_indx=DataArrayInt::New();
3257 _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0);
3262 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
3264 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
3265 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
3266 * \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
3267 * attached to \a this.
3268 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
3270 void MEDCoupling1DGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd)
3272 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
3273 DataArrayInt *c(_conn),*c2(_conn_indx);
3277 if(pos==c->getNumberOfTuples())
3279 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
3280 c2->pushBackSilent(pos+sz);
3284 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !";
3285 throw INTERP_KERNEL::Exception(oss.str().c_str());
3289 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !");
3292 void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex)
3295 nodalConn->incrRef();
3298 nodalConnIndex->incrRef();
3299 _conn_indx=nodalConnIndex;
3304 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
3306 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivity() const
3308 const DataArrayInt *ret(_conn);
3309 return const_cast<DataArrayInt *>(ret);
3313 * \return DataArrayInt * - the internal reference to the nodal connectivity index. The caller is not reponsible to deallocate it.
3315 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const
3317 const DataArrayInt *ret(_conn_indx);
3318 return const_cast<DataArrayInt *>(ret);
3322 * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here".
3323 * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity).
3324 * 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.
3326 * 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.
3328 * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal
3329 * connectivity arrays are different (false)
3330 * \return a new object to be managed by the caller.
3332 * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked
3334 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const
3336 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3337 DataArrayInt *nc=0,*nci=0;
3338 isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci);
3339 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ncs(nc),ncis(nci);
3340 ret->_conn=ncs; ret->_conn_indx=ncis;
3341 ret->setCoords(getCoords());
3346 * This method allows to compute, if needed, the packed nodal connectivity pair.
3347 * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges convered by nodal connectivity index array.
3348 * 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.
3350 * 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)
3351 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3353 * 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
3356 * This method return 3 elements.
3357 * \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
3358 * this pointer can be seen as a new object, that is to managed by the caller.
3359 * \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
3360 * this pointer can be seen as a new object, that is to managed by the caller.
3361 * \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
3362 * output parameters are newly created objects.
3364 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
3366 bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const
3368 if(isPacked())//performs the checkCoherency
3370 const DataArrayInt *c0(_conn),*c1(_conn_indx);
3371 nodalConn=const_cast<DataArrayInt *>(c0); nodalConnIndx=const_cast<DataArrayInt *>(c1);
3372 nodalConn->incrRef(); nodalConnIndx->incrRef();
3375 int bg=_conn_indx->front(),end=_conn_indx->back();
3376 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nc(_conn->selectByTupleId2(bg,end,1));
3377 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nci(_conn_indx->deepCpy());
3378 nci->applyLin(1,-bg);
3379 nodalConn=nc.retn(); nodalConnIndx=nci.retn();
3384 * 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)
3385 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3386 * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned.
3387 * \return bool - true if \a this looks packed, false is not.
3389 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
3391 bool MEDCoupling1DGTUMesh::isPacked() const
3394 return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples();
3397 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2)
3399 std::vector<const MEDCoupling1DGTUMesh *> tmp(2);
3400 tmp[0]=const_cast<MEDCoupling1DGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1DGTUMesh *>(mesh2);
3401 return Merge1DGTUMeshes(tmp);
3404 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a)
3406 std::size_t sz=a.size();
3408 return Merge1DGTUMeshesLL(a);
3409 for(std::size_t ii=0;ii<sz;ii++)
3412 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::Merge1DGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
3413 throw INTERP_KERNEL::Exception(oss.str().c_str());
3415 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
3416 for(std::size_t ii=0;ii<sz;ii++)
3417 if(&(a[ii]->getCellModel())!=cm)
3418 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !");
3419 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > bb(sz);
3420 std::vector< const MEDCoupling1DGTUMesh * > aa(sz);
3422 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
3424 const MEDCoupling1DGTUMesh *cur=a[i];
3425 const DataArrayDouble *coo=cur->getCoords();
3427 spaceDim=coo->getNumberOfComponents();
3430 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !");
3431 for(std::size_t i=0;i<sz;i++)
3433 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
3436 return Merge1DGTUMeshesLL(aa);
3440 * \throw If presence of a null instance in the input vector \a a.
3441 * \throw If a is empty
3443 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a)
3446 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !");
3447 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3449 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !");
3450 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
3451 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3452 (*it)->getNumberOfCells();//to check that all is OK
3453 const DataArrayDouble *coords=(*it)->getCoords();
3454 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3456 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3457 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3459 for(int i=1;it!=a.end();i++,it++)
3462 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !");
3463 if(cm!=&((*it)->getCellModel()))
3464 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3465 (*it)->getNumberOfCells();//to check that all is OK
3466 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3467 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3468 if(coords!=(*it)->getCoords())
3469 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !");
3471 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3472 ret->setCoords(coords);
3473 ret->_conn=DataArrayInt::Aggregate(ncs);
3474 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3479 * 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)
3481 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a)
3484 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : input array must be NON EMPTY !");
3485 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
3486 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3487 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3488 std::vector<int> nbNodesPerElt(a.size());
3489 int nbOfCells=(*it)->getNumberOfCells();
3491 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3492 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3494 int prevNbOfNodes=(*it)->getNumberOfNodes();
3495 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3497 for(int i=1;it!=a.end();i++,it++)
3499 if(cm!=&((*it)->getCellModel()))
3500 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3501 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3502 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3503 nbOfCells+=(*it)->getNumberOfCells();
3504 nbNodesPerElt[i]=nbNodesPerElt[i-1]+prevNbOfNodes;
3505 prevNbOfNodes=(*it)->getNumberOfNodes();
3507 std::vector<const MEDCouplingPointSet *> aps(a.size());
3508 std::copy(a.begin(),a.end(),aps.begin());
3509 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
3510 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3511 ret->setCoords(pts);
3512 ret->_conn=AggregateNodalConnAndShiftNodeIds(ncs,nbNodesPerElt);
3513 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3517 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(int spaceDim) const
3519 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3520 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1,tmp2;
3521 const DataArrayInt *nodalConn(_conn),*nodalConnI(_conn_indx);
3524 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
3532 tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
3536 ret->_conn_indx=tmp2;
3540 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
3541 ret->setCoords(coords);
3544 ret->setCoords(_coords);
3549 * This method aggregate the bbox of each cell and put it into bbox parameter.
3551 * \param [in] arcDetEps - a parameter specifying in case of 2D quadratic polygon cell the detection limit between linear and arc circle. (By default 1e-12)
3552 * For all other cases this input parameter is ignored.
3553 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
3555 * \throw If \a this is not fully set (coordinates and connectivity).
3556 * \throw If a cell in \a this has no valid nodeId.
3558 DataArrayDouble *MEDCoupling1DGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
3560 checkFullyDefined();
3561 int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes());
3562 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
3563 double *bbox(ret->getPointer());
3564 for(int i=0;i<nbOfCells*spaceDim;i++)
3566 bbox[2*i]=std::numeric_limits<double>::max();
3567 bbox[2*i+1]=-std::numeric_limits<double>::max();
3569 const double *coordsPtr(_coords->getConstPointer());
3570 const int *conn(_conn->getConstPointer()),*connI(_conn_indx->getConstPointer());
3571 for(int i=0;i<nbOfCells;i++)
3573 int offset=connI[i];
3574 int nbOfNodesForCell(connI[i+1]-offset),kk(0);
3575 for(int j=0;j<nbOfNodesForCell;j++)
3577 int nodeId=conn[offset+j];
3578 if(nodeId>=0 && nodeId<nbOfNodes)
3580 for(int k=0;k<spaceDim;k++)
3582 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
3583 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
3590 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
3591 throw INTERP_KERNEL::Exception(oss.str().c_str());
3597 std::vector<int> MEDCoupling1DGTUMesh::BuildAPolygonFromParts(const std::vector< std::vector<int> >& parts)
3599 std::vector<int> ret;
3602 ret.insert(ret.end(),parts[0].begin(),parts[0].end());
3603 int ref(ret.back());
3604 std::size_t sz(parts.size()),nbh(1);
3605 std::vector<bool> b(sz,true); b[0]=false;
3609 for(;i<sz;i++) if(b[i] && parts[i].front()==ref) { ret.insert(ret.end(),parts[i].begin()+1,parts[i].end()); nbh++; break; }
3613 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::BuildAPolygonFromParts : the input vector is not a part of a single polygon !");
3615 if(ret.back()==ret.front())
3621 * This method performs an aggregation of \a nodalConns (as DataArrayInt::Aggregate does) but in addition of that a shift is applied on the
3622 * values contained in \a nodalConns using corresponding offset specified in input \a offsetInNodeIdsPerElt.
3623 * But it also manage the values -1, that have a semantic in MEDCoupling1DGTUMesh class (separator for polyhedron).
3625 * \param [in] nodalConns - a list of nodal connectivity arrays same size than \a offsetInNodeIdsPerElt.
3626 * \param [in] offsetInNodeIdsPerElt - a list of offsets to apply.
3627 * \return DataArrayInt * - A new object (to be managed by the caller) that is the result of the aggregation.
3628 * \throw If \a nodalConns or \a offsetInNodeIdsPerElt are empty.
3629 * \throw If \a nodalConns and \a offsetInNodeIdsPerElt have not the same size.
3630 * \throw If presence of null pointer in \a nodalConns.
3631 * \throw If presence of not allocated or array with not exactly one component in \a nodalConns.
3633 DataArrayInt *MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds(const std::vector<const DataArrayInt *>& nodalConns, const std::vector<int>& offsetInNodeIdsPerElt)
3635 std::size_t sz1(nodalConns.size()),sz2(offsetInNodeIdsPerElt.size());
3637 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : input vectors do not have the same size !");
3639 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : empty vectors in input !");
3641 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++)
3644 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of null pointer in input vector !");
3645 if(!(*it)->isAllocated())
3646 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of non allocated array in input vector !");
3647 if((*it)->getNumberOfComponents()!=1)
3648 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of array with not exactly one component !");
3649 nbOfTuples+=(*it)->getNumberOfTuples();
3651 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
3652 int *pt=ret->getPointer();
3654 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++,i++)
3656 int curNbt=(*it)->getNumberOfTuples();
3657 const int *inPt=(*it)->begin();
3658 int offset=offsetInNodeIdsPerElt[i];
3659 for(int j=0;j<curNbt;j++,pt++)
3670 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m)
3673 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh is null !");
3674 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
3676 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh must have exactly one geometric type !");
3677 int geoType((int)*gts.begin());
3678 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(m->getName(),*gts.begin()));
3679 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription());
3680 int nbCells(m->getNumberOfCells());
3681 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
3682 conn->alloc(m->getMeshLength()-nbCells,1); connI->alloc(nbCells+1,1);
3683 int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
3684 const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
3685 for(int i=0;i<nbCells;i++,ciin++,ci++)
3687 if(cin[ciin[0]]==geoType)
3689 if(ciin[1]-ciin[0]>=1)
3691 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
3692 ci[1]=ci[0]+ciin[1]-ciin[0]-1;
3696 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 !";
3697 throw INTERP_KERNEL::Exception(oss.str().c_str());
3702 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 !";
3703 throw INTERP_KERNEL::Exception(oss.str().c_str());
3706 ret->setNodalConnectivity(conn,connI);