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 * Finds nodes not used in any cell and returns an array giving a new id to every node
1010 * by excluding the unused nodes, for which the array holds -1. The result array is
1011 * a mapping in "Old to New" mode.
1012 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
1013 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
1014 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
1015 * if the node is unused or a new id else. The caller is to delete this
1016 * array using decrRef() as it is no more needed.
1017 * \throw If the coordinates array is not set.
1018 * \throw If the nodal connectivity of cells is not defined.
1019 * \throw If the nodal connectivity includes an invalid id.
1021 DataArrayInt *MEDCoupling1SGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
1024 int nbOfNodes=getNumberOfNodes();
1025 int nbOfCells=getNumberOfCells();
1026 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1027 ret->alloc(nbOfNodes,1);
1028 int *traducer=ret->getPointer();
1029 std::fill(traducer,traducer+nbOfNodes,-1);
1030 const int *conn=_conn->begin();
1031 int nbNodesPerCell=getNumberOfNodesPerCell();
1032 for(int i=0;i<nbOfCells;i++)
1033 for(int j=0;j<nbNodesPerCell;j++,conn++)
1034 if(*conn>=0 && *conn<nbOfNodes)
1038 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << conn[j] << " not in [0," << nbOfNodes << ") !";
1039 throw INTERP_KERNEL::Exception(oss.str().c_str());
1041 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
1042 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
1047 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
1048 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
1049 * This method is a generalization of shiftNodeNumbersInConn().
1050 * \warning This method performs no check of validity of new ids. **Use it with care !**
1051 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
1052 * this->getNumberOfNodes(), in "Old to New" mode.
1053 * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
1054 * \throw If the nodal connectivity of cells is not defined.
1056 void MEDCoupling1SGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
1058 getNumberOfCells();//only to check that all is well defined.
1059 _conn->transformWithIndArr(newNodeNumbersO2N,newNodeNumbersO2N+getNumberOfNodes());
1063 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2)
1065 std::vector<const MEDCoupling1SGTUMesh *> tmp(2);
1066 tmp[0]=const_cast<MEDCoupling1SGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1SGTUMesh *>(mesh2);
1067 return Merge1SGTUMeshes(tmp);
1070 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(std::vector<const MEDCoupling1SGTUMesh *>& a)
1072 std::size_t sz=a.size();
1074 return Merge1SGTUMeshesLL(a);
1075 for(std::size_t ii=0;ii<sz;ii++)
1078 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::Merge1SGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
1079 throw INTERP_KERNEL::Exception(oss.str().c_str());
1081 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
1082 for(std::size_t ii=0;ii<sz;ii++)
1083 if(&(a[ii]->getCellModel())!=cm)
1084 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : all items must have the same geo type !");
1085 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> > bb(sz);
1086 std::vector< const MEDCoupling1SGTUMesh * > aa(sz);
1088 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
1090 const MEDCoupling1SGTUMesh *cur=a[i];
1091 const DataArrayDouble *coo=cur->getCoords();
1093 spaceDim=coo->getNumberOfComponents();
1096 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : no spaceDim specified ! unable to perform merge !");
1097 for(std::size_t i=0;i<sz;i++)
1099 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
1102 return Merge1SGTUMeshesLL(aa);
1106 * \throw If presence of a null instance in the input vector \a a.
1107 * \throw If a is empty
1109 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::vector<const MEDCoupling1SGTUMesh *>& a)
1112 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : input array must be NON EMPTY !");
1113 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1115 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : null instance in the first element of input vector !");
1116 std::vector<const DataArrayInt *> ncs(a.size());
1117 (*it)->getNumberOfCells();//to check that all is OK
1118 const DataArrayDouble *coords=(*it)->getCoords();
1119 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1120 ncs[0]=(*it)->getNodalConnectivity();
1122 for(int i=1;it!=a.end();i++,it++)
1125 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : presence of a null instance in the input vector !");
1126 if(cm!=&((*it)->getCellModel()))
1127 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1128 (*it)->getNumberOfCells();//to check that all is OK
1129 ncs[i]=(*it)->getNodalConnectivity();
1130 if(coords!=(*it)->getCoords())
1131 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : not lying on same coords !");
1133 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1134 ret->setCoords(coords);
1135 ret->_conn=DataArrayInt::Aggregate(ncs);
1140 * 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)
1142 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector<const MEDCoupling1SGTUMesh *>& a)
1145 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : input array must be NON EMPTY !");
1146 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1147 int nbOfCells=(*it)->getNumberOfCells();
1148 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1149 int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
1151 for(;it!=a.end();it++)
1153 if(cm!=&((*it)->getCellModel()))
1154 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1155 nbOfCells+=(*it)->getNumberOfCells();
1157 std::vector<const MEDCouplingPointSet *> aps(a.size());
1158 std::copy(a.begin(),a.end(),aps.begin());
1159 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
1160 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1161 ret->setCoords(pts);
1162 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New();
1163 c->alloc(nbOfCells*nbNodesPerCell,1);
1164 int *cPtr=c->getPointer();
1166 for(it=a.begin();it!=a.end();it++)
1168 int curConnLgth=(*it)->getNodalConnectivityLength();
1169 const int *curC=(*it)->_conn->begin();
1170 cPtr=std::transform(curC,curC+curConnLgth,cPtr,std::bind2nd(std::plus<int>(),offset));
1171 offset+=(*it)->getNumberOfNodes();
1174 ret->setNodalConnectivity(c);
1178 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
1180 int ncell=getNumberOfCells();
1181 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1182 ret->setCoords(_coords);
1183 std::size_t nbOfElemsRet=std::distance(begin,end);
1184 const int *inConn=_conn->getConstPointer();
1185 int sz=getNumberOfNodesPerCell();
1186 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1187 int *connPtr=connRet->getPointer();
1188 for(const int *work=begin;work!=end;work++,connPtr+=sz)
1190 if(*work>=0 && *work<ncell)
1191 std::copy(inConn+(work[0])*sz,inConn+(work[0]+1)*sz,connPtr);
1194 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !";
1195 throw INTERP_KERNEL::Exception(oss.str().c_str());
1199 ret->copyTinyInfoFrom(this);
1203 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
1205 int ncell=getNumberOfCells();
1206 int nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : ");
1207 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1208 ret->setCoords(_coords);
1209 const int *inConn=_conn->getConstPointer();
1210 int sz=getNumberOfNodesPerCell();
1211 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1212 int *connPtr=connRet->getPointer();
1214 for(int i=0;i<nbOfElemsRet;i++,connPtr+=sz,curId+=step)
1216 if(curId>=0 && curId<ncell)
1217 std::copy(inConn+curId*sz,inConn+(curId+1)*sz,connPtr);
1220 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : On pos #" << i << " input cell id =" << curId << " should be in [0," << ncell << ") !";
1221 throw INTERP_KERNEL::Exception(oss.str().c_str());
1225 ret->copyTinyInfoFrom(this);
1229 void MEDCoupling1SGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
1231 int sz((int)nodeIdsInUse.size());
1232 int nbCells(getNumberOfCells());
1233 int nbOfNodesPerCell(getNumberOfNodesPerCell());
1234 const int *w(_conn->begin());
1235 for(int i=0;i<nbCells;i++)
1236 for(int j=0;j<nbOfNodesPerCell;j++,w++)
1239 nodeIdsInUse[*w]=true;
1242 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeNodeIdsAlg : At cell #" << i << " presence of node id #" << *w << " should be in [0," << sz << ") !";
1243 throw INTERP_KERNEL::Exception(oss.str().c_str());
1248 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(int spaceDim) const
1250 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1251 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1;
1252 const DataArrayInt *nodalConn(_conn);
1255 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
1262 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
1263 ret->setCoords(coords);
1266 ret->setCoords(_coords);
1270 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol0()
1272 int nbOfCells=getNumberOfCells();
1273 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1274 return DataArrayInt::Range(0,nbOfCells,1);
1275 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1276 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1277 const int *c(_conn->begin());
1278 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1279 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1281 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[2];
1282 newConnPtr[3]=c[0]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1283 retPtr[0]=i; retPtr[1]=i;
1286 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1291 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol1()
1293 int nbOfCells=getNumberOfCells();
1294 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1295 return DataArrayInt::Range(0,nbOfCells,1);
1296 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1297 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1298 const int *c(_conn->begin());
1299 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1300 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1302 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[3];
1303 newConnPtr[3]=c[1]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1304 retPtr[0]=i; retPtr[1]=i;
1307 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1312 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace5()
1314 int nbOfCells=getNumberOfCells();
1315 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1316 return DataArrayInt::Range(0,nbOfCells,1);
1317 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(5*4*nbOfCells,1);
1318 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(5*nbOfCells,1);
1319 const int *c(_conn->begin());
1320 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1321 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=20,retPtr+=5)
1323 for(int j=0;j<20;j++)
1324 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_5_WO[j]];
1325 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i;
1328 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1333 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace6()
1335 int nbOfCells=getNumberOfCells();
1336 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1337 return DataArrayInt::Range(0,nbOfCells,1);
1338 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(6*4*nbOfCells,1);
1339 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(6*nbOfCells,1);
1340 const int *c(_conn->begin());
1341 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1342 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=24,retPtr+=6)
1344 for(int j=0;j<24;j++)
1345 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_6_WO[j]];
1346 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i; retPtr[5]=i;
1349 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1354 void MEDCoupling1SGTUMesh::reprQuickOverview(std::ostream& stream) const
1356 stream << "MEDCoupling1SGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
1357 stream << " Mesh dimension : " << getMeshDimension() << ".";
1359 { stream << " No coordinates set !"; return ; }
1360 if(!_coords->isAllocated())
1361 { stream << " Coordinates set but not allocated !"; return ; }
1362 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
1363 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
1364 if(!(const DataArrayInt *)_conn)
1365 { stream << std::endl << "Nodal connectivity NOT set !"; return ; }
1366 if(_conn->isAllocated())
1368 if(_conn->getNumberOfComponents()==1)
1369 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
1373 void MEDCoupling1SGTUMesh::checkFullyDefined() const
1375 if(!((const DataArrayInt *)_conn) || !((const DataArrayDouble *)_coords))
1376 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFullyDefined : part of this is not fully defined.");
1380 * First step of unserialization process.
1382 bool MEDCoupling1SGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
1384 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEmptyMesh : not implemented yet !");
1387 void MEDCoupling1SGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
1390 double time=getTime(it,order);
1391 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
1393 littleStrings.push_back(getName());
1394 littleStrings.push_back(getDescription());
1395 littleStrings.push_back(getTimeUnit());
1397 std::vector<std::string> littleStrings2,littleStrings3;
1398 if((const DataArrayDouble *)_coords)
1399 _coords->getTinySerializationStrInformation(littleStrings2);
1400 if((const DataArrayInt *)_conn)
1401 _conn->getTinySerializationStrInformation(littleStrings3);
1402 int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size());
1403 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
1404 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
1406 tinyInfo.push_back(getCellModelEnum());
1407 tinyInfo.push_back(it);
1408 tinyInfo.push_back(order);
1409 std::vector<int> tinyInfo2,tinyInfo3;
1410 if((const DataArrayDouble *)_coords)
1411 _coords->getTinySerializationIntInformation(tinyInfo2);
1412 if((const DataArrayInt *)_conn)
1413 _conn->getTinySerializationIntInformation(tinyInfo3);
1414 int sz2((int)tinyInfo2.size()),sz3((int)tinyInfo3.size());
1415 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3);
1416 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1417 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
1419 tinyInfoD.push_back(time);
1422 void MEDCoupling1SGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
1424 std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+tinyInfo[5]);
1425 std::vector<int> tinyInfo1(tinyInfo.begin()+7+tinyInfo[5],tinyInfo.begin()+7+tinyInfo[5]+tinyInfo[6]);
1426 a1->resizeForUnserialization(tinyInfo1);
1427 a2->resizeForUnserialization(tinyInfo2);
1430 void MEDCoupling1SGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
1433 if((const DataArrayInt *)_conn)
1434 if(_conn->isAllocated())
1435 sz=_conn->getNbOfElems();
1436 a1=DataArrayInt::New();
1438 if(sz!=0 && (const DataArrayInt *)_conn)
1439 std::copy(_conn->begin(),_conn->end(),a1->getPointer());
1441 if((const DataArrayDouble *)_coords)
1442 if(_coords->isAllocated())
1443 sz=_coords->getNbOfElems();
1444 a2=DataArrayDouble::New();
1446 if(sz!=0 && (const DataArrayDouble *)_coords)
1447 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
1450 void MEDCoupling1SGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
1451 const std::vector<std::string>& littleStrings)
1453 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
1454 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
1455 setName(littleStrings[0]);
1456 setDescription(littleStrings[1]);
1457 setTimeUnit(littleStrings[2]);
1458 setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
1459 int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]);
1461 _coords=DataArrayDouble::New();
1462 std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+sz2);
1463 _coords->resizeForUnserialization(tinyInfo2);
1464 std::copy(a2->begin(),a2->end(),_coords->getPointer());
1465 _conn=DataArrayInt::New();
1466 std::vector<int> tinyInfo3(tinyInfo.begin()+7+sz2,tinyInfo.begin()+7+sz2+sz3);
1467 _conn->resizeForUnserialization(tinyInfo3);
1468 std::copy(a1->begin(),a1->end(),_conn->getPointer());
1469 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
1470 _coords->finishUnserialization(tinyInfo2,littleStrings2);
1471 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
1472 _conn->finishUnserialization(tinyInfo3,littleStrings3);
1476 * Checks if \a this and \a other meshes are geometrically equivalent with high
1477 * probability, else an exception is thrown. The meshes are considered equivalent if
1478 * (1) meshes contain the same number of nodes and the same number of elements of the
1479 * same types (2) three cells of the two meshes (first, last and middle) are based
1480 * on coincident nodes (with a specified precision).
1481 * \param [in] other - the mesh to compare with.
1482 * \param [in] prec - the precision used to compare nodes of the two meshes.
1483 * \throw If the two meshes do not match.
1485 void MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
1487 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1488 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1490 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single static geometric type !");
1491 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1495 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1496 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1497 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1498 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1499 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1500 if(c1->getHashCode()!=c2->getHashCode())
1501 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1504 MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
1507 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
1508 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1510 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
1511 std::vector<const MEDCoupling1SGTUMesh *> ms(2);
1514 return Merge1SGTUMeshesOnSameCoords(ms);
1517 void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const
1519 checkFullyDefined();
1520 int nbOfNodes=getNumberOfNodes();
1521 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
1522 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
1523 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
1524 const int *conn=_conn->begin();
1525 int nbOfCells=getNumberOfCells();
1526 int nbOfEltsInRevNodal=0;
1527 int nbOfNodesPerCell=getNumberOfNodesPerCell();
1528 for(int eltId=0;eltId<nbOfCells;eltId++)
1530 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1532 if(conn[0]>=0 && conn[0]<nbOfNodes)
1534 nbOfEltsInRevNodal++;
1535 revNodalIndxPtr[conn[0]+1]++;
1539 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
1540 throw INTERP_KERNEL::Exception(oss.str().c_str());
1544 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
1545 conn=_conn->begin();
1546 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
1547 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
1548 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
1549 for(int eltId=0;eltId<nbOfCells;eltId++)
1551 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1553 *std::find_if(revNodalPtr+revNodalIndxPtr[*conn],revNodalPtr+revNodalIndxPtr[*conn+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
1559 * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null.
1561 void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn)
1564 nodalConn->incrRef();
1570 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
1572 DataArrayInt *MEDCoupling1SGTUMesh::getNodalConnectivity() const
1574 const DataArrayInt *ret(_conn);
1575 return const_cast<DataArrayInt *>(ret);
1579 * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted,
1580 * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter.
1581 * If a nodal connectivity previouly existed before the call of this method, it will be reset.
1583 * \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain.
1585 void MEDCoupling1SGTUMesh::allocateCells(int nbOfCells)
1588 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !");
1589 _conn=DataArrayInt::New();
1590 _conn->reserve(getNumberOfNodesPerCell()*nbOfCells);
1595 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
1597 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
1598 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
1599 * \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
1600 * attached to \a this.
1601 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
1603 void MEDCoupling1SGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd)
1605 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
1606 int ref=getNumberOfNodesPerCell();
1609 DataArrayInt *c(_conn);
1611 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
1613 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !");
1617 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this (";
1618 oss << ref << ") !";
1619 throw INTERP_KERNEL::Exception(oss.str().c_str());
1624 * This method builds the dual mesh of \a this and returns it.
1626 * \return MEDCoupling1SGTUMesh * - newly object created to be managed by the caller.
1627 * \throw If \a this is not a mesh containing only simplex cells.
1628 * \throw If \a this is not correctly allocated (coordinates and connectivities have to be correctly set !).
1629 * \throw If at least one node in \a this is orphan (without any simplex cell lying on it !)
1631 MEDCoupling1GTUMesh *MEDCoupling1SGTUMesh::computeDualMesh() const
1633 const INTERP_KERNEL::CellModel& cm(getCellModel());
1635 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : this mesh is not a simplex mesh ! Please invoke simplexize of tetrahedrize on this before calling this method !");
1636 switch(getMeshDimension())
1639 return computeDualMesh3D();
1641 return computeDualMesh2D();
1643 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : meshdimension must be in [2,3] !");
1648 * This method explode each NORM_HEXA8 cells in \a this into 6 NORM_QUAD4 cells and put the result into the MEDCoupling1SGTUMesh returned instance.
1650 * \return MEDCoupling1SGTUMesh * - a newly allocated instances (to be managed by the caller) storing the result of the explosion.
1651 * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
1652 * \throw If \a this is not properly allocated.
1654 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4() const
1656 const INTERP_KERNEL::CellModel& cm(getCellModel());
1657 if(cm.getEnum()!=INTERP_KERNEL::NORM_HEXA8)
1658 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4 : this method can be applied only on HEXA8 mesh !");
1659 int nbHexa8(getNumberOfCells());
1660 const int *inConnPtr(getNodalConnectivity()->begin());
1661 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(getName(),INTERP_KERNEL::NORM_QUAD4));
1662 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()); c->alloc(nbHexa8*6*4,1);
1663 int *cPtr(c->getPointer());
1664 for(int i=0;i<nbHexa8;i++,inConnPtr+=8)
1666 for(int j=0;j<6;j++,cPtr+=4)
1667 cm.fillSonCellNodalConnectivity(j,inConnPtr,cPtr);
1669 ret->setCoords(getCoords());
1670 ret->setNodalConnectivity(c);
1675 * This method starts from an unstructured mesh that hides in reality a cartesian mesh.
1676 * If it is not the case, an exception will be thrown.
1677 * This method returns three objects : The cartesian mesh geometrically equivalent to \a this (within a precision of \a eps) and a permutation of cells
1678 * and a permutation of nodes.
1680 * - this[cellPerm[i]]=ret[i]
1682 * \param [out] cellPerm the permutation array of size \c this->getNumberOfCells()
1683 * \param [out] nodePerm the permutation array of size \c this->getNumberOfNodes()
1684 * \return MEDCouplingCMesh * - a newly allocated mesh that is the result of the structurization of \a this.
1686 MEDCouplingCMesh *MEDCoupling1SGTUMesh::structurizeMe(DataArrayInt *& cellPerm, DataArrayInt *& nodePerm, double eps) const
1689 int spaceDim(getSpaceDimension()),meshDim(getMeshDimension()),nbNodes(getNumberOfNodes());
1690 if(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim)!=getCellModelEnum())
1691 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::structurizeMe : the unique geo type in this is not compatible with the geometric type regarding mesh dimension !");
1692 MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> cm(MEDCouplingCMesh::New());
1693 for(int i=0;i<spaceDim;i++)
1695 std::vector<int> tmp(1,i);
1696 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> elt(static_cast<DataArrayDouble*>(getCoords()->keepSelectedComponents(tmp)));
1697 elt=elt->getDifferentValues(eps);
1699 cm->setCoordsAt(i,elt);
1701 if(nbNodes!=cm->getNumberOfNodes())
1702 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 ?");
1704 { cm->copyTinyInfoFrom(this); }
1705 catch(INTERP_KERNEL::Exception&) { }
1706 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> um(cm->buildUnstructured()),self(buildUnstructured());
1707 self->checkGeoEquivalWith(um,12,eps,cellPerm,nodePerm);
1713 bool UpdateHexa8Cell(int validAxis, int neighId, const int *validConnQuad4NeighSide, int *allFacesNodalConn, int *myNeighbours)
1715 static const int TAB[48]={
1723 static const int TAB2[6]={0,0,3,3,3,3};
1724 if(myNeighbours[validAxis]==neighId && allFacesNodalConn[4*validAxis+0]==validConnQuad4NeighSide[TAB2[validAxis]])
1726 int oldAxis((int)std::distance(myNeighbours,std::find(myNeighbours,myNeighbours+6,neighId)));
1727 std::size_t pos(std::distance(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,std::find(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS+6,oldAxis)));
1728 std::size_t pos0(pos/2),pos1(pos%2);
1729 int oldAxisOpp(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[2*pos0+(pos1+1)%2]);
1730 int oldConn[8],myConn2[8]={-1,-1,-1,-1,-1,-1,-1,-1},myConn[8],edgeConn[2],allFacesTmp[24],neighTmp[6];
1731 oldConn[0]=allFacesNodalConn[0]; oldConn[1]=allFacesNodalConn[1]; oldConn[2]=allFacesNodalConn[2]; oldConn[3]=allFacesNodalConn[3];
1732 oldConn[4]=allFacesNodalConn[4]; oldConn[5]=allFacesNodalConn[7]; oldConn[6]=allFacesNodalConn[6]; oldConn[7]=allFacesNodalConn[5];
1733 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_HEXA8));
1734 for(int i=0;i<4;i++)
1735 myConn2[i]=validConnQuad4NeighSide[(4-i+TAB2[validAxis])%4];
1736 for(int i=0;i<4;i++)
1738 int nodeId(myConn2[i]);//the node id for which the opposite one will be found
1740 INTERP_KERNEL::NormalizedCellType typeOfSon;
1741 for(int j=0;j<12 && !found;j++)
1743 cm.fillSonEdgesNodalConnectivity3D(j,oldConn,-1,edgeConn,typeOfSon);
1744 if(edgeConn[0]==nodeId || edgeConn[1]==nodeId)
1746 if(std::find(allFacesNodalConn+4*oldAxisOpp,allFacesNodalConn+4*oldAxisOpp+4,edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0])!=allFacesNodalConn+4*oldAxisOpp+4)
1748 myConn2[i+4]=edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0];
1754 throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error !");
1756 const int *myTab(TAB+8*validAxis);
1757 for(int i=0;i<8;i++)
1758 myConn[i]=myConn2[myTab[i]];
1759 for(int i=0;i<6;i++)
1761 cm.fillSonCellNodalConnectivity(i,myConn,allFacesTmp+4*i);
1762 std::set<int> s(allFacesTmp+4*i,allFacesTmp+4*i+4);
1764 for(int j=0;j<6 && !found;j++)
1766 std::set<int> s1(allFacesNodalConn+4*j,allFacesNodalConn+4*j+4);
1769 neighTmp[i]=myNeighbours[j];
1774 throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error #2 !");
1776 std::copy(allFacesTmp,allFacesTmp+24,allFacesNodalConn);
1777 std::copy(neighTmp,neighTmp+6,myNeighbours);
1784 * 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
1785 * homogeneous. If it succeeds the result of MEDCouplingUMesh::tetrahedrize will return a conform mesh.
1787 * \return DataArrayInt * - a newly allocated array (to be managed by the caller) containing renumbered cell ids.
1789 * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
1790 * \throw If \a this is not properly allocated.
1791 * \sa MEDCouplingUMesh::tetrahedrize, MEDCouplingUMesh::simplexize.
1793 DataArrayInt *MEDCoupling1SGTUMesh::sortHexa8EachOther()
1795 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> quads(explodeEachHexa8To6Quad4());//checks that only hexa8
1796 int nbHexa8(getNumberOfCells()),*cQuads(quads->getNodalConnectivity()->getPointer());
1797 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> neighOfQuads(DataArrayInt::New()); neighOfQuads->alloc(nbHexa8*6,1); neighOfQuads->fillWithValue(-1);
1798 int *ptNeigh(neighOfQuads->getPointer());
1799 {//neighOfQuads tells for each face of each Quad8 which cell (if!=-1) is connected to this face.
1800 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> quadsTmp(quads->buildUnstructured());
1801 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ccSafe,cciSafe;
1802 DataArrayInt *cc(0),*cci(0);
1803 quadsTmp->findCommonCells(3,0,cc,cci);
1804 ccSafe=cc; cciSafe=cci;
1805 const int *ccPtr(ccSafe->begin()),nbOfPair(cci->getNumberOfTuples()-1);
1806 for(int i=0;i<nbOfPair;i++)
1807 { ptNeigh[ccPtr[2*i+0]]=ccPtr[2*i+1]/6; ptNeigh[ccPtr[2*i+1]]=ccPtr[2*i+0]/6; }
1809 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
1810 std::vector<bool> fetched(nbHexa8,false);
1811 std::vector<bool>::iterator it(std::find(fetched.begin(),fetched.end(),false));
1812 while(it!=fetched.end())//it will turns as time as number of connected zones
1814 int cellId((int)std::distance(fetched.begin(),it));//it is the seed of the connected zone.
1815 std::set<int> s; s.insert(cellId);//s contains already organized.
1818 std::set<int> sNext;
1819 for(std::set<int>::const_iterator it0=s.begin();it0!=s.end();it0++)
1822 int *myNeighb(ptNeigh+6*(*it0));
1823 for(int i=0;i<6;i++)
1825 if(myNeighb[i]!=-1 && !fetched[myNeighb[i]])
1827 std::size_t pos(std::distance(HEXA8_FACE_PAIRS,std::find(HEXA8_FACE_PAIRS,HEXA8_FACE_PAIRS+6,i)));
1828 std::size_t pos0(pos/2),pos1(pos%2);
1829 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]))
1830 ret->pushBackSilent(myNeighb[i]);
1831 fetched[myNeighb[i]]=true;
1832 sNext.insert(myNeighb[i]);
1838 it=std::find(fetched.begin(),fetched.end(),false);
1842 int *conn(getNodalConnectivity()->getPointer());
1843 for(const int *pt=ret->begin();pt!=ret->end();pt++)
1846 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];
1847 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];
1854 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh3D() const
1856 static const int DUAL_TETRA_0[36]={
1857 4,1,0, 6,0,3, 7,3,1,
1858 4,0,1, 5,2,0, 8,1,2,
1859 6,3,0, 5,0,2, 9,2,3,
1862 static const int DUAL_TETRA_1[36]={
1863 8,4,10, 11,5,8, 10,7,11,
1864 9,4,8, 8,5,12, 12,6,9,
1865 10,4,9, 9,6,13, 13,7,10,
1866 12,5,11, 13,6,12, 11,7,13
1868 static const int FACEID_NOT_SH_NODE[4]={2,3,1,0};
1869 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TETRA4)
1870 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh3D : only TETRA4 supported !");
1871 checkFullyDefined();
1872 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured());
1873 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1874 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1875 const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1876 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d1Arr(DataArrayInt::New()),di1Arr(DataArrayInt::New()),rd1Arr(DataArrayInt::New()),rdi1Arr(DataArrayInt::New());
1877 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->explode3DMeshTo1D(d1Arr,di1Arr,rd1Arr,rdi1Arr));
1878 const int *d1(d1Arr->begin());
1879 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1880 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> faces(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
1881 const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
1882 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),facesBaryArr(faces->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
1883 const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+faces->getNumberOfCells()),offset1(offset0+edges->getNumberOfCells());
1885 std::vector<const DataArrayDouble *> v(4); v[0]=getCoords(); v[1]=facesBaryArr; v[2]=edgesBaryArr; v[3]=baryArr;
1886 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0; facesBaryArr=0;
1887 std::string name("DualOf_"); name+=getName();
1888 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYHED)); ret->setCoords(zeArr);
1889 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1890 for(int i=0;i<nbOfNodes;i++,revNodI++)
1892 int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1893 if(nbOfCellsSharingNode==0)
1895 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh3D : Node #" << i << " is orphan !";
1896 throw INTERP_KERNEL::Exception(oss.str().c_str());
1898 for(int j=0;j<nbOfCellsSharingNode;j++)
1900 int curCellId(revNod[revNodI[0]+j]);
1901 const int *connOfCurCell(nodal+4*curCellId);
1902 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1903 if(j!=0) cArr->pushBackSilent(-1);
1906 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;
1907 tmp[2]=curCellId+offset1; tmp[3]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+2]]+nbOfNodes;
1909 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;
1910 tmp[7]=curCellId+offset1; tmp[8]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+5]]+nbOfNodes;
1912 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;
1913 tmp[12]=curCellId+offset1; tmp[13]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+8]]+nbOfNodes;
1914 cArr->insertAtTheEnd(tmp,tmp+14);
1916 for(int k=0;k<4;k++)
1918 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1920 const int *faceId(d2+4*curCellId+k);
1921 if(rdi2[*faceId+1]-rdi2[*faceId]==1)
1923 int tmp2[5]; tmp2[0]=-1; tmp2[1]=i;
1924 tmp2[2]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+0]-8]+offset0;
1925 tmp2[3]=d2[4*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+1]-4]+nbOfNodes;
1926 tmp2[4]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+2]-8]+offset0;
1927 cArr->insertAtTheEnd(tmp2,tmp2+5);
1933 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
1935 ret->setNodalConnectivity(cArr,ciArr);
1939 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh2D() const
1941 static const int DUAL_TRI_0[6]={0,2, 1,0, 2,1};
1942 static const int DUAL_TRI_1[6]={-3,+5, +3,-4, +4,-5};
1943 static const int FACEID_NOT_SH_NODE[3]={1,2,0};
1944 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TRI3)
1945 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh2D : only TRI3 supported !");
1946 checkFullyDefined();
1947 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured());
1948 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1949 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1950 const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1951 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1952 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
1953 const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
1954 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
1955 const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+edges->getNumberOfCells());
1957 std::vector<const DataArrayDouble *> v(3); v[0]=getCoords(); v[1]=edgesBaryArr; v[2]=baryArr;
1958 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0;
1959 std::string name("DualOf_"); name+=getName();
1960 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYGON)); ret->setCoords(zeArr);
1961 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1962 for(int i=0;i<nbOfNodes;i++,revNodI++)
1964 int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1965 if(nbOfCellsSharingNode==0)
1967 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh2D : Node #" << i << " is orphan !";
1968 throw INTERP_KERNEL::Exception(oss.str().c_str());
1970 std::vector< std::vector<int> > polyg;
1971 for(int j=0;j<nbOfCellsSharingNode;j++)
1973 int curCellId(revNod[revNodI[0]+j]);
1974 const int *connOfCurCell(nodal+3*curCellId);
1975 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1976 std::vector<int> locV(3);
1977 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;
1978 polyg.push_back(locV);
1980 for(int k=0;k<3;k++)
1982 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1984 const int *edgeId(d2+3*curCellId+k);
1985 if(rdi2[*edgeId+1]-rdi2[*edgeId]==1)
1987 std::vector<int> locV2(2);
1988 int zeLocEdgeIdRel(DUAL_TRI_1[2*nodePosInCurCell+kk]);
1989 if(zeLocEdgeIdRel>0)
1990 { locV2[0]=d2[3*curCellId+zeLocEdgeIdRel-3]+nbOfNodes; locV2[1]=i; }
1992 { locV2[0]=i; locV2[1]=d2[3*curCellId-zeLocEdgeIdRel-3]+nbOfNodes; }
1993 polyg.push_back(locV2);
1999 std::vector<int> zePolyg(MEDCoupling1DGTUMesh::BuildAPolygonFromParts(polyg));
2000 cArr->insertAtTheEnd(zePolyg.begin(),zePolyg.end());
2001 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
2003 ret->setNodalConnectivity(cArr,ciArr);
2008 * This method aggregate the bbox of each cell and put it into bbox
2010 * \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)
2011 * For all other cases this input parameter is ignored.
2012 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
2014 * \throw If \a this is not fully set (coordinates and connectivity).
2015 * \throw If a cell in \a this has no valid nodeId.
2017 DataArrayDouble *MEDCoupling1SGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
2019 int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()),nbOfNodesPerCell(getNumberOfNodesPerCell());
2020 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
2021 double *bbox(ret->getPointer());
2022 for(int i=0;i<nbOfCells*spaceDim;i++)
2024 bbox[2*i]=std::numeric_limits<double>::max();
2025 bbox[2*i+1]=-std::numeric_limits<double>::max();
2027 const double *coordsPtr(_coords->getConstPointer());
2028 const int *conn(_conn->getConstPointer());
2029 for(int i=0;i<nbOfCells;i++)
2032 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
2035 if(nodeId>=0 && nodeId<nbOfNodes)
2037 for(int k=0;k<spaceDim;k++)
2039 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
2040 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
2047 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
2048 throw INTERP_KERNEL::Exception(oss.str().c_str());
2056 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New()
2058 return new MEDCoupling1DGTUMesh;
2061 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
2063 if(type==INTERP_KERNEL::NORM_ERROR)
2064 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
2065 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
2068 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !";
2069 throw INTERP_KERNEL::Exception(oss.str().c_str());
2071 return new MEDCoupling1DGTUMesh(name,cm);
2074 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh()
2078 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
2082 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
2086 const DataArrayInt *c(other._conn);
2091 _conn_indx=c->deepCpy();
2095 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const
2097 return new MEDCoupling1DGTUMesh(*this,recDeepCpy);
2101 * This method behaves mostly like MEDCoupling1DGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
2102 * The coordinates are shared between \a this and the returned instance.
2104 * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
2105 * \sa MEDCoupling1DGTUMesh::deepCpy
2107 MEDCouplingPointSet *MEDCoupling1DGTUMesh::deepCpyConnectivityOnly() const
2110 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(clone(false));
2111 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy()),ci(_conn_indx->deepCpy());
2112 ret->setNodalConnectivity(c,ci);
2116 void MEDCoupling1DGTUMesh::updateTime() const
2118 MEDCoupling1GTUMesh::updateTime();
2119 const DataArrayInt *c(_conn);
2127 std::size_t MEDCoupling1DGTUMesh::getHeapMemorySizeWithoutChildren() const
2129 return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren();
2132 std::vector<const BigMemoryObject *> MEDCoupling1DGTUMesh::getDirectChildrenWithNull() const
2134 std::vector<const BigMemoryObject *> ret(MEDCoupling1GTUMesh::getDirectChildrenWithNull());
2135 ret.push_back((const DataArrayInt *)_conn);
2136 ret.push_back((const DataArrayInt *)_conn_indx);
2140 MEDCouplingMesh *MEDCoupling1DGTUMesh::deepCpy() const
2145 bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
2148 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !");
2149 std::ostringstream oss; oss.precision(15);
2150 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2153 reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !";
2156 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
2158 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2163 reason="in connectivity of single dynamic geometric type exactly one among this and other is null !";
2166 if(!c1->isEqualIfNotWhy(*c2,reason))
2168 reason.insert(0,"Nodal connectivity DataArrayInt differs : ");
2171 c1=_conn_indx; c2=otherC->_conn_indx;
2176 reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !";
2179 if(!c1->isEqualIfNotWhy(*c2,reason))
2181 reason.insert(0,"Nodal connectivity index DataArrayInt differs : ");
2187 bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
2190 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
2191 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2194 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
2196 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2201 if(!c1->isEqualWithoutConsideringStr(*c2))
2204 c1=_conn_indx; c2=otherC->_conn_indx;
2209 if(!c1->isEqualWithoutConsideringStr(*c2))
2215 * Checks if \a this and \a other meshes are geometrically equivalent with high
2216 * probability, else an exception is thrown. The meshes are considered equivalent if
2217 * (1) meshes contain the same number of nodes and the same number of elements of the
2218 * same types (2) three cells of the two meshes (first, last and middle) are based
2219 * on coincident nodes (with a specified precision).
2220 * \param [in] other - the mesh to compare with.
2221 * \param [in] prec - the precision used to compare nodes of the two meshes.
2222 * \throw If the two meshes do not match.
2224 void MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
2226 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
2227 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2229 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single dynamic geometric type !");
2230 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2234 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
2235 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2236 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
2237 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2238 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
2239 if(c1->getHashCode()!=c2->getHashCode())
2240 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs");
2242 c1=_conn_indx; c2=otherC->_conn_indx;
2246 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !");
2247 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2248 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !");
2249 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2250 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !");
2251 if(c1->getHashCode()!=c2->getHashCode())
2252 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs");
2256 void MEDCoupling1DGTUMesh::checkCoherencyOfConnectivity() const
2258 const DataArrayInt *c1(_conn);
2261 if(c1->getNumberOfComponents()!=1)
2262 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
2263 if(c1->getInfoOnComponent(0)!="")
2264 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
2265 c1->checkAllocated();
2268 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
2270 int sz2=_conn->getNumberOfTuples();
2274 if(c1->getNumberOfComponents()!=1)
2275 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
2276 c1->checkAllocated();
2277 if(c1->getNumberOfTuples()<1)
2278 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !");
2279 if(c1->getInfoOnComponent(0)!="")
2280 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
2281 int f=c1->front(),ll=c1->back();
2284 std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !";
2285 throw INTERP_KERNEL::Exception(oss.str().c_str());
2289 std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !";
2290 throw INTERP_KERNEL::Exception(oss.str().c_str());
2294 std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !";
2295 throw INTERP_KERNEL::Exception(oss.str().c_str());
2299 throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !");
2300 int szOfC1Exp=_conn_indx->back();
2303 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() << " !";
2304 throw INTERP_KERNEL::Exception(oss.str().c_str());
2309 * 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.
2310 * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one.
2311 * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array.
2313 void MEDCoupling1DGTUMesh::checkCoherency() const
2315 MEDCouplingPointSet::checkCoherency();
2316 checkCoherencyOfConnectivity();
2319 void MEDCoupling1DGTUMesh::checkCoherency1(double eps) const
2322 const DataArrayInt *c1(_conn),*c2(_conn_indx);
2323 if(!c2->isMonotonic(true))
2324 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkCoherency1 : the nodal connectivity index is expected to be increasing monotinic !");
2326 int nbOfTuples=c1->getNumberOfTuples();
2327 int nbOfNodes=getNumberOfNodes();
2328 const int *w(c1->begin());
2329 for(int i=0;i<nbOfTuples;i++,w++)
2331 if(*w==-1) continue;
2332 if(*w<0 || *w>=nbOfNodes)
2334 std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !";
2335 throw INTERP_KERNEL::Exception(oss.str().c_str());
2340 void MEDCoupling1DGTUMesh::checkCoherency2(double eps) const
2342 checkCoherency1(eps);
2345 int MEDCoupling1DGTUMesh::getNumberOfCells() const
2347 checkCoherencyOfConnectivity();//do not remove
2348 return _conn_indx->getNumberOfTuples()-1;
2352 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2353 * For each cell in \b this the number of nodes constituting cell is computed.
2354 * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned.
2355 * So for pohyhedrons some nodes can be counted several times in the returned result.
2357 * \return a newly allocated array
2359 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const
2362 _conn_indx->checkMonotonic(true);
2363 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2364 return _conn_indx->deltaShiftIndex();
2366 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2367 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2368 ret->alloc(nbOfCells,1);
2369 int *retPtr=ret->getPointer();
2370 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2371 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2372 *retPtr=ci[1]-ci[0]-std::count(c+ci[0],c+ci[1],-1);
2377 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2378 * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed.
2380 * \return a newly allocated array
2382 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const
2385 _conn_indx->checkMonotonic(true);
2386 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG)
2387 return _conn_indx->deltaShiftIndex();
2388 if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG)
2390 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=_conn_indx->deltaShiftIndex();
2391 ret->applyDivideBy(2);
2395 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2396 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2397 ret->alloc(nbOfCells,1);
2398 int *retPtr=ret->getPointer();
2399 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2400 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2401 *retPtr=std::count(c+ci[0],c+ci[1],-1)+1;
2406 * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell,
2407 * will be counted only once here whereas it will be counted several times in MEDCoupling1DGTUMesh::computeNbOfNodesPerCell method.
2409 * \return DataArrayInt * - new object to be deallocated by the caller.
2410 * \sa MEDCoupling1DGTUMesh::computeNbOfNodesPerCell
2412 DataArrayInt *MEDCoupling1DGTUMesh::computeEffectiveNbOfNodesPerCell() const
2415 _conn_indx->checkMonotonic(true);
2416 int nbOfCells(_conn_indx->getNumberOfTuples()-1);
2417 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2418 ret->alloc(nbOfCells,1);
2419 int *retPtr(ret->getPointer());
2420 const int *ci(_conn_indx->begin()),*c(_conn->begin());
2421 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2423 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2425 std::set<int> s(c+ci[0],c+ci[1]);
2426 *retPtr=(int)s.size();
2431 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2433 std::set<int> s(c+ci[0],c+ci[1]); s.erase(-1);
2434 *retPtr=(int)s.size();
2440 void MEDCoupling1DGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
2442 int nbOfCells(getNumberOfCells());//performs checks
2443 if(cellId>=0 && cellId<nbOfCells)
2445 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2446 int nbOfNodes=stp-strt;
2448 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !");
2449 conn.resize(nbOfNodes);
2450 std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin());
2454 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2455 throw INTERP_KERNEL::Exception(oss.str().c_str());
2459 int MEDCoupling1DGTUMesh::getNumberOfNodesInCell(int cellId) const
2461 int nbOfCells(getNumberOfCells());//performs checks
2462 if(cellId>=0 && cellId<nbOfCells)
2464 const int *conn(_conn->begin());
2465 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2466 return stp-strt-std::count(conn+strt,conn+stp,-1);
2470 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNumberOfNodesInCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2471 throw INTERP_KERNEL::Exception(oss.str().c_str());
2475 std::string MEDCoupling1DGTUMesh::simpleRepr() const
2477 static const char msg0[]="No coordinates specified !";
2478 std::ostringstream ret;
2479 ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
2480 ret << "Description of mesh : \"" << getDescription() << "\"\n";
2482 double tt=getTime(tmpp1,tmpp2);
2483 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
2484 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
2485 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
2488 const int spaceDim=getSpaceDimension();
2489 ret << spaceDim << "\nInfo attached on space dimension : ";
2490 for(int i=0;i<spaceDim;i++)
2491 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
2495 ret << msg0 << "\n";
2496 ret << "Number of nodes : ";
2498 ret << getNumberOfNodes() << "\n";
2500 ret << msg0 << "\n";
2501 ret << "Number of cells : ";
2503 try { checkCoherency(); } catch(INTERP_KERNEL::Exception& /* e */)
2505 ret << "Nodal connectivity arrays are not set or badly set !\n";
2509 ret << getNumberOfCells() << "\n";
2510 ret << "Cell type : " << _cm->getRepr() << "\n";
2514 std::string MEDCoupling1DGTUMesh::advancedRepr() const
2516 std::ostringstream ret;
2517 ret << simpleRepr();
2518 ret << "\nCoordinates array : \n___________________\n\n";
2520 _coords->reprWithoutNameStream(ret);
2522 ret << "No array set !\n";
2523 ret << "\n\nNodal Connectivity : \n____________________\n\n";
2526 try { checkCoherency1(); } catch(INTERP_KERNEL::Exception& /* e */)
2528 ret << "Nodal connectivity arrays are not set or badly set !\n";
2533 int nbOfCells=getNumberOfCells();
2534 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2535 for(int i=0;i<nbOfCells;i++,ci++)
2537 ret << "Cell #" << i << " : ";
2538 std::copy(c+ci[0],c+ci[1],std::ostream_iterator<int>(ret," "));
2544 DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const
2546 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
2547 int spaceDim=getSpaceDimension();
2548 int nbOfCells=getNumberOfCells();//checkCoherency()
2549 int nbOfNodes=getNumberOfNodes();
2550 ret->alloc(nbOfCells,spaceDim);
2551 double *ptToFill=ret->getPointer();
2552 const double *coor=_coords->begin();
2553 const int *nodal=_conn->begin(),*nodali=_conn_indx->begin();
2555 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2557 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2559 std::fill(ptToFill,ptToFill+spaceDim,0.);
2560 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2562 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2564 if(*nodal>=0 && *nodal<nbOfNodes)
2565 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2568 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2569 throw INTERP_KERNEL::Exception(oss.str().c_str());
2571 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(nodali[1]-nodali[0])));
2576 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !";
2577 throw INTERP_KERNEL::Exception(oss.str().c_str());
2583 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2585 std::fill(ptToFill,ptToFill+spaceDim,0.);
2586 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2589 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2591 if(*nodal==-1) continue;
2592 if(*nodal>=0 && *nodal<nbOfNodes)
2594 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2599 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2600 throw INTERP_KERNEL::Exception(oss.str().c_str());
2604 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./nbOfNod));
2607 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !";
2608 throw INTERP_KERNEL::Exception(oss.str().c_str());
2613 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : at cell #" << i << " the nodal index array is invalid !";
2614 throw INTERP_KERNEL::Exception(oss.str().c_str());
2621 void MEDCoupling1DGTUMesh::renumberCells(const int *old2NewBg, bool check)
2623 int nbCells=getNumberOfCells();
2624 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
2625 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
2627 o2n=o2n->checkAndPreparePermutation();
2629 const int *o2nPtr=o2n->getPointer();
2630 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2631 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
2632 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
2633 newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1);
2634 newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx);
2636 int *newC=newConn->getPointer(),*newCI=newConnI->getPointer();
2637 for(int i=0;i<nbCells;i++)
2639 int newPos=o2nPtr[i];
2640 int sz=conni[i+1]-conni[i];
2645 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !";
2646 throw INTERP_KERNEL::Exception(oss.str().c_str());
2649 newConnI->computeOffsets2(); newCI=newConnI->getPointer();
2651 for(int i=0;i<nbCells;i++,conni++)
2654 std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]);
2657 _conn_indx=newConnI;
2660 MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
2662 if(other->getType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED)
2663 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !");
2664 const MEDCoupling1DGTUMesh *otherC=static_cast<const MEDCoupling1DGTUMesh *>(other);
2665 return Merge1DGTUMeshes(this,otherC);
2668 MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const
2670 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
2671 ret->setCoords(getCoords());
2672 const int *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin();
2673 int nbCells=getNumberOfCells();//checkCoherency
2674 int geoType=(int)getCellModelEnum();
2675 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1);
2676 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::New(); cI->alloc(nbCells+1);
2677 int *cPtr=c->getPointer(),*ciPtr=cI->getPointer();
2679 for(int i=0;i<nbCells;i++,ciPtr++)
2681 int sz=nodalConnI[i+1]-nodalConnI[i];
2685 cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr);
2686 ciPtr[1]=ciPtr[0]+sz+1;
2690 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !";
2691 throw INTERP_KERNEL::Exception(oss.str().c_str());
2694 ret->setConnectivity(c,cI,true);
2696 { ret->copyTinyInfoFrom(this); }
2697 catch(INTERP_KERNEL::Exception&) { }
2702 * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes
2704 DataArrayInt *MEDCoupling1DGTUMesh::simplexize(int policy)
2706 int nbOfCells=getNumberOfCells();
2707 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2708 ret->alloc(nbOfCells,1);
2713 void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const
2715 stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
2716 stream << " Mesh dimension : " << getMeshDimension() << ".";
2718 { stream << " No coordinates set !"; return ; }
2719 if(!_coords->isAllocated())
2720 { stream << " Coordinates set but not allocated !"; return ; }
2721 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
2722 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
2724 try { checkCoherency(); } catch(INTERP_KERNEL::Exception& /* e */)
2726 stream << std::endl << "Nodal connectivity NOT set properly !\n";
2730 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
2733 void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
2736 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
2737 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2739 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !");
2740 setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex());
2743 MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
2746 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
2747 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2749 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
2750 std::vector<const MEDCoupling1DGTUMesh *> ms(2);
2753 return Merge1DGTUMeshesOnSameCoords(ms);
2756 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
2759 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2760 ret->setCoords(_coords);
2761 DataArrayInt *c=0,*ci=0;
2762 MEDCouplingUMesh::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci);
2763 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2764 ret->setNodalConnectivity(c,ci);
2768 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
2771 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2772 ret->setCoords(_coords);
2773 DataArrayInt *c=0,*ci=0;
2774 MEDCouplingUMesh::ExtractFromIndexedArrays2(start,end,step,_conn,_conn_indx,c,ci);
2775 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2776 ret->setNodalConnectivity(c,ci);
2780 void MEDCoupling1DGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
2782 int sz((int)nodeIdsInUse.size());
2783 int nbCells(getNumberOfCells());
2784 const int *w(_conn->begin()),*wi(_conn_indx->begin());
2785 for(int i=0;i<nbCells;i++,wi++)
2786 for(const int *pt=w+wi[0];pt!=w+wi[1];pt++)
2789 if(*pt>=0 && *pt<sz)
2790 nodeIdsInUse[*pt]=true;
2793 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeNodeIdsAlg : At cell #" << i << " presence of node id #" << *pt << " should be in [0," << sz << ") !";
2794 throw INTERP_KERNEL::Exception(oss.str().c_str());
2799 void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const
2801 checkFullyDefined();
2802 int nbOfNodes=getNumberOfNodes();
2803 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
2804 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
2805 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
2806 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2807 int nbOfCells=getNumberOfCells();
2808 int nbOfEltsInRevNodal=0;
2809 for(int eltId=0;eltId<nbOfCells;eltId++)
2811 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2812 if(nbOfNodesPerCell>=0)
2814 for(int j=0;j<nbOfNodesPerCell;j++)
2816 int nodeId=conn[conni[eltId]+j];
2817 if(nodeId==-1) continue;
2818 if(nodeId>=0 && nodeId<nbOfNodes)
2820 nbOfEltsInRevNodal++;
2821 revNodalIndxPtr[nodeId+1]++;
2825 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
2826 throw INTERP_KERNEL::Exception(oss.str().c_str());
2832 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << "nodal connectivity is invalid !";
2833 throw INTERP_KERNEL::Exception(oss.str().c_str());
2836 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
2837 conn=_conn->begin();
2838 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
2839 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
2840 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
2841 for(int eltId=0;eltId<nbOfCells;eltId++)
2843 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2844 for(int j=0;j<nbOfNodesPerCell;j++)
2846 int nodeId=conn[conni[eltId]+j];
2848 *std::find_if(revNodalPtr+revNodalIndxPtr[nodeId],revNodalPtr+revNodalIndxPtr[nodeId+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
2853 void MEDCoupling1DGTUMesh::checkFullyDefined() const
2855 if(!((const DataArrayInt *)_conn) || !((const DataArrayInt *)_conn_indx) || !((const DataArrayDouble *)_coords))
2856 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined.");
2859 bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
2861 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !");
2864 void MEDCoupling1DGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
2867 double time=getTime(it,order);
2868 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
2870 littleStrings.push_back(getName());
2871 littleStrings.push_back(getDescription());
2872 littleStrings.push_back(getTimeUnit());
2874 std::vector<std::string> littleStrings2,littleStrings3,littleStrings4;
2875 if((const DataArrayDouble *)_coords)
2876 _coords->getTinySerializationStrInformation(littleStrings2);
2877 if((const DataArrayInt *)_conn)
2878 _conn->getTinySerializationStrInformation(littleStrings3);
2879 if((const DataArrayInt *)_conn_indx)
2880 _conn_indx->getTinySerializationStrInformation(littleStrings4);
2881 int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size()),sz2((int)littleStrings4.size());
2882 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
2883 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
2884 littleStrings.insert(littleStrings.end(),littleStrings4.begin(),littleStrings4.end());
2886 tinyInfo.push_back(getCellModelEnum());
2887 tinyInfo.push_back(it);
2888 tinyInfo.push_back(order);
2889 std::vector<int> tinyInfo2,tinyInfo3,tinyInfo4;
2890 if((const DataArrayDouble *)_coords)
2891 _coords->getTinySerializationIntInformation(tinyInfo2);
2892 if((const DataArrayInt *)_conn)
2893 _conn->getTinySerializationIntInformation(tinyInfo3);
2894 if((const DataArrayInt *)_conn_indx)
2895 _conn_indx->getTinySerializationIntInformation(tinyInfo4);
2896 int sz3((int)tinyInfo2.size()),sz4((int)tinyInfo3.size()),sz5((int)tinyInfo4.size());
2897 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3); tinyInfo.push_back(sz4); tinyInfo.push_back(sz5);
2898 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
2899 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
2900 tinyInfo.insert(tinyInfo.end(),tinyInfo4.begin(),tinyInfo4.end());
2902 tinyInfoD.push_back(time);
2905 void MEDCoupling1DGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
2907 std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+tinyInfo[6]);
2908 std::vector<int> tinyInfo1(tinyInfo.begin()+9+tinyInfo[6],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]);
2909 std::vector<int> tinyInfo12(tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]+tinyInfo[8]);
2910 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(DataArrayInt::New()); p1->resizeForUnserialization(tinyInfo1);
2911 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(DataArrayInt::New()); p2->resizeForUnserialization(tinyInfo12);
2912 std::vector<const DataArrayInt *> v(2); v[0]=p1; v[1]=p2;
2913 p2=DataArrayInt::Aggregate(v);
2914 a2->resizeForUnserialization(tinyInfo2);
2915 a1->alloc(p2->getNbOfElems(),1);
2918 void MEDCoupling1DGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
2921 if((const DataArrayInt *)_conn)
2922 if(_conn->isAllocated())
2923 sz=_conn->getNbOfElems();
2924 if((const DataArrayInt *)_conn_indx)
2925 if(_conn_indx->isAllocated())
2926 sz+=_conn_indx->getNbOfElems();
2927 a1=DataArrayInt::New();
2929 int *work(a1->getPointer());
2930 if(sz!=0 && (const DataArrayInt *)_conn)
2931 work=std::copy(_conn->begin(),_conn->end(),a1->getPointer());
2932 if(sz!=0 && (const DataArrayInt *)_conn_indx)
2933 std::copy(_conn_indx->begin(),_conn_indx->end(),work);
2935 if((const DataArrayDouble *)_coords)
2936 if(_coords->isAllocated())
2937 sz=_coords->getNbOfElems();
2938 a2=DataArrayDouble::New();
2940 if(sz!=0 && (const DataArrayDouble *)_coords)
2941 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
2944 void MEDCoupling1DGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
2945 const std::vector<std::string>& littleStrings)
2947 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
2948 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
2949 setName(littleStrings[0]);
2950 setDescription(littleStrings[1]);
2951 setTimeUnit(littleStrings[2]);
2952 setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
2953 int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]),sz4(tinyInfo[7]),sz5(tinyInfo[8]);
2955 _coords=DataArrayDouble::New();
2956 std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+sz3);
2957 _coords->resizeForUnserialization(tinyInfo2);
2958 std::copy(a2->begin(),a2->end(),_coords->getPointer());
2959 _conn=DataArrayInt::New();
2960 std::vector<int> tinyInfo3(tinyInfo.begin()+9+sz3,tinyInfo.begin()+9+sz3+sz4);
2961 _conn->resizeForUnserialization(tinyInfo3);
2962 std::copy(a1->begin(),a1->begin()+_conn->getNbOfElems(),_conn->getPointer());
2963 _conn_indx=DataArrayInt::New();
2964 std::vector<int> tinyInfo4(tinyInfo.begin()+9+sz3+sz4,tinyInfo.begin()+9+sz3+sz4+sz5);
2965 _conn_indx->resizeForUnserialization(tinyInfo4);
2966 std::copy(a1->begin()+_conn->getNbOfElems(),a1->end(),_conn_indx->getPointer());
2967 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
2968 _coords->finishUnserialization(tinyInfo2,littleStrings2);
2969 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
2970 _conn->finishUnserialization(tinyInfo3,littleStrings3);
2971 std::vector<std::string> littleStrings4(littleStrings.begin()+3+sz0+sz1,littleStrings.begin()+3+sz0+sz1+sz2);
2972 _conn_indx->finishUnserialization(tinyInfo4,littleStrings4);
2976 * Finds nodes not used in any cell and returns an array giving a new id to every node
2977 * by excluding the unused nodes, for which the array holds -1. The result array is
2978 * a mapping in "Old to New" mode.
2979 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
2980 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
2981 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
2982 * if the node is unused or a new id else. The caller is to delete this
2983 * array using decrRef() as it is no more needed.
2984 * \throw If the coordinates array is not set.
2985 * \throw If the nodal connectivity of cells is not defined.
2986 * \throw If the nodal connectivity includes an invalid id.
2988 DataArrayInt *MEDCoupling1DGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
2991 int nbOfNodes=getNumberOfNodes();
2992 int nbOfCells=getNumberOfCells();//checkCoherency
2993 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2994 ret->alloc(nbOfNodes,1);
2995 int *traducer=ret->getPointer();
2996 std::fill(traducer,traducer+nbOfNodes,-1);
2997 const int *conn=_conn->begin(),*conni(_conn_indx->begin());
2998 for(int i=0;i<nbOfCells;i++,conni++)
3000 int nbNodesPerCell=conni[1]-conni[0];
3001 for(int j=0;j<nbNodesPerCell;j++)
3003 int nodeId=conn[conni[0]+j];
3004 if(nodeId==-1) continue;
3005 if(nodeId>=0 && nodeId<nbOfNodes)
3009 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << nodeId << " not in [0," << nbOfNodes << ") !";
3010 throw INTERP_KERNEL::Exception(oss.str().c_str());
3014 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
3015 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
3020 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
3021 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
3022 * This method is a generalization of shiftNodeNumbersInConn().
3023 * \warning This method performs no check of validity of new ids. **Use it with care !**
3024 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
3025 * this->getNumberOfNodes(), in "Old to New" mode.
3026 * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
3027 * \throw If the nodal connectivity of cells is not defined.
3029 void MEDCoupling1DGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
3031 getNumberOfCells();//only to check that all is well defined.
3033 int nbElemsIn=getNumberOfNodes();
3034 int nbOfTuples=_conn->getNumberOfTuples();
3035 int *pt=_conn->getPointer();
3036 for(int i=0;i<nbOfTuples;i++,pt++)
3038 if(*pt==-1) continue;
3039 if(*pt>=0 && *pt<nbElemsIn)
3040 *pt=newNodeNumbersO2N[*pt];
3043 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
3044 throw INTERP_KERNEL::Exception(oss.str().c_str());
3047 _conn->declareAsNew();
3053 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
3054 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
3055 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
3056 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
3058 * \param [in] begin input start of array of node ids.
3059 * \param [in] end input end of array of node ids.
3060 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
3061 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
3063 void MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
3065 int nbOfCells=getNumberOfCells();
3066 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
3068 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
3069 std::vector<bool> fastFinder(sz,false);
3070 for(const int *work=begin;work!=end;work++)
3071 if(*work>=0 && *work<sz)
3072 fastFinder[*work]=true;
3073 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
3074 for(int i=0;i<nbOfCells;i++,conni++)
3076 int ref=0,nbOfHit=0;
3077 int nbNodesPerCell=conni[1]-conni[0];
3078 if(nbNodesPerCell>=0)
3080 for(int j=0;j<nbNodesPerCell;j++)
3082 int nodeId=conn[conni[0]+j];
3086 if(fastFinder[nodeId])
3093 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !";
3094 throw INTERP_KERNEL::Exception(oss.str().c_str());
3096 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
3097 cellIdsKept->pushBackSilent(i);
3099 cellIdsKeptArr=cellIdsKept.retn();
3102 void MEDCoupling1DGTUMesh::allocateCells(int nbOfCells)
3105 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !");
3106 _conn=DataArrayInt::New();
3107 _conn->reserve(nbOfCells*3);
3108 _conn_indx=DataArrayInt::New();
3109 _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0);
3114 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
3116 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
3117 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
3118 * \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
3119 * attached to \a this.
3120 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
3122 void MEDCoupling1DGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd)
3124 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
3125 DataArrayInt *c(_conn),*c2(_conn_indx);
3129 if(pos==c->getNumberOfTuples())
3131 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
3132 c2->pushBackSilent(pos+sz);
3136 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !";
3137 throw INTERP_KERNEL::Exception(oss.str().c_str());
3141 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !");
3144 void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex)
3147 nodalConn->incrRef();
3150 nodalConnIndex->incrRef();
3151 _conn_indx=nodalConnIndex;
3156 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
3158 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivity() const
3160 const DataArrayInt *ret(_conn);
3161 return const_cast<DataArrayInt *>(ret);
3165 * \return DataArrayInt * - the internal reference to the nodal connectivity index. The caller is not reponsible to deallocate it.
3167 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const
3169 const DataArrayInt *ret(_conn_indx);
3170 return const_cast<DataArrayInt *>(ret);
3174 * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here".
3175 * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity).
3176 * 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.
3178 * 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.
3180 * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal
3181 * connectivity arrays are different (false)
3182 * \return a new object to be managed by the caller.
3184 * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked
3186 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const
3188 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3189 DataArrayInt *nc=0,*nci=0;
3190 isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci);
3191 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ncs(nc),ncis(nci);
3192 ret->_conn=ncs; ret->_conn_indx=ncis;
3193 ret->setCoords(getCoords());
3198 * This method allows to compute, if needed, the packed nodal connectivity pair.
3199 * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges convered by nodal connectivity index array.
3200 * 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.
3202 * 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)
3203 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3205 * 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
3208 * This method return 3 elements.
3209 * \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
3210 * this pointer can be seen as a new object, that is to managed by the caller.
3211 * \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
3212 * this pointer can be seen as a new object, that is to managed by the caller.
3213 * \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
3214 * output parameters are newly created objects.
3216 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
3218 bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const
3220 if(isPacked())//performs the checkCoherency
3222 const DataArrayInt *c0(_conn),*c1(_conn_indx);
3223 nodalConn=const_cast<DataArrayInt *>(c0); nodalConnIndx=const_cast<DataArrayInt *>(c1);
3224 nodalConn->incrRef(); nodalConnIndx->incrRef();
3227 int bg=_conn_indx->front(),end=_conn_indx->back();
3228 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nc(_conn->selectByTupleId2(bg,end,1));
3229 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nci(_conn_indx->deepCpy());
3230 nci->applyLin(1,-bg);
3231 nodalConn=nc.retn(); nodalConnIndx=nci.retn();
3236 * 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)
3237 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3238 * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned.
3239 * \return bool - true if \a this looks packed, false is not.
3241 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
3243 bool MEDCoupling1DGTUMesh::isPacked() const
3246 return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples();
3249 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2)
3251 std::vector<const MEDCoupling1DGTUMesh *> tmp(2);
3252 tmp[0]=const_cast<MEDCoupling1DGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1DGTUMesh *>(mesh2);
3253 return Merge1DGTUMeshes(tmp);
3256 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a)
3258 std::size_t sz=a.size();
3260 return Merge1DGTUMeshesLL(a);
3261 for(std::size_t ii=0;ii<sz;ii++)
3264 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::Merge1DGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
3265 throw INTERP_KERNEL::Exception(oss.str().c_str());
3267 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
3268 for(std::size_t ii=0;ii<sz;ii++)
3269 if(&(a[ii]->getCellModel())!=cm)
3270 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !");
3271 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > bb(sz);
3272 std::vector< const MEDCoupling1DGTUMesh * > aa(sz);
3274 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
3276 const MEDCoupling1DGTUMesh *cur=a[i];
3277 const DataArrayDouble *coo=cur->getCoords();
3279 spaceDim=coo->getNumberOfComponents();
3282 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !");
3283 for(std::size_t i=0;i<sz;i++)
3285 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
3288 return Merge1DGTUMeshesLL(aa);
3292 * \throw If presence of a null instance in the input vector \a a.
3293 * \throw If a is empty
3295 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a)
3298 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !");
3299 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3301 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !");
3302 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
3303 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3304 (*it)->getNumberOfCells();//to check that all is OK
3305 const DataArrayDouble *coords=(*it)->getCoords();
3306 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3308 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3309 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3311 for(int i=1;it!=a.end();i++,it++)
3314 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !");
3315 if(cm!=&((*it)->getCellModel()))
3316 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3317 (*it)->getNumberOfCells();//to check that all is OK
3318 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3319 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3320 if(coords!=(*it)->getCoords())
3321 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !");
3323 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3324 ret->setCoords(coords);
3325 ret->_conn=DataArrayInt::Aggregate(ncs);
3326 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3331 * 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)
3333 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a)
3336 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : input array must be NON EMPTY !");
3337 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
3338 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3339 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3340 std::vector<int> nbNodesPerElt(a.size());
3341 int nbOfCells=(*it)->getNumberOfCells();
3343 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3344 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3346 int prevNbOfNodes=(*it)->getNumberOfNodes();
3347 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3349 for(int i=1;it!=a.end();i++,it++)
3351 if(cm!=&((*it)->getCellModel()))
3352 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3353 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3354 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3355 nbOfCells+=(*it)->getNumberOfCells();
3356 nbNodesPerElt[i]=nbNodesPerElt[i-1]+prevNbOfNodes;
3357 prevNbOfNodes=(*it)->getNumberOfNodes();
3359 std::vector<const MEDCouplingPointSet *> aps(a.size());
3360 std::copy(a.begin(),a.end(),aps.begin());
3361 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
3362 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3363 ret->setCoords(pts);
3364 ret->_conn=AggregateNodalConnAndShiftNodeIds(ncs,nbNodesPerElt);
3365 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3369 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(int spaceDim) const
3371 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3372 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1,tmp2;
3373 const DataArrayInt *nodalConn(_conn),*nodalConnI(_conn_indx);
3376 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
3384 tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
3388 ret->_conn_indx=tmp2;
3392 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
3393 ret->setCoords(coords);
3396 ret->setCoords(_coords);
3401 * This method aggregate the bbox of each cell and put it into bbox parameter.
3403 * \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)
3404 * For all other cases this input parameter is ignored.
3405 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
3407 * \throw If \a this is not fully set (coordinates and connectivity).
3408 * \throw If a cell in \a this has no valid nodeId.
3410 DataArrayDouble *MEDCoupling1DGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
3412 checkFullyDefined();
3413 int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes());
3414 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
3415 double *bbox(ret->getPointer());
3416 for(int i=0;i<nbOfCells*spaceDim;i++)
3418 bbox[2*i]=std::numeric_limits<double>::max();
3419 bbox[2*i+1]=-std::numeric_limits<double>::max();
3421 const double *coordsPtr(_coords->getConstPointer());
3422 const int *conn(_conn->getConstPointer()),*connI(_conn_indx->getConstPointer());
3423 for(int i=0;i<nbOfCells;i++)
3425 int offset=connI[i];
3426 int nbOfNodesForCell(connI[i+1]-offset),kk(0);
3427 for(int j=0;j<nbOfNodesForCell;j++)
3429 int nodeId=conn[offset+j];
3430 if(nodeId>=0 && nodeId<nbOfNodes)
3432 for(int k=0;k<spaceDim;k++)
3434 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
3435 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
3442 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
3443 throw INTERP_KERNEL::Exception(oss.str().c_str());
3449 std::vector<int> MEDCoupling1DGTUMesh::BuildAPolygonFromParts(const std::vector< std::vector<int> >& parts)
3451 std::vector<int> ret;
3454 ret.insert(ret.end(),parts[0].begin(),parts[0].end());
3455 int ref(ret.back());
3456 std::size_t sz(parts.size()),nbh(1);
3457 std::vector<bool> b(sz,true); b[0]=false;
3461 for(;i<sz;i++) if(b[i] && parts[i].front()==ref) { ret.insert(ret.end(),parts[i].begin()+1,parts[i].end()); nbh++; break; }
3465 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::BuildAPolygonFromParts : the input vector is not a part of a single polygon !");
3467 if(ret.back()==ret.front())
3473 * This method performs an aggregation of \a nodalConns (as DataArrayInt::Aggregate does) but in addition of that a shift is applied on the
3474 * values contained in \a nodalConns using corresponding offset specified in input \a offsetInNodeIdsPerElt.
3475 * But it also manage the values -1, that have a semantic in MEDCoupling1DGTUMesh class (separator for polyhedron).
3477 * \param [in] nodalConns - a list of nodal connectivity arrays same size than \a offsetInNodeIdsPerElt.
3478 * \param [in] offsetInNodeIdsPerElt - a list of offsets to apply.
3479 * \return DataArrayInt * - A new object (to be managed by the caller) that is the result of the aggregation.
3480 * \throw If \a nodalConns or \a offsetInNodeIdsPerElt are empty.
3481 * \throw If \a nodalConns and \a offsetInNodeIdsPerElt have not the same size.
3482 * \throw If presence of null pointer in \a nodalConns.
3483 * \throw If presence of not allocated or array with not exactly one component in \a nodalConns.
3485 DataArrayInt *MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds(const std::vector<const DataArrayInt *>& nodalConns, const std::vector<int>& offsetInNodeIdsPerElt)
3487 std::size_t sz1(nodalConns.size()),sz2(offsetInNodeIdsPerElt.size());
3489 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : input vectors do not have the same size !");
3491 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : empty vectors in input !");
3493 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++)
3496 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of null pointer in input vector !");
3497 if(!(*it)->isAllocated())
3498 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of non allocated array in input vector !");
3499 if((*it)->getNumberOfComponents()!=1)
3500 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of array with not exactly one component !");
3501 nbOfTuples+=(*it)->getNumberOfTuples();
3503 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
3504 int *pt=ret->getPointer();
3506 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++,i++)
3508 int curNbt=(*it)->getNumberOfTuples();
3509 const int *inPt=(*it)->begin();
3510 int offset=offsetInNodeIdsPerElt[i];
3511 for(int j=0;j<curNbt;j++,pt++)
3522 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m)
3525 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh is null !");
3526 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
3528 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh must have exactly one geometric type !");
3529 int geoType((int)*gts.begin());
3530 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(m->getName(),*gts.begin()));
3531 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription());
3532 int nbCells(m->getNumberOfCells());
3533 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
3534 conn->alloc(m->getMeshLength()-nbCells,1); connI->alloc(nbCells+1,1);
3535 int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
3536 const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
3537 for(int i=0;i<nbCells;i++,ciin++,ci++)
3539 if(cin[ciin[0]]==geoType)
3541 if(ciin[1]-ciin[0]>=1)
3543 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
3544 ci[1]=ci[0]+ciin[1]-ciin[0]-1;
3548 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 !";
3549 throw INTERP_KERNEL::Exception(oss.str().c_str());
3554 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 !";
3555 throw INTERP_KERNEL::Exception(oss.str().c_str());
3558 ret->setNodalConnectivity(conn,connI);