1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (CEA/DEN)
21 #include "MEDCoupling1GTUMesh.hxx"
22 #include "MEDCouplingUMesh.hxx"
23 #include "MEDCouplingFieldDouble.hxx"
24 #include "MEDCouplingCMesh.hxx"
26 #include "SplitterTetra.hxx"
28 using namespace ParaMEDMEM;
30 const int MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[6]={0,1,2,4,3,5};
32 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh():_cm(0)
36 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):_cm(&cm)
41 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const MEDCoupling1GTUMesh& other, bool recDeepCpy):MEDCouplingPointSet(other,recDeepCpy),_cm(other._cm)
45 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
47 if(type==INTERP_KERNEL::NORM_ERROR)
48 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
49 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
51 return MEDCoupling1SGTUMesh::New(name,type);
53 return MEDCoupling1DGTUMesh::New(name,type);
56 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const MEDCouplingUMesh *m)
59 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh is null !");
60 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
62 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh must have exactly one geometric type !");
63 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*gts.begin());
65 return MEDCoupling1SGTUMesh::New(m);
67 return MEDCoupling1DGTUMesh::New(m);
70 const INTERP_KERNEL::CellModel& MEDCoupling1GTUMesh::getCellModel() const
75 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getCellModelEnum() const
77 return _cm->getEnum();
80 int MEDCoupling1GTUMesh::getMeshDimension() const
82 return (int)_cm->getDimension();
86 * This method returns a newly allocated array containing cell ids (ascendingly sorted) whose geometric type are equal to type.
87 * This method does not throw exception if geometric type \a type is not in \a this.
88 * This method throws an INTERP_KERNEL::Exception if meshdimension of \b this is not equal to those of \b type.
89 * The coordinates array is not considered here.
91 * \param [in] type the geometric type
92 * \return cell ids in this having geometric type \a type.
94 DataArrayInt *MEDCoupling1GTUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
96 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
97 if(type==getCellModelEnum())
98 ret->alloc(getNumberOfCells(),1);
106 * Returns nb of cells having the geometric type \a type. No throw if no cells in \a this has the geometric type \a type.
108 int MEDCoupling1GTUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
110 return type==getCellModelEnum()?getNumberOfCells():0;
114 * Returns a type of a cell by its id.
115 * \param [in] cellId - the id of the cell of interest.
116 * \return INTERP_KERNEL::NormalizedCellType - enumeration item describing the cell type.
117 * \throw If \a cellId is invalid. Valid range is [0, \a this->getNumberOfCells() ).
119 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getTypeOfCell(int cellId) const
121 if(cellId>=0 && cellId<getNumberOfCells())
122 return getCellModelEnum();
123 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::getTypeOfCell : Requesting type of cell #" << cellId << " but it should be in [0," << getNumberOfCells() << ") !";
124 throw INTERP_KERNEL::Exception(oss.str().c_str());
128 * Returns a set of all cell types available in \a this mesh.
129 * \return std::set<INTERP_KERNEL::NormalizedCellType> - the set of cell types.
130 * \warning this method does not throw any exception even if \a this is not defined.
132 std::set<INTERP_KERNEL::NormalizedCellType> MEDCoupling1GTUMesh::getAllGeoTypes() const
134 std::set<INTERP_KERNEL::NormalizedCellType> ret;
135 ret.insert(getCellModelEnum());
140 * This method expects that \a this is sorted by types. If not an exception will be thrown.
141 * This method returns in the same format as code (see MEDCouplingUMesh::checkTypeConsistencyAndContig or MEDCouplingUMesh::splitProfilePerType) how
142 * \a this is composed in cell types.
143 * The returned array is of size 3*n where n is the number of different types present in \a this.
144 * For every k in [0,n] ret[3*k+2]==-1 because it has no sense here.
145 * This parameter is kept only for compatibility with other methode listed above.
147 std::vector<int> MEDCoupling1GTUMesh::getDistributionOfTypes() const
149 std::vector<int> ret(3);
150 ret[0]=(int)getCellModelEnum(); ret[1]=getNumberOfCells(); ret[2]=-1;
155 * This method is the opposite of MEDCouplingUMesh::checkTypeConsistencyAndContig method. Given a list of cells in \a profile it returns a list of sub-profiles sorted by geo type.
156 * The result is put in the array \a idsPerType. In the returned parameter \a code, foreach i \a code[3*i+2] refers (if different from -1) to a location into the \a idsPerType.
157 * This method has 1 input \a profile and 3 outputs \a code \a idsInPflPerType and \a idsPerType.
159 * \param [out] code is a vector of size 3*n where n is the number of different geometric type in \a this \b reduced to the profile \a profile. \a code has exactly the same semantic than in MEDCouplingUMesh::checkTypeConsistencyAndContig method.
160 * \param [out] idsInPflPerType is a vector of size of different geometric type in the subpart defined by \a profile of \a this ( equal to \a code.size()/3). For each i,
161 * \a idsInPflPerType[i] stores the tuple ids in \a profile that correspond to the geometric type code[3*i+0]
162 * \param [out] idsPerType is a vector of size of different sub profiles needed to be defined to represent the profile \a profile for a given geometric type.
163 * This vector can be empty in case of all geometric type cells are fully covered in ascending in the given input \a profile.
165 * \warning for performance reasons no deep copy will be performed, if \a profile can been used as this in output parameters \a idsInPflPerType and \a idsPerType.
167 * \throw if \a profile has not exactly one component. It throws too, if \a profile contains some values not in [0,getNumberOfCells()) or if \a this is not fully defined
170 * - Before \a this has 3 cells \a profile contains [0,1,2]
171 * - After \a code contains [NORM_...,nbCells,-1], \a idsInPflPerType [[0,1,2]] and \a idsPerType is empty <br>
174 * - Before \a this has 3 cells \a profile contains [1,2]
175 * - After \a code contains [NORM_...,nbCells,0], \a idsInPflPerType [[0,1]] and \a idsPerType is [[1,2]] <br>
178 void MEDCoupling1GTUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const
181 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile is NULL !");
182 if(profile->getNumberOfComponents()!=1)
183 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile should have exactly one component !");
184 int nbTuples=profile->getNumberOfTuples();
185 int nbOfCells=getNumberOfCells();
186 code.resize(3); idsInPflPerType.resize(1);
187 code[0]=(int)getCellModelEnum(); code[1]=nbTuples;
188 idsInPflPerType.resize(1);
189 if(profile->isIdentity() && nbTuples==nbOfCells)
192 idsInPflPerType[0]=const_cast<DataArrayInt *>(profile); idsInPflPerType[0]->incrRef();
197 profile->checkAllIdsInRange(0,nbOfCells);
198 idsPerType.resize(1);
199 idsPerType[0]=const_cast<DataArrayInt *>(profile); idsPerType[0]->incrRef();
200 idsInPflPerType[0]=DataArrayInt::Range(0,nbTuples,1);
204 * This method tries to minimize at most the number of deep copy.
205 * So if \a idsPerType is not empty it can be returned directly (without copy, but with ref count incremented) in return.
207 * \sa MEDCouplingUMesh::checkTypeConsistencyAndContig
209 DataArrayInt *MEDCoupling1GTUMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const
211 int nbOfCells=getNumberOfCells();
213 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : invalid input code should be exactly of size 3 !");
214 if(code[0]!=(int)getCellModelEnum())
216 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : Mismatch of geometric type ! Asking for " << code[0] << " whereas the geometric type is \a this is " << getCellModelEnum() << " (" << _cm->getRepr() << ") !";
217 throw INTERP_KERNEL::Exception(oss.str().c_str());
221 if(code[1]==nbOfCells)
225 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : mismatch between the number of cells in this (" << nbOfCells << ") and the number of non profile (" << code[1] << ") !";
226 throw INTERP_KERNEL::Exception(oss.str().c_str());
230 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : single geo type mesh ! 0 or -1 is expected at pos #2 of input code !");
231 if(idsPerType.size()!=1)
232 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input code points to DataArrayInt #0 whereas the size of idsPerType is not equal to 1 !");
233 const DataArrayInt *pfl=idsPerType[0];
235 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : the input code points to a NULL DataArrayInt at rank 0 !");
236 if(pfl->getNumberOfComponents()!=1)
237 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input profile should have exactly one component !");
238 pfl->checkAllIdsInRange(0,nbOfCells);
240 return const_cast<DataArrayInt *>(pfl);
243 void MEDCoupling1GTUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const
245 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
246 m->writeVTKLL(ofs,cellData,pointData,byteData);
249 std::string MEDCoupling1GTUMesh::getVTKDataSetType() const
251 return std::string("UnstructuredGrid");
254 std::size_t MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren() const
256 return MEDCouplingPointSet::getHeapMemorySizeWithoutChildren();
259 bool MEDCoupling1GTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
261 if(!MEDCouplingPointSet::isEqualIfNotWhy(other,prec,reason))
264 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualIfNotWhy : input other pointer is null !");
265 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
268 reason="mesh given in input is not castable in MEDCouplingSGTUMesh !";
273 reason="mismatch in geometric type !";
279 bool MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
281 if(!MEDCouplingPointSet::isEqualWithoutConsideringStr(other,prec))
284 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
285 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
293 void MEDCoupling1GTUMesh::checkCoherency() const
295 MEDCouplingPointSet::checkCoherency();
298 DataArrayDouble *MEDCoupling1GTUMesh::getBarycenterAndOwner() const
300 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
301 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=m->getBarycenterAndOwner();
305 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureField(bool isAbs) const
307 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
308 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureField(isAbs);
313 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureFieldOnNode(bool isAbs) const
315 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
316 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureFieldOnNode(isAbs);
324 int MEDCoupling1GTUMesh::getCellContainingPoint(const double *pos, double eps) const
326 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
327 return m->getCellContainingPoint(pos,eps);
330 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::buildOrthogonalField() const
332 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
333 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->buildOrthogonalField();
338 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const double *bbox, double eps) const
340 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
341 return m->getCellsInBoundingBox(bbox,eps);
344 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps)
346 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
347 return m->getCellsInBoundingBox(bbox,eps);
350 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const
352 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
353 return m->buildFacePartOfMySelfNode(start,end,fullyIn);
356 DataArrayInt *MEDCoupling1GTUMesh::findBoundaryNodes() const
358 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
359 return m->findBoundaryNodes();
362 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildBoundaryMesh(bool keepCoords) const
364 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
365 return m->buildBoundaryMesh(keepCoords);
368 void MEDCoupling1GTUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const
370 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
371 m->findCommonCells(compType,startCellId,commonCellsArr,commonCellsIArr);
374 int MEDCoupling1GTUMesh::getNodalConnectivityLength() const
376 const DataArrayInt *c1(getNodalConnectivity());
378 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : no connectivity set !");
379 if(c1->getNumberOfComponents()!=1)
380 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array set must have exactly one component !");
381 if(!c1->isAllocated())
382 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array must be allocated !");
383 return c1->getNumberOfTuples();
387 * This method aggregates all the meshes in \a parts to put them in a single unstructured mesh (those returned).
388 * The order of cells is the returned instance is those in the order of instances in \a parts.
390 * \param [in] parts - all not null parts of single geo type meshes to be aggreagated having the same mesh dimension and same coordinates.
391 * \return MEDCouplingUMesh * - new object to be dealt by the caller.
393 * \throw If one element is null in \a parts.
394 * \throw If not all the parts do not have the same mesh dimension.
395 * \throw If not all the parts do not share the same coordinates.
396 * \throw If not all the parts have their connectivity set properly.
397 * \throw If \a parts is empty.
399 MEDCouplingUMesh *MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh(const std::vector< const MEDCoupling1GTUMesh *>& parts)
402 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : input parts vector is empty !");
403 const MEDCoupling1GTUMesh *firstPart(parts[0]);
405 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : the first instance in input parts is null !");
406 const DataArrayDouble *coords(firstPart->getCoords());
407 int meshDim(firstPart->getMeshDimension());
408 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret(MEDCouplingUMesh::New(firstPart->getName(),meshDim)); ret->setDescription(firstPart->getDescription());
409 ret->setCoords(coords);
410 int nbOfCells(0),connSize(0);
411 for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
414 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of null pointer in input vector !");
415 if((*it)->getMeshDimension()!=meshDim)
416 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances in input vector must have same mesh dimension !");
417 if((*it)->getCoords()!=coords)
418 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances must share the same coordinates pointer !");
419 nbOfCells+=(*it)->getNumberOfCells();
420 connSize+=(*it)->getNodalConnectivityLength();
422 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
423 connI->alloc(nbOfCells+1,1); conn->alloc(connSize+nbOfCells,1);
424 int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
425 for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
427 int curNbCells((*it)->getNumberOfCells());
428 int geoType((int)(*it)->getCellModelEnum());
429 const int *cinPtr((*it)->getNodalConnectivity()->begin());
430 const MEDCoupling1SGTUMesh *ps(dynamic_cast<const MEDCoupling1SGTUMesh *>(*it));
431 const MEDCoupling1DGTUMesh *pd(dynamic_cast<const MEDCoupling1DGTUMesh *>(*it));
434 int nNodesPerCell(ps->getNumberOfNodesPerCell());
435 for(int i=0;i<curNbCells;i++,ci++,cinPtr+=nNodesPerCell)
438 c=std::copy(cinPtr,cinPtr+nNodesPerCell,c);
439 ci[1]=ci[0]+nNodesPerCell+1;
444 const int *ciinPtr(pd->getNodalConnectivityIndex()->begin());
445 for(int i=0;i<curNbCells;i++,ci++,ciinPtr++)
448 c=std::copy(cinPtr+ciinPtr[0],cinPtr+ciinPtr[1],c);
449 ci[1]=ci[0]+ciinPtr[1]-ciinPtr[0]+1;
453 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of instance which type is not in [MEDCoupling1SGTUMesh,MEDCoupling1DGTUMesh] !");
455 ret->setConnectivity(conn,connI,true);
461 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const MEDCoupling1SGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
465 const DataArrayInt *c(other._conn);
471 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
475 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh()
479 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New()
481 return new MEDCoupling1SGTUMesh;
484 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
486 if(type==INTERP_KERNEL::NORM_ERROR)
487 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
488 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
491 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New : the input geometric type " << cm.getRepr() << " is dynamic ! Only static types are allowed here !";
492 throw INTERP_KERNEL::Exception(oss.str().c_str());
494 return new MEDCoupling1SGTUMesh(name,cm);
497 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m)
500 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh is null !");
501 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
503 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh must have exactly one geometric type !");
504 int geoType((int)*gts.begin());
505 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(m->getName(),*gts.begin()));
506 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription());
507 int nbCells(m->getNumberOfCells());
508 int nbOfNodesPerCell(ret->getNumberOfNodesPerCell());
509 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()); conn->alloc(nbCells*nbOfNodesPerCell,1);
510 int *c(conn->getPointer());
511 const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
512 for(int i=0;i<nbCells;i++,ciin++)
514 if(cin[ciin[0]]==geoType)
516 if(ciin[1]-ciin[0]==nbOfNodesPerCell+1)
517 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
520 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 << ") !";
521 throw INTERP_KERNEL::Exception(oss.str().c_str());
526 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 !";
527 throw INTERP_KERNEL::Exception(oss.str().c_str());
530 ret->setNodalConnectivity(conn);
532 { ret->copyTinyInfoFrom(m); }
533 catch(INTERP_KERNEL::Exception&) { }
537 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::clone(bool recDeepCpy) const
539 return new MEDCoupling1SGTUMesh(*this,recDeepCpy);
543 * This method behaves mostly like MEDCoupling1SGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
544 * The coordinates are shared between \a this and the returned instance.
546 * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
547 * \sa MEDCoupling1SGTUMesh::deepCpy
549 MEDCouplingPointSet *MEDCoupling1SGTUMesh::deepCpyConnectivityOnly() const
552 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(clone(false));
553 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy());
554 ret->setNodalConnectivity(c);
558 void MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
561 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
562 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
564 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1SGTUMesh instance !");
565 setNodalConnectivity(otherC->getNodalConnectivity());
568 void MEDCoupling1SGTUMesh::updateTime() const
570 MEDCoupling1GTUMesh::updateTime();
571 const DataArrayInt *c(_conn);
576 std::size_t MEDCoupling1SGTUMesh::getHeapMemorySizeWithoutChildren() const
578 return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren();
581 std::vector<const BigMemoryObject *> MEDCoupling1SGTUMesh::getDirectChildren() const
583 std::vector<const BigMemoryObject *> ret(MEDCoupling1GTUMesh::getDirectChildren());
584 const DataArrayInt *c(_conn);
590 MEDCouplingMesh *MEDCoupling1SGTUMesh::deepCpy() const
595 bool MEDCoupling1SGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
598 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualIfNotWhy : input other pointer is null !");
599 std::ostringstream oss; oss.precision(15);
600 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
603 reason="mesh given in input is not castable in MEDCoupling1SGTUMesh !";
606 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
608 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
613 reason="in connectivity of single static geometric type exactly one among this and other is null !";
616 if(!c1->isEqualIfNotWhy(*c2,reason))
618 reason.insert(0,"Nodal connectivity DataArrayInt differ : ");
624 bool MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
627 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
628 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
631 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
633 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
638 if(!c1->isEqualWithoutConsideringStr(*c2))
643 void MEDCoupling1SGTUMesh::checkCoherencyOfConnectivity() const
645 const DataArrayInt *c1(_conn);
648 if(c1->getNumberOfComponents()!=1)
649 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
650 if(c1->getInfoOnComponent(0)!="")
651 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
652 c1->checkAllocated();
655 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
658 void MEDCoupling1SGTUMesh::checkCoherency() const
660 MEDCouplingPointSet::checkCoherency();
661 checkCoherencyOfConnectivity();
664 void MEDCoupling1SGTUMesh::checkCoherency1(double eps) const
667 const DataArrayInt *c1(_conn);
668 int nbOfTuples=c1->getNumberOfTuples();
669 int nbOfNodesPerCell=(int)_cm->getNumberOfNodes();
670 if(nbOfTuples%nbOfNodesPerCell!=0)
672 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::checkCoherency1 : the nb of tuples in conn is " << nbOfTuples << " and number of nodes per cell is " << nbOfNodesPerCell << ". But " << nbOfTuples << "%" << nbOfNodesPerCell << " !=0 !";
673 throw INTERP_KERNEL::Exception(oss.str().c_str());
675 int nbOfNodes=getNumberOfNodes();
676 int nbOfCells=nbOfTuples/nbOfNodesPerCell;
677 const int *w(c1->begin());
678 for(int i=0;i<nbOfCells;i++)
679 for(int j=0;j<nbOfNodesPerCell;j++,w++)
681 if(*w<0 || *w>=nbOfNodes)
683 std::ostringstream oss; oss << "At node #" << j << " of cell #" << i << ", is equal to " << *w << " must be in [0," << nbOfNodes << ") !";
684 throw INTERP_KERNEL::Exception(oss.str().c_str());
689 void MEDCoupling1SGTUMesh::checkCoherency2(double eps) const
691 checkCoherency1(eps);
694 int MEDCoupling1SGTUMesh::getNumberOfCells() const
696 int nbOfTuples=getNodalConnectivityLength();
697 int nbOfNodesPerCell=getNumberOfNodesPerCell();
698 if(nbOfTuples%nbOfNodesPerCell!=0)
700 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 !";
701 throw INTERP_KERNEL::Exception(oss.str().c_str());
703 return nbOfTuples/nbOfNodesPerCell;
706 int MEDCoupling1SGTUMesh::getNumberOfNodesInCell(int cellId) const
708 return getNumberOfNodesPerCell();
711 int MEDCoupling1SGTUMesh::getNumberOfNodesPerCell() const
713 checkNonDynamicGeoType();
714 return (int)_cm->getNumberOfNodes();
717 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfNodesPerCell() const
719 checkNonDynamicGeoType();
720 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
721 ret->alloc(getNumberOfCells(),1);
722 ret->fillWithValue((int)_cm->getNumberOfNodes());
726 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfFacesPerCell() const
728 checkNonDynamicGeoType();
729 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
730 ret->alloc(getNumberOfCells(),1);
731 ret->fillWithValue((int)_cm->getNumberOfSons());
735 DataArrayInt *MEDCoupling1SGTUMesh::computeEffectiveNbOfNodesPerCell() const
737 checkNonDynamicGeoType();
738 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
739 int nbCells(getNumberOfCells());
740 ret->alloc(nbCells,1);
741 int *retPtr(ret->getPointer());
742 int nbNodesPerCell(getNumberOfNodesPerCell());
743 const int *conn(_conn->begin());
744 for(int i=0;i<nbCells;i++,conn+=nbNodesPerCell,retPtr++)
746 std::set<int> s(conn,conn+nbNodesPerCell);
747 *retPtr=(int)s.size();
752 void MEDCoupling1SGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
754 int sz=getNumberOfNodesPerCell();
756 if(cellId>=0 && cellId<getNumberOfCells())
757 std::copy(_conn->begin()+cellId*sz,_conn->begin()+(cellId+1)*sz,conn.begin());
760 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << getNumberOfCells() << ") !";
761 throw INTERP_KERNEL::Exception(oss.str().c_str());
765 void MEDCoupling1SGTUMesh::checkNonDynamicGeoType() const
768 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkNonDynamicGeoType : internal error ! the internal geo type is dynamic ! should be static !");
771 std::string MEDCoupling1SGTUMesh::simpleRepr() const
773 static const char msg0[]="No coordinates specified !";
774 std::ostringstream ret;
775 ret << "Single static geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
776 ret << "Description of mesh : \"" << getDescription() << "\"\n";
778 double tt=getTime(tmpp1,tmpp2);
779 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
780 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
781 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
784 const int spaceDim=getSpaceDimension();
785 ret << spaceDim << "\nInfo attached on space dimension : ";
786 for(int i=0;i<spaceDim;i++)
787 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
792 ret << "Number of nodes : ";
794 ret << getNumberOfNodes() << "\n";
797 ret << "Number of cells : ";
798 if((const DataArrayInt *)_conn)
800 if(_conn->isAllocated())
802 if(_conn->getNumberOfComponents()==1)
803 ret << getNumberOfCells() << "\n";
805 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
808 ret << "Nodal connectivity array specified but not allocated !" << "\n";
811 ret << "No connectivity specified !" << "\n";
812 ret << "Cell type : " << _cm->getRepr() << "\n";
816 std::string MEDCoupling1SGTUMesh::advancedRepr() const
818 std::ostringstream ret;
820 ret << "\nCoordinates array : \n___________________\n\n";
822 _coords->reprWithoutNameStream(ret);
824 ret << "No array set !\n";
825 ret << "\n\nConnectivity array : \n____________________\n\n";
827 if((const DataArrayInt *)_conn)
829 if(_conn->isAllocated())
831 if(_conn->getNumberOfComponents()==1)
833 int nbOfCells=getNumberOfCells();
834 int sz=getNumberOfNodesPerCell();
835 const int *connPtr=_conn->begin();
836 for(int i=0;i<nbOfCells;i++,connPtr+=sz)
838 ret << "Cell #" << i << " : ";
839 std::copy(connPtr,connPtr+sz,std::ostream_iterator<int>(ret," "));
844 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
847 ret << "Nodal connectivity array specified but not allocated !" << "\n";
850 ret << "No connectivity specified !" << "\n";
854 DataArrayDouble *MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell() const
856 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
857 int spaceDim=getSpaceDimension();
858 int nbOfCells=getNumberOfCells();//checkCoherency()
859 int nbOfNodes=getNumberOfNodes();
860 ret->alloc(nbOfCells,spaceDim);
861 double *ptToFill=ret->getPointer();
862 const double *coor=_coords->begin();
863 const int *nodal=_conn->begin();
864 int sz=getNumberOfNodesPerCell();
865 double coeff=1./(double)sz;
866 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim)
868 std::fill(ptToFill,ptToFill+spaceDim,0.);
869 for(int j=0;j<sz;j++,nodal++)
870 if(*nodal>=0 && *nodal<nbOfNodes)
871 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
874 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
875 throw INTERP_KERNEL::Exception(oss.str().c_str());
877 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),coeff));
882 void MEDCoupling1SGTUMesh::renumberCells(const int *old2NewBg, bool check)
884 int nbCells=getNumberOfCells();
885 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
886 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
888 o2n=o2n->checkAndPreparePermutation();
890 const int *conn=_conn->begin();
891 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o=o2n->invertArrayO2N2N2O(nbCells);
892 const int *n2oPtr=n2o->begin();
893 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
894 newConn->alloc(_conn->getNumberOfTuples(),1);
895 newConn->copyStringInfoFrom(*_conn);
896 int sz=getNumberOfNodesPerCell();
898 int *newC=newConn->getPointer();
899 for(int i=0;i<nbCells;i++,newC+=sz)
902 std::copy(conn+pos*sz,conn+(pos+1)*sz,newC);
908 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
909 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
910 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
911 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
913 * \param [in] begin input start of array of node ids.
914 * \param [in] end input end of array of node ids.
915 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
916 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
918 void MEDCoupling1SGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
920 int nbOfCells=getNumberOfCells();
921 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
923 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
924 std::vector<bool> fastFinder(sz,false);
925 for(const int *work=begin;work!=end;work++)
926 if(*work>=0 && *work<sz)
927 fastFinder[*work]=true;
928 const int *conn=_conn->begin();
929 int nbNodesPerCell=getNumberOfNodesPerCell();
930 for(int i=0;i<nbOfCells;i++,conn+=nbNodesPerCell)
933 for(int j=0;j<nbNodesPerCell;j++)
937 if(fastFinder[conn[j]])
940 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
941 cellIdsKept->pushBackSilent(i);
943 cellIdsKeptArr=cellIdsKept.retn();
946 MEDCouplingMesh *MEDCoupling1SGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
948 if(other->getType()!=SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED)
949 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single static geo type each other !");
950 const MEDCoupling1SGTUMesh *otherC=static_cast<const MEDCoupling1SGTUMesh *>(other);
951 return Merge1SGTUMeshes(this,otherC);
954 MEDCouplingUMesh *MEDCoupling1SGTUMesh::buildUnstructured() const
956 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
957 ret->setCoords(getCoords());
958 const int *nodalConn=_conn->begin();
959 int nbCells=getNumberOfCells();
960 int nbNodesPerCell=getNumberOfNodesPerCell();
961 int geoType=(int)getCellModelEnum();
962 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells*(nbNodesPerCell+1),1);
963 int *cPtr=c->getPointer();
964 for(int i=0;i<nbCells;i++,nodalConn+=nbNodesPerCell)
967 cPtr=std::copy(nodalConn,nodalConn+nbNodesPerCell,cPtr);
969 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::Range(0,(nbCells+1)*(nbNodesPerCell+1),nbNodesPerCell+1);
970 ret->setConnectivity(c,cI,true);
972 { ret->copyTinyInfoFrom(this); }
973 catch(INTERP_KERNEL::Exception&) { }
977 DataArrayInt *MEDCoupling1SGTUMesh::simplexize(int policy)
982 return simplexizePol0();
984 return simplexizePol1();
985 case (int) INTERP_KERNEL::PLANAR_FACE_5:
986 return simplexizePlanarFace5();
987 case (int) INTERP_KERNEL::PLANAR_FACE_6:
988 return simplexizePlanarFace6();
990 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)");
996 struct MEDCouplingAccVisit
998 MEDCouplingAccVisit():_new_nb_of_nodes(0) { }
999 int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; }
1000 int _new_nb_of_nodes;
1006 * Finds nodes not used in any cell and returns an array giving a new id to every node
1007 * by excluding the unused nodes, for which the array holds -1. The result array is
1008 * a mapping in "Old to New" mode.
1009 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
1010 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
1011 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
1012 * if the node is unused or a new id else. The caller is to delete this
1013 * array using decrRef() as it is no more needed.
1014 * \throw If the coordinates array is not set.
1015 * \throw If the nodal connectivity of cells is not defined.
1016 * \throw If the nodal connectivity includes an invalid id.
1018 DataArrayInt *MEDCoupling1SGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
1021 int nbOfNodes=getNumberOfNodes();
1022 int nbOfCells=getNumberOfCells();
1023 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1024 ret->alloc(nbOfNodes,1);
1025 int *traducer=ret->getPointer();
1026 std::fill(traducer,traducer+nbOfNodes,-1);
1027 const int *conn=_conn->begin();
1028 int nbNodesPerCell=getNumberOfNodesPerCell();
1029 for(int i=0;i<nbOfCells;i++)
1030 for(int j=0;j<nbNodesPerCell;j++,conn++)
1031 if(*conn>=0 && *conn<nbOfNodes)
1035 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << conn[j] << " not in [0," << nbOfNodes << ") !";
1036 throw INTERP_KERNEL::Exception(oss.str().c_str());
1038 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
1039 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
1044 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
1045 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
1046 * This method is a generalization of shiftNodeNumbersInConn().
1047 * \warning This method performs no check of validity of new ids. **Use it with care !**
1048 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
1049 * this->getNumberOfNodes(), in "Old to New" mode.
1050 * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
1051 * \throw If the nodal connectivity of cells is not defined.
1053 void MEDCoupling1SGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
1055 getNumberOfCells();//only to check that all is well defined.
1056 _conn->transformWithIndArr(newNodeNumbersO2N,newNodeNumbersO2N+getNumberOfNodes());
1060 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2)
1062 std::vector<const MEDCoupling1SGTUMesh *> tmp(2);
1063 tmp[0]=const_cast<MEDCoupling1SGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1SGTUMesh *>(mesh2);
1064 return Merge1SGTUMeshes(tmp);
1067 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(std::vector<const MEDCoupling1SGTUMesh *>& a)
1069 std::size_t sz=a.size();
1071 return Merge1SGTUMeshesLL(a);
1072 for(std::size_t ii=0;ii<sz;ii++)
1075 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::Merge1SGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
1076 throw INTERP_KERNEL::Exception(oss.str().c_str());
1078 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
1079 for(std::size_t ii=0;ii<sz;ii++)
1080 if(&(a[ii]->getCellModel())!=cm)
1081 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : all items must have the same geo type !");
1082 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> > bb(sz);
1083 std::vector< const MEDCoupling1SGTUMesh * > aa(sz);
1085 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
1087 const MEDCoupling1SGTUMesh *cur=a[i];
1088 const DataArrayDouble *coo=cur->getCoords();
1090 spaceDim=coo->getNumberOfComponents();
1093 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : no spaceDim specified ! unable to perform merge !");
1094 for(std::size_t i=0;i<sz;i++)
1096 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
1099 return Merge1SGTUMeshesLL(aa);
1103 * \throw If presence of a null instance in the input vector \a a.
1104 * \throw If a is empty
1106 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::vector<const MEDCoupling1SGTUMesh *>& a)
1109 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : input array must be NON EMPTY !");
1110 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1112 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : null instance in the first element of input vector !");
1113 std::vector<const DataArrayInt *> ncs(a.size());
1114 (*it)->getNumberOfCells();//to check that all is OK
1115 const DataArrayDouble *coords=(*it)->getCoords();
1116 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1117 ncs[0]=(*it)->getNodalConnectivity();
1119 for(int i=1;it!=a.end();i++,it++)
1122 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : presence of a null instance in the input vector !");
1123 if(cm!=&((*it)->getCellModel()))
1124 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1125 (*it)->getNumberOfCells();//to check that all is OK
1126 ncs[i]=(*it)->getNodalConnectivity();
1127 if(coords!=(*it)->getCoords())
1128 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : not lying on same coords !");
1130 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1131 ret->setCoords(coords);
1132 ret->_conn=DataArrayInt::Aggregate(ncs);
1137 * 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)
1139 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector<const MEDCoupling1SGTUMesh *>& a)
1142 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : input array must be NON EMPTY !");
1143 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1144 int nbOfCells=(*it)->getNumberOfCells();
1145 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1146 int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
1148 for(;it!=a.end();it++)
1150 if(cm!=&((*it)->getCellModel()))
1151 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1152 nbOfCells+=(*it)->getNumberOfCells();
1154 std::vector<const MEDCouplingPointSet *> aps(a.size());
1155 std::copy(a.begin(),a.end(),aps.begin());
1156 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
1157 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1158 ret->setCoords(pts);
1159 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New();
1160 c->alloc(nbOfCells*nbNodesPerCell,1);
1161 int *cPtr=c->getPointer();
1163 for(it=a.begin();it!=a.end();it++)
1165 int curConnLgth=(*it)->getNodalConnectivityLength();
1166 const int *curC=(*it)->_conn->begin();
1167 cPtr=std::transform(curC,curC+curConnLgth,cPtr,std::bind2nd(std::plus<int>(),offset));
1168 offset+=(*it)->getNumberOfNodes();
1171 ret->setNodalConnectivity(c);
1175 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
1177 int ncell=getNumberOfCells();
1178 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1179 ret->setCoords(_coords);
1180 std::size_t nbOfElemsRet=std::distance(begin,end);
1181 const int *inConn=_conn->getConstPointer();
1182 int sz=getNumberOfNodesPerCell();
1183 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1184 int *connPtr=connRet->getPointer();
1185 for(const int *work=begin;work!=end;work++,connPtr+=sz)
1187 if(*work>=0 && *work<ncell)
1188 std::copy(inConn+(work[0])*sz,inConn+(work[0]+1)*sz,connPtr);
1191 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !";
1192 throw INTERP_KERNEL::Exception(oss.str().c_str());
1196 ret->copyTinyInfoFrom(this);
1200 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
1202 int ncell=getNumberOfCells();
1203 int nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : ");
1204 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1205 ret->setCoords(_coords);
1206 const int *inConn=_conn->getConstPointer();
1207 int sz=getNumberOfNodesPerCell();
1208 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1209 int *connPtr=connRet->getPointer();
1211 for(int i=0;i<nbOfElemsRet;i++,connPtr+=sz,curId+=step)
1213 if(curId>=0 && curId<ncell)
1214 std::copy(inConn+curId*sz,inConn+(curId+1)*sz,connPtr);
1217 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : On pos #" << i << " input cell id =" << curId << " should be in [0," << ncell << ") !";
1218 throw INTERP_KERNEL::Exception(oss.str().c_str());
1222 ret->copyTinyInfoFrom(this);
1226 void MEDCoupling1SGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
1228 int sz((int)nodeIdsInUse.size());
1229 int nbCells(getNumberOfCells());
1230 int nbOfNodesPerCell(getNumberOfNodesPerCell());
1231 const int *w(_conn->begin());
1232 for(int i=0;i<nbCells;i++)
1233 for(int j=0;j<nbOfNodesPerCell;j++,w++)
1236 nodeIdsInUse[*w]=true;
1239 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeNodeIdsAlg : At cell #" << i << " presence of node id #" << *w << " should be in [0," << sz << ") !";
1240 throw INTERP_KERNEL::Exception(oss.str().c_str());
1245 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(int spaceDim) const
1247 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1248 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1;
1249 const DataArrayInt *nodalConn(_conn);
1252 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
1259 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
1260 ret->setCoords(coords);
1263 ret->setCoords(_coords);
1267 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol0()
1269 int nbOfCells=getNumberOfCells();
1270 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1271 return DataArrayInt::Range(0,nbOfCells,1);
1272 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1273 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1274 const int *c(_conn->begin());
1275 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1276 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1278 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[2];
1279 newConnPtr[3]=c[0]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1280 retPtr[0]=i; retPtr[1]=i;
1283 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1288 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol1()
1290 int nbOfCells=getNumberOfCells();
1291 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1292 return DataArrayInt::Range(0,nbOfCells,1);
1293 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1294 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1295 const int *c(_conn->begin());
1296 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1297 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1299 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[3];
1300 newConnPtr[3]=c[1]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1301 retPtr[0]=i; retPtr[1]=i;
1304 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1309 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace5()
1311 int nbOfCells=getNumberOfCells();
1312 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1313 return DataArrayInt::Range(0,nbOfCells,1);
1314 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(5*4*nbOfCells,1);
1315 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(5*nbOfCells,1);
1316 const int *c(_conn->begin());
1317 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1318 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=20,retPtr+=5)
1320 for(int j=0;j<20;j++)
1321 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_5_WO[j]];
1322 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i;
1325 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1330 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace6()
1332 int nbOfCells=getNumberOfCells();
1333 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1334 return DataArrayInt::Range(0,nbOfCells,1);
1335 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(6*4*nbOfCells,1);
1336 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(6*nbOfCells,1);
1337 const int *c(_conn->begin());
1338 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1339 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=24,retPtr+=6)
1341 for(int j=0;j<24;j++)
1342 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_6_WO[j]];
1343 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i; retPtr[5]=i;
1346 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1351 void MEDCoupling1SGTUMesh::reprQuickOverview(std::ostream& stream) const
1353 stream << "MEDCoupling1SGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
1354 stream << " Mesh dimension : " << getMeshDimension() << ".";
1356 { stream << " No coordinates set !"; return ; }
1357 if(!_coords->isAllocated())
1358 { stream << " Coordinates set but not allocated !"; return ; }
1359 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
1360 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
1361 if(!(const DataArrayInt *)_conn)
1362 { stream << std::endl << "Nodal connectivity NOT set !"; return ; }
1363 if(_conn->isAllocated())
1365 if(_conn->getNumberOfComponents()==1)
1366 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
1370 void MEDCoupling1SGTUMesh::checkFullyDefined() const
1372 if(!((const DataArrayInt *)_conn) || !((const DataArrayDouble *)_coords))
1373 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFullyDefined : part of this is not fully defined.");
1377 * First step of unserialization process.
1379 bool MEDCoupling1SGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
1381 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEmptyMesh : not implemented yet !");
1384 void MEDCoupling1SGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
1387 double time=getTime(it,order);
1388 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
1390 littleStrings.push_back(getName());
1391 littleStrings.push_back(getDescription());
1392 littleStrings.push_back(getTimeUnit());
1394 std::vector<std::string> littleStrings2,littleStrings3;
1395 if((const DataArrayDouble *)_coords)
1396 _coords->getTinySerializationStrInformation(littleStrings2);
1397 if((const DataArrayInt *)_conn)
1398 _conn->getTinySerializationStrInformation(littleStrings3);
1399 int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size());
1400 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
1401 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
1403 tinyInfo.push_back(getCellModelEnum());
1404 tinyInfo.push_back(it);
1405 tinyInfo.push_back(order);
1406 std::vector<int> tinyInfo2,tinyInfo3;
1407 if((const DataArrayDouble *)_coords)
1408 _coords->getTinySerializationIntInformation(tinyInfo2);
1409 if((const DataArrayInt *)_conn)
1410 _conn->getTinySerializationIntInformation(tinyInfo3);
1411 int sz2((int)tinyInfo2.size()),sz3((int)tinyInfo3.size());
1412 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3);
1413 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1414 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
1416 tinyInfoD.push_back(time);
1419 void MEDCoupling1SGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
1421 std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+tinyInfo[5]);
1422 std::vector<int> tinyInfo1(tinyInfo.begin()+7+tinyInfo[5],tinyInfo.begin()+7+tinyInfo[5]+tinyInfo[6]);
1423 a1->resizeForUnserialization(tinyInfo1);
1424 a2->resizeForUnserialization(tinyInfo2);
1427 void MEDCoupling1SGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
1430 if((const DataArrayInt *)_conn)
1431 if(_conn->isAllocated())
1432 sz=_conn->getNbOfElems();
1433 a1=DataArrayInt::New();
1435 if(sz!=0 && (const DataArrayInt *)_conn)
1436 std::copy(_conn->begin(),_conn->end(),a1->getPointer());
1438 if((const DataArrayDouble *)_coords)
1439 if(_coords->isAllocated())
1440 sz=_coords->getNbOfElems();
1441 a2=DataArrayDouble::New();
1443 if(sz!=0 && (const DataArrayDouble *)_coords)
1444 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
1447 void MEDCoupling1SGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
1448 const std::vector<std::string>& littleStrings)
1450 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
1451 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
1452 setName(littleStrings[0]);
1453 setDescription(littleStrings[1]);
1454 setTimeUnit(littleStrings[2]);
1455 setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
1456 int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]);
1458 _coords=DataArrayDouble::New();
1459 std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+sz2);
1460 _coords->resizeForUnserialization(tinyInfo2);
1461 std::copy(a2->begin(),a2->end(),_coords->getPointer());
1462 _conn=DataArrayInt::New();
1463 std::vector<int> tinyInfo3(tinyInfo.begin()+7+sz2,tinyInfo.begin()+7+sz2+sz3);
1464 _conn->resizeForUnserialization(tinyInfo3);
1465 std::copy(a1->begin(),a1->end(),_conn->getPointer());
1466 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
1467 _coords->finishUnserialization(tinyInfo2,littleStrings2);
1468 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
1469 _conn->finishUnserialization(tinyInfo3,littleStrings3);
1473 * Checks if \a this and \a other meshes are geometrically equivalent with high
1474 * probability, else an exception is thrown. The meshes are considered equivalent if
1475 * (1) meshes contain the same number of nodes and the same number of elements of the
1476 * same types (2) three cells of the two meshes (first, last and middle) are based
1477 * on coincident nodes (with a specified precision).
1478 * \param [in] other - the mesh to compare with.
1479 * \param [in] prec - the precision used to compare nodes of the two meshes.
1480 * \throw If the two meshes do not match.
1482 void MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
1484 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1485 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1487 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single static geometric type !");
1488 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1492 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1493 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1494 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1495 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1496 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1497 if(c1->getHashCode()!=c2->getHashCode())
1498 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1501 MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
1504 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
1505 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1507 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
1508 std::vector<const MEDCoupling1SGTUMesh *> ms(2);
1511 return Merge1SGTUMeshesOnSameCoords(ms);
1514 void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const
1516 checkFullyDefined();
1517 int nbOfNodes=getNumberOfNodes();
1518 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
1519 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
1520 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
1521 const int *conn=_conn->begin();
1522 int nbOfCells=getNumberOfCells();
1523 int nbOfEltsInRevNodal=0;
1524 int nbOfNodesPerCell=getNumberOfNodesPerCell();
1525 for(int eltId=0;eltId<nbOfCells;eltId++)
1527 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1529 if(conn[0]>=0 && conn[0]<nbOfNodes)
1531 nbOfEltsInRevNodal++;
1532 revNodalIndxPtr[conn[0]+1]++;
1536 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
1537 throw INTERP_KERNEL::Exception(oss.str().c_str());
1541 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
1542 conn=_conn->begin();
1543 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
1544 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
1545 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
1546 for(int eltId=0;eltId<nbOfCells;eltId++)
1548 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1550 *std::find_if(revNodalPtr+revNodalIndxPtr[*conn],revNodalPtr+revNodalIndxPtr[*conn+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
1556 * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null.
1558 void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn)
1561 nodalConn->incrRef();
1567 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
1569 DataArrayInt *MEDCoupling1SGTUMesh::getNodalConnectivity() const
1571 const DataArrayInt *ret(_conn);
1572 return const_cast<DataArrayInt *>(ret);
1576 * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted,
1577 * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter.
1578 * If a nodal connectivity previouly existed before the call of this method, it will be reset.
1580 * \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain.
1582 void MEDCoupling1SGTUMesh::allocateCells(int nbOfCells)
1585 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !");
1586 _conn=DataArrayInt::New();
1587 _conn->reserve(getNumberOfNodesPerCell()*nbOfCells);
1592 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
1594 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
1595 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
1596 * \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
1597 * attached to \a this.
1598 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
1600 void MEDCoupling1SGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd)
1602 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
1603 int ref=getNumberOfNodesPerCell();
1606 DataArrayInt *c(_conn);
1608 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
1610 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !");
1614 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this (";
1615 oss << ref << ") !";
1616 throw INTERP_KERNEL::Exception(oss.str().c_str());
1621 * This method builds the dual mesh of \a this and returns it.
1623 * \return MEDCoupling1SGTUMesh * - newly object created to be managed by the caller.
1624 * \throw If \a this is not a mesh containing only simplex cells.
1625 * \throw If \a this is not correctly allocated (coordinates and connectivities have to be correctly set !).
1626 * \throw If at least one node in \a this is orphan (without any simplex cell lying on it !)
1628 MEDCoupling1GTUMesh *MEDCoupling1SGTUMesh::computeDualMesh() const
1630 const INTERP_KERNEL::CellModel& cm(getCellModel());
1632 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : this mesh is not a simplex mesh ! Please invoke simplexize of tetrahedrize on this before calling this method !");
1633 switch(getMeshDimension())
1636 return computeDualMesh3D();
1638 return computeDualMesh2D();
1640 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : meshdimension must be in [2,3] !");
1645 * This method explode each NORM_HEXA8 cells in \a this into 6 NORM_QUAD4 cells and put the result into the MEDCoupling1SGTUMesh returned instance.
1647 * \return MEDCoupling1SGTUMesh * - a newly allocated instances (to be managed by the caller) storing the result of the explosion.
1648 * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
1649 * \throw If \a this is not properly allocated.
1651 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4() const
1653 const INTERP_KERNEL::CellModel& cm(getCellModel());
1654 if(cm.getEnum()!=INTERP_KERNEL::NORM_HEXA8)
1655 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4 : this method can be applied only on HEXA8 mesh !");
1656 int nbHexa8(getNumberOfCells());
1657 const int *inConnPtr(getNodalConnectivity()->begin());
1658 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(getName(),INTERP_KERNEL::NORM_QUAD4));
1659 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()); c->alloc(nbHexa8*6*4,1);
1660 int *cPtr(c->getPointer());
1661 for(int i=0;i<nbHexa8;i++,inConnPtr+=8)
1663 for(int j=0;j<6;j++,cPtr+=4)
1664 cm.fillSonCellNodalConnectivity(j,inConnPtr,cPtr);
1666 ret->setCoords(getCoords());
1667 ret->setNodalConnectivity(c);
1672 * This method starts from an unstructured mesh that hides in reality a cartesian mesh.
1673 * If it is not the case, an exception will be thrown.
1674 * This method returns three objects : The cartesian mesh geometrically equivalent to \a this (within a precision of \a eps) and a permutation of cells
1675 * and a permutation of nodes.
1677 * - this[cellPerm[i]]=ret[i]
1679 * \param [out] cellPerm the permutation array of size \c this->getNumberOfCells()
1680 * \param [out] nodePerm the permutation array of size \c this->getNumberOfNodes()
1681 * \return MEDCouplingCMesh * - a newly allocated mesh that is the result of the structurization of \a this.
1683 MEDCouplingCMesh *MEDCoupling1SGTUMesh::structurizeMe(DataArrayInt *& cellPerm, DataArrayInt *& nodePerm, double eps) const
1686 int spaceDim(getSpaceDimension()),meshDim(getMeshDimension()),nbNodes(getNumberOfNodes());
1687 if(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim)!=getCellModelEnum())
1688 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::structurizeMe : the unique geo type in this is not compatible with the geometric type regarding mesh dimension !");
1689 MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> cm(MEDCouplingCMesh::New());
1690 for(int i=0;i<spaceDim;i++)
1692 std::vector<int> tmp(1,i);
1693 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> elt(static_cast<DataArrayDouble*>(getCoords()->keepSelectedComponents(tmp)));
1694 elt=elt->getDifferentValues(eps);
1696 cm->setCoordsAt(i,elt);
1698 if(nbNodes!=cm->getNumberOfNodes())
1699 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 ?");
1701 { cm->copyTinyInfoFrom(this); }
1702 catch(INTERP_KERNEL::Exception&) { }
1703 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> um(cm->buildUnstructured()),self(buildUnstructured());
1704 self->checkGeoEquivalWith(um,12,eps,cellPerm,nodePerm);
1710 bool UpdateHexa8Cell(int validAxis, int neighId, const int *validConnQuad4NeighSide, int *allFacesNodalConn, int *myNeighbours)
1712 static const int TAB[48]={
1720 static const int TAB2[6]={0,0,3,3,3,3};
1721 if(myNeighbours[validAxis]==neighId && allFacesNodalConn[4*validAxis+0]==validConnQuad4NeighSide[TAB2[validAxis]])
1723 int oldAxis((int)std::distance(myNeighbours,std::find(myNeighbours,myNeighbours+6,neighId)));
1724 std::size_t pos(std::distance(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,std::find(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS+6,oldAxis)));
1725 std::size_t pos0(pos/2),pos1(pos%2);
1726 int oldAxisOpp(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[2*pos0+(pos1+1)%2]);
1727 int oldConn[8],myConn2[8]={-1,-1,-1,-1,-1,-1,-1,-1},myConn[8],edgeConn[2],allFacesTmp[24],neighTmp[6];
1728 oldConn[0]=allFacesNodalConn[0]; oldConn[1]=allFacesNodalConn[1]; oldConn[2]=allFacesNodalConn[2]; oldConn[3]=allFacesNodalConn[3];
1729 oldConn[4]=allFacesNodalConn[4]; oldConn[5]=allFacesNodalConn[7]; oldConn[6]=allFacesNodalConn[6]; oldConn[7]=allFacesNodalConn[5];
1730 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_HEXA8));
1731 for(int i=0;i<4;i++)
1732 myConn2[i]=validConnQuad4NeighSide[(4-i+TAB2[validAxis])%4];
1733 for(int i=0;i<4;i++)
1735 int nodeId(myConn2[i]);//the node id for which the opposite one will be found
1737 INTERP_KERNEL::NormalizedCellType typeOfSon;
1738 for(int j=0;j<12 && !found;j++)
1740 cm.fillSonEdgesNodalConnectivity3D(j,oldConn,-1,edgeConn,typeOfSon);
1741 if(edgeConn[0]==nodeId || edgeConn[1]==nodeId)
1743 if(std::find(allFacesNodalConn+4*oldAxisOpp,allFacesNodalConn+4*oldAxisOpp+4,edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0])!=allFacesNodalConn+4*oldAxisOpp+4)
1745 myConn2[i+4]=edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0];
1751 throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error !");
1753 const int *myTab(TAB+8*validAxis);
1754 for(int i=0;i<8;i++)
1755 myConn[i]=myConn2[myTab[i]];
1756 for(int i=0;i<6;i++)
1758 cm.fillSonCellNodalConnectivity(i,myConn,allFacesTmp+4*i);
1759 std::set<int> s(allFacesTmp+4*i,allFacesTmp+4*i+4);
1761 for(int j=0;j<6 && !found;j++)
1763 std::set<int> s1(allFacesNodalConn+4*j,allFacesNodalConn+4*j+4);
1766 neighTmp[i]=myNeighbours[j];
1771 throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error #2 !");
1773 std::copy(allFacesTmp,allFacesTmp+24,allFacesNodalConn);
1774 std::copy(neighTmp,neighTmp+6,myNeighbours);
1781 * 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
1782 * homogeneous. If it succeeds the result of MEDCouplingUMesh::tetrahedrize will return a conform mesh.
1784 * \return DataArrayInt * - a newly allocated array (to be managed by the caller) containing renumbered cell ids.
1786 * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
1787 * \throw If \a this is not properly allocated.
1788 * \sa MEDCouplingUMesh::tetrahedrize, MEDCouplingUMesh::simplexize.
1790 DataArrayInt *MEDCoupling1SGTUMesh::sortHexa8EachOther()
1792 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> quads(explodeEachHexa8To6Quad4());//checks that only hexa8
1793 int nbHexa8(getNumberOfCells()),*cQuads(quads->getNodalConnectivity()->getPointer());
1794 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> neighOfQuads(DataArrayInt::New()); neighOfQuads->alloc(nbHexa8*6,1); neighOfQuads->fillWithValue(-1);
1795 int *ptNeigh(neighOfQuads->getPointer());
1796 {//neighOfQuads tells for each face of each Quad8 which cell (if!=-1) is connected to this face.
1797 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> quadsTmp(quads->buildUnstructured());
1798 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ccSafe,cciSafe;
1799 DataArrayInt *cc(0),*cci(0);
1800 quadsTmp->findCommonCells(3,0,cc,cci);
1801 ccSafe=cc; cciSafe=cci;
1802 const int *ccPtr(ccSafe->begin()),nbOfPair(cci->getNumberOfTuples()-1);
1803 for(int i=0;i<nbOfPair;i++)
1804 { ptNeigh[ccPtr[2*i+0]]=ccPtr[2*i+1]/6; ptNeigh[ccPtr[2*i+1]]=ccPtr[2*i+0]/6; }
1806 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
1807 std::vector<bool> fetched(nbHexa8,false);
1808 std::vector<bool>::iterator it(std::find(fetched.begin(),fetched.end(),false));
1809 while(it!=fetched.end())//it will turns as time as number of connected zones
1811 int cellId((int)std::distance(fetched.begin(),it));//it is the seed of the connected zone.
1812 std::set<int> s; s.insert(cellId);//s contains already organized.
1815 std::set<int> sNext;
1816 for(std::set<int>::const_iterator it0=s.begin();it0!=s.end();it0++)
1819 int *myNeighb(ptNeigh+6*(*it0));
1820 for(int i=0;i<6;i++)
1822 if(myNeighb[i]!=-1 && !fetched[myNeighb[i]])
1824 std::size_t pos(std::distance(HEXA8_FACE_PAIRS,std::find(HEXA8_FACE_PAIRS,HEXA8_FACE_PAIRS+6,i)));
1825 std::size_t pos0(pos/2),pos1(pos%2);
1826 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]))
1827 ret->pushBackSilent(myNeighb[i]);
1828 fetched[myNeighb[i]]=true;
1829 sNext.insert(myNeighb[i]);
1835 it=std::find(fetched.begin(),fetched.end(),false);
1839 int *conn(getNodalConnectivity()->getPointer());
1840 for(const int *pt=ret->begin();pt!=ret->end();pt++)
1843 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];
1844 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];
1851 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh3D() const
1853 static const int DUAL_TETRA_0[36]={
1854 4,1,0, 6,0,3, 7,3,1,
1855 4,0,1, 5,2,0, 8,1,2,
1856 6,3,0, 5,0,2, 9,2,3,
1859 static const int DUAL_TETRA_1[36]={
1860 8,4,10, 11,5,8, 10,7,11,
1861 9,4,8, 8,5,12, 12,6,9,
1862 10,4,9, 9,6,13, 13,7,10,
1863 12,5,11, 13,6,12, 11,7,13
1865 static const int FACEID_NOT_SH_NODE[4]={2,3,1,0};
1866 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TETRA4)
1867 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh3D : only TETRA4 supported !");
1868 checkFullyDefined();
1869 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured());
1870 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1871 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1872 const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1873 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d1Arr(DataArrayInt::New()),di1Arr(DataArrayInt::New()),rd1Arr(DataArrayInt::New()),rdi1Arr(DataArrayInt::New());
1874 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->explode3DMeshTo1D(d1Arr,di1Arr,rd1Arr,rdi1Arr));
1875 const int *d1(d1Arr->begin());
1876 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1877 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> faces(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
1878 const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
1879 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),facesBaryArr(faces->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
1880 const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+faces->getNumberOfCells()),offset1(offset0+edges->getNumberOfCells());
1882 std::vector<const DataArrayDouble *> v(4); v[0]=getCoords(); v[1]=facesBaryArr; v[2]=edgesBaryArr; v[3]=baryArr;
1883 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0; facesBaryArr=0;
1884 std::string name("DualOf_"); name+=getName();
1885 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYHED)); ret->setCoords(zeArr);
1886 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1887 for(int i=0;i<nbOfNodes;i++,revNodI++)
1889 int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1890 if(nbOfCellsSharingNode==0)
1892 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh3D : Node #" << i << " is orphan !";
1893 throw INTERP_KERNEL::Exception(oss.str().c_str());
1895 for(int j=0;j<nbOfCellsSharingNode;j++)
1897 int curCellId(revNod[revNodI[0]+j]);
1898 const int *connOfCurCell(nodal+4*curCellId);
1899 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1900 if(j!=0) cArr->pushBackSilent(-1);
1903 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;
1904 tmp[2]=curCellId+offset1; tmp[3]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+2]]+nbOfNodes;
1906 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;
1907 tmp[7]=curCellId+offset1; tmp[8]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+5]]+nbOfNodes;
1909 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;
1910 tmp[12]=curCellId+offset1; tmp[13]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+8]]+nbOfNodes;
1911 cArr->insertAtTheEnd(tmp,tmp+14);
1913 for(int k=0;k<4;k++)
1915 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1917 const int *faceId(d2+4*curCellId+k);
1918 if(rdi2[*faceId+1]-rdi2[*faceId]==1)
1920 int tmp2[5]; tmp2[0]=-1; tmp2[1]=i;
1921 tmp2[2]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+0]-8]+offset0;
1922 tmp2[3]=d2[4*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+1]-4]+nbOfNodes;
1923 tmp2[4]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+2]-8]+offset0;
1924 cArr->insertAtTheEnd(tmp2,tmp2+5);
1930 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
1932 ret->setNodalConnectivity(cArr,ciArr);
1936 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh2D() const
1938 static const int DUAL_TRI_0[6]={0,2, 1,0, 2,1};
1939 static const int DUAL_TRI_1[6]={-3,+5, +3,-4, +4,-5};
1940 static const int FACEID_NOT_SH_NODE[3]={1,2,0};
1941 if(getCellModelEnum()!=INTERP_KERNEL::NORM_TRI3)
1942 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh2D : only TRI3 supported !");
1943 checkFullyDefined();
1944 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured());
1945 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1946 thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1947 const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1948 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1949 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0;
1950 const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
1951 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
1952 const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+edges->getNumberOfCells());
1954 std::vector<const DataArrayDouble *> v(3); v[0]=getCoords(); v[1]=edgesBaryArr; v[2]=baryArr;
1955 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0;
1956 std::string name("DualOf_"); name+=getName();
1957 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYGON)); ret->setCoords(zeArr);
1958 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1959 for(int i=0;i<nbOfNodes;i++,revNodI++)
1961 int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1962 if(nbOfCellsSharingNode==0)
1964 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh2D : Node #" << i << " is orphan !";
1965 throw INTERP_KERNEL::Exception(oss.str().c_str());
1967 std::vector< std::vector<int> > polyg;
1968 for(int j=0;j<nbOfCellsSharingNode;j++)
1970 int curCellId(revNod[revNodI[0]+j]);
1971 const int *connOfCurCell(nodal+3*curCellId);
1972 std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1973 std::vector<int> locV(3);
1974 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;
1975 polyg.push_back(locV);
1977 for(int k=0;k<3;k++)
1979 if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1981 const int *edgeId(d2+3*curCellId+k);
1982 if(rdi2[*edgeId+1]-rdi2[*edgeId]==1)
1984 std::vector<int> locV2(2);
1985 int zeLocEdgeIdRel(DUAL_TRI_1[2*nodePosInCurCell+kk]);
1986 if(zeLocEdgeIdRel>0)
1987 { locV2[0]=d2[3*curCellId+zeLocEdgeIdRel-3]+nbOfNodes; locV2[1]=i; }
1989 { locV2[0]=i; locV2[1]=d2[3*curCellId-zeLocEdgeIdRel-3]+nbOfNodes; }
1990 polyg.push_back(locV2);
1996 std::vector<int> zePolyg(MEDCoupling1DGTUMesh::BuildAPolygonFromParts(polyg));
1997 cArr->insertAtTheEnd(zePolyg.begin(),zePolyg.end());
1998 ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
2000 ret->setNodalConnectivity(cArr,ciArr);
2005 * This method aggregate the bbox of each cell and put it into bbox
2007 * \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)
2008 * For all other cases this input parameter is ignored.
2009 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
2011 * \throw If \a this is not fully set (coordinates and connectivity).
2012 * \throw If a cell in \a this has no valid nodeId.
2014 DataArrayDouble *MEDCoupling1SGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
2016 int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()),nbOfNodesPerCell(getNumberOfNodesPerCell());
2017 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
2018 double *bbox(ret->getPointer());
2019 for(int i=0;i<nbOfCells*spaceDim;i++)
2021 bbox[2*i]=std::numeric_limits<double>::max();
2022 bbox[2*i+1]=-std::numeric_limits<double>::max();
2024 const double *coordsPtr(_coords->getConstPointer());
2025 const int *conn(_conn->getConstPointer());
2026 for(int i=0;i<nbOfCells;i++)
2029 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
2032 if(nodeId>=0 && nodeId<nbOfNodes)
2034 for(int k=0;k<spaceDim;k++)
2036 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
2037 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
2044 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
2045 throw INTERP_KERNEL::Exception(oss.str().c_str());
2053 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New()
2055 return new MEDCoupling1DGTUMesh;
2058 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
2060 if(type==INTERP_KERNEL::NORM_ERROR)
2061 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
2062 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
2065 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !";
2066 throw INTERP_KERNEL::Exception(oss.str().c_str());
2068 return new MEDCoupling1DGTUMesh(name,cm);
2071 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh()
2075 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
2079 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
2083 const DataArrayInt *c(other._conn);
2088 _conn_indx=c->deepCpy();
2092 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const
2094 return new MEDCoupling1DGTUMesh(*this,recDeepCpy);
2098 * This method behaves mostly like MEDCoupling1DGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
2099 * The coordinates are shared between \a this and the returned instance.
2101 * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
2102 * \sa MEDCoupling1DGTUMesh::deepCpy
2104 MEDCouplingPointSet *MEDCoupling1DGTUMesh::deepCpyConnectivityOnly() const
2107 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(clone(false));
2108 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy()),ci(_conn_indx->deepCpy());
2109 ret->setNodalConnectivity(c,ci);
2113 void MEDCoupling1DGTUMesh::updateTime() const
2115 MEDCoupling1GTUMesh::updateTime();
2116 const DataArrayInt *c(_conn);
2124 std::size_t MEDCoupling1DGTUMesh::getHeapMemorySizeWithoutChildren() const
2126 return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren();
2129 std::vector<const BigMemoryObject *> MEDCoupling1DGTUMesh::getDirectChildren() const
2131 std::vector<const BigMemoryObject *> ret(MEDCoupling1GTUMesh::getDirectChildren());
2132 const DataArrayInt *c(_conn);
2141 MEDCouplingMesh *MEDCoupling1DGTUMesh::deepCpy() const
2146 bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
2149 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !");
2150 std::ostringstream oss; oss.precision(15);
2151 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2154 reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !";
2157 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
2159 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2164 reason="in connectivity of single dynamic geometric type exactly one among this and other is null !";
2167 if(!c1->isEqualIfNotWhy(*c2,reason))
2169 reason.insert(0,"Nodal connectivity DataArrayInt differs : ");
2172 c1=_conn_indx; c2=otherC->_conn_indx;
2177 reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !";
2180 if(!c1->isEqualIfNotWhy(*c2,reason))
2182 reason.insert(0,"Nodal connectivity index DataArrayInt differs : ");
2188 bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
2191 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
2192 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2195 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
2197 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2202 if(!c1->isEqualWithoutConsideringStr(*c2))
2205 c1=_conn_indx; c2=otherC->_conn_indx;
2210 if(!c1->isEqualWithoutConsideringStr(*c2))
2216 * Checks if \a this and \a other meshes are geometrically equivalent with high
2217 * probability, else an exception is thrown. The meshes are considered equivalent if
2218 * (1) meshes contain the same number of nodes and the same number of elements of the
2219 * same types (2) three cells of the two meshes (first, last and middle) are based
2220 * on coincident nodes (with a specified precision).
2221 * \param [in] other - the mesh to compare with.
2222 * \param [in] prec - the precision used to compare nodes of the two meshes.
2223 * \throw If the two meshes do not match.
2225 void MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
2227 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
2228 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2230 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single dynamic geometric type !");
2231 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2235 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
2236 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2237 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
2238 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2239 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
2240 if(c1->getHashCode()!=c2->getHashCode())
2241 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs");
2243 c1=_conn_indx; c2=otherC->_conn_indx;
2247 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !");
2248 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2249 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !");
2250 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2251 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !");
2252 if(c1->getHashCode()!=c2->getHashCode())
2253 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs");
2257 void MEDCoupling1DGTUMesh::checkCoherencyOfConnectivity() const
2259 const DataArrayInt *c1(_conn);
2262 if(c1->getNumberOfComponents()!=1)
2263 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
2264 if(c1->getInfoOnComponent(0)!="")
2265 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
2266 c1->checkAllocated();
2269 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
2271 int sz2=_conn->getNumberOfTuples();
2275 if(c1->getNumberOfComponents()!=1)
2276 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
2277 c1->checkAllocated();
2278 if(c1->getNumberOfTuples()<1)
2279 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !");
2280 if(c1->getInfoOnComponent(0)!="")
2281 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
2282 int f=c1->front(),ll=c1->back();
2285 std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !";
2286 throw INTERP_KERNEL::Exception(oss.str().c_str());
2290 std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !";
2291 throw INTERP_KERNEL::Exception(oss.str().c_str());
2295 std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !";
2296 throw INTERP_KERNEL::Exception(oss.str().c_str());
2300 throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !");
2301 int szOfC1Exp=_conn_indx->back();
2304 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::checkCoherencyOfConnectivity : The expected length of nodal connectivity array regarding index is " << szOfC1Exp << " but the actual size of it is " << c1->getNumberOfTuples() << " !";
2305 throw INTERP_KERNEL::Exception(oss.str().c_str());
2310 * 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.
2311 * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one.
2312 * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array.
2314 void MEDCoupling1DGTUMesh::checkCoherency() const
2316 MEDCouplingPointSet::checkCoherency();
2317 checkCoherencyOfConnectivity();
2320 void MEDCoupling1DGTUMesh::checkCoherency1(double eps) const
2323 const DataArrayInt *c1(_conn),*c2(_conn_indx);
2324 if(!c2->isMonotonic(true))
2325 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkCoherency1 : the nodal connectivity index is expected to be increasing monotinic !");
2327 int nbOfTuples=c1->getNumberOfTuples();
2328 int nbOfNodes=getNumberOfNodes();
2329 const int *w(c1->begin());
2330 for(int i=0;i<nbOfTuples;i++,w++)
2332 if(*w==-1) continue;
2333 if(*w<0 || *w>=nbOfNodes)
2335 std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !";
2336 throw INTERP_KERNEL::Exception(oss.str().c_str());
2341 void MEDCoupling1DGTUMesh::checkCoherency2(double eps) const
2343 checkCoherency1(eps);
2346 int MEDCoupling1DGTUMesh::getNumberOfCells() const
2348 checkCoherencyOfConnectivity();//do not remove
2349 return _conn_indx->getNumberOfTuples()-1;
2353 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2354 * For each cell in \b this the number of nodes constituting cell is computed.
2355 * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned.
2356 * So for pohyhedrons some nodes can be counted several times in the returned result.
2358 * \return a newly allocated array
2360 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const
2363 _conn_indx->checkMonotonic(true);
2364 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2365 return _conn_indx->deltaShiftIndex();
2367 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2368 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2369 ret->alloc(nbOfCells,1);
2370 int *retPtr=ret->getPointer();
2371 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2372 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2373 *retPtr=ci[1]-ci[0]-std::count(c+ci[0],c+ci[1],-1);
2378 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2379 * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed.
2381 * \return a newly allocated array
2383 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const
2386 _conn_indx->checkMonotonic(true);
2387 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG)
2388 return _conn_indx->deltaShiftIndex();
2389 if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG)
2391 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=_conn_indx->deltaShiftIndex();
2392 ret->applyDivideBy(2);
2396 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2397 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2398 ret->alloc(nbOfCells,1);
2399 int *retPtr=ret->getPointer();
2400 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2401 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2402 *retPtr=std::count(c+ci[0],c+ci[1],-1)+1;
2407 * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell,
2408 * will be counted only once here whereas it will be counted several times in MEDCoupling1DGTUMesh::computeNbOfNodesPerCell method.
2410 * \return DataArrayInt * - new object to be deallocated by the caller.
2411 * \sa MEDCoupling1DGTUMesh::computeNbOfNodesPerCell
2413 DataArrayInt *MEDCoupling1DGTUMesh::computeEffectiveNbOfNodesPerCell() const
2416 _conn_indx->checkMonotonic(true);
2417 int nbOfCells(_conn_indx->getNumberOfTuples()-1);
2418 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2419 ret->alloc(nbOfCells,1);
2420 int *retPtr(ret->getPointer());
2421 const int *ci(_conn_indx->begin()),*c(_conn->begin());
2422 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2424 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2426 std::set<int> s(c+ci[0],c+ci[1]);
2427 *retPtr=(int)s.size();
2432 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2434 std::set<int> s(c+ci[0],c+ci[1]); s.erase(-1);
2435 *retPtr=(int)s.size();
2441 void MEDCoupling1DGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
2443 int nbOfCells(getNumberOfCells());//performs checks
2444 if(cellId>=0 && cellId<nbOfCells)
2446 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2447 int nbOfNodes=stp-strt;
2449 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !");
2450 conn.resize(nbOfNodes);
2451 std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin());
2455 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2456 throw INTERP_KERNEL::Exception(oss.str().c_str());
2460 int MEDCoupling1DGTUMesh::getNumberOfNodesInCell(int cellId) const
2462 int nbOfCells(getNumberOfCells());//performs checks
2463 if(cellId>=0 && cellId<nbOfCells)
2465 const int *conn(_conn->begin());
2466 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2467 return stp-strt-std::count(conn+strt,conn+stp,-1);
2471 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNumberOfNodesInCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2472 throw INTERP_KERNEL::Exception(oss.str().c_str());
2476 std::string MEDCoupling1DGTUMesh::simpleRepr() const
2478 static const char msg0[]="No coordinates specified !";
2479 std::ostringstream ret;
2480 ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
2481 ret << "Description of mesh : \"" << getDescription() << "\"\n";
2483 double tt=getTime(tmpp1,tmpp2);
2484 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
2485 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
2486 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
2489 const int spaceDim=getSpaceDimension();
2490 ret << spaceDim << "\nInfo attached on space dimension : ";
2491 for(int i=0;i<spaceDim;i++)
2492 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
2496 ret << msg0 << "\n";
2497 ret << "Number of nodes : ";
2499 ret << getNumberOfNodes() << "\n";
2501 ret << msg0 << "\n";
2502 ret << "Number of cells : ";
2504 try { checkCoherency(); } catch(INTERP_KERNEL::Exception& /* e */)
2506 ret << "Nodal connectivity arrays are not set or badly set !\n";
2510 ret << getNumberOfCells() << "\n";
2511 ret << "Cell type : " << _cm->getRepr() << "\n";
2515 std::string MEDCoupling1DGTUMesh::advancedRepr() const
2517 std::ostringstream ret;
2518 ret << simpleRepr();
2519 ret << "\nCoordinates array : \n___________________\n\n";
2521 _coords->reprWithoutNameStream(ret);
2523 ret << "No array set !\n";
2524 ret << "\n\nNodal Connectivity : \n____________________\n\n";
2527 try { checkCoherency1(); } catch(INTERP_KERNEL::Exception& /* e */)
2529 ret << "Nodal connectivity arrays are not set or badly set !\n";
2534 int nbOfCells=getNumberOfCells();
2535 const int *ci=_conn_indx->begin(),*c=_conn->begin();
2536 for(int i=0;i<nbOfCells;i++,ci++)
2538 ret << "Cell #" << i << " : ";
2539 std::copy(c+ci[0],c+ci[1],std::ostream_iterator<int>(ret," "));
2545 DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const
2547 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
2548 int spaceDim=getSpaceDimension();
2549 int nbOfCells=getNumberOfCells();//checkCoherency()
2550 int nbOfNodes=getNumberOfNodes();
2551 ret->alloc(nbOfCells,spaceDim);
2552 double *ptToFill=ret->getPointer();
2553 const double *coor=_coords->begin();
2554 const int *nodal=_conn->begin(),*nodali=_conn_indx->begin();
2556 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2558 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2560 std::fill(ptToFill,ptToFill+spaceDim,0.);
2561 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2563 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2565 if(*nodal>=0 && *nodal<nbOfNodes)
2566 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2569 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2570 throw INTERP_KERNEL::Exception(oss.str().c_str());
2572 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(nodali[1]-nodali[0])));
2577 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !";
2578 throw INTERP_KERNEL::Exception(oss.str().c_str());
2584 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2586 std::fill(ptToFill,ptToFill+spaceDim,0.);
2587 if(nodali[0]<nodali[1])// >= to avoid division by 0.
2590 for(int j=nodali[0];j<nodali[1];j++,nodal++)
2592 if(*nodal==-1) continue;
2593 if(*nodal>=0 && *nodal<nbOfNodes)
2595 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2600 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
2601 throw INTERP_KERNEL::Exception(oss.str().c_str());
2605 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./nbOfNod));
2608 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !";
2609 throw INTERP_KERNEL::Exception(oss.str().c_str());
2614 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : at cell #" << i << " the nodal index array is invalid !";
2615 throw INTERP_KERNEL::Exception(oss.str().c_str());
2622 void MEDCoupling1DGTUMesh::renumberCells(const int *old2NewBg, bool check)
2624 int nbCells=getNumberOfCells();
2625 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
2626 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
2628 o2n=o2n->checkAndPreparePermutation();
2630 const int *o2nPtr=o2n->getPointer();
2631 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2632 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
2633 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
2634 newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1);
2635 newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx);
2637 int *newC=newConn->getPointer(),*newCI=newConnI->getPointer();
2638 for(int i=0;i<nbCells;i++)
2640 int newPos=o2nPtr[i];
2641 int sz=conni[i+1]-conni[i];
2646 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !";
2647 throw INTERP_KERNEL::Exception(oss.str().c_str());
2650 newConnI->computeOffsets2(); newCI=newConnI->getPointer();
2652 for(int i=0;i<nbCells;i++,conni++)
2655 std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]);
2658 _conn_indx=newConnI;
2661 MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
2663 if(other->getType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED)
2664 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !");
2665 const MEDCoupling1DGTUMesh *otherC=static_cast<const MEDCoupling1DGTUMesh *>(other);
2666 return Merge1DGTUMeshes(this,otherC);
2669 MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const
2671 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
2672 ret->setCoords(getCoords());
2673 const int *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin();
2674 int nbCells=getNumberOfCells();//checkCoherency
2675 int geoType=(int)getCellModelEnum();
2676 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1);
2677 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::New(); cI->alloc(nbCells+1);
2678 int *cPtr=c->getPointer(),*ciPtr=cI->getPointer();
2680 for(int i=0;i<nbCells;i++,ciPtr++)
2682 int sz=nodalConnI[i+1]-nodalConnI[i];
2686 cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr);
2687 ciPtr[1]=ciPtr[0]+sz+1;
2691 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !";
2692 throw INTERP_KERNEL::Exception(oss.str().c_str());
2695 ret->setConnectivity(c,cI,true);
2697 { ret->copyTinyInfoFrom(this); }
2698 catch(INTERP_KERNEL::Exception&) { }
2703 * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes
2705 DataArrayInt *MEDCoupling1DGTUMesh::simplexize(int policy)
2707 int nbOfCells=getNumberOfCells();
2708 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2709 ret->alloc(nbOfCells,1);
2714 void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const
2716 stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
2717 stream << " Mesh dimension : " << getMeshDimension() << ".";
2719 { stream << " No coordinates set !"; return ; }
2720 if(!_coords->isAllocated())
2721 { stream << " Coordinates set but not allocated !"; return ; }
2722 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
2723 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
2725 try { checkCoherency(); } catch(INTERP_KERNEL::Exception& /* e */)
2727 stream << std::endl << "Nodal connectivity NOT set properly !\n";
2731 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
2734 void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
2737 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
2738 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2740 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !");
2741 setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex());
2744 MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
2747 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
2748 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2750 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
2751 std::vector<const MEDCoupling1DGTUMesh *> ms(2);
2754 return Merge1DGTUMeshesOnSameCoords(ms);
2757 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
2760 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2761 ret->setCoords(_coords);
2762 DataArrayInt *c=0,*ci=0;
2763 MEDCouplingUMesh::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci);
2764 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2765 ret->setNodalConnectivity(c,ci);
2769 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
2772 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2773 ret->setCoords(_coords);
2774 DataArrayInt *c=0,*ci=0;
2775 MEDCouplingUMesh::ExtractFromIndexedArrays2(start,end,step,_conn,_conn_indx,c,ci);
2776 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2777 ret->setNodalConnectivity(c,ci);
2781 void MEDCoupling1DGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
2783 int sz((int)nodeIdsInUse.size());
2784 int nbCells(getNumberOfCells());
2785 const int *w(_conn->begin()),*wi(_conn_indx->begin());
2786 for(int i=0;i<nbCells;i++,wi++)
2787 for(const int *pt=w+wi[0];pt!=w+wi[1];pt++)
2790 if(*pt>=0 && *pt<sz)
2791 nodeIdsInUse[*pt]=true;
2794 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeNodeIdsAlg : At cell #" << i << " presence of node id #" << *pt << " should be in [0," << sz << ") !";
2795 throw INTERP_KERNEL::Exception(oss.str().c_str());
2800 void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const
2802 checkFullyDefined();
2803 int nbOfNodes=getNumberOfNodes();
2804 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
2805 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
2806 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
2807 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2808 int nbOfCells=getNumberOfCells();
2809 int nbOfEltsInRevNodal=0;
2810 for(int eltId=0;eltId<nbOfCells;eltId++)
2812 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2813 if(nbOfNodesPerCell>=0)
2815 for(int j=0;j<nbOfNodesPerCell;j++)
2817 int nodeId=conn[conni[eltId]+j];
2818 if(nodeId==-1) continue;
2819 if(nodeId>=0 && nodeId<nbOfNodes)
2821 nbOfEltsInRevNodal++;
2822 revNodalIndxPtr[nodeId+1]++;
2826 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
2827 throw INTERP_KERNEL::Exception(oss.str().c_str());
2833 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << "nodal connectivity is invalid !";
2834 throw INTERP_KERNEL::Exception(oss.str().c_str());
2837 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
2838 conn=_conn->begin();
2839 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
2840 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
2841 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
2842 for(int eltId=0;eltId<nbOfCells;eltId++)
2844 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2845 for(int j=0;j<nbOfNodesPerCell;j++)
2847 int nodeId=conn[conni[eltId]+j];
2849 *std::find_if(revNodalPtr+revNodalIndxPtr[nodeId],revNodalPtr+revNodalIndxPtr[nodeId+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
2854 void MEDCoupling1DGTUMesh::checkFullyDefined() const
2856 if(!((const DataArrayInt *)_conn) || !((const DataArrayInt *)_conn_indx) || !((const DataArrayDouble *)_coords))
2857 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined.");
2860 bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
2862 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !");
2865 void MEDCoupling1DGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
2868 double time=getTime(it,order);
2869 tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
2871 littleStrings.push_back(getName());
2872 littleStrings.push_back(getDescription());
2873 littleStrings.push_back(getTimeUnit());
2875 std::vector<std::string> littleStrings2,littleStrings3,littleStrings4;
2876 if((const DataArrayDouble *)_coords)
2877 _coords->getTinySerializationStrInformation(littleStrings2);
2878 if((const DataArrayInt *)_conn)
2879 _conn->getTinySerializationStrInformation(littleStrings3);
2880 if((const DataArrayInt *)_conn_indx)
2881 _conn_indx->getTinySerializationStrInformation(littleStrings4);
2882 int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size()),sz2((int)littleStrings4.size());
2883 littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
2884 littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
2885 littleStrings.insert(littleStrings.end(),littleStrings4.begin(),littleStrings4.end());
2887 tinyInfo.push_back(getCellModelEnum());
2888 tinyInfo.push_back(it);
2889 tinyInfo.push_back(order);
2890 std::vector<int> tinyInfo2,tinyInfo3,tinyInfo4;
2891 if((const DataArrayDouble *)_coords)
2892 _coords->getTinySerializationIntInformation(tinyInfo2);
2893 if((const DataArrayInt *)_conn)
2894 _conn->getTinySerializationIntInformation(tinyInfo3);
2895 if((const DataArrayInt *)_conn_indx)
2896 _conn_indx->getTinySerializationIntInformation(tinyInfo4);
2897 int sz3((int)tinyInfo2.size()),sz4((int)tinyInfo3.size()),sz5((int)tinyInfo4.size());
2898 tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3); tinyInfo.push_back(sz4); tinyInfo.push_back(sz5);
2899 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
2900 tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
2901 tinyInfo.insert(tinyInfo.end(),tinyInfo4.begin(),tinyInfo4.end());
2903 tinyInfoD.push_back(time);
2906 void MEDCoupling1DGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
2908 std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+tinyInfo[6]);
2909 std::vector<int> tinyInfo1(tinyInfo.begin()+9+tinyInfo[6],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]);
2910 std::vector<int> tinyInfo12(tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]+tinyInfo[8]);
2911 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(DataArrayInt::New()); p1->resizeForUnserialization(tinyInfo1);
2912 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(DataArrayInt::New()); p2->resizeForUnserialization(tinyInfo12);
2913 std::vector<const DataArrayInt *> v(2); v[0]=p1; v[1]=p2;
2914 p2=DataArrayInt::Aggregate(v);
2915 a2->resizeForUnserialization(tinyInfo2);
2916 a1->alloc(p2->getNbOfElems(),1);
2919 void MEDCoupling1DGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
2922 if((const DataArrayInt *)_conn)
2923 if(_conn->isAllocated())
2924 sz=_conn->getNbOfElems();
2925 if((const DataArrayInt *)_conn_indx)
2926 if(_conn_indx->isAllocated())
2927 sz+=_conn_indx->getNbOfElems();
2928 a1=DataArrayInt::New();
2930 int *work(a1->getPointer());
2931 if(sz!=0 && (const DataArrayInt *)_conn)
2932 work=std::copy(_conn->begin(),_conn->end(),a1->getPointer());
2933 if(sz!=0 && (const DataArrayInt *)_conn_indx)
2934 std::copy(_conn_indx->begin(),_conn_indx->end(),work);
2936 if((const DataArrayDouble *)_coords)
2937 if(_coords->isAllocated())
2938 sz=_coords->getNbOfElems();
2939 a2=DataArrayDouble::New();
2941 if(sz!=0 && (const DataArrayDouble *)_coords)
2942 std::copy(_coords->begin(),_coords->end(),a2->getPointer());
2945 void MEDCoupling1DGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
2946 const std::vector<std::string>& littleStrings)
2948 INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
2949 _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
2950 setName(littleStrings[0]);
2951 setDescription(littleStrings[1]);
2952 setTimeUnit(littleStrings[2]);
2953 setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
2954 int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]),sz4(tinyInfo[7]),sz5(tinyInfo[8]);
2956 _coords=DataArrayDouble::New();
2957 std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+sz3);
2958 _coords->resizeForUnserialization(tinyInfo2);
2959 std::copy(a2->begin(),a2->end(),_coords->getPointer());
2960 _conn=DataArrayInt::New();
2961 std::vector<int> tinyInfo3(tinyInfo.begin()+9+sz3,tinyInfo.begin()+9+sz3+sz4);
2962 _conn->resizeForUnserialization(tinyInfo3);
2963 std::copy(a1->begin(),a1->begin()+_conn->getNbOfElems(),_conn->getPointer());
2964 _conn_indx=DataArrayInt::New();
2965 std::vector<int> tinyInfo4(tinyInfo.begin()+9+sz3+sz4,tinyInfo.begin()+9+sz3+sz4+sz5);
2966 _conn_indx->resizeForUnserialization(tinyInfo4);
2967 std::copy(a1->begin()+_conn->getNbOfElems(),a1->end(),_conn_indx->getPointer());
2968 std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
2969 _coords->finishUnserialization(tinyInfo2,littleStrings2);
2970 std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
2971 _conn->finishUnserialization(tinyInfo3,littleStrings3);
2972 std::vector<std::string> littleStrings4(littleStrings.begin()+3+sz0+sz1,littleStrings.begin()+3+sz0+sz1+sz2);
2973 _conn_indx->finishUnserialization(tinyInfo4,littleStrings4);
2977 * Finds nodes not used in any cell and returns an array giving a new id to every node
2978 * by excluding the unused nodes, for which the array holds -1. The result array is
2979 * a mapping in "Old to New" mode.
2980 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
2981 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
2982 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
2983 * if the node is unused or a new id else. The caller is to delete this
2984 * array using decrRef() as it is no more needed.
2985 * \throw If the coordinates array is not set.
2986 * \throw If the nodal connectivity of cells is not defined.
2987 * \throw If the nodal connectivity includes an invalid id.
2989 DataArrayInt *MEDCoupling1DGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
2992 int nbOfNodes=getNumberOfNodes();
2993 int nbOfCells=getNumberOfCells();//checkCoherency
2994 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2995 ret->alloc(nbOfNodes,1);
2996 int *traducer=ret->getPointer();
2997 std::fill(traducer,traducer+nbOfNodes,-1);
2998 const int *conn=_conn->begin(),*conni(_conn_indx->begin());
2999 for(int i=0;i<nbOfCells;i++,conni++)
3001 int nbNodesPerCell=conni[1]-conni[0];
3002 for(int j=0;j<nbNodesPerCell;j++)
3004 int nodeId=conn[conni[0]+j];
3005 if(nodeId==-1) continue;
3006 if(nodeId>=0 && nodeId<nbOfNodes)
3010 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << nodeId << " not in [0," << nbOfNodes << ") !";
3011 throw INTERP_KERNEL::Exception(oss.str().c_str());
3015 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
3016 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
3021 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
3022 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
3023 * This method is a generalization of shiftNodeNumbersInConn().
3024 * \warning This method performs no check of validity of new ids. **Use it with care !**
3025 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
3026 * this->getNumberOfNodes(), in "Old to New" mode.
3027 * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
3028 * \throw If the nodal connectivity of cells is not defined.
3030 void MEDCoupling1DGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
3032 getNumberOfCells();//only to check that all is well defined.
3034 int nbElemsIn=getNumberOfNodes();
3035 int nbOfTuples=_conn->getNumberOfTuples();
3036 int *pt=_conn->getPointer();
3037 for(int i=0;i<nbOfTuples;i++,pt++)
3039 if(*pt==-1) continue;
3040 if(*pt>=0 && *pt<nbElemsIn)
3041 *pt=newNodeNumbersO2N[*pt];
3044 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
3045 throw INTERP_KERNEL::Exception(oss.str().c_str());
3048 _conn->declareAsNew();
3054 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
3055 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
3056 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
3057 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
3059 * \param [in] begin input start of array of node ids.
3060 * \param [in] end input end of array of node ids.
3061 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
3062 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
3064 void MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
3066 int nbOfCells=getNumberOfCells();
3067 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
3069 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
3070 std::vector<bool> fastFinder(sz,false);
3071 for(const int *work=begin;work!=end;work++)
3072 if(*work>=0 && *work<sz)
3073 fastFinder[*work]=true;
3074 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
3075 for(int i=0;i<nbOfCells;i++,conni++)
3077 int ref=0,nbOfHit=0;
3078 int nbNodesPerCell=conni[1]-conni[0];
3079 if(nbNodesPerCell>=0)
3081 for(int j=0;j<nbNodesPerCell;j++)
3083 int nodeId=conn[conni[0]+j];
3087 if(fastFinder[nodeId])
3094 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !";
3095 throw INTERP_KERNEL::Exception(oss.str().c_str());
3097 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
3098 cellIdsKept->pushBackSilent(i);
3100 cellIdsKeptArr=cellIdsKept.retn();
3103 void MEDCoupling1DGTUMesh::allocateCells(int nbOfCells)
3106 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !");
3107 _conn=DataArrayInt::New();
3108 _conn->reserve(nbOfCells*3);
3109 _conn_indx=DataArrayInt::New();
3110 _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0);
3115 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
3117 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
3118 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
3119 * \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
3120 * attached to \a this.
3121 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
3123 void MEDCoupling1DGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd)
3125 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
3126 DataArrayInt *c(_conn),*c2(_conn_indx);
3130 if(pos==c->getNumberOfTuples())
3132 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
3133 c2->pushBackSilent(pos+sz);
3137 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !";
3138 throw INTERP_KERNEL::Exception(oss.str().c_str());
3142 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !");
3145 void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex)
3148 nodalConn->incrRef();
3151 nodalConnIndex->incrRef();
3152 _conn_indx=nodalConnIndex;
3157 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
3159 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivity() const
3161 const DataArrayInt *ret(_conn);
3162 return const_cast<DataArrayInt *>(ret);
3166 * \return DataArrayInt * - the internal reference to the nodal connectivity index. The caller is not reponsible to deallocate it.
3168 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const
3170 const DataArrayInt *ret(_conn_indx);
3171 return const_cast<DataArrayInt *>(ret);
3175 * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here".
3176 * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity).
3177 * 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.
3179 * 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.
3181 * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal
3182 * connectivity arrays are different (false)
3183 * \return a new object to be managed by the caller.
3185 * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked
3187 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const
3189 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3190 DataArrayInt *nc=0,*nci=0;
3191 isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci);
3192 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ncs(nc),ncis(nci);
3193 ret->_conn=ncs; ret->_conn_indx=ncis;
3194 ret->setCoords(getCoords());
3199 * This method allows to compute, if needed, the packed nodal connectivity pair.
3200 * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges convered by nodal connectivity index array.
3201 * 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.
3203 * 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)
3204 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3206 * 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
3209 * This method return 3 elements.
3210 * \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
3211 * this pointer can be seen as a new object, that is to managed by the caller.
3212 * \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
3213 * this pointer can be seen as a new object, that is to managed by the caller.
3214 * \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
3215 * output parameters are newly created objects.
3217 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
3219 bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const
3221 if(isPacked())//performs the checkCoherency
3223 const DataArrayInt *c0(_conn),*c1(_conn_indx);
3224 nodalConn=const_cast<DataArrayInt *>(c0); nodalConnIndx=const_cast<DataArrayInt *>(c1);
3225 nodalConn->incrRef(); nodalConnIndx->incrRef();
3228 int bg=_conn_indx->front(),end=_conn_indx->back();
3229 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nc(_conn->selectByTupleId2(bg,end,1));
3230 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nci(_conn_indx->deepCpy());
3231 nci->applyLin(1,-bg);
3232 nodalConn=nc.retn(); nodalConnIndx=nci.retn();
3237 * 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)
3238 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3239 * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned.
3240 * \return bool - true if \a this looks packed, false is not.
3242 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
3244 bool MEDCoupling1DGTUMesh::isPacked() const
3247 return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples();
3250 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2)
3252 std::vector<const MEDCoupling1DGTUMesh *> tmp(2);
3253 tmp[0]=const_cast<MEDCoupling1DGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1DGTUMesh *>(mesh2);
3254 return Merge1DGTUMeshes(tmp);
3257 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a)
3259 std::size_t sz=a.size();
3261 return Merge1DGTUMeshesLL(a);
3262 for(std::size_t ii=0;ii<sz;ii++)
3265 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::Merge1DGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
3266 throw INTERP_KERNEL::Exception(oss.str().c_str());
3268 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
3269 for(std::size_t ii=0;ii<sz;ii++)
3270 if(&(a[ii]->getCellModel())!=cm)
3271 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !");
3272 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > bb(sz);
3273 std::vector< const MEDCoupling1DGTUMesh * > aa(sz);
3275 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
3277 const MEDCoupling1DGTUMesh *cur=a[i];
3278 const DataArrayDouble *coo=cur->getCoords();
3280 spaceDim=coo->getNumberOfComponents();
3283 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !");
3284 for(std::size_t i=0;i<sz;i++)
3286 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
3289 return Merge1DGTUMeshesLL(aa);
3293 * \throw If presence of a null instance in the input vector \a a.
3294 * \throw If a is empty
3296 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a)
3299 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !");
3300 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3302 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !");
3303 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
3304 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3305 (*it)->getNumberOfCells();//to check that all is OK
3306 const DataArrayDouble *coords=(*it)->getCoords();
3307 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3309 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3310 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3312 for(int i=1;it!=a.end();i++,it++)
3315 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !");
3316 if(cm!=&((*it)->getCellModel()))
3317 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3318 (*it)->getNumberOfCells();//to check that all is OK
3319 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3320 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3321 if(coords!=(*it)->getCoords())
3322 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !");
3324 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3325 ret->setCoords(coords);
3326 ret->_conn=DataArrayInt::Aggregate(ncs);
3327 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3332 * 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)
3334 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a)
3337 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : input array must be NON EMPTY !");
3338 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
3339 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3340 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3341 std::vector<int> nbNodesPerElt(a.size());
3342 int nbOfCells=(*it)->getNumberOfCells();
3344 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3345 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3347 int prevNbOfNodes=(*it)->getNumberOfNodes();
3348 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3350 for(int i=1;it!=a.end();i++,it++)
3352 if(cm!=&((*it)->getCellModel()))
3353 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3354 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3355 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3356 nbOfCells+=(*it)->getNumberOfCells();
3357 nbNodesPerElt[i]=nbNodesPerElt[i-1]+prevNbOfNodes;
3358 prevNbOfNodes=(*it)->getNumberOfNodes();
3360 std::vector<const MEDCouplingPointSet *> aps(a.size());
3361 std::copy(a.begin(),a.end(),aps.begin());
3362 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
3363 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3364 ret->setCoords(pts);
3365 ret->_conn=AggregateNodalConnAndShiftNodeIds(ncs,nbNodesPerElt);
3366 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3370 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(int spaceDim) const
3372 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3373 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1,tmp2;
3374 const DataArrayInt *nodalConn(_conn),*nodalConnI(_conn_indx);
3377 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
3385 tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
3389 ret->_conn_indx=tmp2;
3393 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
3394 ret->setCoords(coords);
3397 ret->setCoords(_coords);
3402 * This method aggregate the bbox of each cell and put it into bbox parameter.
3404 * \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)
3405 * For all other cases this input parameter is ignored.
3406 * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
3408 * \throw If \a this is not fully set (coordinates and connectivity).
3409 * \throw If a cell in \a this has no valid nodeId.
3411 DataArrayDouble *MEDCoupling1DGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
3413 checkFullyDefined();
3414 int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes());
3415 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
3416 double *bbox(ret->getPointer());
3417 for(int i=0;i<nbOfCells*spaceDim;i++)
3419 bbox[2*i]=std::numeric_limits<double>::max();
3420 bbox[2*i+1]=-std::numeric_limits<double>::max();
3422 const double *coordsPtr(_coords->getConstPointer());
3423 const int *conn(_conn->getConstPointer()),*connI(_conn_indx->getConstPointer());
3424 for(int i=0;i<nbOfCells;i++)
3426 int offset=connI[i];
3427 int nbOfNodesForCell(connI[i+1]-offset),kk(0);
3428 for(int j=0;j<nbOfNodesForCell;j++)
3430 int nodeId=conn[offset+j];
3431 if(nodeId>=0 && nodeId<nbOfNodes)
3433 for(int k=0;k<spaceDim;k++)
3435 bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
3436 bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
3443 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
3444 throw INTERP_KERNEL::Exception(oss.str().c_str());
3450 std::vector<int> MEDCoupling1DGTUMesh::BuildAPolygonFromParts(const std::vector< std::vector<int> >& parts)
3452 std::vector<int> ret;
3455 ret.insert(ret.end(),parts[0].begin(),parts[0].end());
3456 int ref(ret.back());
3457 std::size_t sz(parts.size()),nbh(1);
3458 std::vector<bool> b(sz,true); b[0]=false;
3462 for(;i<sz;i++) if(b[i] && parts[i].front()==ref) { ret.insert(ret.end(),parts[i].begin()+1,parts[i].end()); nbh++; break; }
3466 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::BuildAPolygonFromParts : the input vector is not a part of a single polygon !");
3468 if(ret.back()==ret.front())
3474 * This method performs an aggregation of \a nodalConns (as DataArrayInt::Aggregate does) but in addition of that a shift is applied on the
3475 * values contained in \a nodalConns using corresponding offset specified in input \a offsetInNodeIdsPerElt.
3476 * But it also manage the values -1, that have a semantic in MEDCoupling1DGTUMesh class (separator for polyhedron).
3478 * \param [in] nodalConns - a list of nodal connectivity arrays same size than \a offsetInNodeIdsPerElt.
3479 * \param [in] offsetInNodeIdsPerElt - a list of offsets to apply.
3480 * \return DataArrayInt * - A new object (to be managed by the caller) that is the result of the aggregation.
3481 * \throw If \a nodalConns or \a offsetInNodeIdsPerElt are empty.
3482 * \throw If \a nodalConns and \a offsetInNodeIdsPerElt have not the same size.
3483 * \throw If presence of null pointer in \a nodalConns.
3484 * \throw If presence of not allocated or array with not exactly one component in \a nodalConns.
3486 DataArrayInt *MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds(const std::vector<const DataArrayInt *>& nodalConns, const std::vector<int>& offsetInNodeIdsPerElt)
3488 std::size_t sz1(nodalConns.size()),sz2(offsetInNodeIdsPerElt.size());
3490 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : input vectors do not have the same size !");
3492 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : empty vectors in input !");
3494 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++)
3497 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of null pointer in input vector !");
3498 if(!(*it)->isAllocated())
3499 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of non allocated array in input vector !");
3500 if((*it)->getNumberOfComponents()!=1)
3501 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of array with not exactly one component !");
3502 nbOfTuples+=(*it)->getNumberOfTuples();
3504 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
3505 int *pt=ret->getPointer();
3507 for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++,i++)
3509 int curNbt=(*it)->getNumberOfTuples();
3510 const int *inPt=(*it)->begin();
3511 int offset=offsetInNodeIdsPerElt[i];
3512 for(int j=0;j<curNbt;j++,pt++)
3523 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m)
3526 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh is null !");
3527 std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
3529 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh must have exactly one geometric type !");
3530 int geoType((int)*gts.begin());
3531 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(m->getName(),*gts.begin()));
3532 ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription());
3533 int nbCells(m->getNumberOfCells());
3534 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
3535 conn->alloc(m->getMeshLength()-nbCells,1); connI->alloc(nbCells+1,1);
3536 int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
3537 const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
3538 for(int i=0;i<nbCells;i++,ciin++,ci++)
3540 if(cin[ciin[0]]==geoType)
3542 if(ciin[1]-ciin[0]>=1)
3544 c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
3545 ci[1]=ci[0]+ciin[1]-ciin[0]-1;
3549 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 !";
3550 throw INTERP_KERNEL::Exception(oss.str().c_str());
3555 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 !";
3556 throw INTERP_KERNEL::Exception(oss.str().c_str());
3559 ret->setNodalConnectivity(conn,connI);