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]=nbTuples;
166 idsInPflPerType.resize(1);
167 if(profile->isIdentity() && nbTuples==nbOfCells)
170 idsInPflPerType[0]=const_cast<DataArrayInt *>(profile); idsInPflPerType[0]->incrRef();
175 profile->checkAllIdsInRange(0,nbOfCells);
176 idsPerType.resize(1);
177 idsPerType[0]=const_cast<DataArrayInt *>(profile); idsPerType[0]->incrRef();
178 idsInPflPerType[0]=DataArrayInt::Range(0,nbTuples,1);
182 * This method tries to minimize at most the number of deep copy.
183 * So if \a idsPerType is not empty it can be returned directly (without copy, but with ref count incremented) in return.
185 * \sa MEDCouplingUMesh::checkTypeConsistencyAndContig
187 DataArrayInt *MEDCoupling1GTUMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
189 int nbOfCells=getNumberOfCells();
191 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : invalid input code should be exactly of size 3 !");
192 if(code[0]!=(int)getCellModelEnum())
194 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() << ") !";
195 throw INTERP_KERNEL::Exception(oss.str().c_str());
199 if(code[1]==nbOfCells)
203 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : mismatch between the number of cells in this (" << nbOfCells << ") and the number of non profile (" << code[1] << ") !";
204 throw INTERP_KERNEL::Exception(oss.str().c_str());
208 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : single geo type mesh ! 0 or -1 is expected at pos #2 of input code !");
209 if(idsPerType.size()!=1)
210 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input code points to DataArrayInt #0 whereas the size of idsPerType is not equal to 1 !");
211 const DataArrayInt *pfl=idsPerType[0];
213 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : the input code points to a NULL DataArrayInt at rank 0 !");
214 if(pfl->getNumberOfComponents()!=1)
215 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input profile should have exactly one component !");
216 pfl->checkAllIdsInRange(0,nbOfCells);
218 return const_cast<DataArrayInt *>(pfl);
221 void MEDCoupling1GTUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception)
223 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
224 m->writeVTKLL(ofs,cellData,pointData);
227 std::string MEDCoupling1GTUMesh::getVTKDataSetType() const throw(INTERP_KERNEL::Exception)
229 return std::string("UnstructuredGrid");
232 bool MEDCoupling1GTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
234 if(!MEDCouplingPointSet::isEqualIfNotWhy(other,prec,reason))
237 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualIfNotWhy : input other pointer is null !");
238 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
241 reason="mesh given in input is not castable in MEDCouplingSGTUMesh !";
246 reason="mismatch in geometric type !";
252 bool MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
254 if(!MEDCouplingPointSet::isEqualWithoutConsideringStr(other,prec))
257 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
258 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
266 void MEDCoupling1GTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
268 MEDCouplingPointSet::checkCoherency();
271 DataArrayDouble *MEDCoupling1GTUMesh::getBarycenterAndOwner() const
273 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
274 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=m->getBarycenterAndOwner();
278 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureField(bool isAbs) const
280 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
281 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureField(isAbs);
286 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureFieldOnNode(bool isAbs) const
288 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
289 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureFieldOnNode(isAbs);
297 int MEDCoupling1GTUMesh::getCellContainingPoint(const double *pos, double eps) const
299 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
300 return m->getCellContainingPoint(pos,eps);
303 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::buildOrthogonalField() const
305 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
306 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->buildOrthogonalField();
311 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const double *bbox, double eps) const
313 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
314 return m->getCellsInBoundingBox(bbox,eps);
317 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps)
319 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
320 return m->getCellsInBoundingBox(bbox,eps);
323 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const
325 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
326 return m->buildFacePartOfMySelfNode(start,end,fullyIn);
329 DataArrayInt *MEDCoupling1GTUMesh::findBoundaryNodes() const
331 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
332 return m->findBoundaryNodes();
335 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildBoundaryMesh(bool keepCoords) const
337 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
338 return m->buildBoundaryMesh(keepCoords);
341 void MEDCoupling1GTUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const throw(INTERP_KERNEL::Exception)
343 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
344 m->findCommonCells(compType,startCellId,commonCellsArr,commonCellsIArr);
349 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const MEDCoupling1SGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
353 const DataArrayInt *c(other._conn);
359 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
363 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
365 if(type==INTERP_KERNEL::NORM_ERROR)
366 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
367 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
370 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New : the input geometric type " << cm.getRepr() << " is dynamic ! Only static type are dealed here !";
371 throw INTERP_KERNEL::Exception(oss.str().c_str());
373 return new MEDCoupling1SGTUMesh(name,cm);
376 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::clone(bool recDeepCpy) const
378 return new MEDCoupling1SGTUMesh(*this,recDeepCpy);
381 void MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception)
384 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
385 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
387 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1SGTUMesh instance !");
388 setNodalConnectivity(otherC->getNodalConnectivity());
391 void MEDCoupling1SGTUMesh::updateTime() const
393 MEDCoupling1GTUMesh::updateTime();
394 const DataArrayInt *c(_conn);
399 std::size_t MEDCoupling1SGTUMesh::getHeapMemorySize() const
402 const DataArrayInt *c(_conn);
404 ret+=c->getHeapMemorySize();
405 return MEDCouplingPointSet::getHeapMemorySize()+ret;
408 MEDCouplingMesh *MEDCoupling1SGTUMesh::deepCpy() const
413 bool MEDCoupling1SGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
416 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualIfNotWhy : input other pointer is null !");
417 std::ostringstream oss; oss.precision(15);
418 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
421 reason="mesh given in input is not castable in MEDCoupling1SGTUMesh !";
424 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
426 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
431 reason="in connectivity of single static geometric type exactly one among this and other is null !";
434 if(!c1->isEqualIfNotWhy(*c2,reason))
436 reason.insert(0,"Nodal connectivity DataArrayInt differ : ");
442 bool MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
445 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
446 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
449 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
451 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
456 if(!c1->isEqualWithoutConsideringStr(*c2))
461 void MEDCoupling1SGTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
463 MEDCouplingPointSet::checkCoherency();
464 const DataArrayInt *c1(_conn);
467 if(c1->getNumberOfComponents()!=1)
468 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
469 if(c1->getInfoOnComponent(0)!="")
470 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
471 c1->checkAllocated();
474 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
477 void MEDCoupling1SGTUMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
480 const DataArrayInt *c1(_conn);
481 int nbOfTuples=c1->getNumberOfTuples();
482 int nbOfNodesPerCell=(int)_cm->getNumberOfNodes();
483 if(nbOfTuples%nbOfNodesPerCell!=0)
485 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 !";
486 throw INTERP_KERNEL::Exception(oss.str().c_str());
488 int nbOfNodes=getNumberOfNodes();
489 int nbOfCells=nbOfTuples/nbOfNodesPerCell;
490 const int *w(c1->begin());
491 for(int i=0;i<nbOfCells;i++)
492 for(int j=0;j<nbOfNodesPerCell;j++,w++)
494 if(*w<0 || *w>=nbOfNodes)
496 std::ostringstream oss; oss << "At node #" << j << " of cell #" << i << ", is equal to " << *w << " must be in [0," << nbOfNodes << ") !";
497 throw INTERP_KERNEL::Exception(oss.str().c_str());
502 void MEDCoupling1SGTUMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
504 checkCoherency1(eps);
507 int MEDCoupling1SGTUMesh::getNumberOfCells() const
509 int nbOfTuples=getNodalConnectivityLength();
510 int nbOfNodesPerCell=getNumberOfNodesPerCell();
511 if(nbOfTuples%nbOfNodesPerCell!=0)
513 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 !";
514 throw INTERP_KERNEL::Exception(oss.str().c_str());
516 return nbOfTuples/nbOfNodesPerCell;
519 int MEDCoupling1SGTUMesh::getNumberOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
521 checkNonDynamicGeoType();
522 return (int)_cm->getNumberOfNodes();
525 int MEDCoupling1SGTUMesh::getNodalConnectivityLength() const throw(INTERP_KERNEL::Exception)
527 const DataArrayInt *c1(_conn);
529 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::getNodalConnectivityLength : no connectivity set !");
530 if(c1->getNumberOfComponents()!=1)
531 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::getNodalConnectivityLength : Nodal connectivity array set must have exactly one component !");
532 if(!c1->isAllocated())
533 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::getNodalConnectivityLength : Nodal connectivity array must be allocated !");
534 return c1->getNumberOfTuples();
537 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
539 checkNonDynamicGeoType();
540 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
541 ret->alloc(getNumberOfCells(),1);
542 ret->fillWithValue((int)_cm->getNumberOfNodes());
546 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception)
548 checkNonDynamicGeoType();
549 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
550 ret->alloc(getNumberOfCells(),1);
551 ret->fillWithValue((int)_cm->getNumberOfSons());
555 void MEDCoupling1SGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
557 int sz=getNumberOfNodesPerCell();
559 if(cellId>=0 && cellId<getNumberOfCells())
560 std::copy(_conn->begin()+cellId*sz,_conn->begin()+(cellId+1)*sz,conn.begin());
563 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << getNumberOfCells() << ") !";
564 throw INTERP_KERNEL::Exception(oss.str().c_str());
568 void MEDCoupling1SGTUMesh::checkNonDynamicGeoType() const throw(INTERP_KERNEL::Exception)
571 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkNonDynamicGeoType : internal error ! the internal geo type is dynamic ! should be static !");
574 std::string MEDCoupling1SGTUMesh::simpleRepr() const
576 static const char msg0[]="No coordinates specified !";
577 std::ostringstream ret;
578 ret << "Single static geometic type unstructured mesh with name : \"" << getName() << "\"\n";
579 ret << "Description of mesh : \"" << getDescription() << "\"\n";
581 double tt=getTime(tmpp1,tmpp2);
582 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
583 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
584 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
587 const int spaceDim=getSpaceDimension();
588 ret << spaceDim << "\nInfo attached on space dimension : ";
589 for(int i=0;i<spaceDim;i++)
590 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
595 ret << "Number of nodes : ";
597 ret << getNumberOfNodes() << "\n";
600 ret << "Number of cells : ";
601 if((const DataArrayInt *)_conn)
603 if(_conn->isAllocated())
605 if(_conn->getNumberOfComponents()==1)
606 ret << getNumberOfCells() << "\n";
608 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
611 ret << "Nodal connectivity array specified but not allocated !" << "\n";
614 ret << "No connectivity specified !" << "\n";
615 ret << "Cell type : " << _cm->getRepr() << "\n";
619 std::string MEDCoupling1SGTUMesh::advancedRepr() const
621 std::ostringstream ret;
623 ret << "\nCoordinates array : \n___________________\n\n";
625 _coords->reprWithoutNameStream(ret);
627 ret << "No array set !\n";
628 ret << "\n\nConnectivity array : \n____________________\n\n";
630 if((const DataArrayInt *)_conn)
632 if(_conn->isAllocated())
634 if(_conn->getNumberOfComponents()==1)
636 int nbOfCells=getNumberOfCells();
637 int sz=getNumberOfNodesPerCell();
638 const int *connPtr=_conn->begin();
639 for(int i=0;i<nbOfCells;i++,connPtr+=sz)
641 ret << "Cell #" << i << " : ";
642 std::copy(connPtr,connPtr+sz,std::ostream_iterator<int>(ret," "));
647 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
650 ret << "Nodal connectivity array specified but not allocated !" << "\n";
653 ret << "No connectivity specified !" << "\n";
657 DataArrayDouble *MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
659 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
660 int spaceDim=getSpaceDimension();
661 int nbOfCells=getNumberOfCells();
662 int nbOfNodes=getNumberOfNodes();
663 ret->alloc(nbOfCells,spaceDim);
664 double *ptToFill=ret->getPointer();
665 const double *coor=_coords->begin();
666 const int *nodal=_conn->begin();
667 int sz=getNumberOfNodesPerCell();
668 double coeff=1./(double)sz;
669 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim)
671 std::fill(ptToFill,ptToFill+spaceDim,0.);
672 for(int j=0;j<sz;j++,nodal++)
673 if(*nodal>=0 && *nodal<nbOfNodes)
674 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
677 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
678 throw INTERP_KERNEL::Exception(oss.str().c_str());
680 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),coeff));
685 void MEDCoupling1SGTUMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
687 int nbCells=getNumberOfCells();
688 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
689 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
691 o2n=o2n->checkAndPreparePermutation();
693 const int *conn=_conn->begin();
694 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o=o2n->invertArrayO2N2N2O(nbCells);
695 const int *n2oPtr=n2o->begin();
696 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
697 newConn->alloc(_conn->getNumberOfTuples(),1);
698 newConn->copyStringInfoFrom(*_conn);
699 int sz=getNumberOfNodesPerCell();
701 int *newC=newConn->getPointer();
702 for(int i=0;i<nbCells;i++,newC+=sz)
705 std::copy(conn+pos*sz,conn+(pos+1)*sz,newC);
711 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
712 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
713 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
714 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
716 * \param [in] begin input start of array of node ids.
717 * \param [in] end input end of array of node ids.
718 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
719 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
721 void MEDCoupling1SGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
723 int nbOfCells=getNumberOfCells();
724 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
726 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
727 std::vector<bool> fastFinder(sz,false);
728 for(const int *work=begin;work!=end;work++)
729 if(*work>=0 && *work<sz)
730 fastFinder[*work]=true;
731 const int *conn=_conn->begin();
732 int nbNodesPerCell=getNumberOfNodesPerCell();
733 for(int i=0;i<nbOfCells;i++,conn+=nbNodesPerCell)
736 for(int j=0;j<nbNodesPerCell;j++)
740 if(fastFinder[conn[j]])
743 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
744 cellIdsKept->pushBackSilent(i);
746 cellIdsKeptArr=cellIdsKept.retn();
749 MEDCouplingMesh *MEDCoupling1SGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
751 if(other->getType()!=SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED)
752 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single static geo type each other !");
753 const MEDCoupling1SGTUMesh *otherC=static_cast<const MEDCoupling1SGTUMesh *>(other);
754 return Merge1SGTUMeshes(this,otherC);
757 MEDCouplingUMesh *MEDCoupling1SGTUMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
759 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
760 ret->setCoords(getCoords());
761 const int *nodalConn=_conn->begin();
762 int nbCells=getNumberOfCells();
763 int nbNodesPerCell=getNumberOfNodesPerCell();
764 int geoType=(int)getCellModelEnum();
765 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells*(nbNodesPerCell+1),1);
766 int *cPtr=c->getPointer();
767 for(int i=0;i<nbCells;i++,nodalConn+=nbNodesPerCell)
770 cPtr=std::copy(nodalConn,nodalConn+nbNodesPerCell,cPtr);
772 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::Range(0,(nbCells+1)*(nbNodesPerCell+1),nbNodesPerCell+1);
773 ret->setConnectivity(c,cI,true);
777 DataArrayInt *MEDCoupling1SGTUMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
782 return simplexizePol0();
784 return simplexizePol1();
785 case (int) INTERP_KERNEL::PLANAR_FACE_5:
786 return simplexizePlanarFace5();
787 case (int) INTERP_KERNEL::PLANAR_FACE_6:
788 return simplexizePlanarFace6();
790 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)");
795 * \return DataArrayInt * - the permutation array in "Old to New" mode. For more
796 * info on "Old to New" mode see \ref MEDCouplingArrayRenumbering. The caller
797 * is to delete this array using decrRef() as it is no more needed.
799 DataArrayInt *MEDCoupling1SGTUMesh::mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes)
801 DataArrayInt *ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes);
803 renumberNodes(ret->getConstPointer(),newNbOfNodes);
808 * \return DataArrayInt * - the permutation array in "Old to New" mode. For more
809 * info on "Old to New" mode see \ref MEDCouplingArrayRenumbering. The caller
810 * is to delete this array using decrRef() as it is no more needed.
812 DataArrayInt *MEDCoupling1SGTUMesh::mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes)
814 DataArrayInt *ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes);
816 renumberNodes2(ret->getConstPointer(),newNbOfNodes);
822 struct MEDCouplingAccVisit
824 MEDCouplingAccVisit():_new_nb_of_nodes(0) { }
825 int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; }
826 int _new_nb_of_nodes;
832 * Finds nodes not used in any cell and returns an array giving a new id to every node
833 * by excluding the unused nodes, for which the array holds -1. The result array is
834 * a mapping in "Old to New" mode.
835 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
836 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
837 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
838 * if the node is unused or a new id else. The caller is to delete this
839 * array using decrRef() as it is no more needed.
840 * \throw If the coordinates array is not set.
841 * \throw If the nodal connectivity of cells is not defined.
842 * \throw If the nodal connectivity includes an invalid id.
844 DataArrayInt *MEDCoupling1SGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception)
847 int nbOfNodes=getNumberOfNodes();
848 int nbOfCells=getNumberOfCells();
849 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
850 ret->alloc(nbOfNodes,1);
851 int *traducer=ret->getPointer();
852 std::fill(traducer,traducer+nbOfNodes,-1);
853 const int *conn=_conn->begin();
854 int nbNodesPerCell=getNumberOfNodesPerCell();
855 for(int i=0;i<nbOfCells;i++)
856 for(int j=0;j<nbNodesPerCell;j++,conn++)
857 if(*conn>=0 && *conn<nbOfNodes)
861 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << conn[j] << " not in [0," << nbOfNodes << ") !";
862 throw INTERP_KERNEL::Exception(oss.str().c_str());
864 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
865 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
870 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
871 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
872 * This method is a generalization of shiftNodeNumbersInConn().
873 * \warning This method performs no check of validity of new ids. **Use it with care !**
874 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
875 * this->getNumberOfNodes(), in "Old to New" mode.
876 * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
877 * \throw If the nodal connectivity of cells is not defined.
879 void MEDCoupling1SGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
881 getNumberOfCells();//only to check that all is well defined.
882 _conn->transformWithIndArr(newNodeNumbersO2N,newNodeNumbersO2N+getNumberOfNodes());
886 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2) throw(INTERP_KERNEL::Exception)
888 std::vector<const MEDCoupling1SGTUMesh *> tmp(2);
889 tmp[0]=const_cast<MEDCoupling1SGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1SGTUMesh *>(mesh2);
890 return Merge1SGTUMeshes(tmp);
893 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
895 std::size_t sz=a.size();
897 return Merge1SGTUMeshesLL(a);
898 for(std::size_t ii=0;ii<sz;ii++)
901 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::Merge1SGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
902 throw INTERP_KERNEL::Exception(oss.str().c_str());
904 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
905 for(std::size_t ii=0;ii<sz;ii++)
906 if(&(a[ii]->getCellModel())!=cm)
907 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : all items must have the same geo type !");
908 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> > bb(sz);
909 std::vector< const MEDCoupling1SGTUMesh * > aa(sz);
911 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
913 const MEDCoupling1SGTUMesh *cur=a[i];
914 const DataArrayDouble *coo=cur->getCoords();
916 spaceDim=coo->getNumberOfComponents();
919 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : no spaceDim specified ! unable to perform merge !");
920 for(std::size_t i=0;i<sz;i++)
922 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
925 return Merge1SGTUMeshesLL(aa);
928 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
931 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : input array must be NON EMPTY !");
932 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
934 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : presence of null instance !");
935 int nbOfCells=(*it)->getNumberOfCells();
936 const DataArrayDouble *coords=(*it)->getCoords();
937 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
938 int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
940 for(;it!=a.end();it++)
942 if(cm!=&((*it)->getCellModel()))
943 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
944 nbOfCells+=(*it)->getNumberOfCells();
945 if(coords!=(*it)->getCoords())
946 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : not lying on same coords !");
948 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
949 ret->setCoords(coords);
950 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New();
951 c->alloc(nbOfCells*nbNodesPerCell,1);
952 int *cPtr=c->getPointer();
954 for(it=a.begin();it!=a.end();it++)
956 int curConnLgth=(*it)->getNodalConnectivityLength();
957 const int *curC=(*it)->_conn->begin();
958 cPtr=std::copy(curC,curC+curConnLgth,cPtr);
965 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
968 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : input array must be NON EMPTY !");
969 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
970 int nbOfCells=(*it)->getNumberOfCells();
971 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
972 int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
974 for(;it!=a.end();it++)
976 if(cm!=&((*it)->getCellModel()))
977 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
978 nbOfCells+=(*it)->getNumberOfCells();
980 std::vector<const MEDCouplingPointSet *> aps(a.size());
981 std::copy(a.begin(),a.end(),aps.begin());
982 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
983 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
985 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New();
986 c->alloc(nbOfCells*nbNodesPerCell,1);
987 int *cPtr=c->getPointer();
989 for(it=a.begin();it!=a.end();it++)
991 int curConnLgth=(*it)->getNodalConnectivityLength();
992 const int *curC=(*it)->_conn->begin();
993 cPtr=std::transform(curC,curC+curConnLgth,cPtr,std::bind2nd(std::plus<int>(),offset));
994 offset+=(*it)->getNumberOfNodes();
997 ret->setNodalConnectivity(c);
1001 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
1003 int ncell=getNumberOfCells();
1004 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1005 ret->setCoords(_coords);
1006 std::size_t nbOfElemsRet=std::distance(begin,end);
1007 const int *inConn=_conn->getConstPointer();
1008 int sz=getNumberOfNodesPerCell();
1009 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1010 int *connPtr=connRet->getPointer();
1011 for(const int *work=begin;work!=end;work++,connPtr+=sz)
1013 if(*work>=0 && *work<ncell)
1014 std::copy(inConn+(work[0])*sz,inConn+(work[0]+1)*sz,connPtr);
1017 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !";
1018 throw INTERP_KERNEL::Exception(oss.str().c_str());
1022 ret->copyTinyInfoFrom(this);
1026 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
1028 int ncell=getNumberOfCells();
1029 int nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : ");
1030 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1031 ret->setCoords(_coords);
1032 const int *inConn=_conn->getConstPointer();
1033 int sz=getNumberOfNodesPerCell();
1034 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1035 int *connPtr=connRet->getPointer();
1037 for(int i=0;i<nbOfElemsRet;i++,connPtr+=sz,curId+=step)
1039 if(curId>=0 && curId<ncell)
1040 std::copy(inConn+curId*sz,inConn+(curId+1)*sz,connPtr);
1043 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : On pos #" << i << " input cell id =" << curId << " should be in [0," << ncell << ") !";
1044 throw INTERP_KERNEL::Exception(oss.str().c_str());
1048 ret->copyTinyInfoFrom(this);
1052 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception)
1054 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1055 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1;
1056 const DataArrayInt *nodalConn(_conn);
1059 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
1066 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
1067 ret->setCoords(coords);
1070 ret->setCoords(_coords);
1074 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol0() throw(INTERP_KERNEL::Exception)
1076 int nbOfCells=getNumberOfCells();
1077 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1078 return DataArrayInt::Range(0,nbOfCells,1);
1079 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1080 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1081 const int *c(_conn->begin());
1082 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1083 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1085 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[2];
1086 newConnPtr[3]=c[0]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1087 retPtr[0]=i; retPtr[1]=i;
1090 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1095 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol1() throw(INTERP_KERNEL::Exception)
1097 int nbOfCells=getNumberOfCells();
1098 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1099 return DataArrayInt::Range(0,nbOfCells,1);
1100 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1101 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1102 const int *c(_conn->begin());
1103 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1104 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1106 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[3];
1107 newConnPtr[3]=c[1]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1108 retPtr[0]=i; retPtr[1]=i;
1111 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1116 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace5() throw(INTERP_KERNEL::Exception)
1118 int nbOfCells=getNumberOfCells();
1119 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1120 return DataArrayInt::Range(0,nbOfCells,1);
1121 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(5*4*nbOfCells,1);
1122 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(5*nbOfCells,1);
1123 const int *c(_conn->begin());
1124 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1125 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=20,retPtr+=5)
1127 for(int j=0;j<20;j++)
1128 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_5_WO[j]];
1129 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i;
1132 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1137 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace6() throw(INTERP_KERNEL::Exception)
1139 int nbOfCells=getNumberOfCells();
1140 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1141 return DataArrayInt::Range(0,nbOfCells,1);
1142 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(6*4*nbOfCells,1);
1143 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(6*nbOfCells,1);
1144 const int *c(_conn->begin());
1145 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1146 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=24,retPtr+=6)
1148 for(int j=0;j<24;j++)
1149 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_6_WO[j]];
1150 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i; retPtr[5]=i;
1153 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1158 void MEDCoupling1SGTUMesh::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1160 stream << "MEDCoupling1SGTUMesh C++ instance at " << this << ". Name : \"" << getName() << "\".";
1161 stream << " Mesh dimension : " << getMeshDimension() << ".";
1163 { stream << " No coordinates set !"; return ; }
1164 if(!_coords->isAllocated())
1165 { stream << " Coordinates set but not allocated !"; return ; }
1166 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
1167 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
1168 if(!(const DataArrayInt *)_conn)
1169 { stream << std::endl << "Nodal connectivity NOT set !"; return ; }
1170 if(_conn->isAllocated())
1172 if(_conn->getNumberOfComponents()==1)
1173 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
1177 void MEDCoupling1SGTUMesh::checkFullyDefined() const throw(INTERP_KERNEL::Exception)
1179 if(!((const DataArrayInt *)_conn) || !((const DataArrayDouble *)_coords))
1180 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFullyDefined : part of this is not fully defined.");
1184 * First step of unserialization process.
1186 bool MEDCoupling1SGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
1188 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEmptyMesh : not implemented yet !");
1192 * Checks if \a this and \a other meshes are geometrically equivalent with high
1193 * probability, else an exception is thrown. The meshes are considered equivalent if
1194 * (1) meshes contain the same number of nodes and the same number of elements of the
1195 * same types (2) three cells of the two meshes (first, last and middle) are based
1196 * on coincident nodes (with a specified precision).
1197 * \param [in] other - the mesh to compare with.
1198 * \param [in] prec - the precision used to compare nodes of the two meshes.
1199 * \throw If the two meshes do not match.
1201 void MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception)
1203 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1204 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1206 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not not unstructured with single static geometric type !");
1209 MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
1212 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
1213 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1215 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
1216 std::vector<const MEDCoupling1SGTUMesh *> ms(2);
1219 return Merge1SGTUMeshesOnSameCoords(ms);
1222 void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception)
1224 checkFullyDefined();
1225 int nbOfNodes=getNumberOfNodes();
1226 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
1227 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
1228 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
1229 const int *conn=_conn->begin();
1230 int nbOfCells=getNumberOfCells();
1231 int nbOfEltsInRevNodal=0;
1232 int nbOfNodesPerCell=getNumberOfNodesPerCell();
1233 for(int eltId=0;eltId<nbOfCells;eltId++)
1235 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1237 if(conn[0]>=0 && conn[0]<nbOfNodes)
1239 nbOfEltsInRevNodal++;
1240 revNodalIndxPtr[conn[0]+1]++;
1244 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
1245 throw INTERP_KERNEL::Exception(oss.str().c_str());
1249 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
1250 conn=_conn->begin();
1251 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
1252 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
1253 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
1254 for(int eltId=0;eltId<nbOfCells;eltId++)
1256 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1258 *std::find_if(revNodalPtr+revNodalIndxPtr[*conn],revNodalPtr+revNodalIndxPtr[*conn+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
1264 * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null.
1265 * This method tests, if the input \a nodalConn is not null, that :
1266 * - it has one component.
1267 * - the number of tuples compatible with the number of node per cell.
1269 void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn) throw(INTERP_KERNEL::Exception)
1276 const DataArrayInt *c1(nodalConn);
1277 if(c1->getNumberOfComponents()!=1)
1278 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::setNodalConnectivity : input nodal connectivity array set must have exactly one component !");
1279 if(!c1->isAllocated())
1280 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::setNodalConnectivity : input nodal connectivity array must be allocated !");
1281 int nbTuples=c1->getNumberOfTuples();
1282 if(nbTuples%getNumberOfNodesPerCell()!=0)
1283 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::setNodalConnectivity : input nodal connectivity number of tuples is incompatible with geometric type !");
1284 nodalConn->incrRef();
1290 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
1292 DataArrayInt *MEDCoupling1SGTUMesh::getNodalConnectivity() const throw(INTERP_KERNEL::Exception)
1294 const DataArrayInt *ret(_conn);
1295 return const_cast<DataArrayInt *>(ret);
1299 * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted,
1300 * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter.
1301 * If a nodal connectivity previouly existed before the call of this method, it will be reset.
1303 * \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain.
1305 void MEDCoupling1SGTUMesh::allocateCells(int nbOfCells) throw(INTERP_KERNEL::Exception)
1308 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !");
1309 _conn=DataArrayInt::New();
1310 _conn->reserve(getNumberOfNodesPerCell()*nbOfCells);
1315 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
1317 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
1318 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
1319 * \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
1320 * attached to \a this.
1321 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
1323 void MEDCoupling1SGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) throw(INTERP_KERNEL::Exception)
1325 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
1326 int ref=getNumberOfNodesPerCell();
1329 DataArrayInt *c(_conn);
1331 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
1333 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !");
1337 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this (";
1338 oss << ref << ") !";
1339 throw INTERP_KERNEL::Exception(oss.str().c_str());