1 // Copyright (C) 2007-2016 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 "OrientationInverter.hxx"
29 #include "InterpKernelAutoPtr.hxx"
31 using namespace MEDCoupling;
33 const int MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[6]={0,1,2,4,3,5};
35 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh():_cm(0)
39 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):_cm(&cm)
44 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const MEDCoupling1GTUMesh& other, bool recDeepCpy):MEDCouplingPointSet(other,recDeepCpy),_cm(other._cm)
48 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
50 if(type==INTERP_KERNEL::NORM_ERROR)
51 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
52 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
54 return MEDCoupling1SGTUMesh::New(name,type);
56 return MEDCoupling1DGTUMesh::New(name,type);
59 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const MEDCouplingUMesh *m)
62 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh is null !");
63 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
65 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh must have exactly one geometric type !");
66 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*gts.begin());
68 return MEDCoupling1SGTUMesh::New(m);
70 return MEDCoupling1DGTUMesh::New(m);
73 const INTERP_KERNEL::CellModel& MEDCoupling1GTUMesh::getCellModel() const
78 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getCellModelEnum() const
80 return _cm->getEnum();
83 int MEDCoupling1GTUMesh::getMeshDimension() const
85 return (int)_cm->getDimension();
89 * This method returns a newly allocated array containing cell ids (ascendingly sorted) whose geometric type are equal to type.
90 * This method does not throw exception if geometric type \a type is not in \a this.
91 * This method throws an INTERP_KERNEL::Exception if meshdimension of \b this is not equal to those of \b type.
92 * The coordinates array is not considered here.
94 * \param [in] type the geometric type
95 * \return cell ids in this having geometric type \a type.
97 DataArrayInt *MEDCoupling1GTUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
99 MCAuto<DataArrayInt> ret=DataArrayInt::New();
100 if(type==getCellModelEnum())
101 ret->alloc(getNumberOfCells(),1);
109 * Returns nb of cells having the geometric type \a type. No throw if no cells in \a this has the geometric type \a type.
111 int MEDCoupling1GTUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
113 return type==getCellModelEnum()?getNumberOfCells():0;
117 * Returns a type of a cell by its id.
118 * \param [in] cellId - the id of the cell of interest.
119 * \return INTERP_KERNEL::NormalizedCellType - enumeration item describing the cell type.
120 * \throw If \a cellId is invalid. Valid range is [0, \a this->getNumberOfCells() ).
122 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getTypeOfCell(int cellId) const
124 if(cellId>=0 && cellId<getNumberOfCells())
125 return getCellModelEnum();
126 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::getTypeOfCell : Requesting type of cell #" << cellId << " but it should be in [0," << getNumberOfCells() << ") !";
127 throw INTERP_KERNEL::Exception(oss.str().c_str());
131 * Returns a set of all cell types available in \a this mesh.
132 * \return std::set<INTERP_KERNEL::NormalizedCellType> - the set of cell types.
133 * \warning this method does not throw any exception even if \a this is not defined.
135 std::set<INTERP_KERNEL::NormalizedCellType> MEDCoupling1GTUMesh::getAllGeoTypes() const
137 std::set<INTERP_KERNEL::NormalizedCellType> ret;
138 ret.insert(getCellModelEnum());
143 * This method expects that \a this is sorted by types. If not an exception will be thrown.
144 * This method returns in the same format as code (see MEDCouplingUMesh::checkTypeConsistencyAndContig or MEDCouplingUMesh::splitProfilePerType) how
145 * \a this is composed in cell types.
146 * The returned array is of size 3*n where n is the number of different types present in \a this.
147 * For every k in [0,n] ret[3*k+2]==-1 because it has no sense here.
148 * This parameter is kept only for compatibility with other methode listed above.
150 std::vector<int> MEDCoupling1GTUMesh::getDistributionOfTypes() const
152 std::vector<int> ret(3);
153 ret[0]=(int)getCellModelEnum(); ret[1]=getNumberOfCells(); ret[2]=-1;
158 * 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.
159 * 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.
160 * This method has 1 input \a profile and 3 outputs \a code \a idsInPflPerType and \a idsPerType.
162 * \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.
163 * \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,
164 * \a idsInPflPerType[i] stores the tuple ids in \a profile that correspond to the geometric type code[3*i+0]
165 * \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.
166 * This vector can be empty in case of all geometric type cells are fully covered in ascending in the given input \a profile.
168 * \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.
170 * \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
173 * - Before \a this has 3 cells \a profile contains [0,1,2]
174 * - After \a code contains [NORM_...,nbCells,-1], \a idsInPflPerType [[0,1,2]] and \a idsPerType is empty <br>
177 * - Before \a this has 3 cells \a profile contains [1,2]
178 * - After \a code contains [NORM_...,nbCells,0], \a idsInPflPerType [[0,1]] and \a idsPerType is [[1,2]] <br>
181 void MEDCoupling1GTUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const
184 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile is NULL !");
185 if(profile->getNumberOfComponents()!=1)
186 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile should have exactly one component !");
187 int nbTuples(profile->getNumberOfTuples()),nbOfCells(getNumberOfCells());
188 code.resize(3); idsInPflPerType.resize(1);
189 code[0]=(int)getCellModelEnum(); code[1]=nbTuples;
190 idsInPflPerType.resize(1);
191 if(profile->isIota(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 MCAuto<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::checkConsistencyLight() const
302 MEDCouplingPointSet::checkConsistencyLight();
305 DataArrayDouble *MEDCoupling1GTUMesh::computeCellCenterOfMass() const
307 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
308 MCAuto<DataArrayDouble> ret=m->computeCellCenterOfMass();
312 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureField(bool isAbs) const
314 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
315 MCAuto<MEDCouplingFieldDouble> ret=m->getMeasureField(isAbs);
320 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureFieldOnNode(bool isAbs) const
322 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
323 MCAuto<MEDCouplingFieldDouble> ret=m->getMeasureFieldOnNode(isAbs);
331 int MEDCoupling1GTUMesh::getCellContainingPoint(const double *pos, double eps) const
333 MCAuto<MEDCouplingUMesh> m(buildUnstructured());
334 return m->getCellContainingPoint(pos,eps);
340 void MEDCoupling1GTUMesh::getCellsContainingPoint(const double *pos, double eps, std::vector<int>& elts) const
342 MCAuto<MEDCouplingUMesh> m(buildUnstructured());
343 return m->getCellsContainingPoint(pos,eps,elts);
346 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::buildOrthogonalField() const
348 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
349 MCAuto<MEDCouplingFieldDouble> ret=m->buildOrthogonalField();
354 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const double *bbox, double eps) const
356 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
357 return m->getCellsInBoundingBox(bbox,eps);
360 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps)
362 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
363 return m->getCellsInBoundingBox(bbox,eps);
366 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const
368 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
369 return m->buildFacePartOfMySelfNode(start,end,fullyIn);
372 DataArrayInt *MEDCoupling1GTUMesh::findBoundaryNodes() const
374 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
375 return m->findBoundaryNodes();
378 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildBoundaryMesh(bool keepCoords) const
380 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
381 return m->buildBoundaryMesh(keepCoords);
384 void MEDCoupling1GTUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const
386 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
387 m->findCommonCells(compType,startCellId,commonCellsArr,commonCellsIArr);
390 int MEDCoupling1GTUMesh::getNodalConnectivityLength() const
392 const DataArrayInt *c1(getNodalConnectivity());
394 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : no connectivity set !");
395 if(c1->getNumberOfComponents()!=1)
396 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array set must have exactly one component !");
397 if(!c1->isAllocated())
398 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array must be allocated !");
399 return c1->getNumberOfTuples();
403 * This method aggregates all the meshes in \a parts to put them in a single unstructured mesh (those returned).
404 * The order of cells is the returned instance is those in the order of instances in \a parts.
406 * \param [in] parts - all not null parts of single geo type meshes to be aggreagated having the same mesh dimension and same coordinates.
407 * \return MEDCouplingUMesh * - new object to be dealt by the caller.
409 * \throw If one element is null in \a parts.
410 * \throw If not all the parts do not have the same mesh dimension.
411 * \throw If not all the parts do not share the same coordinates.
412 * \throw If not all the parts have their connectivity set properly.
413 * \throw If \a parts is empty.
415 MEDCouplingUMesh *MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh(const std::vector< const MEDCoupling1GTUMesh *>& parts)
418 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : input parts vector is empty !");
419 const MEDCoupling1GTUMesh *firstPart(parts[0]);
421 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : the first instance in input parts is null !");
422 const DataArrayDouble *coords(firstPart->getCoords());
423 int meshDim(firstPart->getMeshDimension());
424 MCAuto<MEDCouplingUMesh> ret(MEDCouplingUMesh::New(firstPart->getName(),meshDim)); ret->setDescription(firstPart->getDescription());
425 ret->setCoords(coords);
426 int nbOfCells(0),connSize(0);
427 for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
430 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of null pointer in input vector !");
431 if((*it)->getMeshDimension()!=meshDim)
432 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances in input vector must have same mesh dimension !");
433 if((*it)->getCoords()!=coords)
434 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances must share the same coordinates pointer !");
435 nbOfCells+=(*it)->getNumberOfCells();
436 connSize+=(*it)->getNodalConnectivityLength();
438 MCAuto<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
439 connI->alloc(nbOfCells+1,1); conn->alloc(connSize+nbOfCells,1);
440 int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
441 for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
443 int curNbCells((*it)->getNumberOfCells());
444 int geoType((int)(*it)->getCellModelEnum());
445 const int *cinPtr((*it)->getNodalConnectivity()->begin());
446 const MEDCoupling1SGTUMesh *ps(dynamic_cast<const MEDCoupling1SGTUMesh *>(*it));
447 const MEDCoupling1DGTUMesh *pd(dynamic_cast<const MEDCoupling1DGTUMesh *>(*it));
450 int nNodesPerCell(ps->getNumberOfNodesPerCell());
451 for(int i=0;i<curNbCells;i++,ci++,cinPtr+=nNodesPerCell)
454 c=std::copy(cinPtr,cinPtr+nNodesPerCell,c);
455 ci[1]=ci[0]+nNodesPerCell+1;
460 const int *ciinPtr(pd->getNodalConnectivityIndex()->begin());
461 for(int i=0;i<curNbCells;i++,ci++,ciinPtr++)
464 c=std::copy(cinPtr+ciinPtr[0],cinPtr+ciinPtr[1],c);
465 ci[1]=ci[0]+ciinPtr[1]-ciinPtr[0]+1;
469 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of instance which type is not in [MEDCoupling1SGTUMesh,MEDCoupling1DGTUMesh] !");
471 ret->setConnectivity(conn,connI,true);
477 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const MEDCoupling1SGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
481 const DataArrayInt *c(other._conn);
487 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
491 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh()
495 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New()
497 return new MEDCoupling1SGTUMesh;
500 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
502 if(type==INTERP_KERNEL::NORM_ERROR)
503 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
504 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
507 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New : the input geometric type " << cm.getRepr() << " is dynamic ! Only static types are allowed here !";
508 throw INTERP_KERNEL::Exception(oss.str().c_str());
510 return new MEDCoupling1SGTUMesh(name,cm);
513 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m)
516 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh is null !");
517 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
519 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh must have exactly one geometric type !");
520 int geoType((int)*gts.begin());
521 MCAuto<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(m->getName(),*gts.begin()));
522 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription());
523 int nbCells(m->getNumberOfCells());
524 int nbOfNodesPerCell(ret->getNumberOfNodesPerCell());
525 MCAuto<DataArrayInt> conn(DataArrayInt::New()); conn->alloc(nbCells*nbOfNodesPerCell,1);
526 int *c(conn->getPointer());
527 const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
528 for(int i=0;i<nbCells;i++,ciin++)
530 if(cin[ciin[0]]==geoType)
532 if(ciin[1]-ciin[0]==nbOfNodesPerCell+1)
533 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
536 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 << ") !";
537 throw INTERP_KERNEL::Exception(oss.str().c_str());
542 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 !";
543 throw INTERP_KERNEL::Exception(oss.str().c_str());
546 ret->setNodalConnectivity(conn);
548 { ret->copyTinyInfoFrom(m); }
549 catch(INTERP_KERNEL::Exception&) { }
553 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::clone(bool recDeepCpy) const
555 return new MEDCoupling1SGTUMesh(*this,recDeepCpy);
559 * This method behaves mostly like MEDCoupling1SGTUMesh::deepCopy method, except that only nodal connectivity arrays are deeply copied.
560 * The coordinates are shared between \a this and the returned instance.
562 * \return MEDCoupling1SGTUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
563 * \sa MEDCoupling1SGTUMesh::deepCopy
565 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::deepCopyConnectivityOnly() const
567 checkConsistencyLight();
568 MCAuto<MEDCoupling1SGTUMesh> ret(clone(false));
569 MCAuto<DataArrayInt> c(_conn->deepCopy());
570 ret->setNodalConnectivity(c);
574 void MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
577 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
578 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
580 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1SGTUMesh instance !");
581 setNodalConnectivity(otherC->getNodalConnectivity());
584 void MEDCoupling1SGTUMesh::updateTime() const
586 MEDCoupling1GTUMesh::updateTime();
587 const DataArrayInt *c(_conn);
592 std::size_t MEDCoupling1SGTUMesh::getHeapMemorySizeWithoutChildren() const
594 return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren();
597 std::vector<const BigMemoryObject *> MEDCoupling1SGTUMesh::getDirectChildrenWithNull() const
599 std::vector<const BigMemoryObject *> ret(MEDCoupling1GTUMesh::getDirectChildrenWithNull());
600 ret.push_back((const DataArrayInt *)_conn);
604 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::deepCopy() const
609 bool MEDCoupling1SGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
612 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualIfNotWhy : input other pointer is null !");
613 std::ostringstream oss; oss.precision(15);
614 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
617 reason="mesh given in input is not castable in MEDCoupling1SGTUMesh !";
620 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
622 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
627 reason="in connectivity of single static geometric type exactly one among this and other is null !";
630 if(!c1->isEqualIfNotWhy(*c2,reason))
632 reason.insert(0,"Nodal connectivity DataArrayInt differ : ");
638 bool MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
641 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
642 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
645 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
647 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
652 if(!c1->isEqualWithoutConsideringStr(*c2))
657 void MEDCoupling1SGTUMesh::checkConsistencyOfConnectivity() const
659 const DataArrayInt *c1(_conn);
662 if(c1->getNumberOfComponents()!=1)
663 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
664 if(c1->getInfoOnComponent(0)!="")
665 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
666 c1->checkAllocated();
669 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
672 void MEDCoupling1SGTUMesh::checkConsistencyLight() const
674 MEDCouplingPointSet::checkConsistencyLight();
675 checkConsistencyOfConnectivity();
678 void MEDCoupling1SGTUMesh::checkConsistency(double eps) const
680 checkConsistencyLight();
681 const DataArrayInt *c1(_conn);
682 int nbOfTuples=c1->getNumberOfTuples();
683 int nbOfNodesPerCell=(int)_cm->getNumberOfNodes();
684 if(nbOfTuples%nbOfNodesPerCell!=0)
686 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::checkConsistency : the nb of tuples in conn is " << nbOfTuples << " and number of nodes per cell is " << nbOfNodesPerCell << ". But " << nbOfTuples << "%" << nbOfNodesPerCell << " !=0 !";
687 throw INTERP_KERNEL::Exception(oss.str().c_str());
689 int nbOfNodes=getNumberOfNodes();
690 int nbOfCells=nbOfTuples/nbOfNodesPerCell;
691 const int *w(c1->begin());
692 for(int i=0;i<nbOfCells;i++)
693 for(int j=0;j<nbOfNodesPerCell;j++,w++)
695 if(*w<0 || *w>=nbOfNodes)
697 std::ostringstream oss; oss << "At node #" << j << " of cell #" << i << ", is equal to " << *w << " must be in [0," << nbOfNodes << ") !";
698 throw INTERP_KERNEL::Exception(oss.str().c_str());
703 int MEDCoupling1SGTUMesh::getNumberOfCells() const
705 int nbOfTuples=getNodalConnectivityLength();
706 int nbOfNodesPerCell=getNumberOfNodesPerCell();
707 if(nbOfTuples%nbOfNodesPerCell!=0)
709 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 !";
710 throw INTERP_KERNEL::Exception(oss.str().c_str());
712 return nbOfTuples/nbOfNodesPerCell;
715 int MEDCoupling1SGTUMesh::getNumberOfNodesInCell(int cellId) const
717 return getNumberOfNodesPerCell();
720 int MEDCoupling1SGTUMesh::getNumberOfNodesPerCell() const
722 checkNonDynamicGeoType();
723 return (int)_cm->getNumberOfNodes();
726 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfNodesPerCell() const
728 checkNonDynamicGeoType();
729 MCAuto<DataArrayInt> ret=DataArrayInt::New();
730 ret->alloc(getNumberOfCells(),1);
731 ret->fillWithValue((int)_cm->getNumberOfNodes());
735 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfFacesPerCell() const
737 checkNonDynamicGeoType();
738 MCAuto<DataArrayInt> ret=DataArrayInt::New();
739 ret->alloc(getNumberOfCells(),1);
740 ret->fillWithValue((int)_cm->getNumberOfSons());
744 DataArrayInt *MEDCoupling1SGTUMesh::computeEffectiveNbOfNodesPerCell() const
746 checkNonDynamicGeoType();
747 MCAuto<DataArrayInt> ret=DataArrayInt::New();
748 int nbCells(getNumberOfCells());
749 ret->alloc(nbCells,1);
750 int *retPtr(ret->getPointer());
751 int nbNodesPerCell(getNumberOfNodesPerCell());
752 const int *conn(_conn->begin());
753 for(int i=0;i<nbCells;i++,conn+=nbNodesPerCell,retPtr++)
755 std::set<int> s(conn,conn+nbNodesPerCell);
756 *retPtr=(int)s.size();
761 void MEDCoupling1SGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
763 int sz=getNumberOfNodesPerCell();
765 if(cellId>=0 && cellId<getNumberOfCells())
766 std::copy(_conn->begin()+cellId*sz,_conn->begin()+(cellId+1)*sz,conn.begin());
769 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << getNumberOfCells() << ") !";
770 throw INTERP_KERNEL::Exception(oss.str().c_str());
774 void MEDCoupling1SGTUMesh::checkNonDynamicGeoType() const
777 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkNonDynamicGeoType : internal error ! the internal geo type is dynamic ! should be static !");
780 std::string MEDCoupling1SGTUMesh::simpleRepr() const
782 static const char msg0[]="No coordinates specified !";
783 std::ostringstream ret;
784 ret << "Single static geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
785 ret << "Description of mesh : \"" << getDescription() << "\"\n";
787 double tt=getTime(tmpp1,tmpp2);
788 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
789 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
790 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
793 const int spaceDim=getSpaceDimension();
794 ret << spaceDim << "\nInfo attached on space dimension : ";
795 for(int i=0;i<spaceDim;i++)
796 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
801 ret << "Number of nodes : ";
803 ret << getNumberOfNodes() << "\n";
806 ret << "Number of cells : ";
807 if((const DataArrayInt *)_conn)
809 if(_conn->isAllocated())
811 if(_conn->getNumberOfComponents()==1)
812 ret << getNumberOfCells() << "\n";
814 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
817 ret << "Nodal connectivity array specified but not allocated !" << "\n";
820 ret << "No connectivity specified !" << "\n";
821 ret << "Cell type : " << _cm->getRepr() << "\n";
825 std::string MEDCoupling1SGTUMesh::advancedRepr() const
827 std::ostringstream ret;
829 ret << "\nCoordinates array : \n___________________\n\n";
831 _coords->reprWithoutNameStream(ret);
833 ret << "No array set !\n";
834 ret << "\n\nConnectivity array : \n____________________\n\n";
836 if((const DataArrayInt *)_conn)
838 if(_conn->isAllocated())
840 if(_conn->getNumberOfComponents()==1)
842 int nbOfCells=getNumberOfCells();
843 int sz=getNumberOfNodesPerCell();
844 const int *connPtr=_conn->begin();
845 for(int i=0;i<nbOfCells;i++,connPtr+=sz)
847 ret << "Cell #" << i << " : ";
848 std::copy(connPtr,connPtr+sz,std::ostream_iterator<int>(ret," "));
853 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
856 ret << "Nodal connectivity array specified but not allocated !" << "\n";
859 ret << "No connectivity specified !" << "\n";
863 DataArrayDouble *MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell() const
865 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
866 int spaceDim=getSpaceDimension();
867 int nbOfCells=getNumberOfCells();//checkConsistencyLight()
868 int nbOfNodes=getNumberOfNodes();
869 ret->alloc(nbOfCells,spaceDim);
870 double *ptToFill=ret->getPointer();
871 const double *coor=_coords->begin();
872 const int *nodal=_conn->begin();
873 int sz=getNumberOfNodesPerCell();
874 double coeff=1./(double)sz;
875 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim)
877 std::fill(ptToFill,ptToFill+spaceDim,0.);
878 for(int j=0;j<sz;j++,nodal++)
879 if(*nodal>=0 && *nodal<nbOfNodes)
880 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
883 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
884 throw INTERP_KERNEL::Exception(oss.str().c_str());
886 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),coeff));
891 void MEDCoupling1SGTUMesh::renumberCells(const int *old2NewBg, bool check)
893 int nbCells=getNumberOfCells();
894 MCAuto<DataArrayInt> o2n=DataArrayInt::New();
895 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
897 o2n=o2n->checkAndPreparePermutation();
899 const int *conn=_conn->begin();
900 MCAuto<DataArrayInt> n2o=o2n->invertArrayO2N2N2O(nbCells);
901 const int *n2oPtr=n2o->begin();
902 MCAuto<DataArrayInt> newConn=DataArrayInt::New();
903 newConn->alloc(_conn->getNumberOfTuples(),1);
904 newConn->copyStringInfoFrom(*_conn);
905 int sz=getNumberOfNodesPerCell();
907 int *newC=newConn->getPointer();
908 for(int i=0;i<nbCells;i++,newC+=sz)
911 std::copy(conn+pos*sz,conn+(pos+1)*sz,newC);
917 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
918 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
919 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
920 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
922 * \param [in] begin input start of array of node ids.
923 * \param [in] end input end of array of node ids.
924 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
925 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
927 void MEDCoupling1SGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
929 int nbOfCells=getNumberOfCells();
930 MCAuto<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
932 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
933 std::vector<bool> fastFinder(sz,false);
934 for(const int *work=begin;work!=end;work++)
935 if(*work>=0 && *work<sz)
936 fastFinder[*work]=true;
937 const int *conn=_conn->begin();
938 int nbNodesPerCell=getNumberOfNodesPerCell();
939 for(int i=0;i<nbOfCells;i++,conn+=nbNodesPerCell)
942 for(int j=0;j<nbNodesPerCell;j++)
946 if(fastFinder[conn[j]])
949 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
950 cellIdsKept->pushBackSilent(i);
952 cellIdsKeptArr=cellIdsKept.retn();
955 MEDCouplingMesh *MEDCoupling1SGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
957 if(other->getType()!=SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED)
958 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single static geo type each other !");
959 const MEDCoupling1SGTUMesh *otherC=static_cast<const MEDCoupling1SGTUMesh *>(other);
960 return Merge1SGTUMeshes(this,otherC);
963 MEDCouplingUMesh *MEDCoupling1SGTUMesh::buildUnstructured() const
965 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
966 ret->setCoords(getCoords());
967 const int *nodalConn=_conn->begin();
968 int nbCells=getNumberOfCells();
969 int nbNodesPerCell=getNumberOfNodesPerCell();
970 int geoType=(int)getCellModelEnum();
971 MCAuto<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells*(nbNodesPerCell+1),1);
972 int *cPtr=c->getPointer();
973 for(int i=0;i<nbCells;i++,nodalConn+=nbNodesPerCell)
976 cPtr=std::copy(nodalConn,nodalConn+nbNodesPerCell,cPtr);
978 MCAuto<DataArrayInt> cI=DataArrayInt::Range(0,(nbCells+1)*(nbNodesPerCell+1),nbNodesPerCell+1);
979 ret->setConnectivity(c,cI,true);
981 { ret->copyTinyInfoFrom(this); }
982 catch(INTERP_KERNEL::Exception&) { }
986 DataArrayInt *MEDCoupling1SGTUMesh::simplexize(int policy)
991 return simplexizePol0();
993 return simplexizePol1();
994 case (int) INTERP_KERNEL::PLANAR_FACE_5:
995 return simplexizePlanarFace5();
996 case (int) INTERP_KERNEL::PLANAR_FACE_6:
997 return simplexizePlanarFace6();
999 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)");
1005 struct MEDCouplingAccVisit
1007 MEDCouplingAccVisit():_new_nb_of_nodes(0) { }
1008 int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; }
1009 int _new_nb_of_nodes;
1015 * This method returns all node ids used in \b this. The data array returned has to be dealt by the caller.
1016 * The returned node ids are sortes ascendingly. This method is closed to MEDCoupling1SGTUMesh::getNodeIdsInUse except
1017 * the format of returned DataArrayInt instance.
1019 * \return a newly allocated DataArrayInt sorted ascendingly of fetched node ids.
1020 * \sa MEDCoupling1SGTUMesh::getNodeIdsInUse, areAllNodesFetched
1022 DataArrayInt *MEDCoupling1SGTUMesh::computeFetchedNodeIds() const
1024 checkConsistencyOfConnectivity();
1025 int nbNodes(getNumberOfNodes());
1026 std::vector<bool> fetchedNodes(nbNodes,false);
1027 computeNodeIdsAlg(fetchedNodes);
1028 int sz((int)std::count(fetchedNodes.begin(),fetchedNodes.end(),true));
1029 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
1030 int *retPtr(ret->getPointer());
1031 for(int i=0;i<nbNodes;i++)
1038 * Finds nodes not used in any cell and returns an array giving a new id to every node
1039 * by excluding the unused nodes, for which the array holds -1. The result array is
1040 * a mapping in "Old to New" mode.
1041 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
1042 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
1043 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
1044 * if the node is unused or a new id else. The caller is to delete this
1045 * array using decrRef() as it is no more needed.
1046 * \throw If the coordinates array is not set.
1047 * \throw If the nodal connectivity of cells is not defined.
1048 * \throw If the nodal connectivity includes an invalid id.
1049 * \sa MEDCoupling1SGTUMesh::computeFetchedNodeIds, areAllNodesFetched
1051 DataArrayInt *MEDCoupling1SGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
1054 int nbOfNodes=getNumberOfNodes();
1055 int nbOfCells=getNumberOfCells();
1056 MCAuto<DataArrayInt> ret(DataArrayInt::New());
1057 ret->alloc(nbOfNodes,1);
1058 int *traducer=ret->getPointer();
1059 std::fill(traducer,traducer+nbOfNodes,-1);
1060 const int *conn=_conn->begin();
1061 int nbNodesPerCell=getNumberOfNodesPerCell();
1062 for(int i=0;i<nbOfCells;i++)
1063 for(int j=0;j<nbNodesPerCell;j++,conn++)
1064 if(*conn>=0 && *conn<nbOfNodes)
1068 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << conn[j] << " not in [0," << nbOfNodes << ") !";
1069 throw INTERP_KERNEL::Exception(oss.str().c_str());
1071 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
1072 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
1077 * This method renumbers only nodal connectivity in \a this. The renumbering is only an offset applied. So this method is a specialization of
1078 * \a renumberNodesInConn. \b WARNING, this method does not check that the resulting node ids in the nodal connectivity is in a valid range !
1080 * \param [in] offset - specifies the offset to be applied on each element of connectivity.
1082 * \sa renumberNodesInConn
1084 void MEDCoupling1SGTUMesh::renumberNodesWithOffsetInConn(int offset)
1086 getNumberOfCells();//only to check that all is well defined.
1087 _conn->applyLin(1,offset);
1092 * Same than renumberNodesInConn(const int *) except that here the format of old-to-new traducer is using map instead
1093 * 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
1096 void MEDCoupling1SGTUMesh::renumberNodesInConn(const INTERP_KERNEL::HashMap<int,int>& newNodeNumbersO2N)
1098 getNumberOfCells();//only to check that all is well defined.
1099 int *begPtr(_conn->getPointer());
1100 int nbElt(_conn->getNumberOfTuples());
1101 int *endPtr(begPtr+nbElt);
1102 for(int *it=begPtr;it!=endPtr;it++)
1104 INTERP_KERNEL::HashMap<int,int>::const_iterator it2(newNodeNumbersO2N.find(*it));
1105 if(it2!=newNodeNumbersO2N.end())
1111 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::renumberNodesInConn : At pos #" << std::distance(begPtr,it) << " of nodal connectivity value is " << *it << ". Not in map !";
1112 throw INTERP_KERNEL::Exception(oss.str().c_str());
1119 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
1120 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
1121 * This method is a generalization of shiftNodeNumbersInConn().
1122 * \warning This method performs no check of validity of new ids. **Use it with care !**
1123 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
1124 * this->getNumberOfNodes(), in "Old to New" mode.
1125 * See \ref numbering for more info on renumbering modes.
1126 * \throw If the nodal connectivity of cells is not defined.
1128 void MEDCoupling1SGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
1130 getNumberOfCells();//only to check that all is well defined.
1131 _conn->transformWithIndArr(newNodeNumbersO2N,newNodeNumbersO2N+getNumberOfNodes());
1135 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2)
1137 std::vector<const MEDCoupling1SGTUMesh *> tmp(2);
1138 tmp[0]=const_cast<MEDCoupling1SGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1SGTUMesh *>(mesh2);
1139 return Merge1SGTUMeshes(tmp);
1142 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(std::vector<const MEDCoupling1SGTUMesh *>& a)
1144 std::size_t sz=a.size();
1146 return Merge1SGTUMeshesLL(a);
1147 for(std::size_t ii=0;ii<sz;ii++)
1150 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::Merge1SGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
1151 throw INTERP_KERNEL::Exception(oss.str().c_str());
1153 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
1154 for(std::size_t ii=0;ii<sz;ii++)
1155 if(&(a[ii]->getCellModel())!=cm)
1156 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : all items must have the same geo type !");
1157 std::vector< MCAuto<MEDCoupling1SGTUMesh> > bb(sz);
1158 std::vector< const MEDCoupling1SGTUMesh * > aa(sz);
1160 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
1162 const MEDCoupling1SGTUMesh *cur=a[i];
1163 const DataArrayDouble *coo=cur->getCoords();
1165 spaceDim=coo->getNumberOfComponents();
1168 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : no spaceDim specified ! unable to perform merge !");
1169 for(std::size_t i=0;i<sz;i++)
1171 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
1174 return Merge1SGTUMeshesLL(aa);
1178 * \throw If presence of a null instance in the input vector \a a.
1179 * \throw If a is empty
1181 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::vector<const MEDCoupling1SGTUMesh *>& a)
1184 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : input array must be NON EMPTY !");
1185 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1187 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : null instance in the first element of input vector !");
1188 std::vector<const DataArrayInt *> ncs(a.size());
1189 (*it)->getNumberOfCells();//to check that all is OK
1190 const DataArrayDouble *coords=(*it)->getCoords();
1191 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1192 ncs[0]=(*it)->getNodalConnectivity();
1194 for(int i=1;it!=a.end();i++,it++)
1197 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : presence of a null instance in the input vector !");
1198 if(cm!=&((*it)->getCellModel()))
1199 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1200 (*it)->getNumberOfCells();//to check that all is OK
1201 ncs[i]=(*it)->getNodalConnectivity();
1202 if(coords!=(*it)->getCoords())
1203 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : not lying on same coords !");
1205 MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1206 ret->setCoords(coords);
1207 ret->_conn=DataArrayInt::Aggregate(ncs);
1212 * 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)
1214 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector<const MEDCoupling1SGTUMesh *>& a)
1217 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : input array must be NON EMPTY !");
1218 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1219 int nbOfCells=(*it)->getNumberOfCells();
1220 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1221 int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
1223 for(;it!=a.end();it++)
1225 if(cm!=&((*it)->getCellModel()))
1226 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1227 nbOfCells+=(*it)->getNumberOfCells();
1229 std::vector<const MEDCouplingPointSet *> aps(a.size());
1230 std::copy(a.begin(),a.end(),aps.begin());
1231 MCAuto<DataArrayDouble> pts=MergeNodesArray(aps);
1232 MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1233 ret->setCoords(pts);
1234 MCAuto<DataArrayInt> c=DataArrayInt::New();
1235 c->alloc(nbOfCells*nbNodesPerCell,1);
1236 int *cPtr=c->getPointer();
1238 for(it=a.begin();it!=a.end();it++)
1240 int curConnLgth=(*it)->getNodalConnectivityLength();
1241 const int *curC=(*it)->_conn->begin();
1242 cPtr=std::transform(curC,curC+curConnLgth,cPtr,std::bind2nd(std::plus<int>(),offset));
1243 offset+=(*it)->getNumberOfNodes();
1246 ret->setNodalConnectivity(c);
1250 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
1252 int ncell=getNumberOfCells();
1253 MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1254 ret->setCoords(_coords);
1255 std::size_t nbOfElemsRet=std::distance(begin,end);
1256 const int *inConn=_conn->getConstPointer();
1257 int sz=getNumberOfNodesPerCell();
1258 MCAuto<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1259 int *connPtr=connRet->getPointer();
1260 for(const int *work=begin;work!=end;work++,connPtr+=sz)
1262 if(*work>=0 && *work<ncell)
1263 std::copy(inConn+(work[0])*sz,inConn+(work[0]+1)*sz,connPtr);
1266 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !";
1267 throw INTERP_KERNEL::Exception(oss.str().c_str());
1271 ret->copyTinyInfoFrom(this);
1275 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoordsSlice(int start, int end, int step) const
1277 int ncell=getNumberOfCells();
1278 int nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoordsSlice : ");
1279 MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1280 ret->setCoords(_coords);
1281 const int *inConn=_conn->getConstPointer();
1282 int sz=getNumberOfNodesPerCell();
1283 MCAuto<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1284 int *connPtr=connRet->getPointer();
1286 for(int i=0;i<nbOfElemsRet;i++,connPtr+=sz,curId+=step)
1288 if(curId>=0 && curId<ncell)
1289 std::copy(inConn+curId*sz,inConn+(curId+1)*sz,connPtr);
1292 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoordsSlice : On pos #" << i << " input cell id =" << curId << " should be in [0," << ncell << ") !";
1293 throw INTERP_KERNEL::Exception(oss.str().c_str());
1297 ret->copyTinyInfoFrom(this);
1301 void MEDCoupling1SGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
1303 int sz((int)nodeIdsInUse.size());
1304 for(const int *conn=_conn->begin();conn!=_conn->end();conn++)
1306 if(*conn>=0 && *conn<sz)
1307 nodeIdsInUse[*conn]=true;
1310 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeFetchedNodeIds : At pos #" << std::distance(_conn->begin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !";
1311 throw INTERP_KERNEL::Exception(oss.str().c_str());
1316 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(int spaceDim) const
1318 MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1319 MCAuto<DataArrayInt> tmp1;
1320 const DataArrayInt *nodalConn(_conn);
1323 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
1330 MCAuto<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
1331 ret->setCoords(coords);
1334 ret->setCoords(_coords);
1338 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol0()
1340 int nbOfCells=getNumberOfCells();
1341 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1342 return DataArrayInt::Range(0,nbOfCells,1);
1343 MCAuto<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1344 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1345 const int *c(_conn->begin());
1346 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1347 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1349 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[2];
1350 newConnPtr[3]=c[0]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1351 retPtr[0]=i; retPtr[1]=i;
1354 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1359 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol1()
1361 int nbOfCells=getNumberOfCells();
1362 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1363 return DataArrayInt::Range(0,nbOfCells,1);
1364 MCAuto<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1365 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1366 const int *c(_conn->begin());
1367 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1368 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1370 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[3];
1371 newConnPtr[3]=c[1]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1372 retPtr[0]=i; retPtr[1]=i;
1375 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1380 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace5()
1382 int nbOfCells=getNumberOfCells();
1383 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1384 return DataArrayInt::Range(0,nbOfCells,1);
1385 MCAuto<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(5*4*nbOfCells,1);
1386 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(5*nbOfCells,1);
1387 const int *c(_conn->begin());
1388 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1389 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=20,retPtr+=5)
1391 for(int j=0;j<20;j++)
1392 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_5_WO[j]];
1393 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i;
1396 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1401 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace6()
1403 int nbOfCells=getNumberOfCells();
1404 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1405 return DataArrayInt::Range(0,nbOfCells,1);
1406 MCAuto<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(6*4*nbOfCells,1);
1407 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(6*nbOfCells,1);
1408 const int *c(_conn->begin());
1409 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1410 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=24,retPtr+=6)
1412 for(int j=0;j<24;j++)
1413 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_6_WO[j]];
1414 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i; retPtr[5]=i;
1417 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1422 void MEDCoupling1SGTUMesh::reprQuickOverview(std::ostream& stream) const
1424 stream << "MEDCoupling1SGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
1425 stream << " Mesh dimension : " << getMeshDimension() << ".";
1427 { stream << " No coordinates set !"; return ; }
1428 if(!_coords->isAllocated())
1429 { stream << " Coordinates set but not allocated !"; return ; }
1430 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
1431 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
1432 if(!(const DataArrayInt *)_conn)
1433 { stream << std::endl << "Nodal connectivity NOT set !"; return ; }
1434 if(_conn->isAllocated())
1436 if(_conn->getNumberOfComponents()==1)
1437 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
1441 void MEDCoupling1SGTUMesh::checkFullyDefined() const
1443 if(!((const DataArrayInt *)_conn) || !((const DataArrayDouble *)_coords))
1444 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFullyDefined : part of this is not fully defined.");
1448 * First step of unserialization process.
1450 bool MEDCoupling1SGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
1452 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEmptyMesh : not implemented yet !");
1455 void MEDCoupling1SGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
1458 double time=getTime(it,order);
1459 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
1461 littleStrings.push_back(getName());
1462 littleStrings.push_back(getDescription());
1463 littleStrings.push_back(getTimeUnit());
1465 std::vector<std::string> littleStrings2,littleStrings3;
1466 if((const DataArrayDouble *)_coords)
1467 _coords->getTinySerializationStrInformation(littleStrings2);
1468 if((const DataArrayInt *)_conn)
1469 _conn->getTinySerializationStrInformation(littleStrings3);
1470 int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size());
1471 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
1472 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
1474 tinyInfo.push_back(getCellModelEnum());
1475 tinyInfo.push_back(it);
1476 tinyInfo.push_back(order);
1477 std::vector<int> tinyInfo2,tinyInfo3;
1478 if((const DataArrayDouble *)_coords)
1479 _coords->getTinySerializationIntInformation(tinyInfo2);
1480 if((const DataArrayInt *)_conn)
1481 _conn->getTinySerializationIntInformation(tinyInfo3);
1482 int sz2((int)tinyInfo2.size()),sz3((int)tinyInfo3.size());
1483 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3);
1484 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1485 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
1487 tinyInfoD.push_back(time);
1490 void MEDCoupling1SGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
1492 std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+tinyInfo[5]);
1493 std::vector<int> tinyInfo1(tinyInfo.begin()+7+tinyInfo[5],tinyInfo.begin()+7+tinyInfo[5]+tinyInfo[6]);
1494 a1->resizeForUnserialization(tinyInfo1);
1495 a2->resizeForUnserialization(tinyInfo2);
1498 void MEDCoupling1SGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
1501 if((const DataArrayInt *)_conn)
1502 if(_conn->isAllocated())
1503 sz=_conn->getNbOfElems();
1504 a1=DataArrayInt::New();
1506 if(sz!=0 && (const DataArrayInt *)_conn)
1507 std::copy(_conn->begin(),_conn->end(),a1->getPointer());
1509 if((const DataArrayDouble *)_coords)
1510 if(_coords->isAllocated())
1511 sz=_coords->getNbOfElems();
1512 a2=DataArrayDouble::New();
1514 if(sz!=0 && (const DataArrayDouble *)_coords)
1515 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
1518 void MEDCoupling1SGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
1519 const std::vector<std::string>& littleStrings)
1521 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
1522 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
1523 setName(littleStrings[0]);
1524 setDescription(littleStrings[1]);
1525 setTimeUnit(littleStrings[2]);
1526 setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
1527 int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]);
1529 _coords=DataArrayDouble::New();
1530 std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+sz2);
1531 _coords->resizeForUnserialization(tinyInfo2);
1532 std::copy(a2->begin(),a2->end(),_coords->getPointer());
1533 _conn=DataArrayInt::New();
1534 std::vector<int> tinyInfo3(tinyInfo.begin()+7+sz2,tinyInfo.begin()+7+sz2+sz3);
1535 _conn->resizeForUnserialization(tinyInfo3);
1536 std::copy(a1->begin(),a1->end(),_conn->getPointer());
1537 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
1538 _coords->finishUnserialization(tinyInfo2,littleStrings2);
1539 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
1540 _conn->finishUnserialization(tinyInfo3,littleStrings3);
1544 * Checks if \a this and \a other meshes are geometrically equivalent with high
1545 * probability, else an exception is thrown. The meshes are considered equivalent if
1546 * (1) meshes contain the same number of nodes and the same number of elements of the
1547 * same types (2) three cells of the two meshes (first, last and middle) are based
1548 * on coincident nodes (with a specified precision).
1549 * \param [in] other - the mesh to compare with.
1550 * \param [in] prec - the precision used to compare nodes of the two meshes.
1551 * \throw If the two meshes do not match.
1553 void MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
1555 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1556 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1558 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single static geometric type !");
1559 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1563 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1564 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1565 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1566 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1567 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1568 if(c1->getHashCode()!=c2->getHashCode())
1569 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1572 MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
1575 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
1576 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1578 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
1579 std::vector<const MEDCoupling1SGTUMesh *> ms(2);
1582 return Merge1SGTUMeshesOnSameCoords(ms);
1585 void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const
1587 checkFullyDefined();
1588 int nbOfNodes=getNumberOfNodes();
1589 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
1590 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
1591 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
1592 const int *conn=_conn->begin();
1593 int nbOfCells=getNumberOfCells();
1594 int nbOfEltsInRevNodal=0;
1595 int nbOfNodesPerCell=getNumberOfNodesPerCell();
1596 for(int eltId=0;eltId<nbOfCells;eltId++)
1598 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1600 if(conn[0]>=0 && conn[0]<nbOfNodes)
1602 nbOfEltsInRevNodal++;
1603 revNodalIndxPtr[conn[0]+1]++;
1607 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
1608 throw INTERP_KERNEL::Exception(oss.str().c_str());
1612 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
1613 conn=_conn->begin();
1614 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
1615 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
1616 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
1617 for(int eltId=0;eltId<nbOfCells;eltId++)
1619 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1621 *std::find_if(revNodalPtr+revNodalIndxPtr[*conn],revNodalPtr+revNodalIndxPtr[*conn+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
1627 * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null.
1629 void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn)
1632 nodalConn->incrRef();
1638 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
1640 DataArrayInt *MEDCoupling1SGTUMesh::getNodalConnectivity() const
1642 const DataArrayInt *ret(_conn);
1643 return const_cast<DataArrayInt *>(ret);
1647 * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted,
1648 * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter.
1649 * If a nodal connectivity previouly existed before the call of this method, it will be reset.
1651 * \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain.
1653 void MEDCoupling1SGTUMesh::allocateCells(int nbOfCells)
1656 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !");
1657 _conn=DataArrayInt::New();
1658 _conn->reserve(getNumberOfNodesPerCell()*nbOfCells);
1663 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
1665 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
1666 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
1667 * \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
1668 * attached to \a this.
1669 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
1671 void MEDCoupling1SGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd)
1673 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
1674 int ref=getNumberOfNodesPerCell();
1677 DataArrayInt *c(_conn);
1679 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
1681 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !");
1685 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this (";
1686 oss << ref << ") !";
1687 throw INTERP_KERNEL::Exception(oss.str().c_str());
1692 * This method builds the dual mesh of \a this and returns it.
1694 * \return MEDCoupling1SGTUMesh * - newly object created to be managed by the caller.
1695 * \throw If \a this is not a mesh containing only simplex cells.
1696 * \throw If \a this is not correctly allocated (coordinates and connectivities have to be correctly set !).
1697 * \throw If at least one node in \a this is orphan (without any simplex cell lying on it !)
1699 MEDCoupling1GTUMesh *MEDCoupling1SGTUMesh::computeDualMesh() const
1701 const INTERP_KERNEL::CellModel& cm(getCellModel());
1703 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : this mesh is not a simplex mesh ! Please invoke simplexize of tetrahedrize on this before calling this method !");
1704 switch(getMeshDimension())
1707 return computeDualMesh3D();
1709 return computeDualMesh2D();
1711 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : meshdimension must be in [2,3] !");
1716 * This method explode each NORM_HEXA8 cells in \a this into 6 NORM_QUAD4 cells and put the result into the MEDCoupling1SGTUMesh returned instance.
1718 * \return MEDCoupling1SGTUMesh * - a newly allocated instances (to be managed by the caller) storing the result of the explosion.
1719 * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
1720 * \throw If \a this is not properly allocated.
1722 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4() const
1724 const INTERP_KERNEL::CellModel& cm(getCellModel());
1725 if(cm.getEnum()!=INTERP_KERNEL::NORM_HEXA8)
1726 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4 : this method can be applied only on HEXA8 mesh !");
1727 int nbHexa8(getNumberOfCells());
1728 const int *inConnPtr(getNodalConnectivity()->begin());
1729 MCAuto<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(getName(),INTERP_KERNEL::NORM_QUAD4));
1730 MCAuto<DataArrayInt> c(DataArrayInt::New()); c->alloc(nbHexa8*6*4,1);
1731 int *cPtr(c->getPointer());
1732 for(int i=0;i<nbHexa8;i++,inConnPtr+=8)
1734 for(int j=0;j<6;j++,cPtr+=4)
1735 cm.fillSonCellNodalConnectivity(j,inConnPtr,cPtr);
1737 ret->setCoords(getCoords());
1738 ret->setNodalConnectivity(c);
1743 * This method starts from an unstructured mesh that hides in reality a cartesian mesh.
1744 * If it is not the case, an exception will be thrown.
1745 * This method returns three objects : The cartesian mesh geometrically equivalent to \a this (within a precision of \a eps) and a permutation of cells
1746 * and a permutation of nodes.
1748 * - this[cellPerm[i]]=ret[i]
1750 * \param [out] cellPerm the permutation array of size \c this->getNumberOfCells()
1751 * \param [out] nodePerm the permutation array of size \c this->getNumberOfNodes()
1752 * \return MEDCouplingCMesh * - a newly allocated mesh that is the result of the structurization of \a this.
1754 MEDCouplingCMesh *MEDCoupling1SGTUMesh::structurizeMe(DataArrayInt *& cellPerm, DataArrayInt *& nodePerm, double eps) const
1756 checkConsistencyLight();
1757 int spaceDim(getSpaceDimension()),meshDim(getMeshDimension()),nbNodes(getNumberOfNodes());
1758 if(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim)!=getCellModelEnum())
1759 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::structurizeMe : the unique geo type in this is not compatible with the geometric type regarding mesh dimension !");
1760 MCAuto<MEDCouplingCMesh> cm(MEDCouplingCMesh::New());
1761 for(int i=0;i<spaceDim;i++)
1763 std::vector<int> tmp(1,i);
1764 MCAuto<DataArrayDouble> elt(static_cast<DataArrayDouble*>(getCoords()->keepSelectedComponents(tmp)));
1765 elt=elt->getDifferentValues(eps);
1767 cm->setCoordsAt(i,elt);
1769 if(nbNodes!=cm->getNumberOfNodes())
1770 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 ?");
1772 { cm->copyTinyInfoFrom(this); }
1773 catch(INTERP_KERNEL::Exception&) { }
1774 MCAuto<MEDCouplingUMesh> um(cm->buildUnstructured()),self(buildUnstructured());
1775 self->checkGeoEquivalWith(um,12,eps,cellPerm,nodePerm);
1781 bool UpdateHexa8Cell(int validAxis, int neighId, const int *validConnQuad4NeighSide, int *allFacesNodalConn, int *myNeighbours)
1783 static const int TAB[48]={
1791 static const int TAB2[6]={0,0,3,3,3,3};
1792 if(myNeighbours[validAxis]==neighId && allFacesNodalConn[4*validAxis+0]==validConnQuad4NeighSide[TAB2[validAxis]])
1794 int oldAxis((int)std::distance(myNeighbours,std::find(myNeighbours,myNeighbours+6,neighId)));
1795 std::size_t pos(std::distance(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,std::find(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS+6,oldAxis)));
1796 std::size_t pos0(pos/2),pos1(pos%2);
1797 int oldAxisOpp(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[2*pos0+(pos1+1)%2]);
1798 int oldConn[8],myConn2[8]={-1,-1,-1,-1,-1,-1,-1,-1},myConn[8],edgeConn[2],allFacesTmp[24],neighTmp[6];
1799 oldConn[0]=allFacesNodalConn[0]; oldConn[1]=allFacesNodalConn[1]; oldConn[2]=allFacesNodalConn[2]; oldConn[3]=allFacesNodalConn[3];
1800 oldConn[4]=allFacesNodalConn[4]; oldConn[5]=allFacesNodalConn[7]; oldConn[6]=allFacesNodalConn[6]; oldConn[7]=allFacesNodalConn[5];
1801 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_HEXA8));
1802 for(int i=0;i<4;i++)
1803 myConn2[i]=validConnQuad4NeighSide[(4-i+TAB2[validAxis])%4];
1804 for(int i=0;i<4;i++)
1806 int nodeId(myConn2[i]);//the node id for which the opposite one will be found
1808 INTERP_KERNEL::NormalizedCellType typeOfSon;
1809 for(int j=0;j<12 && !found;j++)
1811 cm.fillSonEdgesNodalConnectivity3D(j,oldConn,-1,edgeConn,typeOfSon);
1812 if(edgeConn[0]==nodeId || edgeConn[1]==nodeId)
1814 if(std::find(allFacesNodalConn+4*oldAxisOpp,allFacesNodalConn+4*oldAxisOpp+4,edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0])!=allFacesNodalConn+4*oldAxisOpp+4)
1816 myConn2[i+4]=edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0];
1822 throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error !");
1824 const int *myTab(TAB+8*validAxis);
1825 for(int i=0;i<8;i++)
1826 myConn[i]=myConn2[myTab[i]];
1827 for(int i=0;i<6;i++)
1829 cm.fillSonCellNodalConnectivity(i,myConn,allFacesTmp+4*i);
1830 std::set<int> s(allFacesTmp+4*i,allFacesTmp+4*i+4);
1832 for(int j=0;j<6 && !found;j++)
1834 std::set<int> s1(allFacesNodalConn+4*j,allFacesNodalConn+4*j+4);
1837 neighTmp[i]=myNeighbours[j];
1842 throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error #2 !");
1844 std::copy(allFacesTmp,allFacesTmp+24,allFacesNodalConn);
1845 std::copy(neighTmp,neighTmp+6,myNeighbours);
1852 * 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
1853 * homogeneous. If it succeeds the result of MEDCouplingUMesh::tetrahedrize will return a conform mesh.
1855 * \return DataArrayInt * - a newly allocated array (to be managed by the caller) containing renumbered cell ids.
1857 * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
1858 * \throw If \a this is not properly allocated.
1859 * \sa MEDCouplingUMesh::tetrahedrize, MEDCouplingUMesh::simplexize.
1861 DataArrayInt *MEDCoupling1SGTUMesh::sortHexa8EachOther()
1863 MCAuto<MEDCoupling1SGTUMesh> quads(explodeEachHexa8To6Quad4());//checks that only hexa8
1864 int nbHexa8(getNumberOfCells()),*cQuads(quads->getNodalConnectivity()->getPointer());
1865 MCAuto<DataArrayInt> neighOfQuads(DataArrayInt::New()); neighOfQuads->alloc(nbHexa8*6,1); neighOfQuads->fillWithValue(-1);
1866 int *ptNeigh(neighOfQuads->getPointer());
1867 {//neighOfQuads tells for each face of each Quad8 which cell (if!=-1) is connected to this face.
1868 MCAuto<MEDCouplingUMesh> quadsTmp(quads->buildUnstructured());
1869 MCAuto<DataArrayInt> ccSafe,cciSafe;
1870 DataArrayInt *cc(0),*cci(0);
1871 quadsTmp->findCommonCells(3,0,cc,cci);
1872 ccSafe=cc; cciSafe=cci;
1873 const int *ccPtr(ccSafe->begin()),nbOfPair(cci->getNumberOfTuples()-1);
1874 for(int i=0;i<nbOfPair;i++)
1875 { ptNeigh[ccPtr[2*i+0]]=ccPtr[2*i+1]/6; ptNeigh[ccPtr[2*i+1]]=ccPtr[2*i+0]/6; }
1877 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
1878 std::vector<bool> fetched(nbHexa8,false);
1879 std::vector<bool>::iterator it(std::find(fetched.begin(),fetched.end(),false));
1880 while(it!=fetched.end())//it will turns as time as number of connected zones
1882 int cellId((int)std::distance(fetched.begin(),it));//it is the seed of the connected zone.
1883 std::set<int> s; s.insert(cellId);//s contains already organized.
1886 std::set<int> sNext;
1887 for(std::set<int>::const_iterator it0=s.begin();it0!=s.end();it0++)
1890 int *myNeighb(ptNeigh+6*(*it0));
1891 for(int i=0;i<6;i++)
1893 if(myNeighb[i]!=-1 && !fetched[myNeighb[i]])
1895 std::size_t pos(std::distance(HEXA8_FACE_PAIRS,std::find(HEXA8_FACE_PAIRS,HEXA8_FACE_PAIRS+6,i)));
1896 std::size_t pos0(pos/2),pos1(pos%2);
1897 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]))
1898 ret->pushBackSilent(myNeighb[i]);
1899 fetched[myNeighb[i]]=true;
1900 sNext.insert(myNeighb[i]);
1906 it=std::find(fetched.begin(),fetched.end(),false);
1910 int *conn(getNodalConnectivity()->getPointer());
1911 for(const int *pt=ret->begin();pt!=ret->end();pt++)
1914 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];
1915 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];
1922 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh3D() const
1924 static const int DUAL_TETRA_0[36]={
1925 4,1,0, 6,0,3, 7,3,1,
1926 4,0,1, 5,2,0, 8,1,2,
1927 6,3,0, 5,0,2, 9,2,3,
1930 static const int DUAL_TETRA_1[36]={
1931 8,4,10, 11,5,8, 10,7,11,
1932 9,4,8, 8,5,12, 12,6,9,
1933 10,4,9, 9,6,13, 13,7,10,
1934 12,5,11, 13,6,12, 11,7,13
1936 static const int FACEID_NOT_SH_NODE[4]={2,3,1,0};
1937 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TETRA4)
1938 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh3D : only TETRA4 supported !");
1939 checkFullyDefined();
1940 MCAuto<MEDCouplingUMesh> thisu(buildUnstructured());
1941 MCAuto<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1942 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1943 const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1944 MCAuto<DataArrayInt> d1Arr(DataArrayInt::New()),di1Arr(DataArrayInt::New()),rd1Arr(DataArrayInt::New()),rdi1Arr(DataArrayInt::New());
1945 MCAuto<MEDCouplingUMesh> edges(thisu->explode3DMeshTo1D(d1Arr,di1Arr,rd1Arr,rdi1Arr));
1946 const int *d1(d1Arr->begin());
1947 MCAuto<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1948 MCAuto<MEDCouplingUMesh> faces(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
1949 const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
1950 MCAuto<DataArrayDouble> edgesBaryArr(edges->computeCellCenterOfMass()),facesBaryArr(faces->computeCellCenterOfMass()),baryArr(computeCellCenterOfMass());
1951 const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+faces->getNumberOfCells()),offset1(offset0+edges->getNumberOfCells());
1953 std::vector<const DataArrayDouble *> v(4); v[0]=getCoords(); v[1]=facesBaryArr; v[2]=edgesBaryArr; v[3]=baryArr;
1954 MCAuto<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0; facesBaryArr=0;
1955 std::string name("DualOf_"); name+=getName();
1956 MCAuto<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYHED)); ret->setCoords(zeArr);
1957 MCAuto<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1958 for(int i=0;i<nbOfNodes;i++,revNodI++)
1960 int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1961 if(nbOfCellsSharingNode==0)
1963 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh3D : Node #" << i << " is orphan !";
1964 throw INTERP_KERNEL::Exception(oss.str().c_str());
1966 for(int j=0;j<nbOfCellsSharingNode;j++)
1968 int curCellId(revNod[revNodI[0]+j]);
1969 const int *connOfCurCell(nodal+4*curCellId);
1970 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1971 if(j!=0) cArr->pushBackSilent(-1);
1974 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;
1975 tmp[2]=curCellId+offset1; tmp[3]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+2]]+nbOfNodes;
1977 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;
1978 tmp[7]=curCellId+offset1; tmp[8]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+5]]+nbOfNodes;
1980 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;
1981 tmp[12]=curCellId+offset1; tmp[13]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+8]]+nbOfNodes;
1982 cArr->insertAtTheEnd(tmp,tmp+14);
1984 for(int k=0;k<4;k++)
1986 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1988 const int *faceId(d2+4*curCellId+k);
1989 if(rdi2[*faceId+1]-rdi2[*faceId]==1)
1991 int tmp2[5]; tmp2[0]=-1; tmp2[1]=i;
1992 tmp2[2]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+0]-8]+offset0;
1993 tmp2[3]=d2[4*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+1]-4]+nbOfNodes;
1994 tmp2[4]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+2]-8]+offset0;
1995 cArr->insertAtTheEnd(tmp2,tmp2+5);
2001 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
2003 ret->setNodalConnectivity(cArr,ciArr);
2007 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh2D() const
2009 static const int DUAL_TRI_0[6]={0,2, 1,0, 2,1};
2010 static const int DUAL_TRI_1[6]={-3,+5, +3,-4, +4,-5};
2011 static const int FACEID_NOT_SH_NODE[3]={1,2,0};
2012 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TRI3)
2013 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh2D : only TRI3 supported !");
2014 checkFullyDefined();
2015 MCAuto<MEDCouplingUMesh> thisu(buildUnstructured());
2016 MCAuto<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
2017 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
2018 const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
2019 MCAuto<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
2020 MCAuto<MEDCouplingUMesh> edges(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
2021 const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
2022 MCAuto<DataArrayDouble> edgesBaryArr(edges->computeCellCenterOfMass()),baryArr(computeCellCenterOfMass());
2023 const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+edges->getNumberOfCells());
2025 std::vector<const DataArrayDouble *> v(3); v[0]=getCoords(); v[1]=edgesBaryArr; v[2]=baryArr;
2026 MCAuto<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0;
2027 std::string name("DualOf_"); name+=getName();
2028 MCAuto<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYGON)); ret->setCoords(zeArr);
2029 MCAuto<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
2030 for(int i=0;i<nbOfNodes;i++,revNodI++)
2032 int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
2033 if(nbOfCellsSharingNode==0)
2035 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh2D : Node #" << i << " is orphan !";
2036 throw INTERP_KERNEL::Exception(oss.str().c_str());
2038 std::vector< std::vector<int> > polyg;
2039 for(int j=0;j<nbOfCellsSharingNode;j++)
2041 int curCellId(revNod[revNodI[0]+j]);
2042 const int *connOfCurCell(nodal+3*curCellId);
2043 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
2044 std::vector<int> locV(3);
2045 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;
2046 polyg.push_back(locV);
2048 for(int k=0;k<3;k++)
2050 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
2052 const int *edgeId(d2+3*curCellId+k);
2053 if(rdi2[*edgeId+1]-rdi2[*edgeId]==1)
2055 std::vector<int> locV2(2);
2056 int zeLocEdgeIdRel(DUAL_TRI_1[2*nodePosInCurCell+kk]);
2057 if(zeLocEdgeIdRel>0)
2058 { locV2[0]=d2[3*curCellId+zeLocEdgeIdRel-3]+nbOfNodes; locV2[1]=i; }
2060 { locV2[0]=i; locV2[1]=d2[3*curCellId-zeLocEdgeIdRel-3]+nbOfNodes; }
2061 polyg.push_back(locV2);
2067 std::vector<int> zePolyg(MEDCoupling1DGTUMesh::BuildAPolygonFromParts(polyg));
2068 cArr->insertAtTheEnd(zePolyg.begin(),zePolyg.end());
2069 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
2071 ret->setNodalConnectivity(cArr,ciArr);
2076 * This method aggregate the bbox of each cell and put it into bbox
2078 * \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)
2079 * For all other cases this input parameter is ignored.
2080 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
2082 * \throw If \a this is not fully set (coordinates and connectivity).
2083 * \throw If a cell in \a this has no valid nodeId.
2085 DataArrayDouble *MEDCoupling1SGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
2087 int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()),nbOfNodesPerCell(getNumberOfNodesPerCell());
2088 MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
2089 double *bbox(ret->getPointer());
2090 for(int i=0;i<nbOfCells*spaceDim;i++)
2092 bbox[2*i]=std::numeric_limits<double>::max();
2093 bbox[2*i+1]=-std::numeric_limits<double>::max();
2095 const double *coordsPtr(_coords->getConstPointer());
2096 const int *conn(_conn->getConstPointer());
2097 for(int i=0;i<nbOfCells;i++)
2100 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
2103 if(nodeId>=0 && nodeId<nbOfNodes)
2105 for(int k=0;k<spaceDim;k++)
2107 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
2108 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
2115 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
2116 throw INTERP_KERNEL::Exception(oss.str().c_str());
2123 * 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.
2125 * \return a new instance of field containing the result. The returned instance has to be deallocated by the caller.
2127 MEDCouplingFieldDouble *MEDCoupling1SGTUMesh::computeDiameterField() const
2129 checkFullyDefined();
2130 MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME));
2131 int nbCells(getNumberOfCells());
2132 MCAuto<DataArrayDouble> arr(DataArrayDouble::New());
2133 arr->alloc(nbCells,1);
2134 INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::DiameterCalculator> dc(_cm->buildInstanceOfDiameterCalulator(getSpaceDimension()));
2135 dc->computeFor1SGTUMeshFrmt(nbCells,_conn->begin(),getCoords()->begin(),arr->getPointer());
2138 ret->setName("Diameter");
2143 * This method invert orientation of all cells in \a this.
2144 * After calling this method the absolute value of measure of cells in \a this are the same than before calling.
2145 * This method only operates on the connectivity so coordinates are not touched at all.
2147 void MEDCoupling1SGTUMesh::invertOrientationOfAllCells()
2149 checkConsistencyOfConnectivity();
2150 INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::OrientationInverter> oi(INTERP_KERNEL::OrientationInverter::BuildInstanceFrom(getCellModelEnum()));
2151 int nbOfNodesPerCell((int)_cm->getNumberOfNodes()),nbCells(getNumberOfCells());
2152 int *conn(_conn->getPointer());
2153 for(int i=0;i<nbCells;i++)
2154 oi->operate(conn+i*nbOfNodesPerCell,conn+(i+1)*nbOfNodesPerCell);
2160 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New()
2162 return new MEDCoupling1DGTUMesh;
2165 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
2167 if(type==INTERP_KERNEL::NORM_ERROR)
2168 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
2169 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
2172 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !";
2173 throw INTERP_KERNEL::Exception(oss.str().c_str());
2175 return new MEDCoupling1DGTUMesh(name,cm);
2178 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh()
2182 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
2186 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn_indx(other._conn_indx),_conn(other._conn)
2190 const DataArrayInt *c(other._conn);
2192 _conn=c->deepCopy();
2195 _conn_indx=c->deepCopy();
2199 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const
2201 return new MEDCoupling1DGTUMesh(*this,recDeepCpy);
2205 * This method behaves mostly like MEDCoupling1DGTUMesh::deepCopy method, except that only nodal connectivity arrays are deeply copied.
2206 * The coordinates are shared between \a this and the returned instance.
2208 * \return MEDCoupling1DGTUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
2209 * \sa MEDCoupling1DGTUMesh::deepCopy
2211 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::deepCopyConnectivityOnly() const
2213 checkConsistencyLight();
2214 MCAuto<MEDCoupling1DGTUMesh> ret(clone(false));
2215 MCAuto<DataArrayInt> c(_conn->deepCopy()),ci(_conn_indx->deepCopy());
2216 ret->setNodalConnectivity(c,ci);
2220 void MEDCoupling1DGTUMesh::updateTime() const
2222 MEDCoupling1GTUMesh::updateTime();
2223 const DataArrayInt *c(_conn);
2231 std::size_t MEDCoupling1DGTUMesh::getHeapMemorySizeWithoutChildren() const
2233 return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren();
2236 std::vector<const BigMemoryObject *> MEDCoupling1DGTUMesh::getDirectChildrenWithNull() const
2238 std::vector<const BigMemoryObject *> ret(MEDCoupling1GTUMesh::getDirectChildrenWithNull());
2239 ret.push_back((const DataArrayInt *)_conn);
2240 ret.push_back((const DataArrayInt *)_conn_indx);
2244 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::deepCopy() const
2249 bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
2252 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !");
2253 std::ostringstream oss; oss.precision(15);
2254 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2257 reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !";
2260 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
2262 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2267 reason="in connectivity of single dynamic geometric type exactly one among this and other is null !";
2270 if(!c1->isEqualIfNotWhy(*c2,reason))
2272 reason.insert(0,"Nodal connectivity DataArrayInt differs : ");
2275 c1=_conn_indx; c2=otherC->_conn_indx;
2280 reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !";
2283 if(!c1->isEqualIfNotWhy(*c2,reason))
2285 reason.insert(0,"Nodal connectivity index DataArrayInt differs : ");
2291 bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
2294 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
2295 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2298 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
2300 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2305 if(!c1->isEqualWithoutConsideringStr(*c2))
2308 c1=_conn_indx; c2=otherC->_conn_indx;
2313 if(!c1->isEqualWithoutConsideringStr(*c2))
2319 * Checks if \a this and \a other meshes are geometrically equivalent with high
2320 * probability, else an exception is thrown. The meshes are considered equivalent if
2321 * (1) meshes contain the same number of nodes and the same number of elements of the
2322 * same types (2) three cells of the two meshes (first, last and middle) are based
2323 * on coincident nodes (with a specified precision).
2324 * \param [in] other - the mesh to compare with.
2325 * \param [in] prec - the precision used to compare nodes of the two meshes.
2326 * \throw If the two meshes do not match.
2328 void MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
2330 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
2331 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2333 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single dynamic geometric type !");
2334 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2338 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
2339 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2340 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
2341 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2342 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
2343 if(c1->getHashCode()!=c2->getHashCode())
2344 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs");
2346 c1=_conn_indx; c2=otherC->_conn_indx;
2350 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !");
2351 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2352 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !");
2353 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2354 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !");
2355 if(c1->getHashCode()!=c2->getHashCode())
2356 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs");
2360 void MEDCoupling1DGTUMesh::checkConsistencyOfConnectivity() const
2362 const DataArrayInt *c1(_conn);
2365 if(c1->getNumberOfComponents()!=1)
2366 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
2367 if(c1->getInfoOnComponent(0)!="")
2368 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
2369 c1->checkAllocated();
2372 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
2374 int sz2=_conn->getNumberOfTuples();
2378 if(c1->getNumberOfComponents()!=1)
2379 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
2380 c1->checkAllocated();
2381 if(c1->getNumberOfTuples()<1)
2382 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !");
2383 if(c1->getInfoOnComponent(0)!="")
2384 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
2385 int f=c1->front(),ll=c1->back();
2386 if(f<0 || (sz2>0 && f>=sz2))
2388 std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !";
2389 throw INTERP_KERNEL::Exception(oss.str().c_str());
2393 std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !";
2394 throw INTERP_KERNEL::Exception(oss.str().c_str());
2398 std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !";
2399 throw INTERP_KERNEL::Exception(oss.str().c_str());
2403 throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !");
2404 int szOfC1Exp=_conn_indx->back();
2407 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::checkConsistencyOfConnectivity : The expected length of nodal connectivity array regarding index is " << szOfC1Exp << " but the actual size of it is " << c1->getNumberOfTuples() << " !";
2408 throw INTERP_KERNEL::Exception(oss.str().c_str());
2413 * 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.
2414 * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one.
2415 * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array.
2417 void MEDCoupling1DGTUMesh::checkConsistencyLight() const
2419 MEDCouplingPointSet::checkConsistencyLight();
2420 checkConsistencyOfConnectivity();
2423 void MEDCoupling1DGTUMesh::checkConsistency(double eps) const
2425 checkConsistencyLight();
2426 const DataArrayInt *c1(_conn),*c2(_conn_indx);
2427 if(!c2->isMonotonic(true))
2428 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkConsistency : the nodal connectivity index is expected to be increasing monotinic !");
2430 int nbOfTuples=c1->getNumberOfTuples();
2431 int nbOfNodes=getNumberOfNodes();
2432 const int *w(c1->begin());
2433 for(int i=0;i<nbOfTuples;i++,w++)
2435 if(*w==-1) continue;
2436 if(*w<0 || *w>=nbOfNodes)
2438 std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !";
2439 throw INTERP_KERNEL::Exception(oss.str().c_str());
2444 int MEDCoupling1DGTUMesh::getNumberOfCells() const
2446 checkConsistencyOfConnectivity();//do not remove
2447 return _conn_indx->getNumberOfTuples()-1;
2451 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2452 * For each cell in \b this the number of nodes constituting cell is computed.
2453 * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned.
2454 * So for pohyhedrons some nodes can be counted several times in the returned result.
2456 * \return a newly allocated array
2458 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const
2460 checkConsistencyLight();
2461 _conn_indx->checkMonotonic(true);
2462 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2463 return _conn_indx->deltaShiftIndex();
2465 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2466 MCAuto<DataArrayInt> ret=DataArrayInt::New();
2467 ret->alloc(nbOfCells,1);
2468 int *retPtr=ret->getPointer();
2469 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2470 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2471 *retPtr=ci[1]-ci[0]-std::count(c+ci[0],c+ci[1],-1);
2476 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2477 * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed.
2479 * \return a newly allocated array
2481 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const
2483 checkConsistencyLight();
2484 _conn_indx->checkMonotonic(true);
2485 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG)
2486 return _conn_indx->deltaShiftIndex();
2487 if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG)
2489 MCAuto<DataArrayInt> ret=_conn_indx->deltaShiftIndex();
2490 ret->applyDivideBy(2);
2494 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2495 MCAuto<DataArrayInt> ret=DataArrayInt::New();
2496 ret->alloc(nbOfCells,1);
2497 int *retPtr=ret->getPointer();
2498 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2499 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2500 *retPtr=std::count(c+ci[0],c+ci[1],-1)+1;
2505 * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell,
2506 * will be counted only once here whereas it will be counted several times in MEDCoupling1DGTUMesh::computeNbOfNodesPerCell method.
2508 * \return DataArrayInt * - new object to be deallocated by the caller.
2509 * \sa MEDCoupling1DGTUMesh::computeNbOfNodesPerCell
2511 DataArrayInt *MEDCoupling1DGTUMesh::computeEffectiveNbOfNodesPerCell() const
2513 checkConsistencyLight();
2514 _conn_indx->checkMonotonic(true);
2515 int nbOfCells(_conn_indx->getNumberOfTuples()-1);
2516 MCAuto<DataArrayInt> ret=DataArrayInt::New();
2517 ret->alloc(nbOfCells,1);
2518 int *retPtr(ret->getPointer());
2519 const int *ci(_conn_indx->begin()),*c(_conn->begin());
2520 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2522 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2524 std::set<int> s(c+ci[0],c+ci[1]);
2525 *retPtr=(int)s.size();
2530 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2532 std::set<int> s(c+ci[0],c+ci[1]); s.erase(-1);
2533 *retPtr=(int)s.size();
2539 void MEDCoupling1DGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
2541 int nbOfCells(getNumberOfCells());//performs checks
2542 if(cellId>=0 && cellId<nbOfCells)
2544 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2545 int nbOfNodes=stp-strt;
2547 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !");
2548 conn.resize(nbOfNodes);
2549 std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin());
2553 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2554 throw INTERP_KERNEL::Exception(oss.str().c_str());
2558 int MEDCoupling1DGTUMesh::getNumberOfNodesInCell(int cellId) const
2560 int nbOfCells(getNumberOfCells());//performs checks
2561 if(cellId>=0 && cellId<nbOfCells)
2563 const int *conn(_conn->begin());
2564 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2565 return stp-strt-std::count(conn+strt,conn+stp,-1);
2569 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNumberOfNodesInCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2570 throw INTERP_KERNEL::Exception(oss.str().c_str());
2574 std::string MEDCoupling1DGTUMesh::simpleRepr() const
2576 static const char msg0[]="No coordinates specified !";
2577 std::ostringstream ret;
2578 ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
2579 ret << "Description of mesh : \"" << getDescription() << "\"\n";
2581 double tt=getTime(tmpp1,tmpp2);
2582 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
2583 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
2584 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
2587 const int spaceDim=getSpaceDimension();
2588 ret << spaceDim << "\nInfo attached on space dimension : ";
2589 for(int i=0;i<spaceDim;i++)
2590 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
2594 ret << msg0 << "\n";
2595 ret << "Number of nodes : ";
2597 ret << getNumberOfNodes() << "\n";
2599 ret << msg0 << "\n";
2600 ret << "Number of cells : ";
2602 try { checkConsistencyLight(); } catch(INTERP_KERNEL::Exception& /* e */)
2604 ret << "Nodal connectivity arrays are not set or badly set !\n";
2608 ret << getNumberOfCells() << "\n";
2609 ret << "Cell type : " << _cm->getRepr() << "\n";
2613 std::string MEDCoupling1DGTUMesh::advancedRepr() const
2615 std::ostringstream ret;
2616 ret << simpleRepr();
2617 ret << "\nCoordinates array : \n___________________\n\n";
2619 _coords->reprWithoutNameStream(ret);
2621 ret << "No array set !\n";
2622 ret << "\n\nNodal Connectivity : \n____________________\n\n";
2625 try { checkConsistency(); } catch(INTERP_KERNEL::Exception& /* e */)
2627 ret << "Nodal connectivity arrays are not set or badly set !\n";
2632 int nbOfCells=getNumberOfCells();
2633 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2634 for(int i=0;i<nbOfCells;i++,ci++)
2636 ret << "Cell #" << i << " : ";
2637 std::copy(c+ci[0],c+ci[1],std::ostream_iterator<int>(ret," "));
2643 DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const
2645 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2646 int spaceDim=getSpaceDimension();
2647 int nbOfCells=getNumberOfCells();//checkConsistencyLight()
2648 int nbOfNodes=getNumberOfNodes();
2649 ret->alloc(nbOfCells,spaceDim);
2650 double *ptToFill=ret->getPointer();
2651 const double *coor=_coords->begin();
2652 const int *nodal=_conn->begin(),*nodali=_conn_indx->begin();
2654 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2656 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2658 std::fill(ptToFill,ptToFill+spaceDim,0.);
2659 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2661 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2663 if(*nodal>=0 && *nodal<nbOfNodes)
2664 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2667 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2668 throw INTERP_KERNEL::Exception(oss.str().c_str());
2670 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(nodali[1]-nodali[0])));
2675 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !";
2676 throw INTERP_KERNEL::Exception(oss.str().c_str());
2682 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2684 std::fill(ptToFill,ptToFill+spaceDim,0.);
2685 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2688 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2690 if(*nodal==-1) continue;
2691 if(*nodal>=0 && *nodal<nbOfNodes)
2693 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2698 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2699 throw INTERP_KERNEL::Exception(oss.str().c_str());
2703 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./nbOfNod));
2706 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !";
2707 throw INTERP_KERNEL::Exception(oss.str().c_str());
2712 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : at cell #" << i << " the nodal index array is invalid !";
2713 throw INTERP_KERNEL::Exception(oss.str().c_str());
2720 void MEDCoupling1DGTUMesh::renumberCells(const int *old2NewBg, bool check)
2722 int nbCells=getNumberOfCells();
2723 MCAuto<DataArrayInt> o2n=DataArrayInt::New();
2724 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
2726 o2n=o2n->checkAndPreparePermutation();
2728 const int *o2nPtr=o2n->getPointer();
2729 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2730 MCAuto<DataArrayInt> newConn=DataArrayInt::New();
2731 MCAuto<DataArrayInt> newConnI=DataArrayInt::New();
2732 newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1);
2733 newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx);
2735 int *newC=newConn->getPointer(),*newCI=newConnI->getPointer();
2736 for(int i=0;i<nbCells;i++)
2738 int newPos=o2nPtr[i];
2739 int sz=conni[i+1]-conni[i];
2744 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !";
2745 throw INTERP_KERNEL::Exception(oss.str().c_str());
2748 newConnI->computeOffsetsFull(); newCI=newConnI->getPointer();
2750 for(int i=0;i<nbCells;i++,conni++)
2753 std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]);
2756 _conn_indx=newConnI;
2759 MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
2761 if(other->getType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED)
2762 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !");
2763 const MEDCoupling1DGTUMesh *otherC=static_cast<const MEDCoupling1DGTUMesh *>(other);
2764 return Merge1DGTUMeshes(this,otherC);
2767 MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const
2769 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
2770 ret->setCoords(getCoords());
2771 const int *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin();
2772 int nbCells=getNumberOfCells();//checkConsistencyLight
2773 int geoType=(int)getCellModelEnum();
2774 MCAuto<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1);
2775 MCAuto<DataArrayInt> cI=DataArrayInt::New(); cI->alloc(nbCells+1);
2776 int *cPtr=c->getPointer(),*ciPtr=cI->getPointer();
2778 for(int i=0;i<nbCells;i++,ciPtr++)
2780 int sz=nodalConnI[i+1]-nodalConnI[i];
2784 cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr);
2785 ciPtr[1]=ciPtr[0]+sz+1;
2789 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !";
2790 throw INTERP_KERNEL::Exception(oss.str().c_str());
2793 ret->setConnectivity(c,cI,true);
2795 { ret->copyTinyInfoFrom(this); }
2796 catch(INTERP_KERNEL::Exception&) { }
2801 * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes
2803 DataArrayInt *MEDCoupling1DGTUMesh::simplexize(int policy)
2805 int nbOfCells=getNumberOfCells();
2806 MCAuto<DataArrayInt> ret=DataArrayInt::New();
2807 ret->alloc(nbOfCells,1);
2812 void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const
2814 stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
2815 stream << " Mesh dimension : " << getMeshDimension() << ".";
2817 { stream << " No coordinates set !"; return ; }
2818 if(!_coords->isAllocated())
2819 { stream << " Coordinates set but not allocated !"; return ; }
2820 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
2821 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
2823 try { checkConsistencyLight(); } catch(INTERP_KERNEL::Exception& /* e */)
2825 stream << std::endl << "Nodal connectivity NOT set properly !\n";
2829 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
2832 void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
2835 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
2836 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2838 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !");
2839 setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex());
2842 MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
2845 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
2846 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2848 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
2849 std::vector<const MEDCoupling1DGTUMesh *> ms(2);
2852 return Merge1DGTUMeshesOnSameCoords(ms);
2855 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
2857 checkConsistencyLight();
2858 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2859 ret->setCoords(_coords);
2860 DataArrayInt *c=0,*ci=0;
2861 MEDCouplingUMesh::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci);
2862 MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
2863 ret->setNodalConnectivity(c,ci);
2867 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoordsSlice(int start, int end, int step) const
2869 checkConsistencyLight();
2870 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2871 ret->setCoords(_coords);
2872 DataArrayInt *c=0,*ci=0;
2873 MEDCouplingUMesh::ExtractFromIndexedArraysSlice(start,end,step,_conn,_conn_indx,c,ci);
2874 MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
2875 ret->setNodalConnectivity(c,ci);
2879 void MEDCoupling1DGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
2882 int sz((int)nodeIdsInUse.size());
2883 for(const int *conn=_conn->begin();conn!=_conn->end();conn++)
2885 if(*conn>=0 && *conn<sz)
2886 nodeIdsInUse[*conn]=true;
2891 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeNodeIdsAlg : At pos #" << std::distance(_conn->begin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !";
2892 throw INTERP_KERNEL::Exception(oss.str().c_str());
2898 void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const
2900 checkFullyDefined();
2901 int nbOfNodes=getNumberOfNodes();
2902 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
2903 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
2904 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
2905 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2906 int nbOfCells=getNumberOfCells();
2907 int nbOfEltsInRevNodal=0;
2908 for(int eltId=0;eltId<nbOfCells;eltId++)
2910 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2911 if(nbOfNodesPerCell>=0)
2913 for(int j=0;j<nbOfNodesPerCell;j++)
2915 int nodeId=conn[conni[eltId]+j];
2916 if(nodeId==-1) continue;
2917 if(nodeId>=0 && nodeId<nbOfNodes)
2919 nbOfEltsInRevNodal++;
2920 revNodalIndxPtr[nodeId+1]++;
2924 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
2925 throw INTERP_KERNEL::Exception(oss.str().c_str());
2931 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << "nodal connectivity is invalid !";
2932 throw INTERP_KERNEL::Exception(oss.str().c_str());
2935 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
2936 conn=_conn->begin();
2937 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
2938 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
2939 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
2940 for(int eltId=0;eltId<nbOfCells;eltId++)
2942 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2943 for(int j=0;j<nbOfNodesPerCell;j++)
2945 int nodeId=conn[conni[eltId]+j];
2947 *std::find_if(revNodalPtr+revNodalIndxPtr[nodeId],revNodalPtr+revNodalIndxPtr[nodeId+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
2952 void MEDCoupling1DGTUMesh::checkFullyDefined() const
2954 if(!((const DataArrayInt *)_conn) || !((const DataArrayInt *)_conn_indx) || !((const DataArrayDouble *)_coords))
2955 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined.");
2958 bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
2960 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !");
2963 void MEDCoupling1DGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
2966 double time=getTime(it,order);
2967 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
2969 littleStrings.push_back(getName());
2970 littleStrings.push_back(getDescription());
2971 littleStrings.push_back(getTimeUnit());
2973 std::vector<std::string> littleStrings2,littleStrings3,littleStrings4;
2974 if((const DataArrayDouble *)_coords)
2975 _coords->getTinySerializationStrInformation(littleStrings2);
2976 if((const DataArrayInt *)_conn)
2977 _conn->getTinySerializationStrInformation(littleStrings3);
2978 if((const DataArrayInt *)_conn_indx)
2979 _conn_indx->getTinySerializationStrInformation(littleStrings4);
2980 int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size()),sz2((int)littleStrings4.size());
2981 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
2982 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
2983 littleStrings.insert(littleStrings.end(),littleStrings4.begin(),littleStrings4.end());
2985 tinyInfo.push_back(getCellModelEnum());
2986 tinyInfo.push_back(it);
2987 tinyInfo.push_back(order);
2988 std::vector<int> tinyInfo2,tinyInfo3,tinyInfo4;
2989 if((const DataArrayDouble *)_coords)
2990 _coords->getTinySerializationIntInformation(tinyInfo2);
2991 if((const DataArrayInt *)_conn)
2992 _conn->getTinySerializationIntInformation(tinyInfo3);
2993 if((const DataArrayInt *)_conn_indx)
2994 _conn_indx->getTinySerializationIntInformation(tinyInfo4);
2995 int sz3((int)tinyInfo2.size()),sz4((int)tinyInfo3.size()),sz5((int)tinyInfo4.size());
2996 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3); tinyInfo.push_back(sz4); tinyInfo.push_back(sz5);
2997 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
2998 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
2999 tinyInfo.insert(tinyInfo.end(),tinyInfo4.begin(),tinyInfo4.end());
3001 tinyInfoD.push_back(time);
3004 void MEDCoupling1DGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
3006 std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+tinyInfo[6]);
3007 std::vector<int> tinyInfo1(tinyInfo.begin()+9+tinyInfo[6],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]);
3008 std::vector<int> tinyInfo12(tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]+tinyInfo[8]);
3009 MCAuto<DataArrayInt> p1(DataArrayInt::New()); p1->resizeForUnserialization(tinyInfo1);
3010 MCAuto<DataArrayInt> p2(DataArrayInt::New()); p2->resizeForUnserialization(tinyInfo12);
3011 std::vector<const DataArrayInt *> v(2); v[0]=p1; v[1]=p2;
3012 p2=DataArrayInt::Aggregate(v);
3013 a2->resizeForUnserialization(tinyInfo2);
3014 a1->alloc(p2->getNbOfElems(),1);
3017 void MEDCoupling1DGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
3020 if((const DataArrayInt *)_conn)
3021 if(_conn->isAllocated())
3022 sz=_conn->getNbOfElems();
3023 if((const DataArrayInt *)_conn_indx)
3024 if(_conn_indx->isAllocated())
3025 sz+=_conn_indx->getNbOfElems();
3026 a1=DataArrayInt::New();
3028 int *work(a1->getPointer());
3029 if(sz!=0 && (const DataArrayInt *)_conn)
3030 work=std::copy(_conn->begin(),_conn->end(),a1->getPointer());
3031 if(sz!=0 && (const DataArrayInt *)_conn_indx)
3032 std::copy(_conn_indx->begin(),_conn_indx->end(),work);
3034 if((const DataArrayDouble *)_coords)
3035 if(_coords->isAllocated())
3036 sz=_coords->getNbOfElems();
3037 a2=DataArrayDouble::New();
3039 if(sz!=0 && (const DataArrayDouble *)_coords)
3040 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
3043 void MEDCoupling1DGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
3044 const std::vector<std::string>& littleStrings)
3046 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
3047 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
3048 setName(littleStrings[0]);
3049 setDescription(littleStrings[1]);
3050 setTimeUnit(littleStrings[2]);
3051 setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
3052 int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]),sz4(tinyInfo[7]),sz5(tinyInfo[8]);
3054 _coords=DataArrayDouble::New();
3055 std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+sz3);
3056 _coords->resizeForUnserialization(tinyInfo2);
3057 std::copy(a2->begin(),a2->end(),_coords->getPointer());
3058 _conn=DataArrayInt::New();
3059 std::vector<int> tinyInfo3(tinyInfo.begin()+9+sz3,tinyInfo.begin()+9+sz3+sz4);
3060 _conn->resizeForUnserialization(tinyInfo3);
3061 std::copy(a1->begin(),a1->begin()+_conn->getNbOfElems(),_conn->getPointer());
3062 _conn_indx=DataArrayInt::New();
3063 std::vector<int> tinyInfo4(tinyInfo.begin()+9+sz3+sz4,tinyInfo.begin()+9+sz3+sz4+sz5);
3064 _conn_indx->resizeForUnserialization(tinyInfo4);
3065 std::copy(a1->begin()+_conn->getNbOfElems(),a1->end(),_conn_indx->getPointer());
3066 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
3067 _coords->finishUnserialization(tinyInfo2,littleStrings2);
3068 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
3069 _conn->finishUnserialization(tinyInfo3,littleStrings3);
3070 std::vector<std::string> littleStrings4(littleStrings.begin()+3+sz0+sz1,littleStrings.begin()+3+sz0+sz1+sz2);
3071 _conn_indx->finishUnserialization(tinyInfo4,littleStrings4);
3075 * Finds nodes not used in any cell and returns an array giving a new id to every node
3076 * by excluding the unused nodes, for which the array holds -1. The result array is
3077 * a mapping in "Old to New" mode.
3078 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
3079 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
3080 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
3081 * if the node is unused or a new id else. The caller is to delete this
3082 * array using decrRef() as it is no more needed.
3083 * \throw If the coordinates array is not set.
3084 * \throw If the nodal connectivity of cells is not defined.
3085 * \throw If the nodal connectivity includes an invalid id.
3086 * \sa MEDCoupling1DGTUMesh::getNodeIdsInUse, areAllNodesFetched
3088 DataArrayInt *MEDCoupling1DGTUMesh::computeFetchedNodeIds() const
3091 int nbNodes(getNumberOfNodes());
3092 std::vector<bool> fetchedNodes(nbNodes,false);
3093 computeNodeIdsAlg(fetchedNodes);
3094 int sz((int)std::count(fetchedNodes.begin(),fetchedNodes.end(),true));
3095 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
3096 int *retPtr(ret->getPointer());
3097 for(int i=0;i<nbNodes;i++)
3104 * Finds nodes not used in any cell and returns an array giving a new id to every node
3105 * by excluding the unused nodes, for which the array holds -1. The result array is
3106 * a mapping in "Old to New" mode.
3107 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
3108 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
3109 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
3110 * if the node is unused or a new id else. The caller is to delete this
3111 * array using decrRef() as it is no more needed.
3112 * \throw If the coordinates array is not set.
3113 * \throw If the nodal connectivity of cells is not defined.
3114 * \throw If the nodal connectivity includes an invalid id.
3115 * \sa MEDCoupling1DGTUMesh::computeFetchedNodeIds, areAllNodesFetched
3117 DataArrayInt *MEDCoupling1DGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
3120 int nbOfNodes=getNumberOfNodes();
3121 int nbOfCells=getNumberOfCells();//checkConsistencyLight
3122 MCAuto<DataArrayInt> ret=DataArrayInt::New();
3123 ret->alloc(nbOfNodes,1);
3124 int *traducer=ret->getPointer();
3125 std::fill(traducer,traducer+nbOfNodes,-1);
3126 const int *conn=_conn->begin(),*conni(_conn_indx->begin());
3127 for(int i=0;i<nbOfCells;i++,conni++)
3129 int nbNodesPerCell=conni[1]-conni[0];
3130 for(int j=0;j<nbNodesPerCell;j++)
3132 int nodeId=conn[conni[0]+j];
3133 if(nodeId==-1) continue;
3134 if(nodeId>=0 && nodeId<nbOfNodes)
3138 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << nodeId << " not in [0," << nbOfNodes << ") !";
3139 throw INTERP_KERNEL::Exception(oss.str().c_str());
3143 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
3144 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
3149 * This method renumbers only nodal connectivity in \a this. The renumbering is only an offset applied. So this method is a specialization of
3150 * \a renumberNodesInConn. \b WARNING, this method does not check that the resulting node ids in the nodal connectivity is in a valid range !
3152 * \param [in] offset - specifies the offset to be applied on each element of connectivity.
3154 * \sa renumberNodesInConn
3156 void MEDCoupling1DGTUMesh::renumberNodesWithOffsetInConn(int offset)
3158 getNumberOfCells();//only to check that all is well defined.
3160 int nbOfTuples(_conn->getNumberOfTuples());
3161 int *pt(_conn->getPointer());
3162 for(int i=0;i<nbOfTuples;i++,pt++)
3164 if(*pt==-1) continue;
3172 * Same than renumberNodesInConn(const int *) except that here the format of old-to-new traducer is using map instead
3173 * 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
3176 void MEDCoupling1DGTUMesh::renumberNodesInConn(const INTERP_KERNEL::HashMap<int,int>& newNodeNumbersO2N)
3178 getNumberOfCells();//only to check that all is well defined.
3180 int nbElemsIn(getNumberOfNodes()),nbOfTuples(_conn->getNumberOfTuples());
3181 int *pt(_conn->getPointer());
3182 for(int i=0;i<nbOfTuples;i++,pt++)
3184 if(*pt==-1) continue;
3185 if(*pt>=0 && *pt<nbElemsIn)
3187 INTERP_KERNEL::HashMap<int,int>::const_iterator it(newNodeNumbersO2N.find(*pt));
3188 if(it!=newNodeNumbersO2N.end())
3192 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : At pos #" << i << " of connectivity, node id is " << *pt << ". Not in keys of input map !";
3193 throw INTERP_KERNEL::Exception(oss.str().c_str());
3198 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
3199 throw INTERP_KERNEL::Exception(oss.str().c_str());
3207 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
3208 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
3209 * This method is a generalization of shiftNodeNumbersInConn().
3210 * \warning This method performs no check of validity of new ids. **Use it with care !**
3211 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
3212 * this->getNumberOfNodes(), in "Old to New" mode.
3213 * See \ref numbering for more info on renumbering modes.
3214 * \throw If the nodal connectivity of cells is not defined.
3216 void MEDCoupling1DGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
3218 getNumberOfCells();//only to check that all is well defined.
3220 int nbElemsIn(getNumberOfNodes()),nbOfTuples(_conn->getNumberOfTuples());
3221 int *pt(_conn->getPointer());
3222 for(int i=0;i<nbOfTuples;i++,pt++)
3224 if(*pt==-1) continue;
3225 if(*pt>=0 && *pt<nbElemsIn)
3226 *pt=newNodeNumbersO2N[*pt];
3229 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
3230 throw INTERP_KERNEL::Exception(oss.str().c_str());
3238 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
3239 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
3240 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
3241 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
3243 * \param [in] begin input start of array of node ids.
3244 * \param [in] end input end of array of node ids.
3245 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
3246 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
3248 void MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
3250 int nbOfCells=getNumberOfCells();
3251 MCAuto<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
3253 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
3254 std::vector<bool> fastFinder(sz,false);
3255 for(const int *work=begin;work!=end;work++)
3256 if(*work>=0 && *work<sz)
3257 fastFinder[*work]=true;
3258 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
3259 for(int i=0;i<nbOfCells;i++,conni++)
3261 int ref=0,nbOfHit=0;
3262 int nbNodesPerCell=conni[1]-conni[0];
3263 if(nbNodesPerCell>=0)
3265 for(int j=0;j<nbNodesPerCell;j++)
3267 int nodeId=conn[conni[0]+j];
3271 if(fastFinder[nodeId])
3278 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !";
3279 throw INTERP_KERNEL::Exception(oss.str().c_str());
3281 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
3282 cellIdsKept->pushBackSilent(i);
3284 cellIdsKeptArr=cellIdsKept.retn();
3287 void MEDCoupling1DGTUMesh::allocateCells(int nbOfCells)
3290 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !");
3291 _conn=DataArrayInt::New();
3292 _conn->reserve(nbOfCells*3);
3293 _conn_indx=DataArrayInt::New();
3294 _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0);
3299 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
3301 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
3302 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
3303 * \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
3304 * attached to \a this.
3305 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
3307 void MEDCoupling1DGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd)
3309 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
3310 DataArrayInt *c(_conn),*c2(_conn_indx);
3314 if(pos==c->getNumberOfTuples())
3316 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
3317 c2->pushBackSilent(pos+sz);
3321 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !";
3322 throw INTERP_KERNEL::Exception(oss.str().c_str());
3326 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !");
3329 void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex)
3332 nodalConn->incrRef();
3335 nodalConnIndex->incrRef();
3336 _conn_indx=nodalConnIndex;
3341 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
3343 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivity() const
3345 const DataArrayInt *ret(_conn);
3346 return const_cast<DataArrayInt *>(ret);
3350 * \return DataArrayInt * - the internal reference to the nodal connectivity index. The caller is not reponsible to deallocate it.
3352 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const
3354 const DataArrayInt *ret(_conn_indx);
3355 return const_cast<DataArrayInt *>(ret);
3359 * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here".
3360 * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity).
3361 * 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.
3363 * 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.
3365 * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal
3366 * connectivity arrays are different (false)
3367 * \return a new object to be managed by the caller.
3369 * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked
3371 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const
3373 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3374 DataArrayInt *nc=0,*nci=0;
3375 isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci);
3376 MCAuto<DataArrayInt> ncs(nc),ncis(nci);
3377 ret->_conn=ncs; ret->_conn_indx=ncis;
3378 ret->setCoords(getCoords());
3383 * This method allows to compute, if needed, the packed nodal connectivity pair.
3384 * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges convered by nodal connectivity index array.
3385 * 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.
3387 * 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)
3388 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3390 * 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
3393 * This method return 3 elements.
3394 * \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
3395 * this pointer can be seen as a new object, that is to managed by the caller.
3396 * \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
3397 * this pointer can be seen as a new object, that is to managed by the caller.
3398 * \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
3399 * output parameters are newly created objects.
3401 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkConsistencyLight test
3403 bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const
3405 if(isPacked())//performs the checkConsistencyLight
3407 const DataArrayInt *c0(_conn),*c1(_conn_indx);
3408 nodalConn=const_cast<DataArrayInt *>(c0); nodalConnIndx=const_cast<DataArrayInt *>(c1);
3409 nodalConn->incrRef(); nodalConnIndx->incrRef();
3412 int bg=_conn_indx->front(),end=_conn_indx->back();
3413 MCAuto<DataArrayInt> nc(_conn->selectByTupleIdSafeSlice(bg,end,1));
3414 MCAuto<DataArrayInt> nci(_conn_indx->deepCopy());
3415 nci->applyLin(1,-bg);
3416 nodalConn=nc.retn(); nodalConnIndx=nci.retn();
3421 * 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)
3422 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3423 * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned.
3424 * \return bool - true if \a this looks packed, false is not.
3426 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkConsistencyLight test
3428 bool MEDCoupling1DGTUMesh::isPacked() const
3430 checkConsistencyLight();
3431 return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples();
3434 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2)
3436 std::vector<const MEDCoupling1DGTUMesh *> tmp(2);
3437 tmp[0]=const_cast<MEDCoupling1DGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1DGTUMesh *>(mesh2);
3438 return Merge1DGTUMeshes(tmp);
3441 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a)
3443 std::size_t sz=a.size();
3445 return Merge1DGTUMeshesLL(a);
3446 for(std::size_t ii=0;ii<sz;ii++)
3449 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::Merge1DGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
3450 throw INTERP_KERNEL::Exception(oss.str().c_str());
3452 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
3453 for(std::size_t ii=0;ii<sz;ii++)
3454 if(&(a[ii]->getCellModel())!=cm)
3455 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !");
3456 std::vector< MCAuto<MEDCoupling1DGTUMesh> > bb(sz);
3457 std::vector< const MEDCoupling1DGTUMesh * > aa(sz);
3459 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
3461 const MEDCoupling1DGTUMesh *cur=a[i];
3462 const DataArrayDouble *coo=cur->getCoords();
3464 spaceDim=coo->getNumberOfComponents();
3467 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !");
3468 for(std::size_t i=0;i<sz;i++)
3470 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
3473 return Merge1DGTUMeshesLL(aa);
3477 * \throw If presence of a null instance in the input vector \a a.
3478 * \throw If a is empty
3480 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a)
3483 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !");
3484 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3486 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !");
3487 std::vector< MCAuto<MEDCoupling1DGTUMesh> > objs(a.size());
3488 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3489 (*it)->getNumberOfCells();//to check that all is OK
3490 const DataArrayDouble *coords=(*it)->getCoords();
3491 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3493 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3494 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3496 for(int i=1;it!=a.end();i++,it++)
3499 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !");
3500 if(cm!=&((*it)->getCellModel()))
3501 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3502 (*it)->getNumberOfCells();//to check that all is OK
3503 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3504 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3505 if(coords!=(*it)->getCoords())
3506 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !");
3508 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3509 ret->setCoords(coords);
3510 ret->_conn=DataArrayInt::Aggregate(ncs);
3511 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3516 * 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)
3518 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a)
3521 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : input array must be NON EMPTY !");
3522 std::vector< MCAuto<MEDCoupling1DGTUMesh> > objs(a.size());
3523 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3524 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3525 std::vector<int> nbNodesPerElt(a.size());
3526 int nbOfCells=(*it)->getNumberOfCells();
3528 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3529 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3531 int prevNbOfNodes=(*it)->getNumberOfNodes();
3532 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3534 for(int i=1;it!=a.end();i++,it++)
3536 if(cm!=&((*it)->getCellModel()))
3537 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3538 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3539 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3540 nbOfCells+=(*it)->getNumberOfCells();
3541 nbNodesPerElt[i]=nbNodesPerElt[i-1]+prevNbOfNodes;
3542 prevNbOfNodes=(*it)->getNumberOfNodes();
3544 std::vector<const MEDCouplingPointSet *> aps(a.size());
3545 std::copy(a.begin(),a.end(),aps.begin());
3546 MCAuto<DataArrayDouble> pts=MergeNodesArray(aps);
3547 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3548 ret->setCoords(pts);
3549 ret->_conn=AggregateNodalConnAndShiftNodeIds(ncs,nbNodesPerElt);
3550 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3554 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(int spaceDim) const
3556 MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3557 MCAuto<DataArrayInt> tmp1,tmp2;
3558 const DataArrayInt *nodalConn(_conn),*nodalConnI(_conn_indx);
3561 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
3569 tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
3573 ret->_conn_indx=tmp2;
3577 MCAuto<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
3578 ret->setCoords(coords);
3581 ret->setCoords(_coords);
3586 * This method aggregate the bbox of each cell and put it into bbox parameter.
3588 * \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)
3589 * For all other cases this input parameter is ignored.
3590 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
3592 * \throw If \a this is not fully set (coordinates and connectivity).
3593 * \throw If a cell in \a this has no valid nodeId.
3595 DataArrayDouble *MEDCoupling1DGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
3597 checkFullyDefined();
3598 int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes());
3599 MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
3600 double *bbox(ret->getPointer());
3601 for(int i=0;i<nbOfCells*spaceDim;i++)
3603 bbox[2*i]=std::numeric_limits<double>::max();
3604 bbox[2*i+1]=-std::numeric_limits<double>::max();
3606 const double *coordsPtr(_coords->getConstPointer());
3607 const int *conn(_conn->getConstPointer()),*connI(_conn_indx->getConstPointer());
3608 for(int i=0;i<nbOfCells;i++)
3610 int offset=connI[i];
3611 int nbOfNodesForCell(connI[i+1]-offset),kk(0);
3612 for(int j=0;j<nbOfNodesForCell;j++)
3614 int nodeId=conn[offset+j];
3615 if(nodeId>=0 && nodeId<nbOfNodes)
3617 for(int k=0;k<spaceDim;k++)
3619 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
3620 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
3627 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
3628 throw INTERP_KERNEL::Exception(oss.str().c_str());
3635 * 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.
3637 * \return a new instance of field containing the result. The returned instance has to be deallocated by the caller.
3639 MEDCouplingFieldDouble *MEDCoupling1DGTUMesh::computeDiameterField() const
3641 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::computeDiameterField : not implemented yet for dynamic types !");
3644 std::vector<int> MEDCoupling1DGTUMesh::BuildAPolygonFromParts(const std::vector< std::vector<int> >& parts)
3646 std::vector<int> ret;
3649 ret.insert(ret.end(),parts[0].begin(),parts[0].end());
3650 int ref(ret.back());
3651 std::size_t sz(parts.size()),nbh(1);
3652 std::vector<bool> b(sz,true); b[0]=false;
3656 for(;i<sz;i++) if(b[i] && parts[i].front()==ref) { ret.insert(ret.end(),parts[i].begin()+1,parts[i].end()); nbh++; break; }
3660 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::BuildAPolygonFromParts : the input vector is not a part of a single polygon !");
3662 if(ret.back()==ret.front())
3668 * This method invert orientation of all cells in \a this.
3669 * After calling this method the absolute value of measure of cells in \a this are the same than before calling.
3670 * This method only operates on the connectivity so coordinates are not touched at all.
3672 void MEDCoupling1DGTUMesh::invertOrientationOfAllCells()
3674 checkConsistencyOfConnectivity();
3675 INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::OrientationInverter> oi(INTERP_KERNEL::OrientationInverter::BuildInstanceFrom(getCellModelEnum()));
3676 int nbCells(getNumberOfCells());
3677 const int *connI(_conn_indx->begin());
3678 int *conn(_conn->getPointer());
3679 for(int i=0;i<nbCells;i++)
3680 oi->operate(conn+connI[i],conn+connI[i+1]);
3685 * This method performs an aggregation of \a nodalConns (as DataArrayInt::Aggregate does) but in addition of that a shift is applied on the
3686 * values contained in \a nodalConns using corresponding offset specified in input \a offsetInNodeIdsPerElt.
3687 * But it also manage the values -1, that have a semantic in MEDCoupling1DGTUMesh class (separator for polyhedron).
3689 * \param [in] nodalConns - a list of nodal connectivity arrays same size than \a offsetInNodeIdsPerElt.
3690 * \param [in] offsetInNodeIdsPerElt - a list of offsets to apply.
3691 * \return DataArrayInt * - A new object (to be managed by the caller) that is the result of the aggregation.
3692 * \throw If \a nodalConns or \a offsetInNodeIdsPerElt are empty.
3693 * \throw If \a nodalConns and \a offsetInNodeIdsPerElt have not the same size.
3694 * \throw If presence of null pointer in \a nodalConns.
3695 * \throw If presence of not allocated or array with not exactly one component in \a nodalConns.
3697 DataArrayInt *MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds(const std::vector<const DataArrayInt *>& nodalConns, const std::vector<int>& offsetInNodeIdsPerElt)
3699 std::size_t sz1(nodalConns.size()),sz2(offsetInNodeIdsPerElt.size());
3701 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : input vectors do not have the same size !");
3703 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : empty vectors in input !");
3705 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++)
3708 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of null pointer in input vector !");
3709 if(!(*it)->isAllocated())
3710 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of non allocated array in input vector !");
3711 if((*it)->getNumberOfComponents()!=1)
3712 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of array with not exactly one component !");
3713 nbOfTuples+=(*it)->getNumberOfTuples();
3715 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
3716 int *pt=ret->getPointer();
3718 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++,i++)
3720 int curNbt=(*it)->getNumberOfTuples();
3721 const int *inPt=(*it)->begin();
3722 int offset=offsetInNodeIdsPerElt[i];
3723 for(int j=0;j<curNbt;j++,pt++)
3734 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m)
3737 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh is null !");
3738 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
3740 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh must have exactly one geometric type !");
3741 int geoType((int)*gts.begin());
3742 MCAuto<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(m->getName(),*gts.begin()));
3743 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription());
3744 int nbCells(m->getNumberOfCells());
3745 MCAuto<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
3746 conn->alloc(m->getNodalConnectivityArrayLen()-nbCells,1); connI->alloc(nbCells+1,1);
3747 int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
3748 const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
3749 for(int i=0;i<nbCells;i++,ciin++,ci++)
3751 if(cin[ciin[0]]==geoType)
3753 if(ciin[1]-ciin[0]>=1)
3755 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
3756 ci[1]=ci[0]+ciin[1]-ciin[0]-1;
3760 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 !";
3761 throw INTERP_KERNEL::Exception(oss.str().c_str());
3766 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 !";
3767 throw INTERP_KERNEL::Exception(oss.str().c_str());
3770 ret->setNodalConnectivity(conn,connI);