1 // Copyright (C) 2007-2015 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"
27 #include "DiameterCalculator.hxx"
28 #include "InterpKernelAutoPtr.hxx"
30 using namespace ParaMEDMEM;
32 const int MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[6]={0,1,2,4,3,5};
34 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh():_cm(0)
38 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):_cm(&cm)
43 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const MEDCoupling1GTUMesh& other, bool recDeepCpy):MEDCouplingPointSet(other,recDeepCpy),_cm(other._cm)
47 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
49 if(type==INTERP_KERNEL::NORM_ERROR)
50 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
51 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
53 return MEDCoupling1SGTUMesh::New(name,type);
55 return MEDCoupling1DGTUMesh::New(name,type);
58 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const MEDCouplingUMesh *m)
61 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh is null !");
62 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
64 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh must have exactly one geometric type !");
65 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*gts.begin());
67 return MEDCoupling1SGTUMesh::New(m);
69 return MEDCoupling1DGTUMesh::New(m);
72 const INTERP_KERNEL::CellModel& MEDCoupling1GTUMesh::getCellModel() const
77 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getCellModelEnum() const
79 return _cm->getEnum();
82 int MEDCoupling1GTUMesh::getMeshDimension() const
84 return (int)_cm->getDimension();
88 * This method returns a newly allocated array containing cell ids (ascendingly sorted) whose geometric type are equal to type.
89 * This method does not throw exception if geometric type \a type is not in \a this.
90 * This method throws an INTERP_KERNEL::Exception if meshdimension of \b this is not equal to those of \b type.
91 * The coordinates array is not considered here.
93 * \param [in] type the geometric type
94 * \return cell ids in this having geometric type \a type.
96 DataArrayInt *MEDCoupling1GTUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
98 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
99 if(type==getCellModelEnum())
100 ret->alloc(getNumberOfCells(),1);
108 * Returns nb of cells having the geometric type \a type. No throw if no cells in \a this has the geometric type \a type.
110 int MEDCoupling1GTUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
112 return type==getCellModelEnum()?getNumberOfCells():0;
116 * Returns a type of a cell by its id.
117 * \param [in] cellId - the id of the cell of interest.
118 * \return INTERP_KERNEL::NormalizedCellType - enumeration item describing the cell type.
119 * \throw If \a cellId is invalid. Valid range is [0, \a this->getNumberOfCells() ).
121 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getTypeOfCell(int cellId) const
123 if(cellId>=0 && cellId<getNumberOfCells())
124 return getCellModelEnum();
125 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::getTypeOfCell : Requesting type of cell #" << cellId << " but it should be in [0," << getNumberOfCells() << ") !";
126 throw INTERP_KERNEL::Exception(oss.str().c_str());
130 * Returns a set of all cell types available in \a this mesh.
131 * \return std::set<INTERP_KERNEL::NormalizedCellType> - the set of cell types.
132 * \warning this method does not throw any exception even if \a this is not defined.
134 std::set<INTERP_KERNEL::NormalizedCellType> MEDCoupling1GTUMesh::getAllGeoTypes() const
136 std::set<INTERP_KERNEL::NormalizedCellType> ret;
137 ret.insert(getCellModelEnum());
142 * This method expects that \a this is sorted by types. If not an exception will be thrown.
143 * This method returns in the same format as code (see MEDCouplingUMesh::checkTypeConsistencyAndContig or MEDCouplingUMesh::splitProfilePerType) how
144 * \a this is composed in cell types.
145 * The returned array is of size 3*n where n is the number of different types present in \a this.
146 * For every k in [0,n] ret[3*k+2]==-1 because it has no sense here.
147 * This parameter is kept only for compatibility with other methode listed above.
149 std::vector<int> MEDCoupling1GTUMesh::getDistributionOfTypes() const
151 std::vector<int> ret(3);
152 ret[0]=(int)getCellModelEnum(); ret[1]=getNumberOfCells(); ret[2]=-1;
157 * 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.
158 * 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.
159 * This method has 1 input \a profile and 3 outputs \a code \a idsInPflPerType and \a idsPerType.
161 * \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.
162 * \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,
163 * \a idsInPflPerType[i] stores the tuple ids in \a profile that correspond to the geometric type code[3*i+0]
164 * \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.
165 * This vector can be empty in case of all geometric type cells are fully covered in ascending in the given input \a profile.
167 * \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.
169 * \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
172 * - Before \a this has 3 cells \a profile contains [0,1,2]
173 * - After \a code contains [NORM_...,nbCells,-1], \a idsInPflPerType [[0,1,2]] and \a idsPerType is empty <br>
176 * - Before \a this has 3 cells \a profile contains [1,2]
177 * - After \a code contains [NORM_...,nbCells,0], \a idsInPflPerType [[0,1]] and \a idsPerType is [[1,2]] <br>
180 void MEDCoupling1GTUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const
183 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile is NULL !");
184 if(profile->getNumberOfComponents()!=1)
185 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile should have exactly one component !");
186 int nbTuples=profile->getNumberOfTuples();
187 int nbOfCells=getNumberOfCells();
188 code.resize(3); idsInPflPerType.resize(1);
189 code[0]=(int)getCellModelEnum(); code[1]=nbTuples;
190 idsInPflPerType.resize(1);
191 if(profile->isIdentity() && nbTuples==nbOfCells)
194 idsInPflPerType[0]=const_cast<DataArrayInt *>(profile); idsInPflPerType[0]->incrRef();
199 profile->checkAllIdsInRange(0,nbOfCells);
200 idsPerType.resize(1);
201 idsPerType[0]=const_cast<DataArrayInt *>(profile); idsPerType[0]->incrRef();
202 idsInPflPerType[0]=DataArrayInt::Range(0,nbTuples,1);
206 * This method tries to minimize at most the number of deep copy.
207 * So if \a idsPerType is not empty it can be returned directly (without copy, but with ref count incremented) in return.
209 * \sa MEDCouplingUMesh::checkTypeConsistencyAndContig
211 DataArrayInt *MEDCoupling1GTUMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const
213 int nbOfCells=getNumberOfCells();
215 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : invalid input code should be exactly of size 3 !");
216 if(code[0]!=(int)getCellModelEnum())
218 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() << ") !";
219 throw INTERP_KERNEL::Exception(oss.str().c_str());
223 if(code[1]==nbOfCells)
227 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : mismatch between the number of cells in this (" << nbOfCells << ") and the number of non profile (" << code[1] << ") !";
228 throw INTERP_KERNEL::Exception(oss.str().c_str());
232 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : single geo type mesh ! 0 or -1 is expected at pos #2 of input code !");
233 if(idsPerType.size()!=1)
234 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input code points to DataArrayInt #0 whereas the size of idsPerType is not equal to 1 !");
235 const DataArrayInt *pfl=idsPerType[0];
237 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : the input code points to a NULL DataArrayInt at rank 0 !");
238 if(pfl->getNumberOfComponents()!=1)
239 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input profile should have exactly one component !");
240 pfl->checkAllIdsInRange(0,nbOfCells);
242 return const_cast<DataArrayInt *>(pfl);
245 void MEDCoupling1GTUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const
247 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
248 m->writeVTKLL(ofs,cellData,pointData,byteData);
251 std::string MEDCoupling1GTUMesh::getVTKDataSetType() const
253 return std::string("UnstructuredGrid");
256 std::string MEDCoupling1GTUMesh::getVTKFileExtension() const
258 return std::string("vtu");
261 std::size_t MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren() const
263 return MEDCouplingPointSet::getHeapMemorySizeWithoutChildren();
266 bool MEDCoupling1GTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
268 if(!MEDCouplingPointSet::isEqualIfNotWhy(other,prec,reason))
271 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualIfNotWhy : input other pointer is null !");
272 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
275 reason="mesh given in input is not castable in MEDCouplingSGTUMesh !";
280 reason="mismatch in geometric type !";
286 bool MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
288 if(!MEDCouplingPointSet::isEqualWithoutConsideringStr(other,prec))
291 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
292 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
300 void MEDCoupling1GTUMesh::checkCoherency() const
302 MEDCouplingPointSet::checkCoherency();
305 DataArrayDouble *MEDCoupling1GTUMesh::getBarycenterAndOwner() const
307 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
308 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=m->getBarycenterAndOwner();
312 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureField(bool isAbs) const
314 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
315 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureField(isAbs);
320 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureFieldOnNode(bool isAbs) const
322 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
323 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureFieldOnNode(isAbs);
331 int MEDCoupling1GTUMesh::getCellContainingPoint(const double *pos, double eps) const
333 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
334 return m->getCellContainingPoint(pos,eps);
337 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::buildOrthogonalField() const
339 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
340 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->buildOrthogonalField();
345 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const double *bbox, double eps) const
347 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
348 return m->getCellsInBoundingBox(bbox,eps);
351 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps)
353 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
354 return m->getCellsInBoundingBox(bbox,eps);
357 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const
359 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
360 return m->buildFacePartOfMySelfNode(start,end,fullyIn);
363 DataArrayInt *MEDCoupling1GTUMesh::findBoundaryNodes() const
365 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
366 return m->findBoundaryNodes();
369 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildBoundaryMesh(bool keepCoords) const
371 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
372 return m->buildBoundaryMesh(keepCoords);
375 void MEDCoupling1GTUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const
377 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
378 m->findCommonCells(compType,startCellId,commonCellsArr,commonCellsIArr);
381 int MEDCoupling1GTUMesh::getNodalConnectivityLength() const
383 const DataArrayInt *c1(getNodalConnectivity());
385 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : no connectivity set !");
386 if(c1->getNumberOfComponents()!=1)
387 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array set must have exactly one component !");
388 if(!c1->isAllocated())
389 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array must be allocated !");
390 return c1->getNumberOfTuples();
394 * This method aggregates all the meshes in \a parts to put them in a single unstructured mesh (those returned).
395 * The order of cells is the returned instance is those in the order of instances in \a parts.
397 * \param [in] parts - all not null parts of single geo type meshes to be aggreagated having the same mesh dimension and same coordinates.
398 * \return MEDCouplingUMesh * - new object to be dealt by the caller.
400 * \throw If one element is null in \a parts.
401 * \throw If not all the parts do not have the same mesh dimension.
402 * \throw If not all the parts do not share the same coordinates.
403 * \throw If not all the parts have their connectivity set properly.
404 * \throw If \a parts is empty.
406 MEDCouplingUMesh *MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh(const std::vector< const MEDCoupling1GTUMesh *>& parts)
409 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : input parts vector is empty !");
410 const MEDCoupling1GTUMesh *firstPart(parts[0]);
412 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : the first instance in input parts is null !");
413 const DataArrayDouble *coords(firstPart->getCoords());
414 int meshDim(firstPart->getMeshDimension());
415 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret(MEDCouplingUMesh::New(firstPart->getName(),meshDim)); ret->setDescription(firstPart->getDescription());
416 ret->setCoords(coords);
417 int nbOfCells(0),connSize(0);
418 for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
421 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of null pointer in input vector !");
422 if((*it)->getMeshDimension()!=meshDim)
423 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances in input vector must have same mesh dimension !");
424 if((*it)->getCoords()!=coords)
425 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances must share the same coordinates pointer !");
426 nbOfCells+=(*it)->getNumberOfCells();
427 connSize+=(*it)->getNodalConnectivityLength();
429 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
430 connI->alloc(nbOfCells+1,1); conn->alloc(connSize+nbOfCells,1);
431 int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
432 for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
434 int curNbCells((*it)->getNumberOfCells());
435 int geoType((int)(*it)->getCellModelEnum());
436 const int *cinPtr((*it)->getNodalConnectivity()->begin());
437 const MEDCoupling1SGTUMesh *ps(dynamic_cast<const MEDCoupling1SGTUMesh *>(*it));
438 const MEDCoupling1DGTUMesh *pd(dynamic_cast<const MEDCoupling1DGTUMesh *>(*it));
441 int nNodesPerCell(ps->getNumberOfNodesPerCell());
442 for(int i=0;i<curNbCells;i++,ci++,cinPtr+=nNodesPerCell)
445 c=std::copy(cinPtr,cinPtr+nNodesPerCell,c);
446 ci[1]=ci[0]+nNodesPerCell+1;
451 const int *ciinPtr(pd->getNodalConnectivityIndex()->begin());
452 for(int i=0;i<curNbCells;i++,ci++,ciinPtr++)
455 c=std::copy(cinPtr+ciinPtr[0],cinPtr+ciinPtr[1],c);
456 ci[1]=ci[0]+ciinPtr[1]-ciinPtr[0]+1;
460 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of instance which type is not in [MEDCoupling1SGTUMesh,MEDCoupling1DGTUMesh] !");
462 ret->setConnectivity(conn,connI,true);
468 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const MEDCoupling1SGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
472 const DataArrayInt *c(other._conn);
478 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
482 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh()
486 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New()
488 return new MEDCoupling1SGTUMesh;
491 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
493 if(type==INTERP_KERNEL::NORM_ERROR)
494 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
495 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
498 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New : the input geometric type " << cm.getRepr() << " is dynamic ! Only static types are allowed here !";
499 throw INTERP_KERNEL::Exception(oss.str().c_str());
501 return new MEDCoupling1SGTUMesh(name,cm);
504 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m)
507 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh is null !");
508 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
510 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh must have exactly one geometric type !");
511 int geoType((int)*gts.begin());
512 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(m->getName(),*gts.begin()));
513 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription());
514 int nbCells(m->getNumberOfCells());
515 int nbOfNodesPerCell(ret->getNumberOfNodesPerCell());
516 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()); conn->alloc(nbCells*nbOfNodesPerCell,1);
517 int *c(conn->getPointer());
518 const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
519 for(int i=0;i<nbCells;i++,ciin++)
521 if(cin[ciin[0]]==geoType)
523 if(ciin[1]-ciin[0]==nbOfNodesPerCell+1)
524 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
527 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 << ") !";
528 throw INTERP_KERNEL::Exception(oss.str().c_str());
533 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 !";
534 throw INTERP_KERNEL::Exception(oss.str().c_str());
537 ret->setNodalConnectivity(conn);
539 { ret->copyTinyInfoFrom(m); }
540 catch(INTERP_KERNEL::Exception&) { }
544 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::clone(bool recDeepCpy) const
546 return new MEDCoupling1SGTUMesh(*this,recDeepCpy);
550 * This method behaves mostly like MEDCoupling1SGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
551 * The coordinates are shared between \a this and the returned instance.
553 * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
554 * \sa MEDCoupling1SGTUMesh::deepCpy
556 MEDCouplingPointSet *MEDCoupling1SGTUMesh::deepCpyConnectivityOnly() const
559 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(clone(false));
560 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy());
561 ret->setNodalConnectivity(c);
565 void MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
568 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
569 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
571 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1SGTUMesh instance !");
572 setNodalConnectivity(otherC->getNodalConnectivity());
575 void MEDCoupling1SGTUMesh::updateTime() const
577 MEDCoupling1GTUMesh::updateTime();
578 const DataArrayInt *c(_conn);
583 std::size_t MEDCoupling1SGTUMesh::getHeapMemorySizeWithoutChildren() const
585 return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren();
588 std::vector<const BigMemoryObject *> MEDCoupling1SGTUMesh::getDirectChildrenWithNull() const
590 std::vector<const BigMemoryObject *> ret(MEDCoupling1GTUMesh::getDirectChildrenWithNull());
591 ret.push_back((const DataArrayInt *)_conn);
595 MEDCouplingMesh *MEDCoupling1SGTUMesh::deepCpy() const
600 bool MEDCoupling1SGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
603 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualIfNotWhy : input other pointer is null !");
604 std::ostringstream oss; oss.precision(15);
605 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
608 reason="mesh given in input is not castable in MEDCoupling1SGTUMesh !";
611 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
613 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
618 reason="in connectivity of single static geometric type exactly one among this and other is null !";
621 if(!c1->isEqualIfNotWhy(*c2,reason))
623 reason.insert(0,"Nodal connectivity DataArrayInt differ : ");
629 bool MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
632 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
633 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
636 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
638 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
643 if(!c1->isEqualWithoutConsideringStr(*c2))
648 void MEDCoupling1SGTUMesh::checkCoherencyOfConnectivity() const
650 const DataArrayInt *c1(_conn);
653 if(c1->getNumberOfComponents()!=1)
654 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
655 if(c1->getInfoOnComponent(0)!="")
656 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
657 c1->checkAllocated();
660 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
663 void MEDCoupling1SGTUMesh::checkCoherency() const
665 MEDCouplingPointSet::checkCoherency();
666 checkCoherencyOfConnectivity();
669 void MEDCoupling1SGTUMesh::checkCoherency1(double eps) const
672 const DataArrayInt *c1(_conn);
673 int nbOfTuples=c1->getNumberOfTuples();
674 int nbOfNodesPerCell=(int)_cm->getNumberOfNodes();
675 if(nbOfTuples%nbOfNodesPerCell!=0)
677 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 !";
678 throw INTERP_KERNEL::Exception(oss.str().c_str());
680 int nbOfNodes=getNumberOfNodes();
681 int nbOfCells=nbOfTuples/nbOfNodesPerCell;
682 const int *w(c1->begin());
683 for(int i=0;i<nbOfCells;i++)
684 for(int j=0;j<nbOfNodesPerCell;j++,w++)
686 if(*w<0 || *w>=nbOfNodes)
688 std::ostringstream oss; oss << "At node #" << j << " of cell #" << i << ", is equal to " << *w << " must be in [0," << nbOfNodes << ") !";
689 throw INTERP_KERNEL::Exception(oss.str().c_str());
694 void MEDCoupling1SGTUMesh::checkCoherency2(double eps) const
696 checkCoherency1(eps);
699 int MEDCoupling1SGTUMesh::getNumberOfCells() const
701 int nbOfTuples=getNodalConnectivityLength();
702 int nbOfNodesPerCell=getNumberOfNodesPerCell();
703 if(nbOfTuples%nbOfNodesPerCell!=0)
705 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 !";
706 throw INTERP_KERNEL::Exception(oss.str().c_str());
708 return nbOfTuples/nbOfNodesPerCell;
711 int MEDCoupling1SGTUMesh::getNumberOfNodesInCell(int cellId) const
713 return getNumberOfNodesPerCell();
716 int MEDCoupling1SGTUMesh::getNumberOfNodesPerCell() const
718 checkNonDynamicGeoType();
719 return (int)_cm->getNumberOfNodes();
722 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfNodesPerCell() const
724 checkNonDynamicGeoType();
725 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
726 ret->alloc(getNumberOfCells(),1);
727 ret->fillWithValue((int)_cm->getNumberOfNodes());
731 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfFacesPerCell() const
733 checkNonDynamicGeoType();
734 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
735 ret->alloc(getNumberOfCells(),1);
736 ret->fillWithValue((int)_cm->getNumberOfSons());
740 DataArrayInt *MEDCoupling1SGTUMesh::computeEffectiveNbOfNodesPerCell() const
742 checkNonDynamicGeoType();
743 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
744 int nbCells(getNumberOfCells());
745 ret->alloc(nbCells,1);
746 int *retPtr(ret->getPointer());
747 int nbNodesPerCell(getNumberOfNodesPerCell());
748 const int *conn(_conn->begin());
749 for(int i=0;i<nbCells;i++,conn+=nbNodesPerCell,retPtr++)
751 std::set<int> s(conn,conn+nbNodesPerCell);
752 *retPtr=(int)s.size();
757 void MEDCoupling1SGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
759 int sz=getNumberOfNodesPerCell();
761 if(cellId>=0 && cellId<getNumberOfCells())
762 std::copy(_conn->begin()+cellId*sz,_conn->begin()+(cellId+1)*sz,conn.begin());
765 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << getNumberOfCells() << ") !";
766 throw INTERP_KERNEL::Exception(oss.str().c_str());
770 void MEDCoupling1SGTUMesh::checkNonDynamicGeoType() const
773 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkNonDynamicGeoType : internal error ! the internal geo type is dynamic ! should be static !");
776 std::string MEDCoupling1SGTUMesh::simpleRepr() const
778 static const char msg0[]="No coordinates specified !";
779 std::ostringstream ret;
780 ret << "Single static geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
781 ret << "Description of mesh : \"" << getDescription() << "\"\n";
783 double tt=getTime(tmpp1,tmpp2);
784 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
785 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
786 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
789 const int spaceDim=getSpaceDimension();
790 ret << spaceDim << "\nInfo attached on space dimension : ";
791 for(int i=0;i<spaceDim;i++)
792 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
797 ret << "Number of nodes : ";
799 ret << getNumberOfNodes() << "\n";
802 ret << "Number of cells : ";
803 if((const DataArrayInt *)_conn)
805 if(_conn->isAllocated())
807 if(_conn->getNumberOfComponents()==1)
808 ret << getNumberOfCells() << "\n";
810 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
813 ret << "Nodal connectivity array specified but not allocated !" << "\n";
816 ret << "No connectivity specified !" << "\n";
817 ret << "Cell type : " << _cm->getRepr() << "\n";
821 std::string MEDCoupling1SGTUMesh::advancedRepr() const
823 std::ostringstream ret;
825 ret << "\nCoordinates array : \n___________________\n\n";
827 _coords->reprWithoutNameStream(ret);
829 ret << "No array set !\n";
830 ret << "\n\nConnectivity array : \n____________________\n\n";
832 if((const DataArrayInt *)_conn)
834 if(_conn->isAllocated())
836 if(_conn->getNumberOfComponents()==1)
838 int nbOfCells=getNumberOfCells();
839 int sz=getNumberOfNodesPerCell();
840 const int *connPtr=_conn->begin();
841 for(int i=0;i<nbOfCells;i++,connPtr+=sz)
843 ret << "Cell #" << i << " : ";
844 std::copy(connPtr,connPtr+sz,std::ostream_iterator<int>(ret," "));
849 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
852 ret << "Nodal connectivity array specified but not allocated !" << "\n";
855 ret << "No connectivity specified !" << "\n";
859 DataArrayDouble *MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell() const
861 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
862 int spaceDim=getSpaceDimension();
863 int nbOfCells=getNumberOfCells();//checkCoherency()
864 int nbOfNodes=getNumberOfNodes();
865 ret->alloc(nbOfCells,spaceDim);
866 double *ptToFill=ret->getPointer();
867 const double *coor=_coords->begin();
868 const int *nodal=_conn->begin();
869 int sz=getNumberOfNodesPerCell();
870 double coeff=1./(double)sz;
871 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim)
873 std::fill(ptToFill,ptToFill+spaceDim,0.);
874 for(int j=0;j<sz;j++,nodal++)
875 if(*nodal>=0 && *nodal<nbOfNodes)
876 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
879 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
880 throw INTERP_KERNEL::Exception(oss.str().c_str());
882 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),coeff));
887 void MEDCoupling1SGTUMesh::renumberCells(const int *old2NewBg, bool check)
889 int nbCells=getNumberOfCells();
890 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
891 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
893 o2n=o2n->checkAndPreparePermutation();
895 const int *conn=_conn->begin();
896 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o=o2n->invertArrayO2N2N2O(nbCells);
897 const int *n2oPtr=n2o->begin();
898 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
899 newConn->alloc(_conn->getNumberOfTuples(),1);
900 newConn->copyStringInfoFrom(*_conn);
901 int sz=getNumberOfNodesPerCell();
903 int *newC=newConn->getPointer();
904 for(int i=0;i<nbCells;i++,newC+=sz)
907 std::copy(conn+pos*sz,conn+(pos+1)*sz,newC);
913 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
914 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
915 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
916 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
918 * \param [in] begin input start of array of node ids.
919 * \param [in] end input end of array of node ids.
920 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
921 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
923 void MEDCoupling1SGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
925 int nbOfCells=getNumberOfCells();
926 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
928 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
929 std::vector<bool> fastFinder(sz,false);
930 for(const int *work=begin;work!=end;work++)
931 if(*work>=0 && *work<sz)
932 fastFinder[*work]=true;
933 const int *conn=_conn->begin();
934 int nbNodesPerCell=getNumberOfNodesPerCell();
935 for(int i=0;i<nbOfCells;i++,conn+=nbNodesPerCell)
938 for(int j=0;j<nbNodesPerCell;j++)
942 if(fastFinder[conn[j]])
945 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
946 cellIdsKept->pushBackSilent(i);
948 cellIdsKeptArr=cellIdsKept.retn();
951 MEDCouplingMesh *MEDCoupling1SGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
953 if(other->getType()!=SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED)
954 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single static geo type each other !");
955 const MEDCoupling1SGTUMesh *otherC=static_cast<const MEDCoupling1SGTUMesh *>(other);
956 return Merge1SGTUMeshes(this,otherC);
959 MEDCouplingUMesh *MEDCoupling1SGTUMesh::buildUnstructured() const
961 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
962 ret->setCoords(getCoords());
963 const int *nodalConn=_conn->begin();
964 int nbCells=getNumberOfCells();
965 int nbNodesPerCell=getNumberOfNodesPerCell();
966 int geoType=(int)getCellModelEnum();
967 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells*(nbNodesPerCell+1),1);
968 int *cPtr=c->getPointer();
969 for(int i=0;i<nbCells;i++,nodalConn+=nbNodesPerCell)
972 cPtr=std::copy(nodalConn,nodalConn+nbNodesPerCell,cPtr);
974 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::Range(0,(nbCells+1)*(nbNodesPerCell+1),nbNodesPerCell+1);
975 ret->setConnectivity(c,cI,true);
977 { ret->copyTinyInfoFrom(this); }
978 catch(INTERP_KERNEL::Exception&) { }
982 DataArrayInt *MEDCoupling1SGTUMesh::simplexize(int policy)
987 return simplexizePol0();
989 return simplexizePol1();
990 case (int) INTERP_KERNEL::PLANAR_FACE_5:
991 return simplexizePlanarFace5();
992 case (int) INTERP_KERNEL::PLANAR_FACE_6:
993 return simplexizePlanarFace6();
995 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)");
1001 struct MEDCouplingAccVisit
1003 MEDCouplingAccVisit():_new_nb_of_nodes(0) { }
1004 int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; }
1005 int _new_nb_of_nodes;
1011 * This method returns all node ids used in \b this. The data array returned has to be dealt by the caller.
1012 * The returned node ids are sortes ascendingly. This method is closed to MEDCoupling1SGTUMesh::getNodeIdsInUse except
1013 * the format of returned DataArrayInt instance.
1015 * \return a newly allocated DataArrayInt sorted ascendingly of fetched node ids.
1016 * \sa MEDCoupling1SGTUMesh::getNodeIdsInUse, areAllNodesFetched
1018 DataArrayInt *MEDCoupling1SGTUMesh::computeFetchedNodeIds() const
1020 checkCoherencyOfConnectivity();
1021 int nbNodes(getNumberOfNodes());
1022 std::vector<bool> fetchedNodes(nbNodes,false);
1023 computeNodeIdsAlg(fetchedNodes);
1024 int sz((int)std::count(fetchedNodes.begin(),fetchedNodes.end(),true));
1025 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
1026 int *retPtr(ret->getPointer());
1027 for(int i=0;i<nbNodes;i++)
1034 * Finds nodes not used in any cell and returns an array giving a new id to every node
1035 * by excluding the unused nodes, for which the array holds -1. The result array is
1036 * a mapping in "Old to New" mode.
1037 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
1038 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
1039 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
1040 * if the node is unused or a new id else. The caller is to delete this
1041 * array using decrRef() as it is no more needed.
1042 * \throw If the coordinates array is not set.
1043 * \throw If the nodal connectivity of cells is not defined.
1044 * \throw If the nodal connectivity includes an invalid id.
1045 * \sa MEDCoupling1SGTUMesh::computeFetchedNodeIds, areAllNodesFetched
1047 DataArrayInt *MEDCoupling1SGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
1050 int nbOfNodes=getNumberOfNodes();
1051 int nbOfCells=getNumberOfCells();
1052 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
1053 ret->alloc(nbOfNodes,1);
1054 int *traducer=ret->getPointer();
1055 std::fill(traducer,traducer+nbOfNodes,-1);
1056 const int *conn=_conn->begin();
1057 int nbNodesPerCell=getNumberOfNodesPerCell();
1058 for(int i=0;i<nbOfCells;i++)
1059 for(int j=0;j<nbNodesPerCell;j++,conn++)
1060 if(*conn>=0 && *conn<nbOfNodes)
1064 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << conn[j] << " not in [0," << nbOfNodes << ") !";
1065 throw INTERP_KERNEL::Exception(oss.str().c_str());
1067 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
1068 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
1073 * This method renumbers only nodal connectivity in \a this. The renumbering is only an offset applied. So this method is a specialization of
1074 * \a renumberNodesInConn. \b WARNING, this method does not check that the resulting node ids in the nodal connectivity is in a valid range !
1076 * \param [in] offset - specifies the offset to be applied on each element of connectivity.
1078 * \sa renumberNodesInConn
1080 void MEDCoupling1SGTUMesh::renumberNodesWithOffsetInConn(int offset)
1082 getNumberOfCells();//only to check that all is well defined.
1083 _conn->applyLin(1,offset);
1088 * Same than renumberNodesInConn(const int *) except that here the format of old-to-new traducer is using map instead
1089 * 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
1092 void MEDCoupling1SGTUMesh::renumberNodesInConn(const INTERP_KERNEL::HashMap<int,int>& newNodeNumbersO2N)
1094 getNumberOfCells();//only to check that all is well defined.
1095 int *begPtr(_conn->getPointer());
1096 int nbElt(_conn->getNumberOfTuples());
1097 int *endPtr(begPtr+nbElt);
1098 for(int *it=begPtr;it!=endPtr;it++)
1100 INTERP_KERNEL::HashMap<int,int>::const_iterator it2(newNodeNumbersO2N.find(*it));
1101 if(it2!=newNodeNumbersO2N.end())
1107 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::renumberNodesInConn : At pos #" << std::distance(begPtr,it) << " of nodal connectivity value is " << *it << ". Not in map !";
1108 throw INTERP_KERNEL::Exception(oss.str().c_str());
1115 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
1116 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
1117 * This method is a generalization of shiftNodeNumbersInConn().
1118 * \warning This method performs no check of validity of new ids. **Use it with care !**
1119 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
1120 * this->getNumberOfNodes(), in "Old to New" mode.
1121 * See \ref numbering for more info on renumbering modes.
1122 * \throw If the nodal connectivity of cells is not defined.
1124 void MEDCoupling1SGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
1126 getNumberOfCells();//only to check that all is well defined.
1127 _conn->transformWithIndArr(newNodeNumbersO2N,newNodeNumbersO2N+getNumberOfNodes());
1131 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2)
1133 std::vector<const MEDCoupling1SGTUMesh *> tmp(2);
1134 tmp[0]=const_cast<MEDCoupling1SGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1SGTUMesh *>(mesh2);
1135 return Merge1SGTUMeshes(tmp);
1138 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(std::vector<const MEDCoupling1SGTUMesh *>& a)
1140 std::size_t sz=a.size();
1142 return Merge1SGTUMeshesLL(a);
1143 for(std::size_t ii=0;ii<sz;ii++)
1146 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::Merge1SGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
1147 throw INTERP_KERNEL::Exception(oss.str().c_str());
1149 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
1150 for(std::size_t ii=0;ii<sz;ii++)
1151 if(&(a[ii]->getCellModel())!=cm)
1152 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : all items must have the same geo type !");
1153 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> > bb(sz);
1154 std::vector< const MEDCoupling1SGTUMesh * > aa(sz);
1156 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
1158 const MEDCoupling1SGTUMesh *cur=a[i];
1159 const DataArrayDouble *coo=cur->getCoords();
1161 spaceDim=coo->getNumberOfComponents();
1164 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : no spaceDim specified ! unable to perform merge !");
1165 for(std::size_t i=0;i<sz;i++)
1167 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
1170 return Merge1SGTUMeshesLL(aa);
1174 * \throw If presence of a null instance in the input vector \a a.
1175 * \throw If a is empty
1177 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::vector<const MEDCoupling1SGTUMesh *>& a)
1180 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : input array must be NON EMPTY !");
1181 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1183 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : null instance in the first element of input vector !");
1184 std::vector<const DataArrayInt *> ncs(a.size());
1185 (*it)->getNumberOfCells();//to check that all is OK
1186 const DataArrayDouble *coords=(*it)->getCoords();
1187 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1188 ncs[0]=(*it)->getNodalConnectivity();
1190 for(int i=1;it!=a.end();i++,it++)
1193 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : presence of a null instance in the input vector !");
1194 if(cm!=&((*it)->getCellModel()))
1195 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1196 (*it)->getNumberOfCells();//to check that all is OK
1197 ncs[i]=(*it)->getNodalConnectivity();
1198 if(coords!=(*it)->getCoords())
1199 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : not lying on same coords !");
1201 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1202 ret->setCoords(coords);
1203 ret->_conn=DataArrayInt::Aggregate(ncs);
1208 * 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)
1210 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector<const MEDCoupling1SGTUMesh *>& a)
1213 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : input array must be NON EMPTY !");
1214 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1215 int nbOfCells=(*it)->getNumberOfCells();
1216 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1217 int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
1219 for(;it!=a.end();it++)
1221 if(cm!=&((*it)->getCellModel()))
1222 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1223 nbOfCells+=(*it)->getNumberOfCells();
1225 std::vector<const MEDCouplingPointSet *> aps(a.size());
1226 std::copy(a.begin(),a.end(),aps.begin());
1227 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
1228 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1229 ret->setCoords(pts);
1230 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New();
1231 c->alloc(nbOfCells*nbNodesPerCell,1);
1232 int *cPtr=c->getPointer();
1234 for(it=a.begin();it!=a.end();it++)
1236 int curConnLgth=(*it)->getNodalConnectivityLength();
1237 const int *curC=(*it)->_conn->begin();
1238 cPtr=std::transform(curC,curC+curConnLgth,cPtr,std::bind2nd(std::plus<int>(),offset));
1239 offset+=(*it)->getNumberOfNodes();
1242 ret->setNodalConnectivity(c);
1246 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
1248 int ncell=getNumberOfCells();
1249 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1250 ret->setCoords(_coords);
1251 std::size_t nbOfElemsRet=std::distance(begin,end);
1252 const int *inConn=_conn->getConstPointer();
1253 int sz=getNumberOfNodesPerCell();
1254 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1255 int *connPtr=connRet->getPointer();
1256 for(const int *work=begin;work!=end;work++,connPtr+=sz)
1258 if(*work>=0 && *work<ncell)
1259 std::copy(inConn+(work[0])*sz,inConn+(work[0]+1)*sz,connPtr);
1262 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !";
1263 throw INTERP_KERNEL::Exception(oss.str().c_str());
1267 ret->copyTinyInfoFrom(this);
1271 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
1273 int ncell=getNumberOfCells();
1274 int nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : ");
1275 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1276 ret->setCoords(_coords);
1277 const int *inConn=_conn->getConstPointer();
1278 int sz=getNumberOfNodesPerCell();
1279 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1280 int *connPtr=connRet->getPointer();
1282 for(int i=0;i<nbOfElemsRet;i++,connPtr+=sz,curId+=step)
1284 if(curId>=0 && curId<ncell)
1285 std::copy(inConn+curId*sz,inConn+(curId+1)*sz,connPtr);
1288 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : On pos #" << i << " input cell id =" << curId << " should be in [0," << ncell << ") !";
1289 throw INTERP_KERNEL::Exception(oss.str().c_str());
1293 ret->copyTinyInfoFrom(this);
1297 void MEDCoupling1SGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
1299 int sz((int)nodeIdsInUse.size());
1300 for(const int *conn=_conn->begin();conn!=_conn->end();conn++)
1302 if(*conn>=0 && *conn<sz)
1303 nodeIdsInUse[*conn]=true;
1306 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeFetchedNodeIds : At pos #" << std::distance(_conn->begin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !";
1307 throw INTERP_KERNEL::Exception(oss.str().c_str());
1312 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(int spaceDim) const
1314 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1315 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1;
1316 const DataArrayInt *nodalConn(_conn);
1319 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
1326 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
1327 ret->setCoords(coords);
1330 ret->setCoords(_coords);
1334 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol0()
1336 int nbOfCells=getNumberOfCells();
1337 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1338 return DataArrayInt::Range(0,nbOfCells,1);
1339 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1340 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1341 const int *c(_conn->begin());
1342 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1343 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1345 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[2];
1346 newConnPtr[3]=c[0]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1347 retPtr[0]=i; retPtr[1]=i;
1350 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1355 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol1()
1357 int nbOfCells=getNumberOfCells();
1358 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1359 return DataArrayInt::Range(0,nbOfCells,1);
1360 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1361 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1362 const int *c(_conn->begin());
1363 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1364 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1366 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[3];
1367 newConnPtr[3]=c[1]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1368 retPtr[0]=i; retPtr[1]=i;
1371 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1376 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace5()
1378 int nbOfCells=getNumberOfCells();
1379 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1380 return DataArrayInt::Range(0,nbOfCells,1);
1381 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(5*4*nbOfCells,1);
1382 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(5*nbOfCells,1);
1383 const int *c(_conn->begin());
1384 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1385 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=20,retPtr+=5)
1387 for(int j=0;j<20;j++)
1388 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_5_WO[j]];
1389 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i;
1392 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1397 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace6()
1399 int nbOfCells=getNumberOfCells();
1400 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1401 return DataArrayInt::Range(0,nbOfCells,1);
1402 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(6*4*nbOfCells,1);
1403 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(6*nbOfCells,1);
1404 const int *c(_conn->begin());
1405 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1406 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=24,retPtr+=6)
1408 for(int j=0;j<24;j++)
1409 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_6_WO[j]];
1410 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i; retPtr[5]=i;
1413 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1418 void MEDCoupling1SGTUMesh::reprQuickOverview(std::ostream& stream) const
1420 stream << "MEDCoupling1SGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
1421 stream << " Mesh dimension : " << getMeshDimension() << ".";
1423 { stream << " No coordinates set !"; return ; }
1424 if(!_coords->isAllocated())
1425 { stream << " Coordinates set but not allocated !"; return ; }
1426 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
1427 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
1428 if(!(const DataArrayInt *)_conn)
1429 { stream << std::endl << "Nodal connectivity NOT set !"; return ; }
1430 if(_conn->isAllocated())
1432 if(_conn->getNumberOfComponents()==1)
1433 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
1437 void MEDCoupling1SGTUMesh::checkFullyDefined() const
1439 if(!((const DataArrayInt *)_conn) || !((const DataArrayDouble *)_coords))
1440 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFullyDefined : part of this is not fully defined.");
1444 * First step of unserialization process.
1446 bool MEDCoupling1SGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
1448 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEmptyMesh : not implemented yet !");
1451 void MEDCoupling1SGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
1454 double time=getTime(it,order);
1455 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
1457 littleStrings.push_back(getName());
1458 littleStrings.push_back(getDescription());
1459 littleStrings.push_back(getTimeUnit());
1461 std::vector<std::string> littleStrings2,littleStrings3;
1462 if((const DataArrayDouble *)_coords)
1463 _coords->getTinySerializationStrInformation(littleStrings2);
1464 if((const DataArrayInt *)_conn)
1465 _conn->getTinySerializationStrInformation(littleStrings3);
1466 int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size());
1467 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
1468 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
1470 tinyInfo.push_back(getCellModelEnum());
1471 tinyInfo.push_back(it);
1472 tinyInfo.push_back(order);
1473 std::vector<int> tinyInfo2,tinyInfo3;
1474 if((const DataArrayDouble *)_coords)
1475 _coords->getTinySerializationIntInformation(tinyInfo2);
1476 if((const DataArrayInt *)_conn)
1477 _conn->getTinySerializationIntInformation(tinyInfo3);
1478 int sz2((int)tinyInfo2.size()),sz3((int)tinyInfo3.size());
1479 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3);
1480 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1481 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
1483 tinyInfoD.push_back(time);
1486 void MEDCoupling1SGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
1488 std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+tinyInfo[5]);
1489 std::vector<int> tinyInfo1(tinyInfo.begin()+7+tinyInfo[5],tinyInfo.begin()+7+tinyInfo[5]+tinyInfo[6]);
1490 a1->resizeForUnserialization(tinyInfo1);
1491 a2->resizeForUnserialization(tinyInfo2);
1494 void MEDCoupling1SGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
1497 if((const DataArrayInt *)_conn)
1498 if(_conn->isAllocated())
1499 sz=_conn->getNbOfElems();
1500 a1=DataArrayInt::New();
1502 if(sz!=0 && (const DataArrayInt *)_conn)
1503 std::copy(_conn->begin(),_conn->end(),a1->getPointer());
1505 if((const DataArrayDouble *)_coords)
1506 if(_coords->isAllocated())
1507 sz=_coords->getNbOfElems();
1508 a2=DataArrayDouble::New();
1510 if(sz!=0 && (const DataArrayDouble *)_coords)
1511 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
1514 void MEDCoupling1SGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
1515 const std::vector<std::string>& littleStrings)
1517 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
1518 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
1519 setName(littleStrings[0]);
1520 setDescription(littleStrings[1]);
1521 setTimeUnit(littleStrings[2]);
1522 setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
1523 int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]);
1525 _coords=DataArrayDouble::New();
1526 std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+sz2);
1527 _coords->resizeForUnserialization(tinyInfo2);
1528 std::copy(a2->begin(),a2->end(),_coords->getPointer());
1529 _conn=DataArrayInt::New();
1530 std::vector<int> tinyInfo3(tinyInfo.begin()+7+sz2,tinyInfo.begin()+7+sz2+sz3);
1531 _conn->resizeForUnserialization(tinyInfo3);
1532 std::copy(a1->begin(),a1->end(),_conn->getPointer());
1533 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
1534 _coords->finishUnserialization(tinyInfo2,littleStrings2);
1535 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
1536 _conn->finishUnserialization(tinyInfo3,littleStrings3);
1540 * Checks if \a this and \a other meshes are geometrically equivalent with high
1541 * probability, else an exception is thrown. The meshes are considered equivalent if
1542 * (1) meshes contain the same number of nodes and the same number of elements of the
1543 * same types (2) three cells of the two meshes (first, last and middle) are based
1544 * on coincident nodes (with a specified precision).
1545 * \param [in] other - the mesh to compare with.
1546 * \param [in] prec - the precision used to compare nodes of the two meshes.
1547 * \throw If the two meshes do not match.
1549 void MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
1551 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1552 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1554 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single static geometric type !");
1555 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1559 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1560 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1561 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1562 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1563 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1564 if(c1->getHashCode()!=c2->getHashCode())
1565 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1568 MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
1571 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
1572 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1574 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
1575 std::vector<const MEDCoupling1SGTUMesh *> ms(2);
1578 return Merge1SGTUMeshesOnSameCoords(ms);
1581 void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const
1583 checkFullyDefined();
1584 int nbOfNodes=getNumberOfNodes();
1585 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
1586 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
1587 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
1588 const int *conn=_conn->begin();
1589 int nbOfCells=getNumberOfCells();
1590 int nbOfEltsInRevNodal=0;
1591 int nbOfNodesPerCell=getNumberOfNodesPerCell();
1592 for(int eltId=0;eltId<nbOfCells;eltId++)
1594 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1596 if(conn[0]>=0 && conn[0]<nbOfNodes)
1598 nbOfEltsInRevNodal++;
1599 revNodalIndxPtr[conn[0]+1]++;
1603 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
1604 throw INTERP_KERNEL::Exception(oss.str().c_str());
1608 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
1609 conn=_conn->begin();
1610 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
1611 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
1612 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
1613 for(int eltId=0;eltId<nbOfCells;eltId++)
1615 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1617 *std::find_if(revNodalPtr+revNodalIndxPtr[*conn],revNodalPtr+revNodalIndxPtr[*conn+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
1623 * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null.
1625 void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn)
1628 nodalConn->incrRef();
1634 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
1636 DataArrayInt *MEDCoupling1SGTUMesh::getNodalConnectivity() const
1638 const DataArrayInt *ret(_conn);
1639 return const_cast<DataArrayInt *>(ret);
1643 * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted,
1644 * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter.
1645 * If a nodal connectivity previouly existed before the call of this method, it will be reset.
1647 * \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain.
1649 void MEDCoupling1SGTUMesh::allocateCells(int nbOfCells)
1652 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !");
1653 _conn=DataArrayInt::New();
1654 _conn->reserve(getNumberOfNodesPerCell()*nbOfCells);
1659 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
1661 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
1662 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
1663 * \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
1664 * attached to \a this.
1665 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
1667 void MEDCoupling1SGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd)
1669 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
1670 int ref=getNumberOfNodesPerCell();
1673 DataArrayInt *c(_conn);
1675 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
1677 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !");
1681 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this (";
1682 oss << ref << ") !";
1683 throw INTERP_KERNEL::Exception(oss.str().c_str());
1688 * This method builds the dual mesh of \a this and returns it.
1690 * \return MEDCoupling1SGTUMesh * - newly object created to be managed by the caller.
1691 * \throw If \a this is not a mesh containing only simplex cells.
1692 * \throw If \a this is not correctly allocated (coordinates and connectivities have to be correctly set !).
1693 * \throw If at least one node in \a this is orphan (without any simplex cell lying on it !)
1695 MEDCoupling1GTUMesh *MEDCoupling1SGTUMesh::computeDualMesh() const
1697 const INTERP_KERNEL::CellModel& cm(getCellModel());
1699 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : this mesh is not a simplex mesh ! Please invoke simplexize of tetrahedrize on this before calling this method !");
1700 switch(getMeshDimension())
1703 return computeDualMesh3D();
1705 return computeDualMesh2D();
1707 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : meshdimension must be in [2,3] !");
1712 * This method explode each NORM_HEXA8 cells in \a this into 6 NORM_QUAD4 cells and put the result into the MEDCoupling1SGTUMesh returned instance.
1714 * \return MEDCoupling1SGTUMesh * - a newly allocated instances (to be managed by the caller) storing the result of the explosion.
1715 * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
1716 * \throw If \a this is not properly allocated.
1718 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4() const
1720 const INTERP_KERNEL::CellModel& cm(getCellModel());
1721 if(cm.getEnum()!=INTERP_KERNEL::NORM_HEXA8)
1722 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4 : this method can be applied only on HEXA8 mesh !");
1723 int nbHexa8(getNumberOfCells());
1724 const int *inConnPtr(getNodalConnectivity()->begin());
1725 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(getName(),INTERP_KERNEL::NORM_QUAD4));
1726 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()); c->alloc(nbHexa8*6*4,1);
1727 int *cPtr(c->getPointer());
1728 for(int i=0;i<nbHexa8;i++,inConnPtr+=8)
1730 for(int j=0;j<6;j++,cPtr+=4)
1731 cm.fillSonCellNodalConnectivity(j,inConnPtr,cPtr);
1733 ret->setCoords(getCoords());
1734 ret->setNodalConnectivity(c);
1739 * This method starts from an unstructured mesh that hides in reality a cartesian mesh.
1740 * If it is not the case, an exception will be thrown.
1741 * This method returns three objects : The cartesian mesh geometrically equivalent to \a this (within a precision of \a eps) and a permutation of cells
1742 * and a permutation of nodes.
1744 * - this[cellPerm[i]]=ret[i]
1746 * \param [out] cellPerm the permutation array of size \c this->getNumberOfCells()
1747 * \param [out] nodePerm the permutation array of size \c this->getNumberOfNodes()
1748 * \return MEDCouplingCMesh * - a newly allocated mesh that is the result of the structurization of \a this.
1750 MEDCouplingCMesh *MEDCoupling1SGTUMesh::structurizeMe(DataArrayInt *& cellPerm, DataArrayInt *& nodePerm, double eps) const
1753 int spaceDim(getSpaceDimension()),meshDim(getMeshDimension()),nbNodes(getNumberOfNodes());
1754 if(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim)!=getCellModelEnum())
1755 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::structurizeMe : the unique geo type in this is not compatible with the geometric type regarding mesh dimension !");
1756 MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> cm(MEDCouplingCMesh::New());
1757 for(int i=0;i<spaceDim;i++)
1759 std::vector<int> tmp(1,i);
1760 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> elt(static_cast<DataArrayDouble*>(getCoords()->keepSelectedComponents(tmp)));
1761 elt=elt->getDifferentValues(eps);
1763 cm->setCoordsAt(i,elt);
1765 if(nbNodes!=cm->getNumberOfNodes())
1766 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 ?");
1768 { cm->copyTinyInfoFrom(this); }
1769 catch(INTERP_KERNEL::Exception&) { }
1770 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> um(cm->buildUnstructured()),self(buildUnstructured());
1771 self->checkGeoEquivalWith(um,12,eps,cellPerm,nodePerm);
1777 bool UpdateHexa8Cell(int validAxis, int neighId, const int *validConnQuad4NeighSide, int *allFacesNodalConn, int *myNeighbours)
1779 static const int TAB[48]={
1787 static const int TAB2[6]={0,0,3,3,3,3};
1788 if(myNeighbours[validAxis]==neighId && allFacesNodalConn[4*validAxis+0]==validConnQuad4NeighSide[TAB2[validAxis]])
1790 int oldAxis((int)std::distance(myNeighbours,std::find(myNeighbours,myNeighbours+6,neighId)));
1791 std::size_t pos(std::distance(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,std::find(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS+6,oldAxis)));
1792 std::size_t pos0(pos/2),pos1(pos%2);
1793 int oldAxisOpp(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[2*pos0+(pos1+1)%2]);
1794 int oldConn[8],myConn2[8]={-1,-1,-1,-1,-1,-1,-1,-1},myConn[8],edgeConn[2],allFacesTmp[24],neighTmp[6];
1795 oldConn[0]=allFacesNodalConn[0]; oldConn[1]=allFacesNodalConn[1]; oldConn[2]=allFacesNodalConn[2]; oldConn[3]=allFacesNodalConn[3];
1796 oldConn[4]=allFacesNodalConn[4]; oldConn[5]=allFacesNodalConn[7]; oldConn[6]=allFacesNodalConn[6]; oldConn[7]=allFacesNodalConn[5];
1797 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_HEXA8));
1798 for(int i=0;i<4;i++)
1799 myConn2[i]=validConnQuad4NeighSide[(4-i+TAB2[validAxis])%4];
1800 for(int i=0;i<4;i++)
1802 int nodeId(myConn2[i]);//the node id for which the opposite one will be found
1804 INTERP_KERNEL::NormalizedCellType typeOfSon;
1805 for(int j=0;j<12 && !found;j++)
1807 cm.fillSonEdgesNodalConnectivity3D(j,oldConn,-1,edgeConn,typeOfSon);
1808 if(edgeConn[0]==nodeId || edgeConn[1]==nodeId)
1810 if(std::find(allFacesNodalConn+4*oldAxisOpp,allFacesNodalConn+4*oldAxisOpp+4,edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0])!=allFacesNodalConn+4*oldAxisOpp+4)
1812 myConn2[i+4]=edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0];
1818 throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error !");
1820 const int *myTab(TAB+8*validAxis);
1821 for(int i=0;i<8;i++)
1822 myConn[i]=myConn2[myTab[i]];
1823 for(int i=0;i<6;i++)
1825 cm.fillSonCellNodalConnectivity(i,myConn,allFacesTmp+4*i);
1826 std::set<int> s(allFacesTmp+4*i,allFacesTmp+4*i+4);
1828 for(int j=0;j<6 && !found;j++)
1830 std::set<int> s1(allFacesNodalConn+4*j,allFacesNodalConn+4*j+4);
1833 neighTmp[i]=myNeighbours[j];
1838 throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error #2 !");
1840 std::copy(allFacesTmp,allFacesTmp+24,allFacesNodalConn);
1841 std::copy(neighTmp,neighTmp+6,myNeighbours);
1848 * 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
1849 * homogeneous. If it succeeds the result of MEDCouplingUMesh::tetrahedrize will return a conform mesh.
1851 * \return DataArrayInt * - a newly allocated array (to be managed by the caller) containing renumbered cell ids.
1853 * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
1854 * \throw If \a this is not properly allocated.
1855 * \sa MEDCouplingUMesh::tetrahedrize, MEDCouplingUMesh::simplexize.
1857 DataArrayInt *MEDCoupling1SGTUMesh::sortHexa8EachOther()
1859 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> quads(explodeEachHexa8To6Quad4());//checks that only hexa8
1860 int nbHexa8(getNumberOfCells()),*cQuads(quads->getNodalConnectivity()->getPointer());
1861 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> neighOfQuads(DataArrayInt::New()); neighOfQuads->alloc(nbHexa8*6,1); neighOfQuads->fillWithValue(-1);
1862 int *ptNeigh(neighOfQuads->getPointer());
1863 {//neighOfQuads tells for each face of each Quad8 which cell (if!=-1) is connected to this face.
1864 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> quadsTmp(quads->buildUnstructured());
1865 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ccSafe,cciSafe;
1866 DataArrayInt *cc(0),*cci(0);
1867 quadsTmp->findCommonCells(3,0,cc,cci);
1868 ccSafe=cc; cciSafe=cci;
1869 const int *ccPtr(ccSafe->begin()),nbOfPair(cci->getNumberOfTuples()-1);
1870 for(int i=0;i<nbOfPair;i++)
1871 { ptNeigh[ccPtr[2*i+0]]=ccPtr[2*i+1]/6; ptNeigh[ccPtr[2*i+1]]=ccPtr[2*i+0]/6; }
1873 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
1874 std::vector<bool> fetched(nbHexa8,false);
1875 std::vector<bool>::iterator it(std::find(fetched.begin(),fetched.end(),false));
1876 while(it!=fetched.end())//it will turns as time as number of connected zones
1878 int cellId((int)std::distance(fetched.begin(),it));//it is the seed of the connected zone.
1879 std::set<int> s; s.insert(cellId);//s contains already organized.
1882 std::set<int> sNext;
1883 for(std::set<int>::const_iterator it0=s.begin();it0!=s.end();it0++)
1886 int *myNeighb(ptNeigh+6*(*it0));
1887 for(int i=0;i<6;i++)
1889 if(myNeighb[i]!=-1 && !fetched[myNeighb[i]])
1891 std::size_t pos(std::distance(HEXA8_FACE_PAIRS,std::find(HEXA8_FACE_PAIRS,HEXA8_FACE_PAIRS+6,i)));
1892 std::size_t pos0(pos/2),pos1(pos%2);
1893 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]))
1894 ret->pushBackSilent(myNeighb[i]);
1895 fetched[myNeighb[i]]=true;
1896 sNext.insert(myNeighb[i]);
1902 it=std::find(fetched.begin(),fetched.end(),false);
1906 int *conn(getNodalConnectivity()->getPointer());
1907 for(const int *pt=ret->begin();pt!=ret->end();pt++)
1910 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];
1911 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];
1918 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh3D() const
1920 static const int DUAL_TETRA_0[36]={
1921 4,1,0, 6,0,3, 7,3,1,
1922 4,0,1, 5,2,0, 8,1,2,
1923 6,3,0, 5,0,2, 9,2,3,
1926 static const int DUAL_TETRA_1[36]={
1927 8,4,10, 11,5,8, 10,7,11,
1928 9,4,8, 8,5,12, 12,6,9,
1929 10,4,9, 9,6,13, 13,7,10,
1930 12,5,11, 13,6,12, 11,7,13
1932 static const int FACEID_NOT_SH_NODE[4]={2,3,1,0};
1933 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TETRA4)
1934 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh3D : only TETRA4 supported !");
1935 checkFullyDefined();
1936 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured());
1937 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1938 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1939 const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1940 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d1Arr(DataArrayInt::New()),di1Arr(DataArrayInt::New()),rd1Arr(DataArrayInt::New()),rdi1Arr(DataArrayInt::New());
1941 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->explode3DMeshTo1D(d1Arr,di1Arr,rd1Arr,rdi1Arr));
1942 const int *d1(d1Arr->begin());
1943 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1944 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> faces(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
1945 const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
1946 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),facesBaryArr(faces->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
1947 const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+faces->getNumberOfCells()),offset1(offset0+edges->getNumberOfCells());
1949 std::vector<const DataArrayDouble *> v(4); v[0]=getCoords(); v[1]=facesBaryArr; v[2]=edgesBaryArr; v[3]=baryArr;
1950 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0; facesBaryArr=0;
1951 std::string name("DualOf_"); name+=getName();
1952 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYHED)); ret->setCoords(zeArr);
1953 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1954 for(int i=0;i<nbOfNodes;i++,revNodI++)
1956 int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1957 if(nbOfCellsSharingNode==0)
1959 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh3D : Node #" << i << " is orphan !";
1960 throw INTERP_KERNEL::Exception(oss.str().c_str());
1962 for(int j=0;j<nbOfCellsSharingNode;j++)
1964 int curCellId(revNod[revNodI[0]+j]);
1965 const int *connOfCurCell(nodal+4*curCellId);
1966 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1967 if(j!=0) cArr->pushBackSilent(-1);
1970 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;
1971 tmp[2]=curCellId+offset1; tmp[3]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+2]]+nbOfNodes;
1973 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;
1974 tmp[7]=curCellId+offset1; tmp[8]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+5]]+nbOfNodes;
1976 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;
1977 tmp[12]=curCellId+offset1; tmp[13]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+8]]+nbOfNodes;
1978 cArr->insertAtTheEnd(tmp,tmp+14);
1980 for(int k=0;k<4;k++)
1982 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1984 const int *faceId(d2+4*curCellId+k);
1985 if(rdi2[*faceId+1]-rdi2[*faceId]==1)
1987 int tmp2[5]; tmp2[0]=-1; tmp2[1]=i;
1988 tmp2[2]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+0]-8]+offset0;
1989 tmp2[3]=d2[4*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+1]-4]+nbOfNodes;
1990 tmp2[4]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+2]-8]+offset0;
1991 cArr->insertAtTheEnd(tmp2,tmp2+5);
1997 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
1999 ret->setNodalConnectivity(cArr,ciArr);
2003 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh2D() const
2005 static const int DUAL_TRI_0[6]={0,2, 1,0, 2,1};
2006 static const int DUAL_TRI_1[6]={-3,+5, +3,-4, +4,-5};
2007 static const int FACEID_NOT_SH_NODE[3]={1,2,0};
2008 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TRI3)
2009 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh2D : only TRI3 supported !");
2010 checkFullyDefined();
2011 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured());
2012 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
2013 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
2014 const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
2015 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
2016 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
2017 const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
2018 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
2019 const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+edges->getNumberOfCells());
2021 std::vector<const DataArrayDouble *> v(3); v[0]=getCoords(); v[1]=edgesBaryArr; v[2]=baryArr;
2022 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0;
2023 std::string name("DualOf_"); name+=getName();
2024 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYGON)); ret->setCoords(zeArr);
2025 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
2026 for(int i=0;i<nbOfNodes;i++,revNodI++)
2028 int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
2029 if(nbOfCellsSharingNode==0)
2031 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh2D : Node #" << i << " is orphan !";
2032 throw INTERP_KERNEL::Exception(oss.str().c_str());
2034 std::vector< std::vector<int> > polyg;
2035 for(int j=0;j<nbOfCellsSharingNode;j++)
2037 int curCellId(revNod[revNodI[0]+j]);
2038 const int *connOfCurCell(nodal+3*curCellId);
2039 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
2040 std::vector<int> locV(3);
2041 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;
2042 polyg.push_back(locV);
2044 for(int k=0;k<3;k++)
2046 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
2048 const int *edgeId(d2+3*curCellId+k);
2049 if(rdi2[*edgeId+1]-rdi2[*edgeId]==1)
2051 std::vector<int> locV2(2);
2052 int zeLocEdgeIdRel(DUAL_TRI_1[2*nodePosInCurCell+kk]);
2053 if(zeLocEdgeIdRel>0)
2054 { locV2[0]=d2[3*curCellId+zeLocEdgeIdRel-3]+nbOfNodes; locV2[1]=i; }
2056 { locV2[0]=i; locV2[1]=d2[3*curCellId-zeLocEdgeIdRel-3]+nbOfNodes; }
2057 polyg.push_back(locV2);
2063 std::vector<int> zePolyg(MEDCoupling1DGTUMesh::BuildAPolygonFromParts(polyg));
2064 cArr->insertAtTheEnd(zePolyg.begin(),zePolyg.end());
2065 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
2067 ret->setNodalConnectivity(cArr,ciArr);
2072 * This method aggregate the bbox of each cell and put it into bbox
2074 * \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)
2075 * For all other cases this input parameter is ignored.
2076 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
2078 * \throw If \a this is not fully set (coordinates and connectivity).
2079 * \throw If a cell in \a this has no valid nodeId.
2081 DataArrayDouble *MEDCoupling1SGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
2083 int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()),nbOfNodesPerCell(getNumberOfNodesPerCell());
2084 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
2085 double *bbox(ret->getPointer());
2086 for(int i=0;i<nbOfCells*spaceDim;i++)
2088 bbox[2*i]=std::numeric_limits<double>::max();
2089 bbox[2*i+1]=-std::numeric_limits<double>::max();
2091 const double *coordsPtr(_coords->getConstPointer());
2092 const int *conn(_conn->getConstPointer());
2093 for(int i=0;i<nbOfCells;i++)
2096 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
2099 if(nodeId>=0 && nodeId<nbOfNodes)
2101 for(int k=0;k<spaceDim;k++)
2103 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
2104 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
2111 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
2112 throw INTERP_KERNEL::Exception(oss.str().c_str());
2119 * Returns the cell field giving for each cell in \a this its diameter. Diameter means the max length of all possible SEG2 in the cell.
2121 * \return a new instance of field containing the result. The returned instance has to be deallocated by the caller.
2123 MEDCouplingFieldDouble *MEDCoupling1SGTUMesh::computeDiameterField() const
2125 checkFullyDefined();
2126 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME));
2127 int nbCells(getNumberOfCells());
2128 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr(DataArrayDouble::New());
2129 arr->alloc(nbCells,1);
2130 INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::DiameterCalculator> dc(_cm->buildInstanceOfDiameterCalulator(getSpaceDimension()));
2131 dc->computeFor1SGTUMeshFrmt(nbCells,_conn->begin(),getCoords()->begin(),arr->getPointer());
2134 ret->setName("Diameter");
2140 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New()
2142 return new MEDCoupling1DGTUMesh;
2145 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
2147 if(type==INTERP_KERNEL::NORM_ERROR)
2148 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
2149 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
2152 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !";
2153 throw INTERP_KERNEL::Exception(oss.str().c_str());
2155 return new MEDCoupling1DGTUMesh(name,cm);
2158 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh()
2162 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
2166 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
2170 const DataArrayInt *c(other._conn);
2175 _conn_indx=c->deepCpy();
2179 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const
2181 return new MEDCoupling1DGTUMesh(*this,recDeepCpy);
2185 * This method behaves mostly like MEDCoupling1DGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
2186 * The coordinates are shared between \a this and the returned instance.
2188 * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
2189 * \sa MEDCoupling1DGTUMesh::deepCpy
2191 MEDCouplingPointSet *MEDCoupling1DGTUMesh::deepCpyConnectivityOnly() const
2194 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(clone(false));
2195 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy()),ci(_conn_indx->deepCpy());
2196 ret->setNodalConnectivity(c,ci);
2200 void MEDCoupling1DGTUMesh::updateTime() const
2202 MEDCoupling1GTUMesh::updateTime();
2203 const DataArrayInt *c(_conn);
2211 std::size_t MEDCoupling1DGTUMesh::getHeapMemorySizeWithoutChildren() const
2213 return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren();
2216 std::vector<const BigMemoryObject *> MEDCoupling1DGTUMesh::getDirectChildrenWithNull() const
2218 std::vector<const BigMemoryObject *> ret(MEDCoupling1GTUMesh::getDirectChildrenWithNull());
2219 ret.push_back((const DataArrayInt *)_conn);
2220 ret.push_back((const DataArrayInt *)_conn_indx);
2224 MEDCouplingMesh *MEDCoupling1DGTUMesh::deepCpy() const
2229 bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
2232 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !");
2233 std::ostringstream oss; oss.precision(15);
2234 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2237 reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !";
2240 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
2242 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2247 reason="in connectivity of single dynamic geometric type exactly one among this and other is null !";
2250 if(!c1->isEqualIfNotWhy(*c2,reason))
2252 reason.insert(0,"Nodal connectivity DataArrayInt differs : ");
2255 c1=_conn_indx; c2=otherC->_conn_indx;
2260 reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !";
2263 if(!c1->isEqualIfNotWhy(*c2,reason))
2265 reason.insert(0,"Nodal connectivity index DataArrayInt differs : ");
2271 bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
2274 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
2275 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2278 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
2280 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2285 if(!c1->isEqualWithoutConsideringStr(*c2))
2288 c1=_conn_indx; c2=otherC->_conn_indx;
2293 if(!c1->isEqualWithoutConsideringStr(*c2))
2299 * Checks if \a this and \a other meshes are geometrically equivalent with high
2300 * probability, else an exception is thrown. The meshes are considered equivalent if
2301 * (1) meshes contain the same number of nodes and the same number of elements of the
2302 * same types (2) three cells of the two meshes (first, last and middle) are based
2303 * on coincident nodes (with a specified precision).
2304 * \param [in] other - the mesh to compare with.
2305 * \param [in] prec - the precision used to compare nodes of the two meshes.
2306 * \throw If the two meshes do not match.
2308 void MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
2310 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
2311 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2313 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single dynamic geometric type !");
2314 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2318 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
2319 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2320 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
2321 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2322 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
2323 if(c1->getHashCode()!=c2->getHashCode())
2324 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs");
2326 c1=_conn_indx; c2=otherC->_conn_indx;
2330 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !");
2331 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2332 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !");
2333 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2334 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !");
2335 if(c1->getHashCode()!=c2->getHashCode())
2336 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs");
2340 void MEDCoupling1DGTUMesh::checkCoherencyOfConnectivity() const
2342 const DataArrayInt *c1(_conn);
2345 if(c1->getNumberOfComponents()!=1)
2346 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
2347 if(c1->getInfoOnComponent(0)!="")
2348 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
2349 c1->checkAllocated();
2352 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
2354 int sz2=_conn->getNumberOfTuples();
2358 if(c1->getNumberOfComponents()!=1)
2359 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
2360 c1->checkAllocated();
2361 if(c1->getNumberOfTuples()<1)
2362 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !");
2363 if(c1->getInfoOnComponent(0)!="")
2364 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
2365 int f=c1->front(),ll=c1->back();
2368 std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !";
2369 throw INTERP_KERNEL::Exception(oss.str().c_str());
2373 std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !";
2374 throw INTERP_KERNEL::Exception(oss.str().c_str());
2378 std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !";
2379 throw INTERP_KERNEL::Exception(oss.str().c_str());
2383 throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !");
2384 int szOfC1Exp=_conn_indx->back();
2387 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() << " !";
2388 throw INTERP_KERNEL::Exception(oss.str().c_str());
2393 * 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.
2394 * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one.
2395 * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array.
2397 void MEDCoupling1DGTUMesh::checkCoherency() const
2399 MEDCouplingPointSet::checkCoherency();
2400 checkCoherencyOfConnectivity();
2403 void MEDCoupling1DGTUMesh::checkCoherency1(double eps) const
2406 const DataArrayInt *c1(_conn),*c2(_conn_indx);
2407 if(!c2->isMonotonic(true))
2408 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkCoherency1 : the nodal connectivity index is expected to be increasing monotinic !");
2410 int nbOfTuples=c1->getNumberOfTuples();
2411 int nbOfNodes=getNumberOfNodes();
2412 const int *w(c1->begin());
2413 for(int i=0;i<nbOfTuples;i++,w++)
2415 if(*w==-1) continue;
2416 if(*w<0 || *w>=nbOfNodes)
2418 std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !";
2419 throw INTERP_KERNEL::Exception(oss.str().c_str());
2424 void MEDCoupling1DGTUMesh::checkCoherency2(double eps) const
2426 checkCoherency1(eps);
2429 int MEDCoupling1DGTUMesh::getNumberOfCells() const
2431 checkCoherencyOfConnectivity();//do not remove
2432 return _conn_indx->getNumberOfTuples()-1;
2436 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2437 * For each cell in \b this the number of nodes constituting cell is computed.
2438 * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned.
2439 * So for pohyhedrons some nodes can be counted several times in the returned result.
2441 * \return a newly allocated array
2443 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const
2446 _conn_indx->checkMonotonic(true);
2447 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2448 return _conn_indx->deltaShiftIndex();
2450 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2451 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2452 ret->alloc(nbOfCells,1);
2453 int *retPtr=ret->getPointer();
2454 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2455 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2456 *retPtr=ci[1]-ci[0]-std::count(c+ci[0],c+ci[1],-1);
2461 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2462 * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed.
2464 * \return a newly allocated array
2466 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const
2469 _conn_indx->checkMonotonic(true);
2470 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG)
2471 return _conn_indx->deltaShiftIndex();
2472 if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG)
2474 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=_conn_indx->deltaShiftIndex();
2475 ret->applyDivideBy(2);
2479 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2480 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2481 ret->alloc(nbOfCells,1);
2482 int *retPtr=ret->getPointer();
2483 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2484 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2485 *retPtr=std::count(c+ci[0],c+ci[1],-1)+1;
2490 * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell,
2491 * will be counted only once here whereas it will be counted several times in MEDCoupling1DGTUMesh::computeNbOfNodesPerCell method.
2493 * \return DataArrayInt * - new object to be deallocated by the caller.
2494 * \sa MEDCoupling1DGTUMesh::computeNbOfNodesPerCell
2496 DataArrayInt *MEDCoupling1DGTUMesh::computeEffectiveNbOfNodesPerCell() const
2499 _conn_indx->checkMonotonic(true);
2500 int nbOfCells(_conn_indx->getNumberOfTuples()-1);
2501 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2502 ret->alloc(nbOfCells,1);
2503 int *retPtr(ret->getPointer());
2504 const int *ci(_conn_indx->begin()),*c(_conn->begin());
2505 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2507 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2509 std::set<int> s(c+ci[0],c+ci[1]);
2510 *retPtr=(int)s.size();
2515 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2517 std::set<int> s(c+ci[0],c+ci[1]); s.erase(-1);
2518 *retPtr=(int)s.size();
2524 void MEDCoupling1DGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
2526 int nbOfCells(getNumberOfCells());//performs checks
2527 if(cellId>=0 && cellId<nbOfCells)
2529 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2530 int nbOfNodes=stp-strt;
2532 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !");
2533 conn.resize(nbOfNodes);
2534 std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin());
2538 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2539 throw INTERP_KERNEL::Exception(oss.str().c_str());
2543 int MEDCoupling1DGTUMesh::getNumberOfNodesInCell(int cellId) const
2545 int nbOfCells(getNumberOfCells());//performs checks
2546 if(cellId>=0 && cellId<nbOfCells)
2548 const int *conn(_conn->begin());
2549 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2550 return stp-strt-std::count(conn+strt,conn+stp,-1);
2554 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNumberOfNodesInCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2555 throw INTERP_KERNEL::Exception(oss.str().c_str());
2559 std::string MEDCoupling1DGTUMesh::simpleRepr() const
2561 static const char msg0[]="No coordinates specified !";
2562 std::ostringstream ret;
2563 ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
2564 ret << "Description of mesh : \"" << getDescription() << "\"\n";
2566 double tt=getTime(tmpp1,tmpp2);
2567 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
2568 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
2569 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
2572 const int spaceDim=getSpaceDimension();
2573 ret << spaceDim << "\nInfo attached on space dimension : ";
2574 for(int i=0;i<spaceDim;i++)
2575 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
2579 ret << msg0 << "\n";
2580 ret << "Number of nodes : ";
2582 ret << getNumberOfNodes() << "\n";
2584 ret << msg0 << "\n";
2585 ret << "Number of cells : ";
2587 try { checkCoherency(); } catch(INTERP_KERNEL::Exception& /* e */)
2589 ret << "Nodal connectivity arrays are not set or badly set !\n";
2593 ret << getNumberOfCells() << "\n";
2594 ret << "Cell type : " << _cm->getRepr() << "\n";
2598 std::string MEDCoupling1DGTUMesh::advancedRepr() const
2600 std::ostringstream ret;
2601 ret << simpleRepr();
2602 ret << "\nCoordinates array : \n___________________\n\n";
2604 _coords->reprWithoutNameStream(ret);
2606 ret << "No array set !\n";
2607 ret << "\n\nNodal Connectivity : \n____________________\n\n";
2610 try { checkCoherency1(); } catch(INTERP_KERNEL::Exception& /* e */)
2612 ret << "Nodal connectivity arrays are not set or badly set !\n";
2617 int nbOfCells=getNumberOfCells();
2618 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2619 for(int i=0;i<nbOfCells;i++,ci++)
2621 ret << "Cell #" << i << " : ";
2622 std::copy(c+ci[0],c+ci[1],std::ostream_iterator<int>(ret," "));
2628 DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const
2630 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
2631 int spaceDim=getSpaceDimension();
2632 int nbOfCells=getNumberOfCells();//checkCoherency()
2633 int nbOfNodes=getNumberOfNodes();
2634 ret->alloc(nbOfCells,spaceDim);
2635 double *ptToFill=ret->getPointer();
2636 const double *coor=_coords->begin();
2637 const int *nodal=_conn->begin(),*nodali=_conn_indx->begin();
2639 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2641 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2643 std::fill(ptToFill,ptToFill+spaceDim,0.);
2644 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2646 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2648 if(*nodal>=0 && *nodal<nbOfNodes)
2649 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2652 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2653 throw INTERP_KERNEL::Exception(oss.str().c_str());
2655 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(nodali[1]-nodali[0])));
2660 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !";
2661 throw INTERP_KERNEL::Exception(oss.str().c_str());
2667 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2669 std::fill(ptToFill,ptToFill+spaceDim,0.);
2670 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2673 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2675 if(*nodal==-1) continue;
2676 if(*nodal>=0 && *nodal<nbOfNodes)
2678 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2683 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2684 throw INTERP_KERNEL::Exception(oss.str().c_str());
2688 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./nbOfNod));
2691 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !";
2692 throw INTERP_KERNEL::Exception(oss.str().c_str());
2697 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : at cell #" << i << " the nodal index array is invalid !";
2698 throw INTERP_KERNEL::Exception(oss.str().c_str());
2705 void MEDCoupling1DGTUMesh::renumberCells(const int *old2NewBg, bool check)
2707 int nbCells=getNumberOfCells();
2708 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
2709 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
2711 o2n=o2n->checkAndPreparePermutation();
2713 const int *o2nPtr=o2n->getPointer();
2714 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2715 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
2716 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
2717 newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1);
2718 newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx);
2720 int *newC=newConn->getPointer(),*newCI=newConnI->getPointer();
2721 for(int i=0;i<nbCells;i++)
2723 int newPos=o2nPtr[i];
2724 int sz=conni[i+1]-conni[i];
2729 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !";
2730 throw INTERP_KERNEL::Exception(oss.str().c_str());
2733 newConnI->computeOffsets2(); newCI=newConnI->getPointer();
2735 for(int i=0;i<nbCells;i++,conni++)
2738 std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]);
2741 _conn_indx=newConnI;
2744 MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
2746 if(other->getType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED)
2747 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !");
2748 const MEDCoupling1DGTUMesh *otherC=static_cast<const MEDCoupling1DGTUMesh *>(other);
2749 return Merge1DGTUMeshes(this,otherC);
2752 MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const
2754 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
2755 ret->setCoords(getCoords());
2756 const int *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin();
2757 int nbCells=getNumberOfCells();//checkCoherency
2758 int geoType=(int)getCellModelEnum();
2759 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1);
2760 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::New(); cI->alloc(nbCells+1);
2761 int *cPtr=c->getPointer(),*ciPtr=cI->getPointer();
2763 for(int i=0;i<nbCells;i++,ciPtr++)
2765 int sz=nodalConnI[i+1]-nodalConnI[i];
2769 cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr);
2770 ciPtr[1]=ciPtr[0]+sz+1;
2774 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !";
2775 throw INTERP_KERNEL::Exception(oss.str().c_str());
2778 ret->setConnectivity(c,cI,true);
2780 { ret->copyTinyInfoFrom(this); }
2781 catch(INTERP_KERNEL::Exception&) { }
2786 * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes
2788 DataArrayInt *MEDCoupling1DGTUMesh::simplexize(int policy)
2790 int nbOfCells=getNumberOfCells();
2791 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2792 ret->alloc(nbOfCells,1);
2797 void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const
2799 stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
2800 stream << " Mesh dimension : " << getMeshDimension() << ".";
2802 { stream << " No coordinates set !"; return ; }
2803 if(!_coords->isAllocated())
2804 { stream << " Coordinates set but not allocated !"; return ; }
2805 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
2806 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
2808 try { checkCoherency(); } catch(INTERP_KERNEL::Exception& /* e */)
2810 stream << std::endl << "Nodal connectivity NOT set properly !\n";
2814 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
2817 void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
2820 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
2821 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2823 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !");
2824 setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex());
2827 MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
2830 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
2831 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2833 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
2834 std::vector<const MEDCoupling1DGTUMesh *> ms(2);
2837 return Merge1DGTUMeshesOnSameCoords(ms);
2840 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
2843 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2844 ret->setCoords(_coords);
2845 DataArrayInt *c=0,*ci=0;
2846 MEDCouplingUMesh::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci);
2847 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2848 ret->setNodalConnectivity(c,ci);
2852 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
2855 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2856 ret->setCoords(_coords);
2857 DataArrayInt *c=0,*ci=0;
2858 MEDCouplingUMesh::ExtractFromIndexedArrays2(start,end,step,_conn,_conn_indx,c,ci);
2859 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2860 ret->setNodalConnectivity(c,ci);
2864 void MEDCoupling1DGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
2867 int sz((int)nodeIdsInUse.size());
2868 for(const int *conn=_conn->begin();conn!=_conn->end();conn++)
2870 if(*conn>=0 && *conn<sz)
2871 nodeIdsInUse[*conn]=true;
2876 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeNodeIdsAlg : At pos #" << std::distance(_conn->begin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !";
2877 throw INTERP_KERNEL::Exception(oss.str().c_str());
2883 void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const
2885 checkFullyDefined();
2886 int nbOfNodes=getNumberOfNodes();
2887 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
2888 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
2889 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
2890 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2891 int nbOfCells=getNumberOfCells();
2892 int nbOfEltsInRevNodal=0;
2893 for(int eltId=0;eltId<nbOfCells;eltId++)
2895 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2896 if(nbOfNodesPerCell>=0)
2898 for(int j=0;j<nbOfNodesPerCell;j++)
2900 int nodeId=conn[conni[eltId]+j];
2901 if(nodeId==-1) continue;
2902 if(nodeId>=0 && nodeId<nbOfNodes)
2904 nbOfEltsInRevNodal++;
2905 revNodalIndxPtr[nodeId+1]++;
2909 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
2910 throw INTERP_KERNEL::Exception(oss.str().c_str());
2916 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << "nodal connectivity is invalid !";
2917 throw INTERP_KERNEL::Exception(oss.str().c_str());
2920 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
2921 conn=_conn->begin();
2922 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
2923 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
2924 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
2925 for(int eltId=0;eltId<nbOfCells;eltId++)
2927 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2928 for(int j=0;j<nbOfNodesPerCell;j++)
2930 int nodeId=conn[conni[eltId]+j];
2932 *std::find_if(revNodalPtr+revNodalIndxPtr[nodeId],revNodalPtr+revNodalIndxPtr[nodeId+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
2937 void MEDCoupling1DGTUMesh::checkFullyDefined() const
2939 if(!((const DataArrayInt *)_conn) || !((const DataArrayInt *)_conn_indx) || !((const DataArrayDouble *)_coords))
2940 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined.");
2943 bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
2945 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !");
2948 void MEDCoupling1DGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
2951 double time=getTime(it,order);
2952 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
2954 littleStrings.push_back(getName());
2955 littleStrings.push_back(getDescription());
2956 littleStrings.push_back(getTimeUnit());
2958 std::vector<std::string> littleStrings2,littleStrings3,littleStrings4;
2959 if((const DataArrayDouble *)_coords)
2960 _coords->getTinySerializationStrInformation(littleStrings2);
2961 if((const DataArrayInt *)_conn)
2962 _conn->getTinySerializationStrInformation(littleStrings3);
2963 if((const DataArrayInt *)_conn_indx)
2964 _conn_indx->getTinySerializationStrInformation(littleStrings4);
2965 int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size()),sz2((int)littleStrings4.size());
2966 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
2967 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
2968 littleStrings.insert(littleStrings.end(),littleStrings4.begin(),littleStrings4.end());
2970 tinyInfo.push_back(getCellModelEnum());
2971 tinyInfo.push_back(it);
2972 tinyInfo.push_back(order);
2973 std::vector<int> tinyInfo2,tinyInfo3,tinyInfo4;
2974 if((const DataArrayDouble *)_coords)
2975 _coords->getTinySerializationIntInformation(tinyInfo2);
2976 if((const DataArrayInt *)_conn)
2977 _conn->getTinySerializationIntInformation(tinyInfo3);
2978 if((const DataArrayInt *)_conn_indx)
2979 _conn_indx->getTinySerializationIntInformation(tinyInfo4);
2980 int sz3((int)tinyInfo2.size()),sz4((int)tinyInfo3.size()),sz5((int)tinyInfo4.size());
2981 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3); tinyInfo.push_back(sz4); tinyInfo.push_back(sz5);
2982 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
2983 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
2984 tinyInfo.insert(tinyInfo.end(),tinyInfo4.begin(),tinyInfo4.end());
2986 tinyInfoD.push_back(time);
2989 void MEDCoupling1DGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
2991 std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+tinyInfo[6]);
2992 std::vector<int> tinyInfo1(tinyInfo.begin()+9+tinyInfo[6],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]);
2993 std::vector<int> tinyInfo12(tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]+tinyInfo[8]);
2994 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(DataArrayInt::New()); p1->resizeForUnserialization(tinyInfo1);
2995 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(DataArrayInt::New()); p2->resizeForUnserialization(tinyInfo12);
2996 std::vector<const DataArrayInt *> v(2); v[0]=p1; v[1]=p2;
2997 p2=DataArrayInt::Aggregate(v);
2998 a2->resizeForUnserialization(tinyInfo2);
2999 a1->alloc(p2->getNbOfElems(),1);
3002 void MEDCoupling1DGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
3005 if((const DataArrayInt *)_conn)
3006 if(_conn->isAllocated())
3007 sz=_conn->getNbOfElems();
3008 if((const DataArrayInt *)_conn_indx)
3009 if(_conn_indx->isAllocated())
3010 sz+=_conn_indx->getNbOfElems();
3011 a1=DataArrayInt::New();
3013 int *work(a1->getPointer());
3014 if(sz!=0 && (const DataArrayInt *)_conn)
3015 work=std::copy(_conn->begin(),_conn->end(),a1->getPointer());
3016 if(sz!=0 && (const DataArrayInt *)_conn_indx)
3017 std::copy(_conn_indx->begin(),_conn_indx->end(),work);
3019 if((const DataArrayDouble *)_coords)
3020 if(_coords->isAllocated())
3021 sz=_coords->getNbOfElems();
3022 a2=DataArrayDouble::New();
3024 if(sz!=0 && (const DataArrayDouble *)_coords)
3025 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
3028 void MEDCoupling1DGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
3029 const std::vector<std::string>& littleStrings)
3031 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
3032 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
3033 setName(littleStrings[0]);
3034 setDescription(littleStrings[1]);
3035 setTimeUnit(littleStrings[2]);
3036 setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
3037 int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]),sz4(tinyInfo[7]),sz5(tinyInfo[8]);
3039 _coords=DataArrayDouble::New();
3040 std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+sz3);
3041 _coords->resizeForUnserialization(tinyInfo2);
3042 std::copy(a2->begin(),a2->end(),_coords->getPointer());
3043 _conn=DataArrayInt::New();
3044 std::vector<int> tinyInfo3(tinyInfo.begin()+9+sz3,tinyInfo.begin()+9+sz3+sz4);
3045 _conn->resizeForUnserialization(tinyInfo3);
3046 std::copy(a1->begin(),a1->begin()+_conn->getNbOfElems(),_conn->getPointer());
3047 _conn_indx=DataArrayInt::New();
3048 std::vector<int> tinyInfo4(tinyInfo.begin()+9+sz3+sz4,tinyInfo.begin()+9+sz3+sz4+sz5);
3049 _conn_indx->resizeForUnserialization(tinyInfo4);
3050 std::copy(a1->begin()+_conn->getNbOfElems(),a1->end(),_conn_indx->getPointer());
3051 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
3052 _coords->finishUnserialization(tinyInfo2,littleStrings2);
3053 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
3054 _conn->finishUnserialization(tinyInfo3,littleStrings3);
3055 std::vector<std::string> littleStrings4(littleStrings.begin()+3+sz0+sz1,littleStrings.begin()+3+sz0+sz1+sz2);
3056 _conn_indx->finishUnserialization(tinyInfo4,littleStrings4);
3060 * Finds nodes not used in any cell and returns an array giving a new id to every node
3061 * by excluding the unused nodes, for which the array holds -1. The result array is
3062 * a mapping in "Old to New" mode.
3063 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
3064 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
3065 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
3066 * if the node is unused or a new id else. The caller is to delete this
3067 * array using decrRef() as it is no more needed.
3068 * \throw If the coordinates array is not set.
3069 * \throw If the nodal connectivity of cells is not defined.
3070 * \throw If the nodal connectivity includes an invalid id.
3071 * \sa MEDCoupling1DGTUMesh::getNodeIdsInUse, areAllNodesFetched
3073 DataArrayInt *MEDCoupling1DGTUMesh::computeFetchedNodeIds() const
3076 int nbNodes(getNumberOfNodes());
3077 std::vector<bool> fetchedNodes(nbNodes,false);
3078 computeNodeIdsAlg(fetchedNodes);
3079 int sz((int)std::count(fetchedNodes.begin(),fetchedNodes.end(),true));
3080 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
3081 int *retPtr(ret->getPointer());
3082 for(int i=0;i<nbNodes;i++)
3089 * Finds nodes not used in any cell and returns an array giving a new id to every node
3090 * by excluding the unused nodes, for which the array holds -1. The result array is
3091 * a mapping in "Old to New" mode.
3092 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
3093 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
3094 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
3095 * if the node is unused or a new id else. The caller is to delete this
3096 * array using decrRef() as it is no more needed.
3097 * \throw If the coordinates array is not set.
3098 * \throw If the nodal connectivity of cells is not defined.
3099 * \throw If the nodal connectivity includes an invalid id.
3100 * \sa MEDCoupling1DGTUMesh::computeFetchedNodeIds, areAllNodesFetched
3102 DataArrayInt *MEDCoupling1DGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
3105 int nbOfNodes=getNumberOfNodes();
3106 int nbOfCells=getNumberOfCells();//checkCoherency
3107 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
3108 ret->alloc(nbOfNodes,1);
3109 int *traducer=ret->getPointer();
3110 std::fill(traducer,traducer+nbOfNodes,-1);
3111 const int *conn=_conn->begin(),*conni(_conn_indx->begin());
3112 for(int i=0;i<nbOfCells;i++,conni++)
3114 int nbNodesPerCell=conni[1]-conni[0];
3115 for(int j=0;j<nbNodesPerCell;j++)
3117 int nodeId=conn[conni[0]+j];
3118 if(nodeId==-1) continue;
3119 if(nodeId>=0 && nodeId<nbOfNodes)
3123 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << nodeId << " not in [0," << nbOfNodes << ") !";
3124 throw INTERP_KERNEL::Exception(oss.str().c_str());
3128 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
3129 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
3134 * This method renumbers only nodal connectivity in \a this. The renumbering is only an offset applied. So this method is a specialization of
3135 * \a renumberNodesInConn. \b WARNING, this method does not check that the resulting node ids in the nodal connectivity is in a valid range !
3137 * \param [in] offset - specifies the offset to be applied on each element of connectivity.
3139 * \sa renumberNodesInConn
3141 void MEDCoupling1DGTUMesh::renumberNodesWithOffsetInConn(int offset)
3143 getNumberOfCells();//only to check that all is well defined.
3145 int nbOfTuples(_conn->getNumberOfTuples());
3146 int *pt(_conn->getPointer());
3147 for(int i=0;i<nbOfTuples;i++,pt++)
3149 if(*pt==-1) continue;
3157 * Same than renumberNodesInConn(const int *) except that here the format of old-to-new traducer is using map instead
3158 * 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
3161 void MEDCoupling1DGTUMesh::renumberNodesInConn(const INTERP_KERNEL::HashMap<int,int>& newNodeNumbersO2N)
3163 getNumberOfCells();//only to check that all is well defined.
3165 int nbElemsIn(getNumberOfNodes()),nbOfTuples(_conn->getNumberOfTuples());
3166 int *pt(_conn->getPointer());
3167 for(int i=0;i<nbOfTuples;i++,pt++)
3169 if(*pt==-1) continue;
3170 if(*pt>=0 && *pt<nbElemsIn)
3172 INTERP_KERNEL::HashMap<int,int>::const_iterator it(newNodeNumbersO2N.find(*pt));
3173 if(it!=newNodeNumbersO2N.end())
3177 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : At pos #" << i << " of connectivity, node id is " << *pt << ". Not in keys of input map !";
3178 throw INTERP_KERNEL::Exception(oss.str().c_str());
3183 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
3184 throw INTERP_KERNEL::Exception(oss.str().c_str());
3192 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
3193 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
3194 * This method is a generalization of shiftNodeNumbersInConn().
3195 * \warning This method performs no check of validity of new ids. **Use it with care !**
3196 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
3197 * this->getNumberOfNodes(), in "Old to New" mode.
3198 * See \ref numbering for more info on renumbering modes.
3199 * \throw If the nodal connectivity of cells is not defined.
3201 void MEDCoupling1DGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
3203 getNumberOfCells();//only to check that all is well defined.
3205 int nbElemsIn(getNumberOfNodes()),nbOfTuples(_conn->getNumberOfTuples());
3206 int *pt(_conn->getPointer());
3207 for(int i=0;i<nbOfTuples;i++,pt++)
3209 if(*pt==-1) continue;
3210 if(*pt>=0 && *pt<nbElemsIn)
3211 *pt=newNodeNumbersO2N[*pt];
3214 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
3215 throw INTERP_KERNEL::Exception(oss.str().c_str());
3223 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
3224 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
3225 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
3226 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
3228 * \param [in] begin input start of array of node ids.
3229 * \param [in] end input end of array of node ids.
3230 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
3231 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
3233 void MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
3235 int nbOfCells=getNumberOfCells();
3236 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
3238 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
3239 std::vector<bool> fastFinder(sz,false);
3240 for(const int *work=begin;work!=end;work++)
3241 if(*work>=0 && *work<sz)
3242 fastFinder[*work]=true;
3243 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
3244 for(int i=0;i<nbOfCells;i++,conni++)
3246 int ref=0,nbOfHit=0;
3247 int nbNodesPerCell=conni[1]-conni[0];
3248 if(nbNodesPerCell>=0)
3250 for(int j=0;j<nbNodesPerCell;j++)
3252 int nodeId=conn[conni[0]+j];
3256 if(fastFinder[nodeId])
3263 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !";
3264 throw INTERP_KERNEL::Exception(oss.str().c_str());
3266 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
3267 cellIdsKept->pushBackSilent(i);
3269 cellIdsKeptArr=cellIdsKept.retn();
3272 void MEDCoupling1DGTUMesh::allocateCells(int nbOfCells)
3275 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !");
3276 _conn=DataArrayInt::New();
3277 _conn->reserve(nbOfCells*3);
3278 _conn_indx=DataArrayInt::New();
3279 _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0);
3284 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
3286 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
3287 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
3288 * \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
3289 * attached to \a this.
3290 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
3292 void MEDCoupling1DGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd)
3294 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
3295 DataArrayInt *c(_conn),*c2(_conn_indx);
3299 if(pos==c->getNumberOfTuples())
3301 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
3302 c2->pushBackSilent(pos+sz);
3306 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !";
3307 throw INTERP_KERNEL::Exception(oss.str().c_str());
3311 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !");
3314 void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex)
3317 nodalConn->incrRef();
3320 nodalConnIndex->incrRef();
3321 _conn_indx=nodalConnIndex;
3326 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
3328 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivity() const
3330 const DataArrayInt *ret(_conn);
3331 return const_cast<DataArrayInt *>(ret);
3335 * \return DataArrayInt * - the internal reference to the nodal connectivity index. The caller is not reponsible to deallocate it.
3337 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const
3339 const DataArrayInt *ret(_conn_indx);
3340 return const_cast<DataArrayInt *>(ret);
3344 * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here".
3345 * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity).
3346 * 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.
3348 * 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.
3350 * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal
3351 * connectivity arrays are different (false)
3352 * \return a new object to be managed by the caller.
3354 * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked
3356 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const
3358 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3359 DataArrayInt *nc=0,*nci=0;
3360 isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci);
3361 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ncs(nc),ncis(nci);
3362 ret->_conn=ncs; ret->_conn_indx=ncis;
3363 ret->setCoords(getCoords());
3368 * This method allows to compute, if needed, the packed nodal connectivity pair.
3369 * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges convered by nodal connectivity index array.
3370 * 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.
3372 * 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)
3373 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3375 * 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
3378 * This method return 3 elements.
3379 * \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
3380 * this pointer can be seen as a new object, that is to managed by the caller.
3381 * \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
3382 * this pointer can be seen as a new object, that is to managed by the caller.
3383 * \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
3384 * output parameters are newly created objects.
3386 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
3388 bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const
3390 if(isPacked())//performs the checkCoherency
3392 const DataArrayInt *c0(_conn),*c1(_conn_indx);
3393 nodalConn=const_cast<DataArrayInt *>(c0); nodalConnIndx=const_cast<DataArrayInt *>(c1);
3394 nodalConn->incrRef(); nodalConnIndx->incrRef();
3397 int bg=_conn_indx->front(),end=_conn_indx->back();
3398 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nc(_conn->selectByTupleId2(bg,end,1));
3399 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nci(_conn_indx->deepCpy());
3400 nci->applyLin(1,-bg);
3401 nodalConn=nc.retn(); nodalConnIndx=nci.retn();
3406 * 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)
3407 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3408 * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned.
3409 * \return bool - true if \a this looks packed, false is not.
3411 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
3413 bool MEDCoupling1DGTUMesh::isPacked() const
3416 return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples();
3419 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2)
3421 std::vector<const MEDCoupling1DGTUMesh *> tmp(2);
3422 tmp[0]=const_cast<MEDCoupling1DGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1DGTUMesh *>(mesh2);
3423 return Merge1DGTUMeshes(tmp);
3426 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a)
3428 std::size_t sz=a.size();
3430 return Merge1DGTUMeshesLL(a);
3431 for(std::size_t ii=0;ii<sz;ii++)
3434 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::Merge1DGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
3435 throw INTERP_KERNEL::Exception(oss.str().c_str());
3437 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
3438 for(std::size_t ii=0;ii<sz;ii++)
3439 if(&(a[ii]->getCellModel())!=cm)
3440 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !");
3441 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > bb(sz);
3442 std::vector< const MEDCoupling1DGTUMesh * > aa(sz);
3444 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
3446 const MEDCoupling1DGTUMesh *cur=a[i];
3447 const DataArrayDouble *coo=cur->getCoords();
3449 spaceDim=coo->getNumberOfComponents();
3452 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !");
3453 for(std::size_t i=0;i<sz;i++)
3455 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
3458 return Merge1DGTUMeshesLL(aa);
3462 * \throw If presence of a null instance in the input vector \a a.
3463 * \throw If a is empty
3465 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a)
3468 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !");
3469 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3471 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !");
3472 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
3473 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3474 (*it)->getNumberOfCells();//to check that all is OK
3475 const DataArrayDouble *coords=(*it)->getCoords();
3476 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3478 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3479 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3481 for(int i=1;it!=a.end();i++,it++)
3484 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !");
3485 if(cm!=&((*it)->getCellModel()))
3486 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3487 (*it)->getNumberOfCells();//to check that all is OK
3488 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3489 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3490 if(coords!=(*it)->getCoords())
3491 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !");
3493 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3494 ret->setCoords(coords);
3495 ret->_conn=DataArrayInt::Aggregate(ncs);
3496 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3501 * 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)
3503 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a)
3506 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : input array must be NON EMPTY !");
3507 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
3508 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3509 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3510 std::vector<int> nbNodesPerElt(a.size());
3511 int nbOfCells=(*it)->getNumberOfCells();
3513 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3514 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3516 int prevNbOfNodes=(*it)->getNumberOfNodes();
3517 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3519 for(int i=1;it!=a.end();i++,it++)
3521 if(cm!=&((*it)->getCellModel()))
3522 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3523 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3524 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3525 nbOfCells+=(*it)->getNumberOfCells();
3526 nbNodesPerElt[i]=nbNodesPerElt[i-1]+prevNbOfNodes;
3527 prevNbOfNodes=(*it)->getNumberOfNodes();
3529 std::vector<const MEDCouplingPointSet *> aps(a.size());
3530 std::copy(a.begin(),a.end(),aps.begin());
3531 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
3532 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3533 ret->setCoords(pts);
3534 ret->_conn=AggregateNodalConnAndShiftNodeIds(ncs,nbNodesPerElt);
3535 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3539 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(int spaceDim) const
3541 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3542 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1,tmp2;
3543 const DataArrayInt *nodalConn(_conn),*nodalConnI(_conn_indx);
3546 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
3554 tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
3558 ret->_conn_indx=tmp2;
3562 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
3563 ret->setCoords(coords);
3566 ret->setCoords(_coords);
3571 * This method aggregate the bbox of each cell and put it into bbox parameter.
3573 * \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)
3574 * For all other cases this input parameter is ignored.
3575 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
3577 * \throw If \a this is not fully set (coordinates and connectivity).
3578 * \throw If a cell in \a this has no valid nodeId.
3580 DataArrayDouble *MEDCoupling1DGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
3582 checkFullyDefined();
3583 int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes());
3584 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
3585 double *bbox(ret->getPointer());
3586 for(int i=0;i<nbOfCells*spaceDim;i++)
3588 bbox[2*i]=std::numeric_limits<double>::max();
3589 bbox[2*i+1]=-std::numeric_limits<double>::max();
3591 const double *coordsPtr(_coords->getConstPointer());
3592 const int *conn(_conn->getConstPointer()),*connI(_conn_indx->getConstPointer());
3593 for(int i=0;i<nbOfCells;i++)
3595 int offset=connI[i];
3596 int nbOfNodesForCell(connI[i+1]-offset),kk(0);
3597 for(int j=0;j<nbOfNodesForCell;j++)
3599 int nodeId=conn[offset+j];
3600 if(nodeId>=0 && nodeId<nbOfNodes)
3602 for(int k=0;k<spaceDim;k++)
3604 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
3605 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
3612 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
3613 throw INTERP_KERNEL::Exception(oss.str().c_str());
3620 * Returns the cell field giving for each cell in \a this its diameter. Diameter means the max length of all possible SEG2 in the cell.
3622 * \return a new instance of field containing the result. The returned instance has to be deallocated by the caller.
3624 MEDCouplingFieldDouble *MEDCoupling1DGTUMesh::computeDiameterField() const
3626 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::computeDiameterField : not implemented yet for dynamic types !");
3629 std::vector<int> MEDCoupling1DGTUMesh::BuildAPolygonFromParts(const std::vector< std::vector<int> >& parts)
3631 std::vector<int> ret;
3634 ret.insert(ret.end(),parts[0].begin(),parts[0].end());
3635 int ref(ret.back());
3636 std::size_t sz(parts.size()),nbh(1);
3637 std::vector<bool> b(sz,true); b[0]=false;
3641 for(;i<sz;i++) if(b[i] && parts[i].front()==ref) { ret.insert(ret.end(),parts[i].begin()+1,parts[i].end()); nbh++; break; }
3645 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::BuildAPolygonFromParts : the input vector is not a part of a single polygon !");
3647 if(ret.back()==ret.front())
3653 * This method performs an aggregation of \a nodalConns (as DataArrayInt::Aggregate does) but in addition of that a shift is applied on the
3654 * values contained in \a nodalConns using corresponding offset specified in input \a offsetInNodeIdsPerElt.
3655 * But it also manage the values -1, that have a semantic in MEDCoupling1DGTUMesh class (separator for polyhedron).
3657 * \param [in] nodalConns - a list of nodal connectivity arrays same size than \a offsetInNodeIdsPerElt.
3658 * \param [in] offsetInNodeIdsPerElt - a list of offsets to apply.
3659 * \return DataArrayInt * - A new object (to be managed by the caller) that is the result of the aggregation.
3660 * \throw If \a nodalConns or \a offsetInNodeIdsPerElt are empty.
3661 * \throw If \a nodalConns and \a offsetInNodeIdsPerElt have not the same size.
3662 * \throw If presence of null pointer in \a nodalConns.
3663 * \throw If presence of not allocated or array with not exactly one component in \a nodalConns.
3665 DataArrayInt *MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds(const std::vector<const DataArrayInt *>& nodalConns, const std::vector<int>& offsetInNodeIdsPerElt)
3667 std::size_t sz1(nodalConns.size()),sz2(offsetInNodeIdsPerElt.size());
3669 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : input vectors do not have the same size !");
3671 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : empty vectors in input !");
3673 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++)
3676 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of null pointer in input vector !");
3677 if(!(*it)->isAllocated())
3678 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of non allocated array in input vector !");
3679 if((*it)->getNumberOfComponents()!=1)
3680 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of array with not exactly one component !");
3681 nbOfTuples+=(*it)->getNumberOfTuples();
3683 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
3684 int *pt=ret->getPointer();
3686 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++,i++)
3688 int curNbt=(*it)->getNumberOfTuples();
3689 const int *inPt=(*it)->begin();
3690 int offset=offsetInNodeIdsPerElt[i];
3691 for(int j=0;j<curNbt;j++,pt++)
3702 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m)
3705 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh is null !");
3706 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
3708 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh must have exactly one geometric type !");
3709 int geoType((int)*gts.begin());
3710 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(m->getName(),*gts.begin()));
3711 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription());
3712 int nbCells(m->getNumberOfCells());
3713 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
3714 conn->alloc(m->getMeshLength()-nbCells,1); connI->alloc(nbCells+1,1);
3715 int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
3716 const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
3717 for(int i=0;i<nbCells;i++,ciin++,ci++)
3719 if(cin[ciin[0]]==geoType)
3721 if(ciin[1]-ciin[0]>=1)
3723 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
3724 ci[1]=ci[0]+ciin[1]-ciin[0]-1;
3728 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 !";
3729 throw INTERP_KERNEL::Exception(oss.str().c_str());
3734 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 !";
3735 throw INTERP_KERNEL::Exception(oss.str().c_str());
3738 ret->setNodalConnectivity(conn,connI);