1 // Copyright (C) 2007-2013 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.
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"
25 #include "SplitterTetra.hxx"
27 using namespace ParaMEDMEM;
29 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):_cm(&cm)
34 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const MEDCoupling1GTUMesh& other, bool recDeepCpy):MEDCouplingPointSet(other,recDeepCpy),_cm(other._cm)
38 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
40 if(type==INTERP_KERNEL::NORM_ERROR)
41 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
42 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
44 return MEDCoupling1SGTUMesh::New(name,type);
45 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : not implemented yet !");
48 const INTERP_KERNEL::CellModel& MEDCoupling1GTUMesh::getCellModel() const throw(INTERP_KERNEL::Exception)
53 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getCellModelEnum() const throw(INTERP_KERNEL::Exception)
55 return _cm->getEnum();
58 int MEDCoupling1GTUMesh::getMeshDimension() const
60 return (int)_cm->getDimension();
64 * This method returns a newly allocated array containing cell ids (ascendingly sorted) whose geometric type are equal to type.
65 * This method does not throw exception if geometric type \a type is not in \a this.
66 * This method throws an INTERP_KERNEL::Exception if meshdimension of \b this is not equal to those of \b type.
67 * The coordinates array is not considered here.
69 * \param [in] type the geometric type
70 * \return cell ids in this having geometric type \a type.
72 DataArrayInt *MEDCoupling1GTUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception)
74 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
75 if(type==getCellModelEnum())
76 ret->alloc(getNumberOfCells(),1);
84 * Returns nb of cells having the geometric type \a type. No throw if no cells in \a this has the geometric type \a type.
86 int MEDCoupling1GTUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
88 return type==getCellModelEnum()?getNumberOfCells():0;
92 * Returns a type of a cell by its id.
93 * \param [in] cellId - the id of the cell of interest.
94 * \return INTERP_KERNEL::NormalizedCellType - enumeration item describing the cell type.
95 * \throw If \a cellId is invalid. Valid range is [0, \a this->getNumberOfCells() ).
97 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getTypeOfCell(int cellId) const
99 if(cellId>=0 && cellId<getNumberOfCells())
100 return getCellModelEnum();
101 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::getTypeOfCell : Requesting type of cell #" << cellId << " but it should be in [0," << getNumberOfCells() << ") !";
102 throw INTERP_KERNEL::Exception(oss.str().c_str());
106 * Returns a set of all cell types available in \a this mesh.
107 * \return std::set<INTERP_KERNEL::NormalizedCellType> - the set of cell types.
108 * \warning this method does not throw any exception even if \a this is not defined.
110 std::set<INTERP_KERNEL::NormalizedCellType> MEDCoupling1GTUMesh::getAllGeoTypes() const
112 std::set<INTERP_KERNEL::NormalizedCellType> ret;
113 ret.insert(getCellModelEnum());
118 * This method expects that \a this is sorted by types. If not an exception will be thrown.
119 * This method returns in the same format as code (see MEDCouplingUMesh::checkTypeConsistencyAndContig or MEDCouplingUMesh::splitProfilePerType) how
120 * \a this is composed in cell types.
121 * The returned array is of size 3*n where n is the number of different types present in \a this.
122 * For every k in [0,n] ret[3*k+2]==0 because it has no sense here.
123 * This parameter is kept only for compatibility with other methode listed above.
125 std::vector<int> MEDCoupling1GTUMesh::getDistributionOfTypes() const throw(INTERP_KERNEL::Exception)
127 std::vector<int> ret(3);
128 ret[0]=(int)getCellModelEnum(); ret[1]=getNumberOfCells(); ret[2]=0;
133 * 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.
134 * 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.
135 * This method has 1 input \a profile and 3 outputs \a code \a idsInPflPerType and \a idsPerType.
137 * \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.
138 * \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,
139 * \a idsInPflPerType[i] stores the tuple ids in \a profile that correspond to the geometric type code[3*i+0]
140 * \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.
141 * This vector can be empty in case of all geometric type cells are fully covered in ascending in the given input \a profile.
143 * \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.
145 * \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
148 * - Before \a this has 3 cells \a profile contains [0,1,2]
149 * - After \a code contains [NORM_...,nbCells,-1], \a idsInPflPerType [[0,1,2]] and \a idsPerType is empty <br>
152 * - Before \a this has 3 cells \a profile contains [1,2]
153 * - After \a code contains [NORM_...,nbCells,0], \a idsInPflPerType [[0,1]] and \a idsPerType is [[1,2]] <br>
156 void MEDCoupling1GTUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
159 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile is NULL !");
160 if(profile->getNumberOfComponents()!=1)
161 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile should have exactly one component !");
162 int nbTuples=profile->getNumberOfTuples();
163 int nbOfCells=getNumberOfCells();
164 code.resize(3); idsInPflPerType.resize(1);
165 code[0]=(int)getCellModelEnum(); code[1]=nbOfCells;
166 idsInPflPerType.resize(1);
167 if(profile->isIdentity() && nbTuples==nbOfCells)
170 idsInPflPerType[0]=const_cast<DataArrayInt *>(profile); idsInPflPerType[0]->incrRef();
174 profile->checkAllIdsInRange(0,nbOfCells);
175 idsPerType.resize(1);
176 idsPerType[0]=const_cast<DataArrayInt *>(profile); idsPerType[0]->incrRef();
177 idsInPflPerType[0]=DataArrayInt::Range(0,nbTuples,1);
181 * This method tries to minimize at most the number of deep copy.
182 * So if \a idsPerType is not empty it can be returned directly (without copy, but with ref count incremented) in return.
184 * \sa MEDCouplingUMesh::checkTypeConsistencyAndContig
186 DataArrayInt *MEDCoupling1GTUMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
188 int nbOfCells=getNumberOfCells();
190 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : invalid input code should be exactly of size 3 !");
191 if(code[0]!=(int)getCellModelEnum())
193 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() << ") !";
194 throw INTERP_KERNEL::Exception(oss.str().c_str());
198 if(code[1]==nbOfCells)
202 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : mismatch between the number of cells in this (" << nbOfCells << ") and the number of non profile (" << code[1] << ") !";
203 throw INTERP_KERNEL::Exception(oss.str().c_str());
207 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : single geo type mesh ! 0 or -1 is expected at pos #2 of input code !");
208 if(idsPerType.size()!=1)
209 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input code points to DataArrayInt #0 whereas the size of idsPerType is not equal to 1 !");
210 const DataArrayInt *pfl=idsPerType[0];
212 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : the input code points to a NULL DataArrayInt at rank 0 !");
213 if(pfl->getNumberOfComponents()!=1)
214 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input profile should have exactly one component !");
215 pfl->checkAllIdsInRange(0,nbOfCells);
217 return const_cast<DataArrayInt *>(pfl);
220 void MEDCoupling1GTUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception)
222 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
223 m->writeVTKLL(ofs,cellData,pointData);
226 std::string MEDCoupling1GTUMesh::getVTKDataSetType() const throw(INTERP_KERNEL::Exception)
228 return std::string("UnstructuredGrid");
231 bool MEDCoupling1GTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
233 if(!MEDCouplingPointSet::isEqualIfNotWhy(other,prec,reason))
236 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualIfNotWhy : input other pointer is null !");
237 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
240 reason="mesh given in input is not castable in MEDCouplingSGTUMesh !";
243 if(&_cm!=&otherC->_cm)
245 reason="mismatch in geometric type !";
251 bool MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
253 if(!MEDCouplingPointSet::isEqualWithoutConsideringStr(other,prec))
256 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
257 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
260 if(&_cm!=&otherC->_cm)
265 void MEDCoupling1GTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
267 MEDCouplingPointSet::checkCoherency();
270 DataArrayDouble *MEDCoupling1GTUMesh::getBarycenterAndOwner() const
272 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
273 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=m->getBarycenterAndOwner();
277 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureField(bool isAbs) const
279 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
280 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureField(isAbs);
285 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureFieldOnNode(bool isAbs) const
287 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
288 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureFieldOnNode(isAbs);
296 int MEDCoupling1GTUMesh::getCellContainingPoint(const double *pos, double eps) const
298 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
299 return m->getCellContainingPoint(pos,eps);
302 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::buildOrthogonalField() const
304 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
305 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->buildOrthogonalField();
310 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const double *bbox, double eps) const
312 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
313 return m->getCellsInBoundingBox(bbox,eps);
316 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps)
318 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
319 return m->getCellsInBoundingBox(bbox,eps);
322 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const
324 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
325 return m->buildFacePartOfMySelfNode(start,end,fullyIn);
328 DataArrayInt *MEDCoupling1GTUMesh::findBoundaryNodes() const
330 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
331 return m->findBoundaryNodes();
334 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildBoundaryMesh(bool keepCoords) const
336 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
337 return m->buildBoundaryMesh(keepCoords);
340 void MEDCoupling1GTUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const throw(INTERP_KERNEL::Exception)
342 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
343 m->findCommonCells(compType,startCellId,commonCellsArr,commonCellsIArr);
348 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const MEDCoupling1SGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
352 const DataArrayInt *c(other._conn);
358 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
362 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
364 if(type==INTERP_KERNEL::NORM_ERROR)
365 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
366 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
369 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New : the input geometric type " << cm.getRepr() << " is dynamic ! Only static type are dealed here !";
370 throw INTERP_KERNEL::Exception(oss.str().c_str());
372 return new MEDCoupling1SGTUMesh(name,cm);
375 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::clone(bool recDeepCpy) const
377 return new MEDCoupling1SGTUMesh(*this,recDeepCpy);
380 void MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception)
383 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
384 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
386 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1SGTUMesh instance !");
387 setNodalConnectivity(otherC->getNodalConnectivity());
390 void MEDCoupling1SGTUMesh::updateTime() const
392 MEDCoupling1GTUMesh::updateTime();
393 const DataArrayInt *c(_conn);
398 std::size_t MEDCoupling1SGTUMesh::getHeapMemorySize() const
401 const DataArrayInt *c(_conn);
403 ret+=c->getHeapMemorySize();
404 return MEDCouplingPointSet::getHeapMemorySize()+ret;
407 MEDCouplingMesh *MEDCoupling1SGTUMesh::deepCpy() const
412 bool MEDCoupling1SGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
415 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualIfNotWhy : input other pointer is null !");
416 std::ostringstream oss; oss.precision(15);
417 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
420 reason="mesh given in input is not castable in MEDCoupling1SGTUMesh !";
423 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
425 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
430 reason="in connectivity of single static geometric type exactly one among this and other is null !";
433 if(!c1->isEqualIfNotWhy(*c2,reason))
435 reason.insert(0,"Nodal connectivity DataArrayInt differ : ");
441 bool MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
444 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
445 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
448 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
450 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
455 if(!c1->isEqualWithoutConsideringStr(*c2))
460 void MEDCoupling1SGTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
462 MEDCouplingPointSet::checkCoherency();
463 const DataArrayInt *c1(_conn);
466 if(c1->getNumberOfComponents()!=1)
467 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
468 if(c1->getInfoOnComponent(0)!="")
469 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
470 c1->checkAllocated();
473 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
476 void MEDCoupling1SGTUMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
479 const DataArrayInt *c1(_conn);
480 int nbOfTuples=c1->getNumberOfTuples();
481 int nbOfNodesPerCell=(int)_cm->getNumberOfNodes();
482 if(nbOfTuples%nbOfNodesPerCell!=0)
484 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 !";
485 throw INTERP_KERNEL::Exception(oss.str().c_str());
487 int nbOfNodes=getNumberOfNodes();
488 int nbOfCells=nbOfTuples/nbOfNodesPerCell;
489 const int *w(c1->begin());
490 for(int i=0;i<nbOfCells;i++)
491 for(int j=0;j<nbOfNodesPerCell;j++,w++)
493 if(*w<0 || *w>=nbOfNodes)
495 std::ostringstream oss; oss << "At node #" << j << " of cell #" << i << ", is equal to " << *w << " must be in [0," << nbOfNodes << ") !";
496 throw INTERP_KERNEL::Exception(oss.str().c_str());
501 void MEDCoupling1SGTUMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
503 checkCoherency1(eps);
506 int MEDCoupling1SGTUMesh::getNumberOfCells() const
508 int nbOfTuples=getNodalConnectivityLength();
509 int nbOfNodesPerCell=getNumberOfNodesPerCell();
510 if(nbOfTuples%nbOfNodesPerCell!=0)
512 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 !";
513 throw INTERP_KERNEL::Exception(oss.str().c_str());
515 return nbOfTuples/nbOfNodesPerCell;
518 int MEDCoupling1SGTUMesh::getNumberOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
520 checkNonDynamicGeoType();
521 return (int)_cm->getNumberOfNodes();
524 int MEDCoupling1SGTUMesh::getNodalConnectivityLength() const throw(INTERP_KERNEL::Exception)
526 const DataArrayInt *c1(_conn);
528 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::getNodalConnectivityLength : no connectivity set !");
529 if(c1->getNumberOfComponents()!=1)
530 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::getNodalConnectivityLength : Nodal connectivity array set must have exactly one component !");
531 if(!c1->isAllocated())
532 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::getNodalConnectivityLength : Nodal connectivity array must be allocated !");
533 return c1->getNumberOfTuples();
536 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
538 checkNonDynamicGeoType();
539 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
540 ret->alloc(getNumberOfCells(),1);
541 ret->fillWithValue((int)_cm->getNumberOfNodes());
545 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception)
547 checkNonDynamicGeoType();
548 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
549 ret->alloc(getNumberOfCells(),1);
550 ret->fillWithValue((int)_cm->getNumberOfSons());
554 void MEDCoupling1SGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
556 int sz=getNumberOfNodesPerCell();
558 if(cellId>=0 && cellId<getNumberOfCells())
559 std::copy(_conn->begin()+cellId*sz,_conn->begin()+(cellId+1)*sz,conn.begin());
562 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << getNumberOfCells() << ") !";
563 throw INTERP_KERNEL::Exception(oss.str().c_str());
567 void MEDCoupling1SGTUMesh::checkNonDynamicGeoType() const throw(INTERP_KERNEL::Exception)
570 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkNonDynamicGeoType : internal error ! the internal geo type is dynamic ! should be static !");
573 std::string MEDCoupling1SGTUMesh::simpleRepr() const
575 static const char msg0[]="No coordinates specified !";
576 std::ostringstream ret;
577 ret << "Single static geometic type unstructured mesh with name : \"" << getName() << "\"\n";
578 ret << "Description of mesh : \"" << getDescription() << "\"\n";
580 double tt=getTime(tmpp1,tmpp2);
581 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
582 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
583 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
586 const int spaceDim=getSpaceDimension();
587 ret << spaceDim << "\nInfo attached on space dimension : ";
588 for(int i=0;i<spaceDim;i++)
589 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
594 ret << "Number of nodes : ";
596 ret << getNumberOfNodes() << "\n";
599 ret << "Number of cells : ";
600 if((const DataArrayInt *)_conn)
602 if(_conn->isAllocated())
604 if(_conn->getNumberOfComponents()==1)
605 ret << getNumberOfCells() << "\n";
607 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
610 ret << "Nodal connectivity array specified but not allocated !" << "\n";
613 ret << "No connectivity specified !" << "\n";
614 ret << "Cell type : " << _cm->getRepr() << "\n";
618 std::string MEDCoupling1SGTUMesh::advancedRepr() const
620 std::ostringstream ret;
622 ret << "\nCoordinates array : \n___________________\n\n";
624 _coords->reprWithoutNameStream(ret);
626 ret << "No array set !\n";
627 ret << "\n\nConnectivity array : \n____________________\n\n";
629 if((const DataArrayInt *)_conn)
631 if(_conn->isAllocated())
633 if(_conn->getNumberOfComponents()==1)
635 int nbOfCells=getNumberOfCells();
636 int sz=getNumberOfNodesPerCell();
637 const int *connPtr=_conn->begin();
638 for(int i=0;i<nbOfCells;i++,connPtr+=sz)
640 ret << "Cell #" << i << " : ";
641 std::copy(connPtr,connPtr+sz,std::ostream_iterator<int>(ret," "));
646 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
649 ret << "Nodal connectivity array specified but not allocated !" << "\n";
652 ret << "No connectivity specified !" << "\n";
656 DataArrayDouble *MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
658 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
659 int spaceDim=getSpaceDimension();
660 int nbOfCells=getNumberOfCells();
661 int nbOfNodes=getNumberOfNodes();
662 ret->alloc(nbOfCells,spaceDim);
663 double *ptToFill=ret->getPointer();
664 const double *coor=_coords->begin();
665 const int *nodal=_conn->begin();
666 int sz=getNumberOfNodesPerCell();
667 double coeff=1./(double)sz;
668 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim)
670 std::fill(ptToFill,ptToFill+spaceDim,0.);
671 for(int j=0;j<sz;j++,nodal++)
672 if(*nodal>=0 && *nodal<nbOfNodes)
673 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
676 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
677 throw INTERP_KERNEL::Exception(oss.str().c_str());
679 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),coeff));
684 void MEDCoupling1SGTUMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
686 int nbCells=getNumberOfCells();
687 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
688 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
690 o2n=o2n->checkAndPreparePermutation();
692 const int *conn=_conn->begin();
693 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o=o2n->invertArrayO2N2N2O(nbCells);
694 const int *n2oPtr=n2o->begin();
695 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
696 newConn->alloc(_conn->getNumberOfTuples(),1);
697 newConn->copyStringInfoFrom(*_conn);
698 int sz=getNumberOfNodesPerCell();
700 int *newC=newConn->getPointer();
701 for(int i=0;i<nbCells;i++,newC+=sz)
704 std::copy(conn+pos*sz,conn+(pos+1)*sz,newC);
710 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
711 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
712 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
713 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
715 * \param [in] begin input start of array of node ids.
716 * \param [in] end input end of array of node ids.
717 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
718 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
720 void MEDCoupling1SGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
722 int nbOfCells=getNumberOfCells();
723 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
725 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
726 std::vector<bool> fastFinder(sz,false);
727 for(const int *work=begin;work!=end;work++)
728 if(*work>=0 && *work<sz)
729 fastFinder[*work]=true;
730 const int *conn=_conn->begin();
731 int nbNodesPerCell=getNumberOfNodesPerCell();
732 for(int i=0;i<nbOfCells;i++,conn+=nbNodesPerCell)
735 for(int j=0;j<nbNodesPerCell;j++)
739 if(fastFinder[conn[j]])
742 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
743 cellIdsKept->pushBackSilent(i);
745 cellIdsKeptArr=cellIdsKept.retn();
748 MEDCouplingMesh *MEDCoupling1SGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
750 if(other->getType()!=SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED)
751 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single static geo type each other !");
752 const MEDCoupling1SGTUMesh *otherC=static_cast<const MEDCoupling1SGTUMesh *>(other);
753 return Merge1SGTUMeshes(this,otherC);
756 MEDCouplingUMesh *MEDCoupling1SGTUMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
758 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
759 ret->setCoords(getCoords());
760 const int *nodalConn=_conn->begin();
761 int nbCells=getNumberOfCells();
762 int nbNodesPerCell=getNumberOfNodesPerCell();
763 int geoType=(int)getCellModelEnum();
764 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells*(nbNodesPerCell+1),1);
765 int *cPtr=c->getPointer();
766 for(int i=0;i<nbCells;i++,nodalConn+=nbNodesPerCell)
769 cPtr=std::copy(nodalConn,nodalConn+nbNodesPerCell,cPtr);
771 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::Range(0,(nbCells+1)*(nbNodesPerCell+1),nbNodesPerCell+1);
772 ret->setConnectivity(c,cI,true);
776 DataArrayInt *MEDCoupling1SGTUMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
781 return simplexizePol0();
783 return simplexizePol1();
784 case (int) INTERP_KERNEL::PLANAR_FACE_5:
785 return simplexizePlanarFace5();
786 case (int) INTERP_KERNEL::PLANAR_FACE_6:
787 return simplexizePlanarFace6();
789 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)");
794 * \return DataArrayInt * - the permutation array in "Old to New" mode. For more
795 * info on "Old to New" mode see \ref MEDCouplingArrayRenumbering. The caller
796 * is to delete this array using decrRef() as it is no more needed.
798 DataArrayInt *MEDCoupling1SGTUMesh::mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes)
800 DataArrayInt *ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes);
802 renumberNodes(ret->getConstPointer(),newNbOfNodes);
807 * \return DataArrayInt * - the permutation array in "Old to New" mode. For more
808 * info on "Old to New" mode see \ref MEDCouplingArrayRenumbering. The caller
809 * is to delete this array using decrRef() as it is no more needed.
811 DataArrayInt *MEDCoupling1SGTUMesh::mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes)
813 DataArrayInt *ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes);
815 renumberNodes2(ret->getConstPointer(),newNbOfNodes);
820 * Removes unused nodes (the node coordinates array is shorten) and returns an array
821 * mapping between new and old node ids in "Old to New" mode. -1 values in the returned
822 * array mean that the corresponding old node is no more used.
823 * \return DataArrayInt * - a new instance of DataArrayInt of length \a
824 * this->getNumberOfNodes() before call of this method. The caller is to
825 * delete this array using decrRef() as it is no more needed.
826 * \throw If the coordinates array is not set.
827 * \throw If the nodal connectivity of cells is not defined.
828 * \throw If the nodal connectivity includes an invalid id.
830 * \ref cpp_mcumesh_zipCoordsTraducer "Here is a C++ example".<br>
831 * \ref py_mcumesh_zipCoordsTraducer "Here is a Python example".
833 DataArrayInt *MEDCoupling1SGTUMesh::zipCoordsTraducer() throw(INTERP_KERNEL::Exception)
836 DataArrayInt *traducer=getNodeIdsInUse(newNbOfNodes);
837 renumberNodes(traducer->getConstPointer(),newNbOfNodes);
843 struct MEDCouplingAccVisit
845 MEDCouplingAccVisit():_new_nb_of_nodes(0) { }
846 int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; }
847 int _new_nb_of_nodes;
853 * Finds nodes not used in any cell and returns an array giving a new id to every node
854 * by excluding the unused nodes, for which the array holds -1. The result array is
855 * a mapping in "Old to New" mode.
856 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
857 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
858 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
859 * if the node is unused or a new id else. The caller is to delete this
860 * array using decrRef() as it is no more needed.
861 * \throw If the coordinates array is not set.
862 * \throw If the nodal connectivity of cells is not defined.
863 * \throw If the nodal connectivity includes an invalid id.
865 DataArrayInt *MEDCoupling1SGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception)
868 int nbOfNodes=getNumberOfNodes();
869 int nbOfCells=getNumberOfCells();
870 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
871 ret->alloc(nbOfNodes,1);
872 int *traducer=ret->getPointer();
873 std::fill(traducer,traducer+nbOfNodes,-1);
874 const int *conn=_conn->begin();
875 int nbNodesPerCell=getNumberOfNodesPerCell();
876 for(int i=0;i<nbOfCells;i++)
877 for(int j=0;j<nbNodesPerCell;j++)
878 if(conn[j]>=0 && conn[j]<nbOfNodes)
882 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << conn[j] << " not in [0," << nbOfNodes << ") !";
883 throw INTERP_KERNEL::Exception(oss.str().c_str());
885 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
886 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
891 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
892 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
893 * This method is a generalization of shiftNodeNumbersInConn().
894 * \warning This method performs no check of validity of new ids. **Use it with care !**
895 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
896 * this->getNumberOfNodes(), in "Old to New" mode.
897 * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
898 * \throw If the nodal connectivity of cells is not defined.
900 void MEDCoupling1SGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
902 getNumberOfCells();//only to check that all is well defined.
903 _conn->renumberInPlace(newNodeNumbersO2N);
907 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2) throw(INTERP_KERNEL::Exception)
909 std::vector<const MEDCoupling1SGTUMesh *> tmp(2);
910 tmp[0]=const_cast<MEDCoupling1SGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1SGTUMesh *>(mesh2);
911 return Merge1SGTUMeshes(tmp);
914 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
916 std::size_t sz=a.size();
918 return Merge1SGTUMeshesLL(a);
919 for(std::size_t ii=0;ii<sz;ii++)
922 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::Merge1SGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
923 throw INTERP_KERNEL::Exception(oss.str().c_str());
925 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
926 for(std::size_t ii=0;ii<sz;ii++)
927 if(&(a[ii]->getCellModel())!=cm)
928 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : all items must have the same geo type !");
929 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> > bb(sz);
930 std::vector< const MEDCoupling1SGTUMesh * > aa(sz);
932 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
934 const MEDCoupling1SGTUMesh *cur=a[i];
935 const DataArrayDouble *coo=cur->getCoords();
937 spaceDim=coo->getNumberOfComponents();
940 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : no spaceDim specified ! unable to perform merge !");
941 for(std::size_t i=0;i<sz;i++)
943 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
946 return Merge1SGTUMeshesLL(aa);
949 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
952 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : input array must be NON EMPTY !");
953 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
955 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : presence of null instance !");
956 int nbOfCells=(*it)->getNumberOfCells();
957 const DataArrayDouble *coords=(*it)->getCoords();
958 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
959 int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
960 for(;it!=a.end();it++)
962 if(cm!=&((*it)->getCellModel()))
963 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
964 nbOfCells+=(*it)->getNumberOfCells();
965 if(coords!=(*it)->getCoords())
966 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : not lying on same coords !");
968 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
969 ret->setCoords(coords);
970 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New();
971 c->alloc(nbOfCells*nbNodesPerCell,1);
972 int *cPtr=c->getPointer();
974 for(it=a.begin();it!=a.end();it++)
976 int curConnLgth=(*it)->getNodalConnectivityLength();
977 const int *curC=(*it)->_conn->begin();
978 cPtr=std::copy(curC,curC+curConnLgth,cPtr);
985 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
988 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : input array must be NON EMPTY !");
989 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
990 int nbOfCells=(*it)->getNumberOfCells();
991 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
992 int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
993 for(;it!=a.end();it++)
995 if(cm!=&((*it)->getCellModel()))
996 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
997 nbOfCells+=(*it)->getNumberOfCells();
999 std::vector<const MEDCouplingPointSet *> aps(a.size());
1000 std::copy(a.begin(),a.end(),aps.begin());
1001 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
1002 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1003 ret->setCoords(pts);
1004 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New();
1005 c->alloc(nbOfCells*nbNodesPerCell,1);
1006 int *cPtr=c->getPointer();
1008 for(it=a.begin();it!=a.end();it++)
1010 int curConnLgth=(*it)->getNodalConnectivityLength();
1011 const int *curC=(*it)->_conn->begin();
1012 cPtr=std::transform(curC,curC+curConnLgth,cPtr,std::bind2nd(std::plus<int>(),offset));
1013 offset+=(*it)->getNumberOfNodes();
1020 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
1022 int ncell=getNumberOfCells();
1023 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1024 ret->setCoords(_coords);
1025 std::size_t nbOfElemsRet=std::distance(begin,end);
1026 const int *inConn=_conn->getConstPointer();
1027 int sz=getNumberOfNodesPerCell();
1028 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1029 int *connPtr=connRet->getPointer();
1030 for(const int *work=begin;work!=end;work++,connPtr+=sz)
1032 if(*work>=0 && *work<ncell)
1033 std::copy(inConn+(work[0])*sz,inConn+(work[0]+1)*sz,connPtr);
1036 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !";
1037 throw INTERP_KERNEL::Exception(oss.str().c_str());
1041 ret->copyTinyInfoFrom(this);
1045 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
1047 int ncell=getNumberOfCells();
1048 int nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : ");
1049 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1050 ret->setCoords(_coords);
1051 const int *inConn=_conn->getConstPointer();
1052 int sz=getNumberOfNodesPerCell();
1053 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1054 int *connPtr=connRet->getPointer();
1056 for(int i=0;i<nbOfElemsRet;i++,connPtr+=sz,curId+=step)
1058 if(curId>=0 && curId<ncell)
1059 std::copy(inConn+curId*sz,inConn+(curId+1)*sz,connPtr);
1062 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : On pos #" << i << " input cell id =" << curId << " should be in [0," << ncell << ") !";
1063 throw INTERP_KERNEL::Exception(oss.str().c_str());
1067 ret->copyTinyInfoFrom(this);
1071 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception)
1073 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1074 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1;
1075 const DataArrayInt *nodalConn(_conn);
1078 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
1088 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
1089 ret->setCoords(coords);
1092 ret->setCoords(_coords);
1096 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol0() throw(INTERP_KERNEL::Exception)
1098 int nbOfCells=getNumberOfCells();
1099 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1100 return DataArrayInt::Range(0,nbOfCells,1);
1101 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1102 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1103 const int *c(_conn->begin());
1104 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1105 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1107 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[2];
1108 newConnPtr[3]=c[0]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1109 retPtr[0]=i; retPtr[1]=i;
1112 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1117 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol1() throw(INTERP_KERNEL::Exception)
1119 int nbOfCells=getNumberOfCells();
1120 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1121 return DataArrayInt::Range(0,nbOfCells,1);
1122 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1123 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1124 const int *c(_conn->begin());
1125 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1126 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1128 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[3];
1129 newConnPtr[3]=c[1]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1130 retPtr[0]=i; retPtr[1]=i;
1133 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1138 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace5() throw(INTERP_KERNEL::Exception)
1140 int nbOfCells=getNumberOfCells();
1141 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1142 return DataArrayInt::Range(0,nbOfCells,1);
1143 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(5*4*nbOfCells,1);
1144 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(5*nbOfCells,1);
1145 const int *c(_conn->begin());
1146 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1147 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=20,retPtr+=5)
1149 for(int j=0;j<20;j++)
1150 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_5_WO[j]];
1151 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i;
1154 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1159 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace6() throw(INTERP_KERNEL::Exception)
1161 int nbOfCells=getNumberOfCells();
1162 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1163 return DataArrayInt::Range(0,nbOfCells,1);
1164 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(6*4*nbOfCells,1);
1165 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(6*nbOfCells,1);
1166 const int *c(_conn->begin());
1167 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1168 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=20,retPtr+=6)
1170 for(int j=0;j<24;j++)
1171 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_6_WO[j]];
1172 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i; retPtr[5]=i;
1175 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1180 void MEDCoupling1SGTUMesh::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1182 stream << "MEDCoupling1SGTUMesh C++ instance at " << this << ". Name : \"" << getName() << "\".";
1183 stream << " Mesh dimension : " << getMeshDimension() << ".";
1185 { stream << " No coordinates set !"; return ; }
1186 if(!_coords->isAllocated())
1187 { stream << " Coordinates set but not allocated !"; return ; }
1188 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
1189 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
1190 if(!(const DataArrayInt *)_conn)
1191 { stream << std::endl << "Nodal connectivity NOT set !"; return ; }
1192 if(_conn->isAllocated())
1194 if(_conn->getNumberOfComponents()==1)
1195 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
1199 void MEDCoupling1SGTUMesh::checkFullyDefined() const throw(INTERP_KERNEL::Exception)
1201 if(!((const DataArrayInt *)_conn) || !((const DataArrayDouble *)_coords))
1202 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFullyDefined : part of this is not fully defined.");
1206 * First step of unserialization process.
1208 bool MEDCoupling1SGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
1210 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEmptyMesh : not implemented yet !");
1214 * Checks if \a this and \a other meshes are geometrically equivalent with high
1215 * probability, else an exception is thrown. The meshes are considered equivalent if
1216 * (1) meshes contain the same number of nodes and the same number of elements of the
1217 * same types (2) three cells of the two meshes (first, last and middle) are based
1218 * on coincident nodes (with a specified precision).
1219 * \param [in] other - the mesh to compare with.
1220 * \param [in] prec - the precision used to compare nodes of the two meshes.
1221 * \throw If the two meshes do not match.
1223 void MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception)
1225 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1226 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1228 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not not unstructured with single static geometric type !");
1231 MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
1234 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
1235 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1237 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
1238 std::vector<const MEDCoupling1SGTUMesh *> ms(2);
1241 return Merge1SGTUMeshesOnSameCoords(ms);
1244 void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception)
1246 checkFullyDefined();
1247 int nbOfNodes=getNumberOfNodes();
1248 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
1249 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
1250 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
1251 const int *conn=_conn->begin();
1252 int nbOfCells=getNumberOfCells();
1253 int nbOfEltsInRevNodal=0;
1254 int nbOfNodesPerCell=getNumberOfNodesPerCell();
1255 for(int eltId=0;eltId<nbOfCells;eltId++)
1257 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1259 if(conn[0]>=0 && conn[0]<nbOfNodes)
1261 nbOfEltsInRevNodal++;
1262 revNodalIndxPtr[conn[0]+1]++;
1266 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
1267 throw INTERP_KERNEL::Exception(oss.str().c_str());
1271 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
1272 conn=_conn->begin();
1273 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
1274 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
1275 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
1276 for(int eltId=0;eltId<nbOfCells;eltId++)
1278 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1280 *std::find_if(revNodalPtr+revNodalIndxPtr[*conn],revNodalPtr+revNodalIndxPtr[*conn+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
1286 * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null.
1287 * This method tests, if the input \a nodalConn is not null, that :
1288 * - it has one component.
1289 * - the number of tuples compatible with the number of node per cell.
1291 void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn) throw(INTERP_KERNEL::Exception)
1298 const DataArrayInt *c1(nodalConn);
1299 if(c1->getNumberOfComponents()!=1)
1300 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::setNodalConnectivity : input nodal connectivity array set must have exactly one component !");
1301 if(!c1->isAllocated())
1302 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::setNodalConnectivity : input nodal connectivity array must be allocated !");
1303 int nbTuples=c1->getNumberOfTuples();
1304 if(nbTuples%getNumberOfNodesPerCell()!=0)
1305 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::setNodalConnectivity : input nodal connectivity number of tuples is incompatible with geometric type !");
1306 nodalConn->incrRef();
1312 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
1314 DataArrayInt *MEDCoupling1SGTUMesh::getNodalConnectivity() const throw(INTERP_KERNEL::Exception)
1316 const DataArrayInt *ret(_conn);
1317 return const_cast<DataArrayInt *>(ret);
1321 * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted,
1322 * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter.
1323 * If a nodal connectivity previouly existed before the call of this method, it will be reset.
1325 * \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain.
1327 void MEDCoupling1SGTUMesh::allocateCells(int nbOfCells) throw(INTERP_KERNEL::Exception)
1330 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !");
1331 _conn=DataArrayInt::New();
1332 _conn->reserve(getNumberOfNodesPerCell()*nbOfCells);
1337 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
1339 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
1340 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
1341 * \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
1342 * attached to \a this.
1343 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
1345 void MEDCoupling1SGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) throw(INTERP_KERNEL::Exception)
1347 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
1348 int ref=getNumberOfNodesPerCell();
1351 DataArrayInt *c(_conn);
1353 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
1355 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !");
1359 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this (";
1360 oss << ref << ") !";
1361 throw INTERP_KERNEL::Exception(oss.str().c_str());