1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (CEA/DEN)
21 #include "MEDCoupling1GTUMesh.hxx"
22 #include "MEDCouplingUMesh.hxx"
23 #include "MEDCouplingFieldDouble.hxx"
24 #include "MEDCouplingCMesh.hxx"
26 #include "SplitterTetra.hxx"
28 using namespace ParaMEDMEM;
30 const int MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[6]={0,1,2,4,3,5};
32 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh():_cm(0)
36 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):_cm(&cm)
41 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const MEDCoupling1GTUMesh& other, bool recDeepCpy):MEDCouplingPointSet(other,recDeepCpy),_cm(other._cm)
45 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
47 if(type==INTERP_KERNEL::NORM_ERROR)
48 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
49 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
51 return MEDCoupling1SGTUMesh::New(name,type);
53 return MEDCoupling1DGTUMesh::New(name,type);
56 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const MEDCouplingUMesh *m)
59 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh is null !");
60 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
62 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh must have exactly one geometric type !");
63 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*gts.begin());
65 return MEDCoupling1SGTUMesh::New(m);
67 return MEDCoupling1DGTUMesh::New(m);
70 const INTERP_KERNEL::CellModel& MEDCoupling1GTUMesh::getCellModel() const
75 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getCellModelEnum() const
77 return _cm->getEnum();
80 int MEDCoupling1GTUMesh::getMeshDimension() const
82 return (int)_cm->getDimension();
86 * This method returns a newly allocated array containing cell ids (ascendingly sorted) whose geometric type are equal to type.
87 * This method does not throw exception if geometric type \a type is not in \a this.
88 * This method throws an INTERP_KERNEL::Exception if meshdimension of \b this is not equal to those of \b type.
89 * The coordinates array is not considered here.
91 * \param [in] type the geometric type
92 * \return cell ids in this having geometric type \a type.
94 DataArrayInt *MEDCoupling1GTUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
96 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
97 if(type==getCellModelEnum())
98 ret->alloc(getNumberOfCells(),1);
106 * Returns nb of cells having the geometric type \a type. No throw if no cells in \a this has the geometric type \a type.
108 int MEDCoupling1GTUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
110 return type==getCellModelEnum()?getNumberOfCells():0;
114 * Returns a type of a cell by its id.
115 * \param [in] cellId - the id of the cell of interest.
116 * \return INTERP_KERNEL::NormalizedCellType - enumeration item describing the cell type.
117 * \throw If \a cellId is invalid. Valid range is [0, \a this->getNumberOfCells() ).
119 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getTypeOfCell(int cellId) const
121 if(cellId>=0 && cellId<getNumberOfCells())
122 return getCellModelEnum();
123 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::getTypeOfCell : Requesting type of cell #" << cellId << " but it should be in [0," << getNumberOfCells() << ") !";
124 throw INTERP_KERNEL::Exception(oss.str().c_str());
128 * Returns a set of all cell types available in \a this mesh.
129 * \return std::set<INTERP_KERNEL::NormalizedCellType> - the set of cell types.
130 * \warning this method does not throw any exception even if \a this is not defined.
132 std::set<INTERP_KERNEL::NormalizedCellType> MEDCoupling1GTUMesh::getAllGeoTypes() const
134 std::set<INTERP_KERNEL::NormalizedCellType> ret;
135 ret.insert(getCellModelEnum());
140 * This method expects that \a this is sorted by types. If not an exception will be thrown.
141 * This method returns in the same format as code (see MEDCouplingUMesh::checkTypeConsistencyAndContig or MEDCouplingUMesh::splitProfilePerType) how
142 * \a this is composed in cell types.
143 * The returned array is of size 3*n where n is the number of different types present in \a this.
144 * For every k in [0,n] ret[3*k+2]==-1 because it has no sense here.
145 * This parameter is kept only for compatibility with other methode listed above.
147 std::vector<int> MEDCoupling1GTUMesh::getDistributionOfTypes() const
149 std::vector<int> ret(3);
150 ret[0]=(int)getCellModelEnum(); ret[1]=getNumberOfCells(); ret[2]=-1;
155 * This method is the opposite of MEDCouplingUMesh::checkTypeConsistencyAndContig method. Given a list of cells in \a profile it returns a list of sub-profiles sorted by geo type.
156 * The result is put in the array \a idsPerType. In the returned parameter \a code, foreach i \a code[3*i+2] refers (if different from -1) to a location into the \a idsPerType.
157 * This method has 1 input \a profile and 3 outputs \a code \a idsInPflPerType and \a idsPerType.
159 * \param [out] code is a vector of size 3*n where n is the number of different geometric type in \a this \b reduced to the profile \a profile. \a code has exactly the same semantic than in MEDCouplingUMesh::checkTypeConsistencyAndContig method.
160 * \param [out] idsInPflPerType is a vector of size of different geometric type in the subpart defined by \a profile of \a this ( equal to \a code.size()/3). For each i,
161 * \a idsInPflPerType[i] stores the tuple ids in \a profile that correspond to the geometric type code[3*i+0]
162 * \param [out] idsPerType is a vector of size of different sub profiles needed to be defined to represent the profile \a profile for a given geometric type.
163 * This vector can be empty in case of all geometric type cells are fully covered in ascending in the given input \a profile.
165 * \warning for performance reasons no deep copy will be performed, if \a profile can been used as this in output parameters \a idsInPflPerType and \a idsPerType.
167 * \throw if \a profile has not exactly one component. It throws too, if \a profile contains some values not in [0,getNumberOfCells()) or if \a this is not fully defined
170 * - Before \a this has 3 cells \a profile contains [0,1,2]
171 * - After \a code contains [NORM_...,nbCells,-1], \a idsInPflPerType [[0,1,2]] and \a idsPerType is empty <br>
174 * - Before \a this has 3 cells \a profile contains [1,2]
175 * - After \a code contains [NORM_...,nbCells,0], \a idsInPflPerType [[0,1]] and \a idsPerType is [[1,2]] <br>
178 void MEDCoupling1GTUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const
181 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile is NULL !");
182 if(profile->getNumberOfComponents()!=1)
183 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile should have exactly one component !");
184 int nbTuples=profile->getNumberOfTuples();
185 int nbOfCells=getNumberOfCells();
186 code.resize(3); idsInPflPerType.resize(1);
187 code[0]=(int)getCellModelEnum(); code[1]=nbTuples;
188 idsInPflPerType.resize(1);
189 if(profile->isIdentity() && nbTuples==nbOfCells)
192 idsInPflPerType[0]=const_cast<DataArrayInt *>(profile); idsInPflPerType[0]->incrRef();
197 profile->checkAllIdsInRange(0,nbOfCells);
198 idsPerType.resize(1);
199 idsPerType[0]=const_cast<DataArrayInt *>(profile); idsPerType[0]->incrRef();
200 idsInPflPerType[0]=DataArrayInt::Range(0,nbTuples,1);
204 * This method tries to minimize at most the number of deep copy.
205 * So if \a idsPerType is not empty it can be returned directly (without copy, but with ref count incremented) in return.
207 * \sa MEDCouplingUMesh::checkTypeConsistencyAndContig
209 DataArrayInt *MEDCoupling1GTUMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const
211 int nbOfCells=getNumberOfCells();
213 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : invalid input code should be exactly of size 3 !");
214 if(code[0]!=(int)getCellModelEnum())
216 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : Mismatch of geometric type ! Asking for " << code[0] << " whereas the geometric type is \a this is " << getCellModelEnum() << " (" << _cm->getRepr() << ") !";
217 throw INTERP_KERNEL::Exception(oss.str().c_str());
221 if(code[1]==nbOfCells)
225 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : mismatch between the number of cells in this (" << nbOfCells << ") and the number of non profile (" << code[1] << ") !";
226 throw INTERP_KERNEL::Exception(oss.str().c_str());
230 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : single geo type mesh ! 0 or -1 is expected at pos #2 of input code !");
231 if(idsPerType.size()!=1)
232 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input code points to DataArrayInt #0 whereas the size of idsPerType is not equal to 1 !");
233 const DataArrayInt *pfl=idsPerType[0];
235 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : the input code points to a NULL DataArrayInt at rank 0 !");
236 if(pfl->getNumberOfComponents()!=1)
237 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input profile should have exactly one component !");
238 pfl->checkAllIdsInRange(0,nbOfCells);
240 return const_cast<DataArrayInt *>(pfl);
243 void MEDCoupling1GTUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const
245 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
246 m->writeVTKLL(ofs,cellData,pointData,byteData);
249 std::string MEDCoupling1GTUMesh::getVTKDataSetType() const
251 return std::string("UnstructuredGrid");
254 std::string MEDCoupling1GTUMesh::getVTKFileExtension() const
256 return std::string("vtu");
259 std::size_t MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren() const
261 return MEDCouplingPointSet::getHeapMemorySizeWithoutChildren();
264 bool MEDCoupling1GTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
266 if(!MEDCouplingPointSet::isEqualIfNotWhy(other,prec,reason))
269 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualIfNotWhy : input other pointer is null !");
270 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
273 reason="mesh given in input is not castable in MEDCouplingSGTUMesh !";
278 reason="mismatch in geometric type !";
284 bool MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
286 if(!MEDCouplingPointSet::isEqualWithoutConsideringStr(other,prec))
289 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
290 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
298 void MEDCoupling1GTUMesh::checkCoherency() const
300 MEDCouplingPointSet::checkCoherency();
303 DataArrayDouble *MEDCoupling1GTUMesh::getBarycenterAndOwner() const
305 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
306 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=m->getBarycenterAndOwner();
310 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureField(bool isAbs) const
312 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
313 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureField(isAbs);
318 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureFieldOnNode(bool isAbs) const
320 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
321 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureFieldOnNode(isAbs);
329 int MEDCoupling1GTUMesh::getCellContainingPoint(const double *pos, double eps) const
331 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
332 return m->getCellContainingPoint(pos,eps);
335 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::buildOrthogonalField() const
337 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
338 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->buildOrthogonalField();
343 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const double *bbox, double eps) const
345 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
346 return m->getCellsInBoundingBox(bbox,eps);
349 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps)
351 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
352 return m->getCellsInBoundingBox(bbox,eps);
355 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const
357 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
358 return m->buildFacePartOfMySelfNode(start,end,fullyIn);
361 DataArrayInt *MEDCoupling1GTUMesh::findBoundaryNodes() const
363 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
364 return m->findBoundaryNodes();
367 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildBoundaryMesh(bool keepCoords) const
369 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
370 return m->buildBoundaryMesh(keepCoords);
373 void MEDCoupling1GTUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const
375 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
376 m->findCommonCells(compType,startCellId,commonCellsArr,commonCellsIArr);
379 int MEDCoupling1GTUMesh::getNodalConnectivityLength() const
381 const DataArrayInt *c1(getNodalConnectivity());
383 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : no connectivity set !");
384 if(c1->getNumberOfComponents()!=1)
385 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array set must have exactly one component !");
386 if(!c1->isAllocated())
387 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array must be allocated !");
388 return c1->getNumberOfTuples();
392 * This method aggregates all the meshes in \a parts to put them in a single unstructured mesh (those returned).
393 * The order of cells is the returned instance is those in the order of instances in \a parts.
395 * \param [in] parts - all not null parts of single geo type meshes to be aggreagated having the same mesh dimension and same coordinates.
396 * \return MEDCouplingUMesh * - new object to be dealt by the caller.
398 * \throw If one element is null in \a parts.
399 * \throw If not all the parts do not have the same mesh dimension.
400 * \throw If not all the parts do not share the same coordinates.
401 * \throw If not all the parts have their connectivity set properly.
402 * \throw If \a parts is empty.
404 MEDCouplingUMesh *MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh(const std::vector< const MEDCoupling1GTUMesh *>& parts)
407 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : input parts vector is empty !");
408 const MEDCoupling1GTUMesh *firstPart(parts[0]);
410 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : the first instance in input parts is null !");
411 const DataArrayDouble *coords(firstPart->getCoords());
412 int meshDim(firstPart->getMeshDimension());
413 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret(MEDCouplingUMesh::New(firstPart->getName(),meshDim)); ret->setDescription(firstPart->getDescription());
414 ret->setCoords(coords);
415 int nbOfCells(0),connSize(0);
416 for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
419 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of null pointer in input vector !");
420 if((*it)->getMeshDimension()!=meshDim)
421 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances in input vector must have same mesh dimension !");
422 if((*it)->getCoords()!=coords)
423 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances must share the same coordinates pointer !");
424 nbOfCells+=(*it)->getNumberOfCells();
425 connSize+=(*it)->getNodalConnectivityLength();
427 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
428 connI->alloc(nbOfCells+1,1); conn->alloc(connSize+nbOfCells,1);
429 int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
430 for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
432 int curNbCells((*it)->getNumberOfCells());
433 int geoType((int)(*it)->getCellModelEnum());
434 const int *cinPtr((*it)->getNodalConnectivity()->begin());
435 const MEDCoupling1SGTUMesh *ps(dynamic_cast<const MEDCoupling1SGTUMesh *>(*it));
436 const MEDCoupling1DGTUMesh *pd(dynamic_cast<const MEDCoupling1DGTUMesh *>(*it));
439 int nNodesPerCell(ps->getNumberOfNodesPerCell());
440 for(int i=0;i<curNbCells;i++,ci++,cinPtr+=nNodesPerCell)
443 c=std::copy(cinPtr,cinPtr+nNodesPerCell,c);
444 ci[1]=ci[0]+nNodesPerCell+1;
449 const int *ciinPtr(pd->getNodalConnectivityIndex()->begin());
450 for(int i=0;i<curNbCells;i++,ci++,ciinPtr++)
453 c=std::copy(cinPtr+ciinPtr[0],cinPtr+ciinPtr[1],c);
454 ci[1]=ci[0]+ciinPtr[1]-ciinPtr[0]+1;
458 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of instance which type is not in [MEDCoupling1SGTUMesh,MEDCoupling1DGTUMesh] !");
460 ret->setConnectivity(conn,connI,true);
466 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const MEDCoupling1SGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
470 const DataArrayInt *c(other._conn);
476 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
480 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh()
484 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New()
486 return new MEDCoupling1SGTUMesh;
489 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
491 if(type==INTERP_KERNEL::NORM_ERROR)
492 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
493 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
496 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New : the input geometric type " << cm.getRepr() << " is dynamic ! Only static types are allowed here !";
497 throw INTERP_KERNEL::Exception(oss.str().c_str());
499 return new MEDCoupling1SGTUMesh(name,cm);
502 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m)
505 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh is null !");
506 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
508 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh must have exactly one geometric type !");
509 int geoType((int)*gts.begin());
510 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(m->getName(),*gts.begin()));
511 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription());
512 int nbCells(m->getNumberOfCells());
513 int nbOfNodesPerCell(ret->getNumberOfNodesPerCell());
514 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()); conn->alloc(nbCells*nbOfNodesPerCell,1);
515 int *c(conn->getPointer());
516 const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
517 for(int i=0;i<nbCells;i++,ciin++)
519 if(cin[ciin[0]]==geoType)
521 if(ciin[1]-ciin[0]==nbOfNodesPerCell+1)
522 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
525 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m) : something is wrong in the input mesh at cell #" << i << " ! The size of cell is not those expected (" << nbOfNodesPerCell << ") !";
526 throw INTERP_KERNEL::Exception(oss.str().c_str());
531 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m) : something is wrong in the input mesh at cell #" << i << " ! The geometric type is not those expected !";
532 throw INTERP_KERNEL::Exception(oss.str().c_str());
535 ret->setNodalConnectivity(conn);
537 { ret->copyTinyInfoFrom(m); }
538 catch(INTERP_KERNEL::Exception&) { }
542 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::clone(bool recDeepCpy) const
544 return new MEDCoupling1SGTUMesh(*this,recDeepCpy);
548 * This method behaves mostly like MEDCoupling1SGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
549 * The coordinates are shared between \a this and the returned instance.
551 * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
552 * \sa MEDCoupling1SGTUMesh::deepCpy
554 MEDCouplingPointSet *MEDCoupling1SGTUMesh::deepCpyConnectivityOnly() const
557 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(clone(false));
558 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy());
559 ret->setNodalConnectivity(c);
563 void MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
566 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
567 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
569 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1SGTUMesh instance !");
570 setNodalConnectivity(otherC->getNodalConnectivity());
573 void MEDCoupling1SGTUMesh::updateTime() const
575 MEDCoupling1GTUMesh::updateTime();
576 const DataArrayInt *c(_conn);
581 std::size_t MEDCoupling1SGTUMesh::getHeapMemorySizeWithoutChildren() const
583 return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren();
586 std::vector<const BigMemoryObject *> MEDCoupling1SGTUMesh::getDirectChildrenWithNull() const
588 std::vector<const BigMemoryObject *> ret(MEDCoupling1GTUMesh::getDirectChildrenWithNull());
589 ret.push_back((const DataArrayInt *)_conn);
593 MEDCouplingMesh *MEDCoupling1SGTUMesh::deepCpy() const
598 bool MEDCoupling1SGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
601 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualIfNotWhy : input other pointer is null !");
602 std::ostringstream oss; oss.precision(15);
603 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
606 reason="mesh given in input is not castable in MEDCoupling1SGTUMesh !";
609 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
611 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
616 reason="in connectivity of single static geometric type exactly one among this and other is null !";
619 if(!c1->isEqualIfNotWhy(*c2,reason))
621 reason.insert(0,"Nodal connectivity DataArrayInt differ : ");
627 bool MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
630 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
631 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
634 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
636 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
641 if(!c1->isEqualWithoutConsideringStr(*c2))
646 void MEDCoupling1SGTUMesh::checkCoherencyOfConnectivity() const
648 const DataArrayInt *c1(_conn);
651 if(c1->getNumberOfComponents()!=1)
652 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
653 if(c1->getInfoOnComponent(0)!="")
654 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
655 c1->checkAllocated();
658 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
661 void MEDCoupling1SGTUMesh::checkCoherency() const
663 MEDCouplingPointSet::checkCoherency();
664 checkCoherencyOfConnectivity();
667 void MEDCoupling1SGTUMesh::checkCoherency1(double eps) const
670 const DataArrayInt *c1(_conn);
671 int nbOfTuples=c1->getNumberOfTuples();
672 int nbOfNodesPerCell=(int)_cm->getNumberOfNodes();
673 if(nbOfTuples%nbOfNodesPerCell!=0)
675 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::checkCoherency1 : the nb of tuples in conn is " << nbOfTuples << " and number of nodes per cell is " << nbOfNodesPerCell << ". But " << nbOfTuples << "%" << nbOfNodesPerCell << " !=0 !";
676 throw INTERP_KERNEL::Exception(oss.str().c_str());
678 int nbOfNodes=getNumberOfNodes();
679 int nbOfCells=nbOfTuples/nbOfNodesPerCell;
680 const int *w(c1->begin());
681 for(int i=0;i<nbOfCells;i++)
682 for(int j=0;j<nbOfNodesPerCell;j++,w++)
684 if(*w<0 || *w>=nbOfNodes)
686 std::ostringstream oss; oss << "At node #" << j << " of cell #" << i << ", is equal to " << *w << " must be in [0," << nbOfNodes << ") !";
687 throw INTERP_KERNEL::Exception(oss.str().c_str());
692 void MEDCoupling1SGTUMesh::checkCoherency2(double eps) const
694 checkCoherency1(eps);
697 int MEDCoupling1SGTUMesh::getNumberOfCells() const
699 int nbOfTuples=getNodalConnectivityLength();
700 int nbOfNodesPerCell=getNumberOfNodesPerCell();
701 if(nbOfTuples%nbOfNodesPerCell!=0)
703 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh:getNumberOfCells: : the nb of tuples in conn is " << nbOfTuples << " and number of nodes per cell is " << nbOfNodesPerCell << ". But " << nbOfTuples << "%" << nbOfNodesPerCell << " !=0 !";
704 throw INTERP_KERNEL::Exception(oss.str().c_str());
706 return nbOfTuples/nbOfNodesPerCell;
709 int MEDCoupling1SGTUMesh::getNumberOfNodesInCell(int cellId) const
711 return getNumberOfNodesPerCell();
714 int MEDCoupling1SGTUMesh::getNumberOfNodesPerCell() const
716 checkNonDynamicGeoType();
717 return (int)_cm->getNumberOfNodes();
720 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfNodesPerCell() const
722 checkNonDynamicGeoType();
723 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
724 ret->alloc(getNumberOfCells(),1);
725 ret->fillWithValue((int)_cm->getNumberOfNodes());
729 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfFacesPerCell() const
731 checkNonDynamicGeoType();
732 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
733 ret->alloc(getNumberOfCells(),1);
734 ret->fillWithValue((int)_cm->getNumberOfSons());
738 DataArrayInt *MEDCoupling1SGTUMesh::computeEffectiveNbOfNodesPerCell() const
740 checkNonDynamicGeoType();
741 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
742 int nbCells(getNumberOfCells());
743 ret->alloc(nbCells,1);
744 int *retPtr(ret->getPointer());
745 int nbNodesPerCell(getNumberOfNodesPerCell());
746 const int *conn(_conn->begin());
747 for(int i=0;i<nbCells;i++,conn+=nbNodesPerCell,retPtr++)
749 std::set<int> s(conn,conn+nbNodesPerCell);
750 *retPtr=(int)s.size();
755 void MEDCoupling1SGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
757 int sz=getNumberOfNodesPerCell();
759 if(cellId>=0 && cellId<getNumberOfCells())
760 std::copy(_conn->begin()+cellId*sz,_conn->begin()+(cellId+1)*sz,conn.begin());
763 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << getNumberOfCells() << ") !";
764 throw INTERP_KERNEL::Exception(oss.str().c_str());
768 void MEDCoupling1SGTUMesh::checkNonDynamicGeoType() const
771 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkNonDynamicGeoType : internal error ! the internal geo type is dynamic ! should be static !");
774 std::string MEDCoupling1SGTUMesh::simpleRepr() const
776 static const char msg0[]="No coordinates specified !";
777 std::ostringstream ret;
778 ret << "Single static geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
779 ret << "Description of mesh : \"" << getDescription() << "\"\n";
781 double tt=getTime(tmpp1,tmpp2);
782 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
783 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
784 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
787 const int spaceDim=getSpaceDimension();
788 ret << spaceDim << "\nInfo attached on space dimension : ";
789 for(int i=0;i<spaceDim;i++)
790 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
795 ret << "Number of nodes : ";
797 ret << getNumberOfNodes() << "\n";
800 ret << "Number of cells : ";
801 if((const DataArrayInt *)_conn)
803 if(_conn->isAllocated())
805 if(_conn->getNumberOfComponents()==1)
806 ret << getNumberOfCells() << "\n";
808 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
811 ret << "Nodal connectivity array specified but not allocated !" << "\n";
814 ret << "No connectivity specified !" << "\n";
815 ret << "Cell type : " << _cm->getRepr() << "\n";
819 std::string MEDCoupling1SGTUMesh::advancedRepr() const
821 std::ostringstream ret;
823 ret << "\nCoordinates array : \n___________________\n\n";
825 _coords->reprWithoutNameStream(ret);
827 ret << "No array set !\n";
828 ret << "\n\nConnectivity array : \n____________________\n\n";
830 if((const DataArrayInt *)_conn)
832 if(_conn->isAllocated())
834 if(_conn->getNumberOfComponents()==1)
836 int nbOfCells=getNumberOfCells();
837 int sz=getNumberOfNodesPerCell();
838 const int *connPtr=_conn->begin();
839 for(int i=0;i<nbOfCells;i++,connPtr+=sz)
841 ret << "Cell #" << i << " : ";
842 std::copy(connPtr,connPtr+sz,std::ostream_iterator<int>(ret," "));
847 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
850 ret << "Nodal connectivity array specified but not allocated !" << "\n";
853 ret << "No connectivity specified !" << "\n";
857 DataArrayDouble *MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell() const
859 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
860 int spaceDim=getSpaceDimension();
861 int nbOfCells=getNumberOfCells();//checkCoherency()
862 int nbOfNodes=getNumberOfNodes();
863 ret->alloc(nbOfCells,spaceDim);
864 double *ptToFill=ret->getPointer();
865 const double *coor=_coords->begin();
866 const int *nodal=_conn->begin();
867 int sz=getNumberOfNodesPerCell();
868 double coeff=1./(double)sz;
869 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim)
871 std::fill(ptToFill,ptToFill+spaceDim,0.);
872 for(int j=0;j<sz;j++,nodal++)
873 if(*nodal>=0 && *nodal<nbOfNodes)
874 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
877 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
878 throw INTERP_KERNEL::Exception(oss.str().c_str());
880 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),coeff));
885 void MEDCoupling1SGTUMesh::renumberCells(const int *old2NewBg, bool check)
887 int nbCells=getNumberOfCells();
888 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
889 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
891 o2n=o2n->checkAndPreparePermutation();
893 const int *conn=_conn->begin();
894 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o=o2n->invertArrayO2N2N2O(nbCells);
895 const int *n2oPtr=n2o->begin();
896 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
897 newConn->alloc(_conn->getNumberOfTuples(),1);
898 newConn->copyStringInfoFrom(*_conn);
899 int sz=getNumberOfNodesPerCell();
901 int *newC=newConn->getPointer();
902 for(int i=0;i<nbCells;i++,newC+=sz)
905 std::copy(conn+pos*sz,conn+(pos+1)*sz,newC);
911 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
912 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
913 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
914 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
916 * \param [in] begin input start of array of node ids.
917 * \param [in] end input end of array of node ids.
918 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
919 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
921 void MEDCoupling1SGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
923 int nbOfCells=getNumberOfCells();
924 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
926 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
927 std::vector<bool> fastFinder(sz,false);
928 for(const int *work=begin;work!=end;work++)
929 if(*work>=0 && *work<sz)
930 fastFinder[*work]=true;
931 const int *conn=_conn->begin();
932 int nbNodesPerCell=getNumberOfNodesPerCell();
933 for(int i=0;i<nbOfCells;i++,conn+=nbNodesPerCell)
936 for(int j=0;j<nbNodesPerCell;j++)
940 if(fastFinder[conn[j]])
943 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
944 cellIdsKept->pushBackSilent(i);
946 cellIdsKeptArr=cellIdsKept.retn();
949 MEDCouplingMesh *MEDCoupling1SGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
951 if(other->getType()!=SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED)
952 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single static geo type each other !");
953 const MEDCoupling1SGTUMesh *otherC=static_cast<const MEDCoupling1SGTUMesh *>(other);
954 return Merge1SGTUMeshes(this,otherC);
957 MEDCouplingUMesh *MEDCoupling1SGTUMesh::buildUnstructured() const
959 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
960 ret->setCoords(getCoords());
961 const int *nodalConn=_conn->begin();
962 int nbCells=getNumberOfCells();
963 int nbNodesPerCell=getNumberOfNodesPerCell();
964 int geoType=(int)getCellModelEnum();
965 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells*(nbNodesPerCell+1),1);
966 int *cPtr=c->getPointer();
967 for(int i=0;i<nbCells;i++,nodalConn+=nbNodesPerCell)
970 cPtr=std::copy(nodalConn,nodalConn+nbNodesPerCell,cPtr);
972 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::Range(0,(nbCells+1)*(nbNodesPerCell+1),nbNodesPerCell+1);
973 ret->setConnectivity(c,cI,true);
975 { ret->copyTinyInfoFrom(this); }
976 catch(INTERP_KERNEL::Exception&) { }
980 DataArrayInt *MEDCoupling1SGTUMesh::simplexize(int policy)
985 return simplexizePol0();
987 return simplexizePol1();
988 case (int) INTERP_KERNEL::PLANAR_FACE_5:
989 return simplexizePlanarFace5();
990 case (int) INTERP_KERNEL::PLANAR_FACE_6:
991 return simplexizePlanarFace6();
993 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::simplexize : unrecognized policy ! Must be :\n - 0 or 1 (only available for meshdim=2) \n - PLANAR_FACE_5, PLANAR_FACE_6 (only for meshdim=3)");
999 struct MEDCouplingAccVisit
1001 MEDCouplingAccVisit():_new_nb_of_nodes(0) { }
1002 int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; }
1003 int _new_nb_of_nodes;
1009 * This method returns all node ids used in \b this. The data array returned has to be dealt by the caller.
1010 * The returned node ids are sortes ascendingly. This method is closed to MEDCoupling1SGTUMesh::getNodeIdsInUse except
1011 * the format of returned DataArrayInt instance.
1013 * \return a newly allocated DataArrayInt sorted ascendingly of fetched node ids.
1014 * \sa MEDCoupling1SGTUMesh::getNodeIdsInUse
1016 DataArrayInt *MEDCoupling1SGTUMesh::computeFetchedNodeIds() const
1018 checkCoherencyOfConnectivity();
1019 int nbNodes(getNumberOfNodes());
1020 std::vector<bool> fetchedNodes(nbNodes,false);
1021 computeNodeIdsAlg(fetchedNodes);
1022 int sz((int)std::count(fetchedNodes.begin(),fetchedNodes.end(),true));
1023 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
1024 int *retPtr(ret->getPointer());
1025 for(int i=0;i<nbNodes;i++)
1032 * Finds nodes not used in any cell and returns an array giving a new id to every node
1033 * by excluding the unused nodes, for which the array holds -1. The result array is
1034 * a mapping in "Old to New" mode.
1035 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
1036 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
1037 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
1038 * if the node is unused or a new id else. The caller is to delete this
1039 * array using decrRef() as it is no more needed.
1040 * \throw If the coordinates array is not set.
1041 * \throw If the nodal connectivity of cells is not defined.
1042 * \throw If the nodal connectivity includes an invalid id.
1043 * \sa MEDCoupling1SGTUMesh::computeFetchedNodeIds
1045 DataArrayInt *MEDCoupling1SGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
1048 int nbOfNodes=getNumberOfNodes();
1049 int nbOfCells=getNumberOfCells();
1050 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
1051 ret->alloc(nbOfNodes,1);
1052 int *traducer=ret->getPointer();
1053 std::fill(traducer,traducer+nbOfNodes,-1);
1054 const int *conn=_conn->begin();
1055 int nbNodesPerCell=getNumberOfNodesPerCell();
1056 for(int i=0;i<nbOfCells;i++)
1057 for(int j=0;j<nbNodesPerCell;j++,conn++)
1058 if(*conn>=0 && *conn<nbOfNodes)
1062 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << conn[j] << " not in [0," << nbOfNodes << ") !";
1063 throw INTERP_KERNEL::Exception(oss.str().c_str());
1065 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
1066 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
1071 * Same than renumberNodesInConn(const int *) except that here the format of old-to-new traducer is using map instead
1072 * of array. This method is dedicated for renumbering from a big set of nodes the a tiny set of nodes which is the case during extraction
1075 void MEDCoupling1SGTUMesh::renumberNodesInConn(const std::map<int,int>& newNodeNumbersO2N)
1077 getNumberOfCells();//only to check that all is well defined.
1078 int *begPtr(_conn->getPointer());
1079 int nbElt(_conn->getNumberOfTuples());
1080 int *endPtr(begPtr+nbElt);
1081 for(int *it=begPtr;it!=endPtr;it++)
1083 std::map<int,int>::const_iterator it2(newNodeNumbersO2N.find(*it));
1084 if(it2!=newNodeNumbersO2N.end())
1090 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::renumberNodesInConn : At pos #" << std::distance(begPtr,it) << " of nodal connectivity value is " << *it << ". Not in map !";
1091 throw INTERP_KERNEL::Exception(oss.str().c_str());
1098 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
1099 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
1100 * This method is a generalization of shiftNodeNumbersInConn().
1101 * \warning This method performs no check of validity of new ids. **Use it with care !**
1102 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
1103 * this->getNumberOfNodes(), in "Old to New" mode.
1104 * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
1105 * \throw If the nodal connectivity of cells is not defined.
1107 void MEDCoupling1SGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
1109 getNumberOfCells();//only to check that all is well defined.
1110 _conn->transformWithIndArr(newNodeNumbersO2N,newNodeNumbersO2N+getNumberOfNodes());
1114 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2)
1116 std::vector<const MEDCoupling1SGTUMesh *> tmp(2);
1117 tmp[0]=const_cast<MEDCoupling1SGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1SGTUMesh *>(mesh2);
1118 return Merge1SGTUMeshes(tmp);
1121 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(std::vector<const MEDCoupling1SGTUMesh *>& a)
1123 std::size_t sz=a.size();
1125 return Merge1SGTUMeshesLL(a);
1126 for(std::size_t ii=0;ii<sz;ii++)
1129 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::Merge1SGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
1130 throw INTERP_KERNEL::Exception(oss.str().c_str());
1132 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
1133 for(std::size_t ii=0;ii<sz;ii++)
1134 if(&(a[ii]->getCellModel())!=cm)
1135 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : all items must have the same geo type !");
1136 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> > bb(sz);
1137 std::vector< const MEDCoupling1SGTUMesh * > aa(sz);
1139 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
1141 const MEDCoupling1SGTUMesh *cur=a[i];
1142 const DataArrayDouble *coo=cur->getCoords();
1144 spaceDim=coo->getNumberOfComponents();
1147 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : no spaceDim specified ! unable to perform merge !");
1148 for(std::size_t i=0;i<sz;i++)
1150 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
1153 return Merge1SGTUMeshesLL(aa);
1157 * \throw If presence of a null instance in the input vector \a a.
1158 * \throw If a is empty
1160 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::vector<const MEDCoupling1SGTUMesh *>& a)
1163 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : input array must be NON EMPTY !");
1164 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1166 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : null instance in the first element of input vector !");
1167 std::vector<const DataArrayInt *> ncs(a.size());
1168 (*it)->getNumberOfCells();//to check that all is OK
1169 const DataArrayDouble *coords=(*it)->getCoords();
1170 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1171 ncs[0]=(*it)->getNodalConnectivity();
1173 for(int i=1;it!=a.end();i++,it++)
1176 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : presence of a null instance in the input vector !");
1177 if(cm!=&((*it)->getCellModel()))
1178 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1179 (*it)->getNumberOfCells();//to check that all is OK
1180 ncs[i]=(*it)->getNodalConnectivity();
1181 if(coords!=(*it)->getCoords())
1182 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : not lying on same coords !");
1184 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1185 ret->setCoords(coords);
1186 ret->_conn=DataArrayInt::Aggregate(ncs);
1191 * 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)
1193 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector<const MEDCoupling1SGTUMesh *>& a)
1196 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : input array must be NON EMPTY !");
1197 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1198 int nbOfCells=(*it)->getNumberOfCells();
1199 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1200 int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
1202 for(;it!=a.end();it++)
1204 if(cm!=&((*it)->getCellModel()))
1205 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1206 nbOfCells+=(*it)->getNumberOfCells();
1208 std::vector<const MEDCouplingPointSet *> aps(a.size());
1209 std::copy(a.begin(),a.end(),aps.begin());
1210 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
1211 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1212 ret->setCoords(pts);
1213 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New();
1214 c->alloc(nbOfCells*nbNodesPerCell,1);
1215 int *cPtr=c->getPointer();
1217 for(it=a.begin();it!=a.end();it++)
1219 int curConnLgth=(*it)->getNodalConnectivityLength();
1220 const int *curC=(*it)->_conn->begin();
1221 cPtr=std::transform(curC,curC+curConnLgth,cPtr,std::bind2nd(std::plus<int>(),offset));
1222 offset+=(*it)->getNumberOfNodes();
1225 ret->setNodalConnectivity(c);
1229 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
1231 int ncell=getNumberOfCells();
1232 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1233 ret->setCoords(_coords);
1234 std::size_t nbOfElemsRet=std::distance(begin,end);
1235 const int *inConn=_conn->getConstPointer();
1236 int sz=getNumberOfNodesPerCell();
1237 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1238 int *connPtr=connRet->getPointer();
1239 for(const int *work=begin;work!=end;work++,connPtr+=sz)
1241 if(*work>=0 && *work<ncell)
1242 std::copy(inConn+(work[0])*sz,inConn+(work[0]+1)*sz,connPtr);
1245 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !";
1246 throw INTERP_KERNEL::Exception(oss.str().c_str());
1250 ret->copyTinyInfoFrom(this);
1254 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
1256 int ncell=getNumberOfCells();
1257 int nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : ");
1258 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1259 ret->setCoords(_coords);
1260 const int *inConn=_conn->getConstPointer();
1261 int sz=getNumberOfNodesPerCell();
1262 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1263 int *connPtr=connRet->getPointer();
1265 for(int i=0;i<nbOfElemsRet;i++,connPtr+=sz,curId+=step)
1267 if(curId>=0 && curId<ncell)
1268 std::copy(inConn+curId*sz,inConn+(curId+1)*sz,connPtr);
1271 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : On pos #" << i << " input cell id =" << curId << " should be in [0," << ncell << ") !";
1272 throw INTERP_KERNEL::Exception(oss.str().c_str());
1276 ret->copyTinyInfoFrom(this);
1280 void MEDCoupling1SGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
1282 int sz((int)nodeIdsInUse.size());
1283 for(const int *conn=_conn->begin();conn!=_conn->end();conn++)
1285 if(*conn>=0 && *conn<sz)
1286 nodeIdsInUse[*conn]=true;
1289 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeFetchedNodeIds : At pos #" << std::distance(_conn->begin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !";
1290 throw INTERP_KERNEL::Exception(oss.str().c_str());
1295 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(int spaceDim) const
1297 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1298 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1;
1299 const DataArrayInt *nodalConn(_conn);
1302 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
1309 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
1310 ret->setCoords(coords);
1313 ret->setCoords(_coords);
1317 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol0()
1319 int nbOfCells=getNumberOfCells();
1320 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1321 return DataArrayInt::Range(0,nbOfCells,1);
1322 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1323 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1324 const int *c(_conn->begin());
1325 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1326 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1328 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[2];
1329 newConnPtr[3]=c[0]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1330 retPtr[0]=i; retPtr[1]=i;
1333 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1338 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol1()
1340 int nbOfCells=getNumberOfCells();
1341 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1342 return DataArrayInt::Range(0,nbOfCells,1);
1343 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1344 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1345 const int *c(_conn->begin());
1346 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1347 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1349 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[3];
1350 newConnPtr[3]=c[1]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1351 retPtr[0]=i; retPtr[1]=i;
1354 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1359 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace5()
1361 int nbOfCells=getNumberOfCells();
1362 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1363 return DataArrayInt::Range(0,nbOfCells,1);
1364 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(5*4*nbOfCells,1);
1365 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(5*nbOfCells,1);
1366 const int *c(_conn->begin());
1367 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1368 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=20,retPtr+=5)
1370 for(int j=0;j<20;j++)
1371 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_5_WO[j]];
1372 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i;
1375 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1380 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace6()
1382 int nbOfCells=getNumberOfCells();
1383 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1384 return DataArrayInt::Range(0,nbOfCells,1);
1385 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(6*4*nbOfCells,1);
1386 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(6*nbOfCells,1);
1387 const int *c(_conn->begin());
1388 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1389 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=24,retPtr+=6)
1391 for(int j=0;j<24;j++)
1392 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_6_WO[j]];
1393 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i; retPtr[5]=i;
1396 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1401 void MEDCoupling1SGTUMesh::reprQuickOverview(std::ostream& stream) const
1403 stream << "MEDCoupling1SGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
1404 stream << " Mesh dimension : " << getMeshDimension() << ".";
1406 { stream << " No coordinates set !"; return ; }
1407 if(!_coords->isAllocated())
1408 { stream << " Coordinates set but not allocated !"; return ; }
1409 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
1410 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
1411 if(!(const DataArrayInt *)_conn)
1412 { stream << std::endl << "Nodal connectivity NOT set !"; return ; }
1413 if(_conn->isAllocated())
1415 if(_conn->getNumberOfComponents()==1)
1416 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
1420 void MEDCoupling1SGTUMesh::checkFullyDefined() const
1422 if(!((const DataArrayInt *)_conn) || !((const DataArrayDouble *)_coords))
1423 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFullyDefined : part of this is not fully defined.");
1427 * First step of unserialization process.
1429 bool MEDCoupling1SGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
1431 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEmptyMesh : not implemented yet !");
1434 void MEDCoupling1SGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
1437 double time=getTime(it,order);
1438 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
1440 littleStrings.push_back(getName());
1441 littleStrings.push_back(getDescription());
1442 littleStrings.push_back(getTimeUnit());
1444 std::vector<std::string> littleStrings2,littleStrings3;
1445 if((const DataArrayDouble *)_coords)
1446 _coords->getTinySerializationStrInformation(littleStrings2);
1447 if((const DataArrayInt *)_conn)
1448 _conn->getTinySerializationStrInformation(littleStrings3);
1449 int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size());
1450 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
1451 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
1453 tinyInfo.push_back(getCellModelEnum());
1454 tinyInfo.push_back(it);
1455 tinyInfo.push_back(order);
1456 std::vector<int> tinyInfo2,tinyInfo3;
1457 if((const DataArrayDouble *)_coords)
1458 _coords->getTinySerializationIntInformation(tinyInfo2);
1459 if((const DataArrayInt *)_conn)
1460 _conn->getTinySerializationIntInformation(tinyInfo3);
1461 int sz2((int)tinyInfo2.size()),sz3((int)tinyInfo3.size());
1462 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3);
1463 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1464 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
1466 tinyInfoD.push_back(time);
1469 void MEDCoupling1SGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
1471 std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+tinyInfo[5]);
1472 std::vector<int> tinyInfo1(tinyInfo.begin()+7+tinyInfo[5],tinyInfo.begin()+7+tinyInfo[5]+tinyInfo[6]);
1473 a1->resizeForUnserialization(tinyInfo1);
1474 a2->resizeForUnserialization(tinyInfo2);
1477 void MEDCoupling1SGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
1480 if((const DataArrayInt *)_conn)
1481 if(_conn->isAllocated())
1482 sz=_conn->getNbOfElems();
1483 a1=DataArrayInt::New();
1485 if(sz!=0 && (const DataArrayInt *)_conn)
1486 std::copy(_conn->begin(),_conn->end(),a1->getPointer());
1488 if((const DataArrayDouble *)_coords)
1489 if(_coords->isAllocated())
1490 sz=_coords->getNbOfElems();
1491 a2=DataArrayDouble::New();
1493 if(sz!=0 && (const DataArrayDouble *)_coords)
1494 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
1497 void MEDCoupling1SGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
1498 const std::vector<std::string>& littleStrings)
1500 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
1501 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
1502 setName(littleStrings[0]);
1503 setDescription(littleStrings[1]);
1504 setTimeUnit(littleStrings[2]);
1505 setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
1506 int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]);
1508 _coords=DataArrayDouble::New();
1509 std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+sz2);
1510 _coords->resizeForUnserialization(tinyInfo2);
1511 std::copy(a2->begin(),a2->end(),_coords->getPointer());
1512 _conn=DataArrayInt::New();
1513 std::vector<int> tinyInfo3(tinyInfo.begin()+7+sz2,tinyInfo.begin()+7+sz2+sz3);
1514 _conn->resizeForUnserialization(tinyInfo3);
1515 std::copy(a1->begin(),a1->end(),_conn->getPointer());
1516 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
1517 _coords->finishUnserialization(tinyInfo2,littleStrings2);
1518 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
1519 _conn->finishUnserialization(tinyInfo3,littleStrings3);
1523 * Checks if \a this and \a other meshes are geometrically equivalent with high
1524 * probability, else an exception is thrown. The meshes are considered equivalent if
1525 * (1) meshes contain the same number of nodes and the same number of elements of the
1526 * same types (2) three cells of the two meshes (first, last and middle) are based
1527 * on coincident nodes (with a specified precision).
1528 * \param [in] other - the mesh to compare with.
1529 * \param [in] prec - the precision used to compare nodes of the two meshes.
1530 * \throw If the two meshes do not match.
1532 void MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
1534 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1535 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1537 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single static geometric type !");
1538 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1542 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1543 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1544 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1545 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1546 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1547 if(c1->getHashCode()!=c2->getHashCode())
1548 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1551 MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
1554 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
1555 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1557 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
1558 std::vector<const MEDCoupling1SGTUMesh *> ms(2);
1561 return Merge1SGTUMeshesOnSameCoords(ms);
1564 void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const
1566 checkFullyDefined();
1567 int nbOfNodes=getNumberOfNodes();
1568 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
1569 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
1570 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
1571 const int *conn=_conn->begin();
1572 int nbOfCells=getNumberOfCells();
1573 int nbOfEltsInRevNodal=0;
1574 int nbOfNodesPerCell=getNumberOfNodesPerCell();
1575 for(int eltId=0;eltId<nbOfCells;eltId++)
1577 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1579 if(conn[0]>=0 && conn[0]<nbOfNodes)
1581 nbOfEltsInRevNodal++;
1582 revNodalIndxPtr[conn[0]+1]++;
1586 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
1587 throw INTERP_KERNEL::Exception(oss.str().c_str());
1591 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
1592 conn=_conn->begin();
1593 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
1594 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
1595 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
1596 for(int eltId=0;eltId<nbOfCells;eltId++)
1598 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1600 *std::find_if(revNodalPtr+revNodalIndxPtr[*conn],revNodalPtr+revNodalIndxPtr[*conn+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
1606 * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null.
1608 void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn)
1611 nodalConn->incrRef();
1617 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
1619 DataArrayInt *MEDCoupling1SGTUMesh::getNodalConnectivity() const
1621 const DataArrayInt *ret(_conn);
1622 return const_cast<DataArrayInt *>(ret);
1626 * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted,
1627 * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter.
1628 * If a nodal connectivity previouly existed before the call of this method, it will be reset.
1630 * \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain.
1632 void MEDCoupling1SGTUMesh::allocateCells(int nbOfCells)
1635 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !");
1636 _conn=DataArrayInt::New();
1637 _conn->reserve(getNumberOfNodesPerCell()*nbOfCells);
1642 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
1644 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
1645 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
1646 * \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
1647 * attached to \a this.
1648 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
1650 void MEDCoupling1SGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd)
1652 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
1653 int ref=getNumberOfNodesPerCell();
1656 DataArrayInt *c(_conn);
1658 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
1660 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !");
1664 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this (";
1665 oss << ref << ") !";
1666 throw INTERP_KERNEL::Exception(oss.str().c_str());
1671 * This method builds the dual mesh of \a this and returns it.
1673 * \return MEDCoupling1SGTUMesh * - newly object created to be managed by the caller.
1674 * \throw If \a this is not a mesh containing only simplex cells.
1675 * \throw If \a this is not correctly allocated (coordinates and connectivities have to be correctly set !).
1676 * \throw If at least one node in \a this is orphan (without any simplex cell lying on it !)
1678 MEDCoupling1GTUMesh *MEDCoupling1SGTUMesh::computeDualMesh() const
1680 const INTERP_KERNEL::CellModel& cm(getCellModel());
1682 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : this mesh is not a simplex mesh ! Please invoke simplexize of tetrahedrize on this before calling this method !");
1683 switch(getMeshDimension())
1686 return computeDualMesh3D();
1688 return computeDualMesh2D();
1690 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : meshdimension must be in [2,3] !");
1695 * This method explode each NORM_HEXA8 cells in \a this into 6 NORM_QUAD4 cells and put the result into the MEDCoupling1SGTUMesh returned instance.
1697 * \return MEDCoupling1SGTUMesh * - a newly allocated instances (to be managed by the caller) storing the result of the explosion.
1698 * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
1699 * \throw If \a this is not properly allocated.
1701 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4() const
1703 const INTERP_KERNEL::CellModel& cm(getCellModel());
1704 if(cm.getEnum()!=INTERP_KERNEL::NORM_HEXA8)
1705 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4 : this method can be applied only on HEXA8 mesh !");
1706 int nbHexa8(getNumberOfCells());
1707 const int *inConnPtr(getNodalConnectivity()->begin());
1708 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(getName(),INTERP_KERNEL::NORM_QUAD4));
1709 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()); c->alloc(nbHexa8*6*4,1);
1710 int *cPtr(c->getPointer());
1711 for(int i=0;i<nbHexa8;i++,inConnPtr+=8)
1713 for(int j=0;j<6;j++,cPtr+=4)
1714 cm.fillSonCellNodalConnectivity(j,inConnPtr,cPtr);
1716 ret->setCoords(getCoords());
1717 ret->setNodalConnectivity(c);
1722 * This method starts from an unstructured mesh that hides in reality a cartesian mesh.
1723 * If it is not the case, an exception will be thrown.
1724 * This method returns three objects : The cartesian mesh geometrically equivalent to \a this (within a precision of \a eps) and a permutation of cells
1725 * and a permutation of nodes.
1727 * - this[cellPerm[i]]=ret[i]
1729 * \param [out] cellPerm the permutation array of size \c this->getNumberOfCells()
1730 * \param [out] nodePerm the permutation array of size \c this->getNumberOfNodes()
1731 * \return MEDCouplingCMesh * - a newly allocated mesh that is the result of the structurization of \a this.
1733 MEDCouplingCMesh *MEDCoupling1SGTUMesh::structurizeMe(DataArrayInt *& cellPerm, DataArrayInt *& nodePerm, double eps) const
1736 int spaceDim(getSpaceDimension()),meshDim(getMeshDimension()),nbNodes(getNumberOfNodes());
1737 if(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim)!=getCellModelEnum())
1738 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::structurizeMe : the unique geo type in this is not compatible with the geometric type regarding mesh dimension !");
1739 MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> cm(MEDCouplingCMesh::New());
1740 for(int i=0;i<spaceDim;i++)
1742 std::vector<int> tmp(1,i);
1743 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> elt(static_cast<DataArrayDouble*>(getCoords()->keepSelectedComponents(tmp)));
1744 elt=elt->getDifferentValues(eps);
1746 cm->setCoordsAt(i,elt);
1748 if(nbNodes!=cm->getNumberOfNodes())
1749 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 ?");
1751 { cm->copyTinyInfoFrom(this); }
1752 catch(INTERP_KERNEL::Exception&) { }
1753 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> um(cm->buildUnstructured()),self(buildUnstructured());
1754 self->checkGeoEquivalWith(um,12,eps,cellPerm,nodePerm);
1760 bool UpdateHexa8Cell(int validAxis, int neighId, const int *validConnQuad4NeighSide, int *allFacesNodalConn, int *myNeighbours)
1762 static const int TAB[48]={
1770 static const int TAB2[6]={0,0,3,3,3,3};
1771 if(myNeighbours[validAxis]==neighId && allFacesNodalConn[4*validAxis+0]==validConnQuad4NeighSide[TAB2[validAxis]])
1773 int oldAxis((int)std::distance(myNeighbours,std::find(myNeighbours,myNeighbours+6,neighId)));
1774 std::size_t pos(std::distance(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,std::find(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS+6,oldAxis)));
1775 std::size_t pos0(pos/2),pos1(pos%2);
1776 int oldAxisOpp(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[2*pos0+(pos1+1)%2]);
1777 int oldConn[8],myConn2[8]={-1,-1,-1,-1,-1,-1,-1,-1},myConn[8],edgeConn[2],allFacesTmp[24],neighTmp[6];
1778 oldConn[0]=allFacesNodalConn[0]; oldConn[1]=allFacesNodalConn[1]; oldConn[2]=allFacesNodalConn[2]; oldConn[3]=allFacesNodalConn[3];
1779 oldConn[4]=allFacesNodalConn[4]; oldConn[5]=allFacesNodalConn[7]; oldConn[6]=allFacesNodalConn[6]; oldConn[7]=allFacesNodalConn[5];
1780 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_HEXA8));
1781 for(int i=0;i<4;i++)
1782 myConn2[i]=validConnQuad4NeighSide[(4-i+TAB2[validAxis])%4];
1783 for(int i=0;i<4;i++)
1785 int nodeId(myConn2[i]);//the node id for which the opposite one will be found
1787 INTERP_KERNEL::NormalizedCellType typeOfSon;
1788 for(int j=0;j<12 && !found;j++)
1790 cm.fillSonEdgesNodalConnectivity3D(j,oldConn,-1,edgeConn,typeOfSon);
1791 if(edgeConn[0]==nodeId || edgeConn[1]==nodeId)
1793 if(std::find(allFacesNodalConn+4*oldAxisOpp,allFacesNodalConn+4*oldAxisOpp+4,edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0])!=allFacesNodalConn+4*oldAxisOpp+4)
1795 myConn2[i+4]=edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0];
1801 throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error !");
1803 const int *myTab(TAB+8*validAxis);
1804 for(int i=0;i<8;i++)
1805 myConn[i]=myConn2[myTab[i]];
1806 for(int i=0;i<6;i++)
1808 cm.fillSonCellNodalConnectivity(i,myConn,allFacesTmp+4*i);
1809 std::set<int> s(allFacesTmp+4*i,allFacesTmp+4*i+4);
1811 for(int j=0;j<6 && !found;j++)
1813 std::set<int> s1(allFacesNodalConn+4*j,allFacesNodalConn+4*j+4);
1816 neighTmp[i]=myNeighbours[j];
1821 throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error #2 !");
1823 std::copy(allFacesTmp,allFacesTmp+24,allFacesNodalConn);
1824 std::copy(neighTmp,neighTmp+6,myNeighbours);
1831 * 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
1832 * homogeneous. If it succeeds the result of MEDCouplingUMesh::tetrahedrize will return a conform mesh.
1834 * \return DataArrayInt * - a newly allocated array (to be managed by the caller) containing renumbered cell ids.
1836 * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
1837 * \throw If \a this is not properly allocated.
1838 * \sa MEDCouplingUMesh::tetrahedrize, MEDCouplingUMesh::simplexize.
1840 DataArrayInt *MEDCoupling1SGTUMesh::sortHexa8EachOther()
1842 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> quads(explodeEachHexa8To6Quad4());//checks that only hexa8
1843 int nbHexa8(getNumberOfCells()),*cQuads(quads->getNodalConnectivity()->getPointer());
1844 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> neighOfQuads(DataArrayInt::New()); neighOfQuads->alloc(nbHexa8*6,1); neighOfQuads->fillWithValue(-1);
1845 int *ptNeigh(neighOfQuads->getPointer());
1846 {//neighOfQuads tells for each face of each Quad8 which cell (if!=-1) is connected to this face.
1847 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> quadsTmp(quads->buildUnstructured());
1848 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ccSafe,cciSafe;
1849 DataArrayInt *cc(0),*cci(0);
1850 quadsTmp->findCommonCells(3,0,cc,cci);
1851 ccSafe=cc; cciSafe=cci;
1852 const int *ccPtr(ccSafe->begin()),nbOfPair(cci->getNumberOfTuples()-1);
1853 for(int i=0;i<nbOfPair;i++)
1854 { ptNeigh[ccPtr[2*i+0]]=ccPtr[2*i+1]/6; ptNeigh[ccPtr[2*i+1]]=ccPtr[2*i+0]/6; }
1856 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
1857 std::vector<bool> fetched(nbHexa8,false);
1858 std::vector<bool>::iterator it(std::find(fetched.begin(),fetched.end(),false));
1859 while(it!=fetched.end())//it will turns as time as number of connected zones
1861 int cellId((int)std::distance(fetched.begin(),it));//it is the seed of the connected zone.
1862 std::set<int> s; s.insert(cellId);//s contains already organized.
1865 std::set<int> sNext;
1866 for(std::set<int>::const_iterator it0=s.begin();it0!=s.end();it0++)
1869 int *myNeighb(ptNeigh+6*(*it0));
1870 for(int i=0;i<6;i++)
1872 if(myNeighb[i]!=-1 && !fetched[myNeighb[i]])
1874 std::size_t pos(std::distance(HEXA8_FACE_PAIRS,std::find(HEXA8_FACE_PAIRS,HEXA8_FACE_PAIRS+6,i)));
1875 std::size_t pos0(pos/2),pos1(pos%2);
1876 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]))
1877 ret->pushBackSilent(myNeighb[i]);
1878 fetched[myNeighb[i]]=true;
1879 sNext.insert(myNeighb[i]);
1885 it=std::find(fetched.begin(),fetched.end(),false);
1889 int *conn(getNodalConnectivity()->getPointer());
1890 for(const int *pt=ret->begin();pt!=ret->end();pt++)
1893 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];
1894 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];
1901 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh3D() const
1903 static const int DUAL_TETRA_0[36]={
1904 4,1,0, 6,0,3, 7,3,1,
1905 4,0,1, 5,2,0, 8,1,2,
1906 6,3,0, 5,0,2, 9,2,3,
1909 static const int DUAL_TETRA_1[36]={
1910 8,4,10, 11,5,8, 10,7,11,
1911 9,4,8, 8,5,12, 12,6,9,
1912 10,4,9, 9,6,13, 13,7,10,
1913 12,5,11, 13,6,12, 11,7,13
1915 static const int FACEID_NOT_SH_NODE[4]={2,3,1,0};
1916 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TETRA4)
1917 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh3D : only TETRA4 supported !");
1918 checkFullyDefined();
1919 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured());
1920 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1921 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1922 const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1923 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d1Arr(DataArrayInt::New()),di1Arr(DataArrayInt::New()),rd1Arr(DataArrayInt::New()),rdi1Arr(DataArrayInt::New());
1924 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->explode3DMeshTo1D(d1Arr,di1Arr,rd1Arr,rdi1Arr));
1925 const int *d1(d1Arr->begin());
1926 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1927 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> faces(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
1928 const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
1929 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),facesBaryArr(faces->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
1930 const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+faces->getNumberOfCells()),offset1(offset0+edges->getNumberOfCells());
1932 std::vector<const DataArrayDouble *> v(4); v[0]=getCoords(); v[1]=facesBaryArr; v[2]=edgesBaryArr; v[3]=baryArr;
1933 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0; facesBaryArr=0;
1934 std::string name("DualOf_"); name+=getName();
1935 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYHED)); ret->setCoords(zeArr);
1936 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1937 for(int i=0;i<nbOfNodes;i++,revNodI++)
1939 int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1940 if(nbOfCellsSharingNode==0)
1942 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh3D : Node #" << i << " is orphan !";
1943 throw INTERP_KERNEL::Exception(oss.str().c_str());
1945 for(int j=0;j<nbOfCellsSharingNode;j++)
1947 int curCellId(revNod[revNodI[0]+j]);
1948 const int *connOfCurCell(nodal+4*curCellId);
1949 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1950 if(j!=0) cArr->pushBackSilent(-1);
1953 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;
1954 tmp[2]=curCellId+offset1; tmp[3]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+2]]+nbOfNodes;
1956 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;
1957 tmp[7]=curCellId+offset1; tmp[8]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+5]]+nbOfNodes;
1959 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;
1960 tmp[12]=curCellId+offset1; tmp[13]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+8]]+nbOfNodes;
1961 cArr->insertAtTheEnd(tmp,tmp+14);
1963 for(int k=0;k<4;k++)
1965 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1967 const int *faceId(d2+4*curCellId+k);
1968 if(rdi2[*faceId+1]-rdi2[*faceId]==1)
1970 int tmp2[5]; tmp2[0]=-1; tmp2[1]=i;
1971 tmp2[2]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+0]-8]+offset0;
1972 tmp2[3]=d2[4*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+1]-4]+nbOfNodes;
1973 tmp2[4]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+2]-8]+offset0;
1974 cArr->insertAtTheEnd(tmp2,tmp2+5);
1980 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
1982 ret->setNodalConnectivity(cArr,ciArr);
1986 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh2D() const
1988 static const int DUAL_TRI_0[6]={0,2, 1,0, 2,1};
1989 static const int DUAL_TRI_1[6]={-3,+5, +3,-4, +4,-5};
1990 static const int FACEID_NOT_SH_NODE[3]={1,2,0};
1991 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TRI3)
1992 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh2D : only TRI3 supported !");
1993 checkFullyDefined();
1994 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured());
1995 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1996 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1997 const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1998 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1999 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
2000 const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
2001 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
2002 const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+edges->getNumberOfCells());
2004 std::vector<const DataArrayDouble *> v(3); v[0]=getCoords(); v[1]=edgesBaryArr; v[2]=baryArr;
2005 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0;
2006 std::string name("DualOf_"); name+=getName();
2007 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYGON)); ret->setCoords(zeArr);
2008 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
2009 for(int i=0;i<nbOfNodes;i++,revNodI++)
2011 int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
2012 if(nbOfCellsSharingNode==0)
2014 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh2D : Node #" << i << " is orphan !";
2015 throw INTERP_KERNEL::Exception(oss.str().c_str());
2017 std::vector< std::vector<int> > polyg;
2018 for(int j=0;j<nbOfCellsSharingNode;j++)
2020 int curCellId(revNod[revNodI[0]+j]);
2021 const int *connOfCurCell(nodal+3*curCellId);
2022 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
2023 std::vector<int> locV(3);
2024 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;
2025 polyg.push_back(locV);
2027 for(int k=0;k<3;k++)
2029 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
2031 const int *edgeId(d2+3*curCellId+k);
2032 if(rdi2[*edgeId+1]-rdi2[*edgeId]==1)
2034 std::vector<int> locV2(2);
2035 int zeLocEdgeIdRel(DUAL_TRI_1[2*nodePosInCurCell+kk]);
2036 if(zeLocEdgeIdRel>0)
2037 { locV2[0]=d2[3*curCellId+zeLocEdgeIdRel-3]+nbOfNodes; locV2[1]=i; }
2039 { locV2[0]=i; locV2[1]=d2[3*curCellId-zeLocEdgeIdRel-3]+nbOfNodes; }
2040 polyg.push_back(locV2);
2046 std::vector<int> zePolyg(MEDCoupling1DGTUMesh::BuildAPolygonFromParts(polyg));
2047 cArr->insertAtTheEnd(zePolyg.begin(),zePolyg.end());
2048 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
2050 ret->setNodalConnectivity(cArr,ciArr);
2055 * This method aggregate the bbox of each cell and put it into bbox
2057 * \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)
2058 * For all other cases this input parameter is ignored.
2059 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
2061 * \throw If \a this is not fully set (coordinates and connectivity).
2062 * \throw If a cell in \a this has no valid nodeId.
2064 DataArrayDouble *MEDCoupling1SGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
2066 int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()),nbOfNodesPerCell(getNumberOfNodesPerCell());
2067 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
2068 double *bbox(ret->getPointer());
2069 for(int i=0;i<nbOfCells*spaceDim;i++)
2071 bbox[2*i]=std::numeric_limits<double>::max();
2072 bbox[2*i+1]=-std::numeric_limits<double>::max();
2074 const double *coordsPtr(_coords->getConstPointer());
2075 const int *conn(_conn->getConstPointer());
2076 for(int i=0;i<nbOfCells;i++)
2079 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
2082 if(nodeId>=0 && nodeId<nbOfNodes)
2084 for(int k=0;k<spaceDim;k++)
2086 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
2087 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
2094 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
2095 throw INTERP_KERNEL::Exception(oss.str().c_str());
2103 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New()
2105 return new MEDCoupling1DGTUMesh;
2108 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
2110 if(type==INTERP_KERNEL::NORM_ERROR)
2111 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
2112 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
2115 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !";
2116 throw INTERP_KERNEL::Exception(oss.str().c_str());
2118 return new MEDCoupling1DGTUMesh(name,cm);
2121 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh()
2125 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
2129 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
2133 const DataArrayInt *c(other._conn);
2138 _conn_indx=c->deepCpy();
2142 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const
2144 return new MEDCoupling1DGTUMesh(*this,recDeepCpy);
2148 * This method behaves mostly like MEDCoupling1DGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
2149 * The coordinates are shared between \a this and the returned instance.
2151 * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
2152 * \sa MEDCoupling1DGTUMesh::deepCpy
2154 MEDCouplingPointSet *MEDCoupling1DGTUMesh::deepCpyConnectivityOnly() const
2157 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(clone(false));
2158 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy()),ci(_conn_indx->deepCpy());
2159 ret->setNodalConnectivity(c,ci);
2163 void MEDCoupling1DGTUMesh::updateTime() const
2165 MEDCoupling1GTUMesh::updateTime();
2166 const DataArrayInt *c(_conn);
2174 std::size_t MEDCoupling1DGTUMesh::getHeapMemorySizeWithoutChildren() const
2176 return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren();
2179 std::vector<const BigMemoryObject *> MEDCoupling1DGTUMesh::getDirectChildrenWithNull() const
2181 std::vector<const BigMemoryObject *> ret(MEDCoupling1GTUMesh::getDirectChildrenWithNull());
2182 ret.push_back((const DataArrayInt *)_conn);
2183 ret.push_back((const DataArrayInt *)_conn_indx);
2187 MEDCouplingMesh *MEDCoupling1DGTUMesh::deepCpy() const
2192 bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
2195 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !");
2196 std::ostringstream oss; oss.precision(15);
2197 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2200 reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !";
2203 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
2205 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2210 reason="in connectivity of single dynamic geometric type exactly one among this and other is null !";
2213 if(!c1->isEqualIfNotWhy(*c2,reason))
2215 reason.insert(0,"Nodal connectivity DataArrayInt differs : ");
2218 c1=_conn_indx; c2=otherC->_conn_indx;
2223 reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !";
2226 if(!c1->isEqualIfNotWhy(*c2,reason))
2228 reason.insert(0,"Nodal connectivity index DataArrayInt differs : ");
2234 bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
2237 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
2238 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2241 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
2243 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2248 if(!c1->isEqualWithoutConsideringStr(*c2))
2251 c1=_conn_indx; c2=otherC->_conn_indx;
2256 if(!c1->isEqualWithoutConsideringStr(*c2))
2262 * Checks if \a this and \a other meshes are geometrically equivalent with high
2263 * probability, else an exception is thrown. The meshes are considered equivalent if
2264 * (1) meshes contain the same number of nodes and the same number of elements of the
2265 * same types (2) three cells of the two meshes (first, last and middle) are based
2266 * on coincident nodes (with a specified precision).
2267 * \param [in] other - the mesh to compare with.
2268 * \param [in] prec - the precision used to compare nodes of the two meshes.
2269 * \throw If the two meshes do not match.
2271 void MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
2273 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
2274 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2276 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single dynamic geometric type !");
2277 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2281 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
2282 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2283 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
2284 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2285 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
2286 if(c1->getHashCode()!=c2->getHashCode())
2287 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs");
2289 c1=_conn_indx; c2=otherC->_conn_indx;
2293 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !");
2294 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2295 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !");
2296 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2297 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !");
2298 if(c1->getHashCode()!=c2->getHashCode())
2299 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs");
2303 void MEDCoupling1DGTUMesh::checkCoherencyOfConnectivity() const
2305 const DataArrayInt *c1(_conn);
2308 if(c1->getNumberOfComponents()!=1)
2309 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
2310 if(c1->getInfoOnComponent(0)!="")
2311 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
2312 c1->checkAllocated();
2315 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
2317 int sz2=_conn->getNumberOfTuples();
2321 if(c1->getNumberOfComponents()!=1)
2322 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
2323 c1->checkAllocated();
2324 if(c1->getNumberOfTuples()<1)
2325 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !");
2326 if(c1->getInfoOnComponent(0)!="")
2327 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
2328 int f=c1->front(),ll=c1->back();
2331 std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !";
2332 throw INTERP_KERNEL::Exception(oss.str().c_str());
2336 std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !";
2337 throw INTERP_KERNEL::Exception(oss.str().c_str());
2341 std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !";
2342 throw INTERP_KERNEL::Exception(oss.str().c_str());
2346 throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !");
2347 int szOfC1Exp=_conn_indx->back();
2350 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() << " !";
2351 throw INTERP_KERNEL::Exception(oss.str().c_str());
2356 * 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.
2357 * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one.
2358 * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array.
2360 void MEDCoupling1DGTUMesh::checkCoherency() const
2362 MEDCouplingPointSet::checkCoherency();
2363 checkCoherencyOfConnectivity();
2366 void MEDCoupling1DGTUMesh::checkCoherency1(double eps) const
2369 const DataArrayInt *c1(_conn),*c2(_conn_indx);
2370 if(!c2->isMonotonic(true))
2371 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkCoherency1 : the nodal connectivity index is expected to be increasing monotinic !");
2373 int nbOfTuples=c1->getNumberOfTuples();
2374 int nbOfNodes=getNumberOfNodes();
2375 const int *w(c1->begin());
2376 for(int i=0;i<nbOfTuples;i++,w++)
2378 if(*w==-1) continue;
2379 if(*w<0 || *w>=nbOfNodes)
2381 std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !";
2382 throw INTERP_KERNEL::Exception(oss.str().c_str());
2387 void MEDCoupling1DGTUMesh::checkCoherency2(double eps) const
2389 checkCoherency1(eps);
2392 int MEDCoupling1DGTUMesh::getNumberOfCells() const
2394 checkCoherencyOfConnectivity();//do not remove
2395 return _conn_indx->getNumberOfTuples()-1;
2399 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2400 * For each cell in \b this the number of nodes constituting cell is computed.
2401 * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned.
2402 * So for pohyhedrons some nodes can be counted several times in the returned result.
2404 * \return a newly allocated array
2406 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const
2409 _conn_indx->checkMonotonic(true);
2410 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2411 return _conn_indx->deltaShiftIndex();
2413 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2414 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2415 ret->alloc(nbOfCells,1);
2416 int *retPtr=ret->getPointer();
2417 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2418 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2419 *retPtr=ci[1]-ci[0]-std::count(c+ci[0],c+ci[1],-1);
2424 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2425 * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed.
2427 * \return a newly allocated array
2429 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const
2432 _conn_indx->checkMonotonic(true);
2433 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG)
2434 return _conn_indx->deltaShiftIndex();
2435 if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG)
2437 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=_conn_indx->deltaShiftIndex();
2438 ret->applyDivideBy(2);
2442 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2443 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2444 ret->alloc(nbOfCells,1);
2445 int *retPtr=ret->getPointer();
2446 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2447 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2448 *retPtr=std::count(c+ci[0],c+ci[1],-1)+1;
2453 * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell,
2454 * will be counted only once here whereas it will be counted several times in MEDCoupling1DGTUMesh::computeNbOfNodesPerCell method.
2456 * \return DataArrayInt * - new object to be deallocated by the caller.
2457 * \sa MEDCoupling1DGTUMesh::computeNbOfNodesPerCell
2459 DataArrayInt *MEDCoupling1DGTUMesh::computeEffectiveNbOfNodesPerCell() const
2462 _conn_indx->checkMonotonic(true);
2463 int nbOfCells(_conn_indx->getNumberOfTuples()-1);
2464 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2465 ret->alloc(nbOfCells,1);
2466 int *retPtr(ret->getPointer());
2467 const int *ci(_conn_indx->begin()),*c(_conn->begin());
2468 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2470 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2472 std::set<int> s(c+ci[0],c+ci[1]);
2473 *retPtr=(int)s.size();
2478 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2480 std::set<int> s(c+ci[0],c+ci[1]); s.erase(-1);
2481 *retPtr=(int)s.size();
2487 void MEDCoupling1DGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
2489 int nbOfCells(getNumberOfCells());//performs checks
2490 if(cellId>=0 && cellId<nbOfCells)
2492 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2493 int nbOfNodes=stp-strt;
2495 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !");
2496 conn.resize(nbOfNodes);
2497 std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin());
2501 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2502 throw INTERP_KERNEL::Exception(oss.str().c_str());
2506 int MEDCoupling1DGTUMesh::getNumberOfNodesInCell(int cellId) const
2508 int nbOfCells(getNumberOfCells());//performs checks
2509 if(cellId>=0 && cellId<nbOfCells)
2511 const int *conn(_conn->begin());
2512 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2513 return stp-strt-std::count(conn+strt,conn+stp,-1);
2517 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNumberOfNodesInCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2518 throw INTERP_KERNEL::Exception(oss.str().c_str());
2522 std::string MEDCoupling1DGTUMesh::simpleRepr() const
2524 static const char msg0[]="No coordinates specified !";
2525 std::ostringstream ret;
2526 ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
2527 ret << "Description of mesh : \"" << getDescription() << "\"\n";
2529 double tt=getTime(tmpp1,tmpp2);
2530 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
2531 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
2532 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
2535 const int spaceDim=getSpaceDimension();
2536 ret << spaceDim << "\nInfo attached on space dimension : ";
2537 for(int i=0;i<spaceDim;i++)
2538 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
2542 ret << msg0 << "\n";
2543 ret << "Number of nodes : ";
2545 ret << getNumberOfNodes() << "\n";
2547 ret << msg0 << "\n";
2548 ret << "Number of cells : ";
2550 try { checkCoherency(); } catch(INTERP_KERNEL::Exception& /* e */)
2552 ret << "Nodal connectivity arrays are not set or badly set !\n";
2556 ret << getNumberOfCells() << "\n";
2557 ret << "Cell type : " << _cm->getRepr() << "\n";
2561 std::string MEDCoupling1DGTUMesh::advancedRepr() const
2563 std::ostringstream ret;
2564 ret << simpleRepr();
2565 ret << "\nCoordinates array : \n___________________\n\n";
2567 _coords->reprWithoutNameStream(ret);
2569 ret << "No array set !\n";
2570 ret << "\n\nNodal Connectivity : \n____________________\n\n";
2573 try { checkCoherency1(); } catch(INTERP_KERNEL::Exception& /* e */)
2575 ret << "Nodal connectivity arrays are not set or badly set !\n";
2580 int nbOfCells=getNumberOfCells();
2581 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2582 for(int i=0;i<nbOfCells;i++,ci++)
2584 ret << "Cell #" << i << " : ";
2585 std::copy(c+ci[0],c+ci[1],std::ostream_iterator<int>(ret," "));
2591 DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const
2593 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
2594 int spaceDim=getSpaceDimension();
2595 int nbOfCells=getNumberOfCells();//checkCoherency()
2596 int nbOfNodes=getNumberOfNodes();
2597 ret->alloc(nbOfCells,spaceDim);
2598 double *ptToFill=ret->getPointer();
2599 const double *coor=_coords->begin();
2600 const int *nodal=_conn->begin(),*nodali=_conn_indx->begin();
2602 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2604 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2606 std::fill(ptToFill,ptToFill+spaceDim,0.);
2607 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2609 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2611 if(*nodal>=0 && *nodal<nbOfNodes)
2612 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2615 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2616 throw INTERP_KERNEL::Exception(oss.str().c_str());
2618 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(nodali[1]-nodali[0])));
2623 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !";
2624 throw INTERP_KERNEL::Exception(oss.str().c_str());
2630 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2632 std::fill(ptToFill,ptToFill+spaceDim,0.);
2633 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2636 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2638 if(*nodal==-1) continue;
2639 if(*nodal>=0 && *nodal<nbOfNodes)
2641 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2646 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2647 throw INTERP_KERNEL::Exception(oss.str().c_str());
2651 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./nbOfNod));
2654 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !";
2655 throw INTERP_KERNEL::Exception(oss.str().c_str());
2660 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : at cell #" << i << " the nodal index array is invalid !";
2661 throw INTERP_KERNEL::Exception(oss.str().c_str());
2668 void MEDCoupling1DGTUMesh::renumberCells(const int *old2NewBg, bool check)
2670 int nbCells=getNumberOfCells();
2671 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
2672 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
2674 o2n=o2n->checkAndPreparePermutation();
2676 const int *o2nPtr=o2n->getPointer();
2677 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2678 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
2679 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
2680 newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1);
2681 newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx);
2683 int *newC=newConn->getPointer(),*newCI=newConnI->getPointer();
2684 for(int i=0;i<nbCells;i++)
2686 int newPos=o2nPtr[i];
2687 int sz=conni[i+1]-conni[i];
2692 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !";
2693 throw INTERP_KERNEL::Exception(oss.str().c_str());
2696 newConnI->computeOffsets2(); newCI=newConnI->getPointer();
2698 for(int i=0;i<nbCells;i++,conni++)
2701 std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]);
2704 _conn_indx=newConnI;
2707 MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
2709 if(other->getType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED)
2710 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !");
2711 const MEDCoupling1DGTUMesh *otherC=static_cast<const MEDCoupling1DGTUMesh *>(other);
2712 return Merge1DGTUMeshes(this,otherC);
2715 MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const
2717 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
2718 ret->setCoords(getCoords());
2719 const int *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin();
2720 int nbCells=getNumberOfCells();//checkCoherency
2721 int geoType=(int)getCellModelEnum();
2722 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1);
2723 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::New(); cI->alloc(nbCells+1);
2724 int *cPtr=c->getPointer(),*ciPtr=cI->getPointer();
2726 for(int i=0;i<nbCells;i++,ciPtr++)
2728 int sz=nodalConnI[i+1]-nodalConnI[i];
2732 cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr);
2733 ciPtr[1]=ciPtr[0]+sz+1;
2737 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !";
2738 throw INTERP_KERNEL::Exception(oss.str().c_str());
2741 ret->setConnectivity(c,cI,true);
2743 { ret->copyTinyInfoFrom(this); }
2744 catch(INTERP_KERNEL::Exception&) { }
2749 * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes
2751 DataArrayInt *MEDCoupling1DGTUMesh::simplexize(int policy)
2753 int nbOfCells=getNumberOfCells();
2754 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2755 ret->alloc(nbOfCells,1);
2760 void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const
2762 stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
2763 stream << " Mesh dimension : " << getMeshDimension() << ".";
2765 { stream << " No coordinates set !"; return ; }
2766 if(!_coords->isAllocated())
2767 { stream << " Coordinates set but not allocated !"; return ; }
2768 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
2769 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
2771 try { checkCoherency(); } catch(INTERP_KERNEL::Exception& /* e */)
2773 stream << std::endl << "Nodal connectivity NOT set properly !\n";
2777 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
2780 void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
2783 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
2784 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2786 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !");
2787 setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex());
2790 MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
2793 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
2794 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2796 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
2797 std::vector<const MEDCoupling1DGTUMesh *> ms(2);
2800 return Merge1DGTUMeshesOnSameCoords(ms);
2803 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
2806 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2807 ret->setCoords(_coords);
2808 DataArrayInt *c=0,*ci=0;
2809 MEDCouplingUMesh::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci);
2810 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2811 ret->setNodalConnectivity(c,ci);
2815 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
2818 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2819 ret->setCoords(_coords);
2820 DataArrayInt *c=0,*ci=0;
2821 MEDCouplingUMesh::ExtractFromIndexedArrays2(start,end,step,_conn,_conn_indx,c,ci);
2822 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2823 ret->setNodalConnectivity(c,ci);
2827 void MEDCoupling1DGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
2830 int sz((int)nodeIdsInUse.size());
2831 for(const int *conn=_conn->begin();conn!=_conn->end();conn++)
2833 if(*conn>=0 && *conn<sz)
2834 nodeIdsInUse[*conn]=true;
2839 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeNodeIdsAlg : At pos #" << std::distance(_conn->begin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !";
2840 throw INTERP_KERNEL::Exception(oss.str().c_str());
2846 void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const
2848 checkFullyDefined();
2849 int nbOfNodes=getNumberOfNodes();
2850 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
2851 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
2852 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
2853 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2854 int nbOfCells=getNumberOfCells();
2855 int nbOfEltsInRevNodal=0;
2856 for(int eltId=0;eltId<nbOfCells;eltId++)
2858 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2859 if(nbOfNodesPerCell>=0)
2861 for(int j=0;j<nbOfNodesPerCell;j++)
2863 int nodeId=conn[conni[eltId]+j];
2864 if(nodeId==-1) continue;
2865 if(nodeId>=0 && nodeId<nbOfNodes)
2867 nbOfEltsInRevNodal++;
2868 revNodalIndxPtr[nodeId+1]++;
2872 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
2873 throw INTERP_KERNEL::Exception(oss.str().c_str());
2879 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << "nodal connectivity is invalid !";
2880 throw INTERP_KERNEL::Exception(oss.str().c_str());
2883 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
2884 conn=_conn->begin();
2885 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
2886 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
2887 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
2888 for(int eltId=0;eltId<nbOfCells;eltId++)
2890 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2891 for(int j=0;j<nbOfNodesPerCell;j++)
2893 int nodeId=conn[conni[eltId]+j];
2895 *std::find_if(revNodalPtr+revNodalIndxPtr[nodeId],revNodalPtr+revNodalIndxPtr[nodeId+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
2900 void MEDCoupling1DGTUMesh::checkFullyDefined() const
2902 if(!((const DataArrayInt *)_conn) || !((const DataArrayInt *)_conn_indx) || !((const DataArrayDouble *)_coords))
2903 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined.");
2906 bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
2908 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !");
2911 void MEDCoupling1DGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
2914 double time=getTime(it,order);
2915 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
2917 littleStrings.push_back(getName());
2918 littleStrings.push_back(getDescription());
2919 littleStrings.push_back(getTimeUnit());
2921 std::vector<std::string> littleStrings2,littleStrings3,littleStrings4;
2922 if((const DataArrayDouble *)_coords)
2923 _coords->getTinySerializationStrInformation(littleStrings2);
2924 if((const DataArrayInt *)_conn)
2925 _conn->getTinySerializationStrInformation(littleStrings3);
2926 if((const DataArrayInt *)_conn_indx)
2927 _conn_indx->getTinySerializationStrInformation(littleStrings4);
2928 int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size()),sz2((int)littleStrings4.size());
2929 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
2930 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
2931 littleStrings.insert(littleStrings.end(),littleStrings4.begin(),littleStrings4.end());
2933 tinyInfo.push_back(getCellModelEnum());
2934 tinyInfo.push_back(it);
2935 tinyInfo.push_back(order);
2936 std::vector<int> tinyInfo2,tinyInfo3,tinyInfo4;
2937 if((const DataArrayDouble *)_coords)
2938 _coords->getTinySerializationIntInformation(tinyInfo2);
2939 if((const DataArrayInt *)_conn)
2940 _conn->getTinySerializationIntInformation(tinyInfo3);
2941 if((const DataArrayInt *)_conn_indx)
2942 _conn_indx->getTinySerializationIntInformation(tinyInfo4);
2943 int sz3((int)tinyInfo2.size()),sz4((int)tinyInfo3.size()),sz5((int)tinyInfo4.size());
2944 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3); tinyInfo.push_back(sz4); tinyInfo.push_back(sz5);
2945 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
2946 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
2947 tinyInfo.insert(tinyInfo.end(),tinyInfo4.begin(),tinyInfo4.end());
2949 tinyInfoD.push_back(time);
2952 void MEDCoupling1DGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
2954 std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+tinyInfo[6]);
2955 std::vector<int> tinyInfo1(tinyInfo.begin()+9+tinyInfo[6],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]);
2956 std::vector<int> tinyInfo12(tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]+tinyInfo[8]);
2957 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(DataArrayInt::New()); p1->resizeForUnserialization(tinyInfo1);
2958 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(DataArrayInt::New()); p2->resizeForUnserialization(tinyInfo12);
2959 std::vector<const DataArrayInt *> v(2); v[0]=p1; v[1]=p2;
2960 p2=DataArrayInt::Aggregate(v);
2961 a2->resizeForUnserialization(tinyInfo2);
2962 a1->alloc(p2->getNbOfElems(),1);
2965 void MEDCoupling1DGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
2968 if((const DataArrayInt *)_conn)
2969 if(_conn->isAllocated())
2970 sz=_conn->getNbOfElems();
2971 if((const DataArrayInt *)_conn_indx)
2972 if(_conn_indx->isAllocated())
2973 sz+=_conn_indx->getNbOfElems();
2974 a1=DataArrayInt::New();
2976 int *work(a1->getPointer());
2977 if(sz!=0 && (const DataArrayInt *)_conn)
2978 work=std::copy(_conn->begin(),_conn->end(),a1->getPointer());
2979 if(sz!=0 && (const DataArrayInt *)_conn_indx)
2980 std::copy(_conn_indx->begin(),_conn_indx->end(),work);
2982 if((const DataArrayDouble *)_coords)
2983 if(_coords->isAllocated())
2984 sz=_coords->getNbOfElems();
2985 a2=DataArrayDouble::New();
2987 if(sz!=0 && (const DataArrayDouble *)_coords)
2988 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
2991 void MEDCoupling1DGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
2992 const std::vector<std::string>& littleStrings)
2994 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
2995 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
2996 setName(littleStrings[0]);
2997 setDescription(littleStrings[1]);
2998 setTimeUnit(littleStrings[2]);
2999 setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
3000 int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]),sz4(tinyInfo[7]),sz5(tinyInfo[8]);
3002 _coords=DataArrayDouble::New();
3003 std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+sz3);
3004 _coords->resizeForUnserialization(tinyInfo2);
3005 std::copy(a2->begin(),a2->end(),_coords->getPointer());
3006 _conn=DataArrayInt::New();
3007 std::vector<int> tinyInfo3(tinyInfo.begin()+9+sz3,tinyInfo.begin()+9+sz3+sz4);
3008 _conn->resizeForUnserialization(tinyInfo3);
3009 std::copy(a1->begin(),a1->begin()+_conn->getNbOfElems(),_conn->getPointer());
3010 _conn_indx=DataArrayInt::New();
3011 std::vector<int> tinyInfo4(tinyInfo.begin()+9+sz3+sz4,tinyInfo.begin()+9+sz3+sz4+sz5);
3012 _conn_indx->resizeForUnserialization(tinyInfo4);
3013 std::copy(a1->begin()+_conn->getNbOfElems(),a1->end(),_conn_indx->getPointer());
3014 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
3015 _coords->finishUnserialization(tinyInfo2,littleStrings2);
3016 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
3017 _conn->finishUnserialization(tinyInfo3,littleStrings3);
3018 std::vector<std::string> littleStrings4(littleStrings.begin()+3+sz0+sz1,littleStrings.begin()+3+sz0+sz1+sz2);
3019 _conn_indx->finishUnserialization(tinyInfo4,littleStrings4);
3023 * Finds nodes not used in any cell and returns an array giving a new id to every node
3024 * by excluding the unused nodes, for which the array holds -1. The result array is
3025 * a mapping in "Old to New" mode.
3026 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
3027 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
3028 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
3029 * if the node is unused or a new id else. The caller is to delete this
3030 * array using decrRef() as it is no more needed.
3031 * \throw If the coordinates array is not set.
3032 * \throw If the nodal connectivity of cells is not defined.
3033 * \throw If the nodal connectivity includes an invalid id.
3034 * \sa MEDCoupling1DGTUMesh::computeFetchedNodeIds
3036 DataArrayInt *MEDCoupling1DGTUMesh::computeFetchedNodeIds() const
3039 int nbNodes(getNumberOfNodes());
3040 std::vector<bool> fetchedNodes(nbNodes,false);
3041 computeNodeIdsAlg(fetchedNodes);
3042 int sz((int)std::count(fetchedNodes.begin(),fetchedNodes.end(),true));
3043 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
3044 int *retPtr(ret->getPointer());
3045 for(int i=0;i<nbNodes;i++)
3052 * Finds nodes not used in any cell and returns an array giving a new id to every node
3053 * by excluding the unused nodes, for which the array holds -1. The result array is
3054 * a mapping in "Old to New" mode.
3055 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
3056 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
3057 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
3058 * if the node is unused or a new id else. The caller is to delete this
3059 * array using decrRef() as it is no more needed.
3060 * \throw If the coordinates array is not set.
3061 * \throw If the nodal connectivity of cells is not defined.
3062 * \throw If the nodal connectivity includes an invalid id.
3063 * \sa MEDCoupling1DGTUMesh::computeFetchedNodeIds
3065 DataArrayInt *MEDCoupling1DGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
3068 int nbOfNodes=getNumberOfNodes();
3069 int nbOfCells=getNumberOfCells();//checkCoherency
3070 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
3071 ret->alloc(nbOfNodes,1);
3072 int *traducer=ret->getPointer();
3073 std::fill(traducer,traducer+nbOfNodes,-1);
3074 const int *conn=_conn->begin(),*conni(_conn_indx->begin());
3075 for(int i=0;i<nbOfCells;i++,conni++)
3077 int nbNodesPerCell=conni[1]-conni[0];
3078 for(int j=0;j<nbNodesPerCell;j++)
3080 int nodeId=conn[conni[0]+j];
3081 if(nodeId==-1) continue;
3082 if(nodeId>=0 && nodeId<nbOfNodes)
3086 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << nodeId << " not in [0," << nbOfNodes << ") !";
3087 throw INTERP_KERNEL::Exception(oss.str().c_str());
3091 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
3092 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
3097 * Same than renumberNodesInConn(const int *) except that here the format of old-to-new traducer is using map instead
3098 * of array. This method is dedicated for renumbering from a big set of nodes the a tiny set of nodes which is the case during extraction
3101 void MEDCoupling1DGTUMesh::renumberNodesInConn(const std::map<int,int>& newNodeNumbersO2N)
3103 getNumberOfCells();//only to check that all is well defined.
3105 int nbElemsIn(getNumberOfNodes()),nbOfTuples(_conn->getNumberOfTuples());
3106 int *pt(_conn->getPointer());
3107 for(int i=0;i<nbOfTuples;i++,pt++)
3109 if(*pt==-1) continue;
3110 if(*pt>=0 && *pt<nbElemsIn)
3112 std::map<int,int>::const_iterator it(newNodeNumbersO2N.find(*pt));
3113 if(it!=newNodeNumbersO2N.end())
3117 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : At pos #" << i << " of connectivity, node id is " << *pt << ". Not in keys of input map !";
3118 throw INTERP_KERNEL::Exception(oss.str().c_str());
3123 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
3124 throw INTERP_KERNEL::Exception(oss.str().c_str());
3132 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
3133 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
3134 * This method is a generalization of shiftNodeNumbersInConn().
3135 * \warning This method performs no check of validity of new ids. **Use it with care !**
3136 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
3137 * this->getNumberOfNodes(), in "Old to New" mode.
3138 * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
3139 * \throw If the nodal connectivity of cells is not defined.
3141 void MEDCoupling1DGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
3143 getNumberOfCells();//only to check that all is well defined.
3145 int nbElemsIn(getNumberOfNodes()),nbOfTuples(_conn->getNumberOfTuples());
3146 int *pt(_conn->getPointer());
3147 for(int i=0;i<nbOfTuples;i++,pt++)
3149 if(*pt==-1) continue;
3150 if(*pt>=0 && *pt<nbElemsIn)
3151 *pt=newNodeNumbersO2N[*pt];
3154 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
3155 throw INTERP_KERNEL::Exception(oss.str().c_str());
3163 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
3164 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
3165 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
3166 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
3168 * \param [in] begin input start of array of node ids.
3169 * \param [in] end input end of array of node ids.
3170 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
3171 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
3173 void MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
3175 int nbOfCells=getNumberOfCells();
3176 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
3178 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
3179 std::vector<bool> fastFinder(sz,false);
3180 for(const int *work=begin;work!=end;work++)
3181 if(*work>=0 && *work<sz)
3182 fastFinder[*work]=true;
3183 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
3184 for(int i=0;i<nbOfCells;i++,conni++)
3186 int ref=0,nbOfHit=0;
3187 int nbNodesPerCell=conni[1]-conni[0];
3188 if(nbNodesPerCell>=0)
3190 for(int j=0;j<nbNodesPerCell;j++)
3192 int nodeId=conn[conni[0]+j];
3196 if(fastFinder[nodeId])
3203 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !";
3204 throw INTERP_KERNEL::Exception(oss.str().c_str());
3206 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
3207 cellIdsKept->pushBackSilent(i);
3209 cellIdsKeptArr=cellIdsKept.retn();
3212 void MEDCoupling1DGTUMesh::allocateCells(int nbOfCells)
3215 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !");
3216 _conn=DataArrayInt::New();
3217 _conn->reserve(nbOfCells*3);
3218 _conn_indx=DataArrayInt::New();
3219 _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0);
3224 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
3226 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
3227 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
3228 * \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
3229 * attached to \a this.
3230 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
3232 void MEDCoupling1DGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd)
3234 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
3235 DataArrayInt *c(_conn),*c2(_conn_indx);
3239 if(pos==c->getNumberOfTuples())
3241 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
3242 c2->pushBackSilent(pos+sz);
3246 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !";
3247 throw INTERP_KERNEL::Exception(oss.str().c_str());
3251 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !");
3254 void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex)
3257 nodalConn->incrRef();
3260 nodalConnIndex->incrRef();
3261 _conn_indx=nodalConnIndex;
3266 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
3268 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivity() const
3270 const DataArrayInt *ret(_conn);
3271 return const_cast<DataArrayInt *>(ret);
3275 * \return DataArrayInt * - the internal reference to the nodal connectivity index. The caller is not reponsible to deallocate it.
3277 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const
3279 const DataArrayInt *ret(_conn_indx);
3280 return const_cast<DataArrayInt *>(ret);
3284 * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here".
3285 * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity).
3286 * 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.
3288 * 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.
3290 * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal
3291 * connectivity arrays are different (false)
3292 * \return a new object to be managed by the caller.
3294 * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked
3296 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const
3298 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3299 DataArrayInt *nc=0,*nci=0;
3300 isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci);
3301 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ncs(nc),ncis(nci);
3302 ret->_conn=ncs; ret->_conn_indx=ncis;
3303 ret->setCoords(getCoords());
3308 * This method allows to compute, if needed, the packed nodal connectivity pair.
3309 * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges convered by nodal connectivity index array.
3310 * 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.
3312 * 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)
3313 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3315 * 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
3318 * This method return 3 elements.
3319 * \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
3320 * this pointer can be seen as a new object, that is to managed by the caller.
3321 * \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
3322 * this pointer can be seen as a new object, that is to managed by the caller.
3323 * \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
3324 * output parameters are newly created objects.
3326 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
3328 bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const
3330 if(isPacked())//performs the checkCoherency
3332 const DataArrayInt *c0(_conn),*c1(_conn_indx);
3333 nodalConn=const_cast<DataArrayInt *>(c0); nodalConnIndx=const_cast<DataArrayInt *>(c1);
3334 nodalConn->incrRef(); nodalConnIndx->incrRef();
3337 int bg=_conn_indx->front(),end=_conn_indx->back();
3338 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nc(_conn->selectByTupleId2(bg,end,1));
3339 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nci(_conn_indx->deepCpy());
3340 nci->applyLin(1,-bg);
3341 nodalConn=nc.retn(); nodalConnIndx=nci.retn();
3346 * 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)
3347 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3348 * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned.
3349 * \return bool - true if \a this looks packed, false is not.
3351 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
3353 bool MEDCoupling1DGTUMesh::isPacked() const
3356 return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples();
3359 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2)
3361 std::vector<const MEDCoupling1DGTUMesh *> tmp(2);
3362 tmp[0]=const_cast<MEDCoupling1DGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1DGTUMesh *>(mesh2);
3363 return Merge1DGTUMeshes(tmp);
3366 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a)
3368 std::size_t sz=a.size();
3370 return Merge1DGTUMeshesLL(a);
3371 for(std::size_t ii=0;ii<sz;ii++)
3374 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::Merge1DGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
3375 throw INTERP_KERNEL::Exception(oss.str().c_str());
3377 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
3378 for(std::size_t ii=0;ii<sz;ii++)
3379 if(&(a[ii]->getCellModel())!=cm)
3380 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !");
3381 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > bb(sz);
3382 std::vector< const MEDCoupling1DGTUMesh * > aa(sz);
3384 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
3386 const MEDCoupling1DGTUMesh *cur=a[i];
3387 const DataArrayDouble *coo=cur->getCoords();
3389 spaceDim=coo->getNumberOfComponents();
3392 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !");
3393 for(std::size_t i=0;i<sz;i++)
3395 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
3398 return Merge1DGTUMeshesLL(aa);
3402 * \throw If presence of a null instance in the input vector \a a.
3403 * \throw If a is empty
3405 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a)
3408 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !");
3409 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3411 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !");
3412 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
3413 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3414 (*it)->getNumberOfCells();//to check that all is OK
3415 const DataArrayDouble *coords=(*it)->getCoords();
3416 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3418 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3419 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3421 for(int i=1;it!=a.end();i++,it++)
3424 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !");
3425 if(cm!=&((*it)->getCellModel()))
3426 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3427 (*it)->getNumberOfCells();//to check that all is OK
3428 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3429 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3430 if(coords!=(*it)->getCoords())
3431 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !");
3433 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3434 ret->setCoords(coords);
3435 ret->_conn=DataArrayInt::Aggregate(ncs);
3436 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3441 * 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)
3443 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a)
3446 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : input array must be NON EMPTY !");
3447 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
3448 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3449 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3450 std::vector<int> nbNodesPerElt(a.size());
3451 int nbOfCells=(*it)->getNumberOfCells();
3453 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3454 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3456 int prevNbOfNodes=(*it)->getNumberOfNodes();
3457 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3459 for(int i=1;it!=a.end();i++,it++)
3461 if(cm!=&((*it)->getCellModel()))
3462 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3463 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3464 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3465 nbOfCells+=(*it)->getNumberOfCells();
3466 nbNodesPerElt[i]=nbNodesPerElt[i-1]+prevNbOfNodes;
3467 prevNbOfNodes=(*it)->getNumberOfNodes();
3469 std::vector<const MEDCouplingPointSet *> aps(a.size());
3470 std::copy(a.begin(),a.end(),aps.begin());
3471 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
3472 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3473 ret->setCoords(pts);
3474 ret->_conn=AggregateNodalConnAndShiftNodeIds(ncs,nbNodesPerElt);
3475 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3479 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(int spaceDim) const
3481 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3482 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1,tmp2;
3483 const DataArrayInt *nodalConn(_conn),*nodalConnI(_conn_indx);
3486 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
3494 tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
3498 ret->_conn_indx=tmp2;
3502 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
3503 ret->setCoords(coords);
3506 ret->setCoords(_coords);
3511 * This method aggregate the bbox of each cell and put it into bbox parameter.
3513 * \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)
3514 * For all other cases this input parameter is ignored.
3515 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
3517 * \throw If \a this is not fully set (coordinates and connectivity).
3518 * \throw If a cell in \a this has no valid nodeId.
3520 DataArrayDouble *MEDCoupling1DGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
3522 checkFullyDefined();
3523 int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes());
3524 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
3525 double *bbox(ret->getPointer());
3526 for(int i=0;i<nbOfCells*spaceDim;i++)
3528 bbox[2*i]=std::numeric_limits<double>::max();
3529 bbox[2*i+1]=-std::numeric_limits<double>::max();
3531 const double *coordsPtr(_coords->getConstPointer());
3532 const int *conn(_conn->getConstPointer()),*connI(_conn_indx->getConstPointer());
3533 for(int i=0;i<nbOfCells;i++)
3535 int offset=connI[i];
3536 int nbOfNodesForCell(connI[i+1]-offset),kk(0);
3537 for(int j=0;j<nbOfNodesForCell;j++)
3539 int nodeId=conn[offset+j];
3540 if(nodeId>=0 && nodeId<nbOfNodes)
3542 for(int k=0;k<spaceDim;k++)
3544 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
3545 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
3552 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
3553 throw INTERP_KERNEL::Exception(oss.str().c_str());
3559 std::vector<int> MEDCoupling1DGTUMesh::BuildAPolygonFromParts(const std::vector< std::vector<int> >& parts)
3561 std::vector<int> ret;
3564 ret.insert(ret.end(),parts[0].begin(),parts[0].end());
3565 int ref(ret.back());
3566 std::size_t sz(parts.size()),nbh(1);
3567 std::vector<bool> b(sz,true); b[0]=false;
3571 for(;i<sz;i++) if(b[i] && parts[i].front()==ref) { ret.insert(ret.end(),parts[i].begin()+1,parts[i].end()); nbh++; break; }
3575 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::BuildAPolygonFromParts : the input vector is not a part of a single polygon !");
3577 if(ret.back()==ret.front())
3583 * This method performs an aggregation of \a nodalConns (as DataArrayInt::Aggregate does) but in addition of that a shift is applied on the
3584 * values contained in \a nodalConns using corresponding offset specified in input \a offsetInNodeIdsPerElt.
3585 * But it also manage the values -1, that have a semantic in MEDCoupling1DGTUMesh class (separator for polyhedron).
3587 * \param [in] nodalConns - a list of nodal connectivity arrays same size than \a offsetInNodeIdsPerElt.
3588 * \param [in] offsetInNodeIdsPerElt - a list of offsets to apply.
3589 * \return DataArrayInt * - A new object (to be managed by the caller) that is the result of the aggregation.
3590 * \throw If \a nodalConns or \a offsetInNodeIdsPerElt are empty.
3591 * \throw If \a nodalConns and \a offsetInNodeIdsPerElt have not the same size.
3592 * \throw If presence of null pointer in \a nodalConns.
3593 * \throw If presence of not allocated or array with not exactly one component in \a nodalConns.
3595 DataArrayInt *MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds(const std::vector<const DataArrayInt *>& nodalConns, const std::vector<int>& offsetInNodeIdsPerElt)
3597 std::size_t sz1(nodalConns.size()),sz2(offsetInNodeIdsPerElt.size());
3599 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : input vectors do not have the same size !");
3601 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : empty vectors in input !");
3603 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++)
3606 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of null pointer in input vector !");
3607 if(!(*it)->isAllocated())
3608 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of non allocated array in input vector !");
3609 if((*it)->getNumberOfComponents()!=1)
3610 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of array with not exactly one component !");
3611 nbOfTuples+=(*it)->getNumberOfTuples();
3613 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
3614 int *pt=ret->getPointer();
3616 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++,i++)
3618 int curNbt=(*it)->getNumberOfTuples();
3619 const int *inPt=(*it)->begin();
3620 int offset=offsetInNodeIdsPerElt[i];
3621 for(int j=0;j<curNbt;j++,pt++)
3632 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m)
3635 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh is null !");
3636 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
3638 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh must have exactly one geometric type !");
3639 int geoType((int)*gts.begin());
3640 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(m->getName(),*gts.begin()));
3641 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription());
3642 int nbCells(m->getNumberOfCells());
3643 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
3644 conn->alloc(m->getMeshLength()-nbCells,1); connI->alloc(nbCells+1,1);
3645 int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
3646 const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
3647 for(int i=0;i<nbCells;i++,ciin++,ci++)
3649 if(cin[ciin[0]]==geoType)
3651 if(ciin[1]-ciin[0]>=1)
3653 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
3654 ci[1]=ci[0]+ciin[1]-ciin[0]-1;
3658 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 !";
3659 throw INTERP_KERNEL::Exception(oss.str().c_str());
3664 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 !";
3665 throw INTERP_KERNEL::Exception(oss.str().c_str());
3668 ret->setNodalConnectivity(conn,connI);