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);
46 return MEDCoupling1DGTUMesh::New(name,type);
49 const INTERP_KERNEL::CellModel& MEDCoupling1GTUMesh::getCellModel() const throw(INTERP_KERNEL::Exception)
54 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getCellModelEnum() const throw(INTERP_KERNEL::Exception)
56 return _cm->getEnum();
59 int MEDCoupling1GTUMesh::getMeshDimension() const
61 return (int)_cm->getDimension();
65 * This method returns a newly allocated array containing cell ids (ascendingly sorted) whose geometric type are equal to type.
66 * This method does not throw exception if geometric type \a type is not in \a this.
67 * This method throws an INTERP_KERNEL::Exception if meshdimension of \b this is not equal to those of \b type.
68 * The coordinates array is not considered here.
70 * \param [in] type the geometric type
71 * \return cell ids in this having geometric type \a type.
73 DataArrayInt *MEDCoupling1GTUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception)
75 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
76 if(type==getCellModelEnum())
77 ret->alloc(getNumberOfCells(),1);
85 * Returns nb of cells having the geometric type \a type. No throw if no cells in \a this has the geometric type \a type.
87 int MEDCoupling1GTUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
89 return type==getCellModelEnum()?getNumberOfCells():0;
93 * Returns a type of a cell by its id.
94 * \param [in] cellId - the id of the cell of interest.
95 * \return INTERP_KERNEL::NormalizedCellType - enumeration item describing the cell type.
96 * \throw If \a cellId is invalid. Valid range is [0, \a this->getNumberOfCells() ).
98 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getTypeOfCell(int cellId) const
100 if(cellId>=0 && cellId<getNumberOfCells())
101 return getCellModelEnum();
102 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::getTypeOfCell : Requesting type of cell #" << cellId << " but it should be in [0," << getNumberOfCells() << ") !";
103 throw INTERP_KERNEL::Exception(oss.str().c_str());
107 * Returns a set of all cell types available in \a this mesh.
108 * \return std::set<INTERP_KERNEL::NormalizedCellType> - the set of cell types.
109 * \warning this method does not throw any exception even if \a this is not defined.
111 std::set<INTERP_KERNEL::NormalizedCellType> MEDCoupling1GTUMesh::getAllGeoTypes() const
113 std::set<INTERP_KERNEL::NormalizedCellType> ret;
114 ret.insert(getCellModelEnum());
119 * This method expects that \a this is sorted by types. If not an exception will be thrown.
120 * This method returns in the same format as code (see MEDCouplingUMesh::checkTypeConsistencyAndContig or MEDCouplingUMesh::splitProfilePerType) how
121 * \a this is composed in cell types.
122 * The returned array is of size 3*n where n is the number of different types present in \a this.
123 * For every k in [0,n] ret[3*k+2]==0 because it has no sense here.
124 * This parameter is kept only for compatibility with other methode listed above.
126 std::vector<int> MEDCoupling1GTUMesh::getDistributionOfTypes() const throw(INTERP_KERNEL::Exception)
128 std::vector<int> ret(3);
129 ret[0]=(int)getCellModelEnum(); ret[1]=getNumberOfCells(); ret[2]=0;
134 * 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.
135 * 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.
136 * This method has 1 input \a profile and 3 outputs \a code \a idsInPflPerType and \a idsPerType.
138 * \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.
139 * \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,
140 * \a idsInPflPerType[i] stores the tuple ids in \a profile that correspond to the geometric type code[3*i+0]
141 * \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.
142 * This vector can be empty in case of all geometric type cells are fully covered in ascending in the given input \a profile.
144 * \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.
146 * \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
149 * - Before \a this has 3 cells \a profile contains [0,1,2]
150 * - After \a code contains [NORM_...,nbCells,-1], \a idsInPflPerType [[0,1,2]] and \a idsPerType is empty <br>
153 * - Before \a this has 3 cells \a profile contains [1,2]
154 * - After \a code contains [NORM_...,nbCells,0], \a idsInPflPerType [[0,1]] and \a idsPerType is [[1,2]] <br>
157 void MEDCoupling1GTUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
160 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile is NULL !");
161 if(profile->getNumberOfComponents()!=1)
162 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile should have exactly one component !");
163 int nbTuples=profile->getNumberOfTuples();
164 int nbOfCells=getNumberOfCells();
165 code.resize(3); idsInPflPerType.resize(1);
166 code[0]=(int)getCellModelEnum(); code[1]=nbTuples;
167 idsInPflPerType.resize(1);
168 if(profile->isIdentity() && nbTuples==nbOfCells)
171 idsInPflPerType[0]=const_cast<DataArrayInt *>(profile); idsInPflPerType[0]->incrRef();
176 profile->checkAllIdsInRange(0,nbOfCells);
177 idsPerType.resize(1);
178 idsPerType[0]=const_cast<DataArrayInt *>(profile); idsPerType[0]->incrRef();
179 idsInPflPerType[0]=DataArrayInt::Range(0,nbTuples,1);
183 * This method tries to minimize at most the number of deep copy.
184 * So if \a idsPerType is not empty it can be returned directly (without copy, but with ref count incremented) in return.
186 * \sa MEDCouplingUMesh::checkTypeConsistencyAndContig
188 DataArrayInt *MEDCoupling1GTUMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
190 int nbOfCells=getNumberOfCells();
192 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : invalid input code should be exactly of size 3 !");
193 if(code[0]!=(int)getCellModelEnum())
195 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() << ") !";
196 throw INTERP_KERNEL::Exception(oss.str().c_str());
200 if(code[1]==nbOfCells)
204 std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : mismatch between the number of cells in this (" << nbOfCells << ") and the number of non profile (" << code[1] << ") !";
205 throw INTERP_KERNEL::Exception(oss.str().c_str());
209 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : single geo type mesh ! 0 or -1 is expected at pos #2 of input code !");
210 if(idsPerType.size()!=1)
211 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input code points to DataArrayInt #0 whereas the size of idsPerType is not equal to 1 !");
212 const DataArrayInt *pfl=idsPerType[0];
214 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : the input code points to a NULL DataArrayInt at rank 0 !");
215 if(pfl->getNumberOfComponents()!=1)
216 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input profile should have exactly one component !");
217 pfl->checkAllIdsInRange(0,nbOfCells);
219 return const_cast<DataArrayInt *>(pfl);
222 void MEDCoupling1GTUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception)
224 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
225 m->writeVTKLL(ofs,cellData,pointData);
228 std::string MEDCoupling1GTUMesh::getVTKDataSetType() const throw(INTERP_KERNEL::Exception)
230 return std::string("UnstructuredGrid");
233 std::size_t MEDCoupling1GTUMesh::getHeapMemorySize() const
235 return MEDCouplingPointSet::getHeapMemorySize();
238 bool MEDCoupling1GTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
240 if(!MEDCouplingPointSet::isEqualIfNotWhy(other,prec,reason))
243 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualIfNotWhy : input other pointer is null !");
244 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
247 reason="mesh given in input is not castable in MEDCouplingSGTUMesh !";
252 reason="mismatch in geometric type !";
258 bool MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
260 if(!MEDCouplingPointSet::isEqualWithoutConsideringStr(other,prec))
263 throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
264 const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
272 void MEDCoupling1GTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
274 MEDCouplingPointSet::checkCoherency();
277 DataArrayDouble *MEDCoupling1GTUMesh::getBarycenterAndOwner() const
279 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
280 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=m->getBarycenterAndOwner();
284 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureField(bool isAbs) const
286 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
287 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureField(isAbs);
292 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureFieldOnNode(bool isAbs) const
294 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
295 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureFieldOnNode(isAbs);
303 int MEDCoupling1GTUMesh::getCellContainingPoint(const double *pos, double eps) const
305 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
306 return m->getCellContainingPoint(pos,eps);
309 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::buildOrthogonalField() const
311 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
312 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->buildOrthogonalField();
317 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const double *bbox, double eps) const
319 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
320 return m->getCellsInBoundingBox(bbox,eps);
323 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps)
325 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
326 return m->getCellsInBoundingBox(bbox,eps);
329 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const
331 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
332 return m->buildFacePartOfMySelfNode(start,end,fullyIn);
335 DataArrayInt *MEDCoupling1GTUMesh::findBoundaryNodes() const
337 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
338 return m->findBoundaryNodes();
341 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildBoundaryMesh(bool keepCoords) const
343 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
344 return m->buildBoundaryMesh(keepCoords);
347 void MEDCoupling1GTUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const throw(INTERP_KERNEL::Exception)
349 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
350 m->findCommonCells(compType,startCellId,commonCellsArr,commonCellsIArr);
355 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const MEDCoupling1SGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
359 const DataArrayInt *c(other._conn);
365 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
369 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
371 if(type==INTERP_KERNEL::NORM_ERROR)
372 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
373 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
376 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New : the input geometric type " << cm.getRepr() << " is dynamic ! Only static types are allowed here !";
377 throw INTERP_KERNEL::Exception(oss.str().c_str());
379 return new MEDCoupling1SGTUMesh(name,cm);
382 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::clone(bool recDeepCpy) const
384 return new MEDCoupling1SGTUMesh(*this,recDeepCpy);
387 void MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception)
390 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
391 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
393 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1SGTUMesh instance !");
394 setNodalConnectivity(otherC->getNodalConnectivity());
397 void MEDCoupling1SGTUMesh::updateTime() const
399 MEDCoupling1GTUMesh::updateTime();
400 const DataArrayInt *c(_conn);
405 std::size_t MEDCoupling1SGTUMesh::getHeapMemorySize() const
408 const DataArrayInt *c(_conn);
410 ret+=c->getHeapMemorySize();
411 return MEDCoupling1GTUMesh::getHeapMemorySize()+ret;
414 MEDCouplingMesh *MEDCoupling1SGTUMesh::deepCpy() const
419 bool MEDCoupling1SGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
422 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualIfNotWhy : input other pointer is null !");
423 std::ostringstream oss; oss.precision(15);
424 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
427 reason="mesh given in input is not castable in MEDCoupling1SGTUMesh !";
430 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
432 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
437 reason="in connectivity of single static geometric type exactly one among this and other is null !";
440 if(!c1->isEqualIfNotWhy(*c2,reason))
442 reason.insert(0,"Nodal connectivity DataArrayInt differ : ");
448 bool MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
451 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
452 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
455 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
457 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
462 if(!c1->isEqualWithoutConsideringStr(*c2))
467 void MEDCoupling1SGTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
469 MEDCouplingPointSet::checkCoherency();
470 const DataArrayInt *c1(_conn);
473 if(c1->getNumberOfComponents()!=1)
474 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
475 if(c1->getInfoOnComponent(0)!="")
476 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
477 c1->checkAllocated();
480 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
483 void MEDCoupling1SGTUMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
486 const DataArrayInt *c1(_conn);
487 int nbOfTuples=c1->getNumberOfTuples();
488 int nbOfNodesPerCell=(int)_cm->getNumberOfNodes();
489 if(nbOfTuples%nbOfNodesPerCell!=0)
491 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 !";
492 throw INTERP_KERNEL::Exception(oss.str().c_str());
494 int nbOfNodes=getNumberOfNodes();
495 int nbOfCells=nbOfTuples/nbOfNodesPerCell;
496 const int *w(c1->begin());
497 for(int i=0;i<nbOfCells;i++)
498 for(int j=0;j<nbOfNodesPerCell;j++,w++)
500 if(*w<0 || *w>=nbOfNodes)
502 std::ostringstream oss; oss << "At node #" << j << " of cell #" << i << ", is equal to " << *w << " must be in [0," << nbOfNodes << ") !";
503 throw INTERP_KERNEL::Exception(oss.str().c_str());
508 void MEDCoupling1SGTUMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
510 checkCoherency1(eps);
513 int MEDCoupling1SGTUMesh::getNumberOfCells() const
515 int nbOfTuples=getNodalConnectivityLength();
516 int nbOfNodesPerCell=getNumberOfNodesPerCell();
517 if(nbOfTuples%nbOfNodesPerCell!=0)
519 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 !";
520 throw INTERP_KERNEL::Exception(oss.str().c_str());
522 return nbOfTuples/nbOfNodesPerCell;
525 int MEDCoupling1SGTUMesh::getNumberOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
527 checkNonDynamicGeoType();
528 return (int)_cm->getNumberOfNodes();
531 int MEDCoupling1SGTUMesh::getNodalConnectivityLength() const throw(INTERP_KERNEL::Exception)
533 const DataArrayInt *c1(_conn);
535 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::getNodalConnectivityLength : no connectivity set !");
536 if(c1->getNumberOfComponents()!=1)
537 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::getNodalConnectivityLength : Nodal connectivity array set must have exactly one component !");
538 if(!c1->isAllocated())
539 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::getNodalConnectivityLength : Nodal connectivity array must be allocated !");
540 return c1->getNumberOfTuples();
543 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
545 checkNonDynamicGeoType();
546 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
547 ret->alloc(getNumberOfCells(),1);
548 ret->fillWithValue((int)_cm->getNumberOfNodes());
552 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception)
554 checkNonDynamicGeoType();
555 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
556 ret->alloc(getNumberOfCells(),1);
557 ret->fillWithValue((int)_cm->getNumberOfSons());
561 void MEDCoupling1SGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
563 int sz=getNumberOfNodesPerCell();
565 if(cellId>=0 && cellId<getNumberOfCells())
566 std::copy(_conn->begin()+cellId*sz,_conn->begin()+(cellId+1)*sz,conn.begin());
569 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << getNumberOfCells() << ") !";
570 throw INTERP_KERNEL::Exception(oss.str().c_str());
574 void MEDCoupling1SGTUMesh::checkNonDynamicGeoType() const throw(INTERP_KERNEL::Exception)
577 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkNonDynamicGeoType : internal error ! the internal geo type is dynamic ! should be static !");
580 std::string MEDCoupling1SGTUMesh::simpleRepr() const
582 static const char msg0[]="No coordinates specified !";
583 std::ostringstream ret;
584 ret << "Single static geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
585 ret << "Description of mesh : \"" << getDescription() << "\"\n";
587 double tt=getTime(tmpp1,tmpp2);
588 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
589 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
590 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
593 const int spaceDim=getSpaceDimension();
594 ret << spaceDim << "\nInfo attached on space dimension : ";
595 for(int i=0;i<spaceDim;i++)
596 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
601 ret << "Number of nodes : ";
603 ret << getNumberOfNodes() << "\n";
606 ret << "Number of cells : ";
607 if((const DataArrayInt *)_conn)
609 if(_conn->isAllocated())
611 if(_conn->getNumberOfComponents()==1)
612 ret << getNumberOfCells() << "\n";
614 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
617 ret << "Nodal connectivity array specified but not allocated !" << "\n";
620 ret << "No connectivity specified !" << "\n";
621 ret << "Cell type : " << _cm->getRepr() << "\n";
625 std::string MEDCoupling1SGTUMesh::advancedRepr() const
627 std::ostringstream ret;
629 ret << "\nCoordinates array : \n___________________\n\n";
631 _coords->reprWithoutNameStream(ret);
633 ret << "No array set !\n";
634 ret << "\n\nConnectivity array : \n____________________\n\n";
636 if((const DataArrayInt *)_conn)
638 if(_conn->isAllocated())
640 if(_conn->getNumberOfComponents()==1)
642 int nbOfCells=getNumberOfCells();
643 int sz=getNumberOfNodesPerCell();
644 const int *connPtr=_conn->begin();
645 for(int i=0;i<nbOfCells;i++,connPtr+=sz)
647 ret << "Cell #" << i << " : ";
648 std::copy(connPtr,connPtr+sz,std::ostream_iterator<int>(ret," "));
653 ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
656 ret << "Nodal connectivity array specified but not allocated !" << "\n";
659 ret << "No connectivity specified !" << "\n";
663 DataArrayDouble *MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
665 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
666 int spaceDim=getSpaceDimension();
667 int nbOfCells=getNumberOfCells();//checkCoherency()
668 int nbOfNodes=getNumberOfNodes();
669 ret->alloc(nbOfCells,spaceDim);
670 double *ptToFill=ret->getPointer();
671 const double *coor=_coords->begin();
672 const int *nodal=_conn->begin();
673 int sz=getNumberOfNodesPerCell();
674 double coeff=1./(double)sz;
675 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim)
677 std::fill(ptToFill,ptToFill+spaceDim,0.);
678 for(int j=0;j<sz;j++,nodal++)
679 if(*nodal>=0 && *nodal<nbOfNodes)
680 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
683 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
684 throw INTERP_KERNEL::Exception(oss.str().c_str());
686 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),coeff));
691 void MEDCoupling1SGTUMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
693 int nbCells=getNumberOfCells();
694 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
695 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
697 o2n=o2n->checkAndPreparePermutation();
699 const int *conn=_conn->begin();
700 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o=o2n->invertArrayO2N2N2O(nbCells);
701 const int *n2oPtr=n2o->begin();
702 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
703 newConn->alloc(_conn->getNumberOfTuples(),1);
704 newConn->copyStringInfoFrom(*_conn);
705 int sz=getNumberOfNodesPerCell();
707 int *newC=newConn->getPointer();
708 for(int i=0;i<nbCells;i++,newC+=sz)
711 std::copy(conn+pos*sz,conn+(pos+1)*sz,newC);
717 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
718 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
719 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
720 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
722 * \param [in] begin input start of array of node ids.
723 * \param [in] end input end of array of node ids.
724 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
725 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
727 void MEDCoupling1SGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
729 int nbOfCells=getNumberOfCells();
730 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
732 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
733 std::vector<bool> fastFinder(sz,false);
734 for(const int *work=begin;work!=end;work++)
735 if(*work>=0 && *work<sz)
736 fastFinder[*work]=true;
737 const int *conn=_conn->begin();
738 int nbNodesPerCell=getNumberOfNodesPerCell();
739 for(int i=0;i<nbOfCells;i++,conn+=nbNodesPerCell)
742 for(int j=0;j<nbNodesPerCell;j++)
746 if(fastFinder[conn[j]])
749 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
750 cellIdsKept->pushBackSilent(i);
752 cellIdsKeptArr=cellIdsKept.retn();
755 MEDCouplingMesh *MEDCoupling1SGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
757 if(other->getType()!=SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED)
758 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single static geo type each other !");
759 const MEDCoupling1SGTUMesh *otherC=static_cast<const MEDCoupling1SGTUMesh *>(other);
760 return Merge1SGTUMeshes(this,otherC);
763 MEDCouplingUMesh *MEDCoupling1SGTUMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
765 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
766 ret->setCoords(getCoords());
767 const int *nodalConn=_conn->begin();
768 int nbCells=getNumberOfCells();
769 int nbNodesPerCell=getNumberOfNodesPerCell();
770 int geoType=(int)getCellModelEnum();
771 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells*(nbNodesPerCell+1),1);
772 int *cPtr=c->getPointer();
773 for(int i=0;i<nbCells;i++,nodalConn+=nbNodesPerCell)
776 cPtr=std::copy(nodalConn,nodalConn+nbNodesPerCell,cPtr);
778 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::Range(0,(nbCells+1)*(nbNodesPerCell+1),nbNodesPerCell+1);
779 ret->setConnectivity(c,cI,true);
783 DataArrayInt *MEDCoupling1SGTUMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
788 return simplexizePol0();
790 return simplexizePol1();
791 case (int) INTERP_KERNEL::PLANAR_FACE_5:
792 return simplexizePlanarFace5();
793 case (int) INTERP_KERNEL::PLANAR_FACE_6:
794 return simplexizePlanarFace6();
796 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)");
802 struct MEDCouplingAccVisit
804 MEDCouplingAccVisit():_new_nb_of_nodes(0) { }
805 int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; }
806 int _new_nb_of_nodes;
812 * Finds nodes not used in any cell and returns an array giving a new id to every node
813 * by excluding the unused nodes, for which the array holds -1. The result array is
814 * a mapping in "Old to New" mode.
815 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
816 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
817 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
818 * if the node is unused or a new id else. The caller is to delete this
819 * array using decrRef() as it is no more needed.
820 * \throw If the coordinates array is not set.
821 * \throw If the nodal connectivity of cells is not defined.
822 * \throw If the nodal connectivity includes an invalid id.
824 DataArrayInt *MEDCoupling1SGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception)
827 int nbOfNodes=getNumberOfNodes();
828 int nbOfCells=getNumberOfCells();
829 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
830 ret->alloc(nbOfNodes,1);
831 int *traducer=ret->getPointer();
832 std::fill(traducer,traducer+nbOfNodes,-1);
833 const int *conn=_conn->begin();
834 int nbNodesPerCell=getNumberOfNodesPerCell();
835 for(int i=0;i<nbOfCells;i++)
836 for(int j=0;j<nbNodesPerCell;j++,conn++)
837 if(*conn>=0 && *conn<nbOfNodes)
841 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << conn[j] << " not in [0," << nbOfNodes << ") !";
842 throw INTERP_KERNEL::Exception(oss.str().c_str());
844 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
845 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
850 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
851 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
852 * This method is a generalization of shiftNodeNumbersInConn().
853 * \warning This method performs no check of validity of new ids. **Use it with care !**
854 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
855 * this->getNumberOfNodes(), in "Old to New" mode.
856 * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
857 * \throw If the nodal connectivity of cells is not defined.
859 void MEDCoupling1SGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
861 getNumberOfCells();//only to check that all is well defined.
862 _conn->transformWithIndArr(newNodeNumbersO2N,newNodeNumbersO2N+getNumberOfNodes());
866 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2) throw(INTERP_KERNEL::Exception)
868 std::vector<const MEDCoupling1SGTUMesh *> tmp(2);
869 tmp[0]=const_cast<MEDCoupling1SGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1SGTUMesh *>(mesh2);
870 return Merge1SGTUMeshes(tmp);
873 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
875 std::size_t sz=a.size();
877 return Merge1SGTUMeshesLL(a);
878 for(std::size_t ii=0;ii<sz;ii++)
881 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::Merge1SGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
882 throw INTERP_KERNEL::Exception(oss.str().c_str());
884 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
885 for(std::size_t ii=0;ii<sz;ii++)
886 if(&(a[ii]->getCellModel())!=cm)
887 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : all items must have the same geo type !");
888 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> > bb(sz);
889 std::vector< const MEDCoupling1SGTUMesh * > aa(sz);
891 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
893 const MEDCoupling1SGTUMesh *cur=a[i];
894 const DataArrayDouble *coo=cur->getCoords();
896 spaceDim=coo->getNumberOfComponents();
899 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : no spaceDim specified ! unable to perform merge !");
900 for(std::size_t i=0;i<sz;i++)
902 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
905 return Merge1SGTUMeshesLL(aa);
908 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
911 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : input array must be NON EMPTY !");
912 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
914 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : presence of null instance !");
915 std::vector<const DataArrayInt *> ncs(a.size());
916 int nbOfCells=(*it)->getNumberOfCells();
917 const DataArrayDouble *coords=(*it)->getCoords();
918 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
919 int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
920 ncs[0]=(*it)->getNodalConnectivity();
922 for(int i=1;it!=a.end();i++,it++)
924 if(cm!=&((*it)->getCellModel()))
925 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
926 (*it)->getNumberOfCells();//to check that all is OK
927 ncs[i]=(*it)->getNodalConnectivity();
928 if(coords!=(*it)->getCoords())
929 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : not lying on same coords !");
931 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
932 ret->setCoords(coords);
933 ret->_conn=DataArrayInt::Aggregate(ncs);
937 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
940 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : input array must be NON EMPTY !");
941 std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
942 int nbOfCells=(*it)->getNumberOfCells();
943 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
944 int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
946 for(;it!=a.end();it++)
948 if(cm!=&((*it)->getCellModel()))
949 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
950 nbOfCells+=(*it)->getNumberOfCells();
952 std::vector<const MEDCouplingPointSet *> aps(a.size());
953 std::copy(a.begin(),a.end(),aps.begin());
954 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
955 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
957 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New();
958 c->alloc(nbOfCells*nbNodesPerCell,1);
959 int *cPtr=c->getPointer();
961 for(it=a.begin();it!=a.end();it++)
963 int curConnLgth=(*it)->getNodalConnectivityLength();
964 const int *curC=(*it)->_conn->begin();
965 cPtr=std::transform(curC,curC+curConnLgth,cPtr,std::bind2nd(std::plus<int>(),offset));
966 offset+=(*it)->getNumberOfNodes();
969 ret->setNodalConnectivity(c);
973 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
975 int ncell=getNumberOfCells();
976 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
977 ret->setCoords(_coords);
978 std::size_t nbOfElemsRet=std::distance(begin,end);
979 const int *inConn=_conn->getConstPointer();
980 int sz=getNumberOfNodesPerCell();
981 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
982 int *connPtr=connRet->getPointer();
983 for(const int *work=begin;work!=end;work++,connPtr+=sz)
985 if(*work>=0 && *work<ncell)
986 std::copy(inConn+(work[0])*sz,inConn+(work[0]+1)*sz,connPtr);
989 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !";
990 throw INTERP_KERNEL::Exception(oss.str().c_str());
994 ret->copyTinyInfoFrom(this);
998 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
1000 int ncell=getNumberOfCells();
1001 int nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : ");
1002 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1003 ret->setCoords(_coords);
1004 const int *inConn=_conn->getConstPointer();
1005 int sz=getNumberOfNodesPerCell();
1006 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1007 int *connPtr=connRet->getPointer();
1009 for(int i=0;i<nbOfElemsRet;i++,connPtr+=sz,curId+=step)
1011 if(curId>=0 && curId<ncell)
1012 std::copy(inConn+curId*sz,inConn+(curId+1)*sz,connPtr);
1015 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : On pos #" << i << " input cell id =" << curId << " should be in [0," << ncell << ") !";
1016 throw INTERP_KERNEL::Exception(oss.str().c_str());
1020 ret->copyTinyInfoFrom(this);
1024 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception)
1026 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1027 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1;
1028 const DataArrayInt *nodalConn(_conn);
1031 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
1038 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
1039 ret->setCoords(coords);
1042 ret->setCoords(_coords);
1046 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol0() throw(INTERP_KERNEL::Exception)
1048 int nbOfCells=getNumberOfCells();
1049 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1050 return DataArrayInt::Range(0,nbOfCells,1);
1051 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1052 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1053 const int *c(_conn->begin());
1054 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1055 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1057 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[2];
1058 newConnPtr[3]=c[0]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1059 retPtr[0]=i; retPtr[1]=i;
1062 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1067 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol1() throw(INTERP_KERNEL::Exception)
1069 int nbOfCells=getNumberOfCells();
1070 if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1071 return DataArrayInt::Range(0,nbOfCells,1);
1072 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1073 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1074 const int *c(_conn->begin());
1075 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1076 for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1078 newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[3];
1079 newConnPtr[3]=c[1]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1080 retPtr[0]=i; retPtr[1]=i;
1083 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1088 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace5() throw(INTERP_KERNEL::Exception)
1090 int nbOfCells=getNumberOfCells();
1091 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1092 return DataArrayInt::Range(0,nbOfCells,1);
1093 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(5*4*nbOfCells,1);
1094 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(5*nbOfCells,1);
1095 const int *c(_conn->begin());
1096 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1097 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=20,retPtr+=5)
1099 for(int j=0;j<20;j++)
1100 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_5_WO[j]];
1101 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i;
1104 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1109 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace6() throw(INTERP_KERNEL::Exception)
1111 int nbOfCells=getNumberOfCells();
1112 if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1113 return DataArrayInt::Range(0,nbOfCells,1);
1114 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(6*4*nbOfCells,1);
1115 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(6*nbOfCells,1);
1116 const int *c(_conn->begin());
1117 int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1118 for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=24,retPtr+=6)
1120 for(int j=0;j<24;j++)
1121 newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_6_WO[j]];
1122 retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i; retPtr[5]=i;
1125 _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1130 void MEDCoupling1SGTUMesh::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1132 stream << "MEDCoupling1SGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
1133 stream << " Mesh dimension : " << getMeshDimension() << ".";
1135 { stream << " No coordinates set !"; return ; }
1136 if(!_coords->isAllocated())
1137 { stream << " Coordinates set but not allocated !"; return ; }
1138 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
1139 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
1140 if(!(const DataArrayInt *)_conn)
1141 { stream << std::endl << "Nodal connectivity NOT set !"; return ; }
1142 if(_conn->isAllocated())
1144 if(_conn->getNumberOfComponents()==1)
1145 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
1149 void MEDCoupling1SGTUMesh::checkFullyDefined() const throw(INTERP_KERNEL::Exception)
1151 if(!((const DataArrayInt *)_conn) || !((const DataArrayDouble *)_coords))
1152 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFullyDefined : part of this is not fully defined.");
1156 * First step of unserialization process.
1158 bool MEDCoupling1SGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
1160 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEmptyMesh : not implemented yet !");
1164 * Checks if \a this and \a other meshes are geometrically equivalent with high
1165 * probability, else an exception is thrown. The meshes are considered equivalent if
1166 * (1) meshes contain the same number of nodes and the same number of elements of the
1167 * same types (2) three cells of the two meshes (first, last and middle) are based
1168 * on coincident nodes (with a specified precision).
1169 * \param [in] other - the mesh to compare with.
1170 * \param [in] prec - the precision used to compare nodes of the two meshes.
1171 * \throw If the two meshes do not match.
1173 void MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception)
1175 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1176 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1178 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not not unstructured with single static geometric type !");
1179 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1183 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1184 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1185 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1186 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1187 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1188 if(c1->getHashCode()!=c2->getHashCode())
1189 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1192 MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
1195 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
1196 const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1198 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
1199 std::vector<const MEDCoupling1SGTUMesh *> ms(2);
1202 return Merge1SGTUMeshesOnSameCoords(ms);
1205 void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception)
1207 checkFullyDefined();
1208 int nbOfNodes=getNumberOfNodes();
1209 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
1210 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
1211 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
1212 const int *conn=_conn->begin();
1213 int nbOfCells=getNumberOfCells();
1214 int nbOfEltsInRevNodal=0;
1215 int nbOfNodesPerCell=getNumberOfNodesPerCell();
1216 for(int eltId=0;eltId<nbOfCells;eltId++)
1218 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1220 if(conn[0]>=0 && conn[0]<nbOfNodes)
1222 nbOfEltsInRevNodal++;
1223 revNodalIndxPtr[conn[0]+1]++;
1227 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
1228 throw INTERP_KERNEL::Exception(oss.str().c_str());
1232 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
1233 conn=_conn->begin();
1234 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
1235 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
1236 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
1237 for(int eltId=0;eltId<nbOfCells;eltId++)
1239 for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1241 *std::find_if(revNodalPtr+revNodalIndxPtr[*conn],revNodalPtr+revNodalIndxPtr[*conn+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
1247 * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null.
1249 void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn) throw(INTERP_KERNEL::Exception)
1252 nodalConn->incrRef();
1258 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
1260 DataArrayInt *MEDCoupling1SGTUMesh::getNodalConnectivity() const throw(INTERP_KERNEL::Exception)
1262 const DataArrayInt *ret(_conn);
1263 return const_cast<DataArrayInt *>(ret);
1267 * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted,
1268 * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter.
1269 * If a nodal connectivity previouly existed before the call of this method, it will be reset.
1271 * \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain.
1273 void MEDCoupling1SGTUMesh::allocateCells(int nbOfCells) throw(INTERP_KERNEL::Exception)
1276 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !");
1277 _conn=DataArrayInt::New();
1278 _conn->reserve(getNumberOfNodesPerCell()*nbOfCells);
1283 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
1285 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
1286 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
1287 * \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
1288 * attached to \a this.
1289 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
1291 void MEDCoupling1SGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) throw(INTERP_KERNEL::Exception)
1293 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
1294 int ref=getNumberOfNodesPerCell();
1297 DataArrayInt *c(_conn);
1299 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
1301 throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !");
1305 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this (";
1306 oss << ref << ") !";
1307 throw INTERP_KERNEL::Exception(oss.str().c_str());
1311 //== find static tony
1313 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
1315 if(type==INTERP_KERNEL::NORM_ERROR)
1316 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
1317 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
1320 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !";
1321 throw INTERP_KERNEL::Exception(oss.str().c_str());
1323 return new MEDCoupling1DGTUMesh(name,cm);
1326 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
1330 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
1334 const DataArrayInt *c(other._conn);
1339 _conn_indx=c->deepCpy();
1343 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const
1345 return new MEDCoupling1DGTUMesh(*this,recDeepCpy);
1348 void MEDCoupling1DGTUMesh::updateTime() const
1350 MEDCoupling1GTUMesh::updateTime();
1351 const DataArrayInt *c(_conn);
1359 std::size_t MEDCoupling1DGTUMesh::getHeapMemorySize() const
1362 const DataArrayInt *c(_conn);
1364 ret+=c->getHeapMemorySize();
1367 ret+=c->getHeapMemorySize();
1368 return MEDCoupling1GTUMesh::getHeapMemorySize()+ret;
1371 MEDCouplingMesh *MEDCoupling1DGTUMesh::deepCpy() const
1376 bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
1379 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !");
1380 std::ostringstream oss; oss.precision(15);
1381 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1384 reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !";
1387 if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
1389 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1394 reason="in connectivity of single dynamic geometric type exactly one among this and other is null !";
1397 if(!c1->isEqualIfNotWhy(*c2,reason))
1399 reason.insert(0,"Nodal connectivity DataArrayInt differs : ");
1402 c1=_conn_indx; c2=otherC->_conn_indx;
1407 reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !";
1410 if(!c1->isEqualIfNotWhy(*c2,reason))
1412 reason.insert(0,"Nodal connectivity index DataArrayInt differs : ");
1418 bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
1421 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
1422 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1425 if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
1427 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1432 if(!c1->isEqualWithoutConsideringStr(*c2))
1435 c1=_conn_indx; c2=otherC->_conn_indx;
1440 if(!c1->isEqualWithoutConsideringStr(*c2))
1446 * Checks if \a this and \a other meshes are geometrically equivalent with high
1447 * probability, else an exception is thrown. The meshes are considered equivalent if
1448 * (1) meshes contain the same number of nodes and the same number of elements of the
1449 * same types (2) three cells of the two meshes (first, last and middle) are based
1450 * on coincident nodes (with a specified precision).
1451 * \param [in] other - the mesh to compare with.
1452 * \param [in] prec - the precision used to compare nodes of the two meshes.
1453 * \throw If the two meshes do not match.
1455 void MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception)
1457 MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1458 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1460 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not not unstructured with single static geometric type !");
1461 const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1465 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1466 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1467 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1468 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1469 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1470 if(c1->getHashCode()!=c2->getHashCode())
1471 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1473 c1=_conn_indx; c2=otherC->_conn_indx;
1477 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !");
1478 if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1479 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !");
1480 if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1481 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !");
1482 if(c1->getHashCode()!=c2->getHashCode())
1483 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs");
1488 * If \a this pass this method, you are sure that connectivity arrays are not null, with exactly one component, no name, no component name, allocated.
1489 * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one.
1490 * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array.
1492 void MEDCoupling1DGTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
1494 MEDCouplingPointSet::checkCoherency();
1495 const DataArrayInt *c1(_conn);
1498 if(c1->getNumberOfComponents()!=1)
1499 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
1500 if(c1->getInfoOnComponent(0)!="")
1501 throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
1502 c1->checkAllocated();
1505 throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
1507 int sz2=_conn->getNumberOfTuples();
1511 if(c1->getNumberOfComponents()!=1)
1512 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
1513 c1->checkAllocated();
1514 if(c1->getNumberOfTuples()<1)
1515 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !");
1516 if(c1->getInfoOnComponent(0)!="")
1517 throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
1518 int f=c1->front(),ll=c1->back();
1521 std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !";
1522 throw INTERP_KERNEL::Exception(oss.str().c_str());
1526 std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !";
1527 throw INTERP_KERNEL::Exception(oss.str().c_str());
1531 std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !";
1532 throw INTERP_KERNEL::Exception(oss.str().c_str());
1536 throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !");
1537 int szOfC1Exp=_conn_indx->back();
1540 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::checkCoherency : The expected length of nodal connectivity array regarding index is " << szOfC1Exp << " but the actual size of it is " << c1->getNumberOfTuples() << " !";
1541 throw INTERP_KERNEL::Exception(oss.str().c_str());
1545 void MEDCoupling1DGTUMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
1548 const DataArrayInt *c1(_conn),*c2(_conn_indx);
1549 if(!c2->isMonotonic(true))
1550 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkCoherency1 : the nodal connectivity index is expected to be increasing monotinic !");
1552 int nbOfTuples=c1->getNumberOfTuples();
1553 int nbOfNodes=getNumberOfNodes();
1554 const int *w(c1->begin());
1555 for(int i=0;i<nbOfTuples;i++,w++)
1557 if(*w==-1) continue;
1558 if(*w<0 || *w>=nbOfNodes)
1560 std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !";
1561 throw INTERP_KERNEL::Exception(oss.str().c_str());
1566 void MEDCoupling1DGTUMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
1568 checkCoherency1(eps);
1571 int MEDCoupling1DGTUMesh::getNumberOfCells() const
1573 checkCoherency();//do not remove
1574 return _conn_indx->getNumberOfTuples()-1;
1578 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
1579 * For each cell in \b this the number of nodes constituting cell is computed.
1580 * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned.
1581 * So for pohyhedrons some nodes can be counted several times in the returned result.
1583 * \return a newly allocated array
1585 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
1588 _conn_indx->checkMonotonic(true);
1589 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
1590 return _conn_indx->deltaShiftIndex();
1592 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
1593 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1594 ret->alloc(nbOfCells,1);
1595 int *retPtr=ret->getPointer();
1596 const int *ci=_conn_indx->begin(),*c=_conn->begin();
1597 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
1598 *retPtr=ci[1]-ci[0]-std::count(c+ci[0],c+ci[1],-1);
1603 * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
1604 * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed.
1606 * \return a newly allocated array
1608 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception)
1611 _conn_indx->checkMonotonic(true);
1612 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG)
1613 return _conn_indx->deltaShiftIndex();
1614 if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG)
1616 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=_conn_indx->deltaShiftIndex();
1617 ret->applyDivideBy(2);
1621 int nbOfCells=_conn_indx->getNumberOfTuples()-1;
1622 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1623 ret->alloc(nbOfCells,1);
1624 int *retPtr=ret->getPointer();
1625 const int *ci=_conn_indx->begin(),*c=_conn->begin();
1626 for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
1627 *retPtr=std::count(c+ci[0],c+ci[1],-1)+1;
1631 void MEDCoupling1DGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
1633 int nbOfCells=getNumberOfCells();//performs checks
1634 if(cellId>=0 && cellId<nbOfCells)
1636 int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
1637 int nbOfNodes=stp-strt;
1639 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !");
1640 conn.resize(nbOfNodes);
1641 std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin());
1645 std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
1646 throw INTERP_KERNEL::Exception(oss.str().c_str());
1650 std::string MEDCoupling1DGTUMesh::simpleRepr() const
1652 static const char msg0[]="No coordinates specified !";
1653 std::ostringstream ret;
1654 ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
1655 ret << "Description of mesh : \"" << getDescription() << "\"\n";
1657 double tt=getTime(tmpp1,tmpp2);
1658 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
1659 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
1660 ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
1663 const int spaceDim=getSpaceDimension();
1664 ret << spaceDim << "\nInfo attached on space dimension : ";
1665 for(int i=0;i<spaceDim;i++)
1666 ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
1670 ret << msg0 << "\n";
1671 ret << "Number of nodes : ";
1673 ret << getNumberOfNodes() << "\n";
1675 ret << msg0 << "\n";
1676 ret << "Number of cells : ";
1678 try { checkCoherency(); } catch(INTERP_KERNEL::Exception& e)
1680 ret << "Nodal connectivity arrays are not set or badly set !\n";
1684 ret << getNumberOfCells() << "\n";
1685 ret << "Cell type : " << _cm->getRepr() << "\n";
1689 std::string MEDCoupling1DGTUMesh::advancedRepr() const
1691 std::ostringstream ret;
1692 ret << simpleRepr();
1693 ret << "\nCoordinates array : \n___________________\n\n";
1695 _coords->reprWithoutNameStream(ret);
1697 ret << "No array set !\n";
1698 ret << "\n\nNodal Connectivity : \n____________________\n\n";
1701 try { checkCoherency1(); } catch(INTERP_KERNEL::Exception& e)
1703 ret << "Nodal connectivity arrays are not set or badly set !\n";
1708 int nbOfCells=getNumberOfCells();
1709 const int *ci=_conn_indx->begin(),*c=_conn->begin();
1710 for(int i=0;i<nbOfCells;i++,ci++)
1712 ret << "Cell #" << i << " : ";
1713 std::copy(c+ci[0],c+ci[1],std::ostream_iterator<int>(ret," "));
1719 DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
1721 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1722 int spaceDim=getSpaceDimension();
1723 int nbOfCells=getNumberOfCells();//checkCoherency()
1724 int nbOfNodes=getNumberOfNodes();
1725 ret->alloc(nbOfCells,spaceDim);
1726 double *ptToFill=ret->getPointer();
1727 const double *coor=_coords->begin();
1728 const int *nodal=_conn->begin(),*nodali=_conn_indx->begin();
1730 if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
1732 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
1734 std::fill(ptToFill,ptToFill+spaceDim,0.);
1735 if(nodali[0]>=nodali[1])// >= to avoid division by 0.
1737 for(int j=nodali[0];j<nodali[1];j++,nodal++)
1739 if(*nodal>=0 && *nodal<nbOfNodes)
1740 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
1743 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
1744 throw INTERP_KERNEL::Exception(oss.str().c_str());
1746 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(nodali[1]-nodali[0])));
1751 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !";
1752 throw INTERP_KERNEL::Exception(oss.str().c_str());
1758 for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
1760 std::fill(ptToFill,ptToFill+spaceDim,0.);
1761 if(nodali[0]>=nodali[1])// >= to avoid division by 0.
1764 for(int j=nodali[0];j<nodali[1];j++,nodal++)
1766 if(*nodal==-1) continue;
1767 if(*nodal>=0 && *nodal<nbOfNodes)
1769 std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
1774 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !";
1775 throw INTERP_KERNEL::Exception(oss.str().c_str());
1779 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./nbOfNod));
1782 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !";
1783 throw INTERP_KERNEL::Exception(oss.str().c_str());
1788 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : at cell #" << i << " the nodal index array is invalid !";
1789 throw INTERP_KERNEL::Exception(oss.str().c_str());
1796 void MEDCoupling1DGTUMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
1798 int nbCells=getNumberOfCells();
1799 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
1800 o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
1802 o2n=o2n->checkAndPreparePermutation();
1804 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
1805 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o=o2n->invertArrayO2N2N2O(nbCells);
1806 const int *n2oPtr=n2o->begin();
1807 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
1808 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
1809 newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1);
1810 newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx);
1812 int *newC=newConn->getPointer(),*newCI=newConnI->getPointer();
1813 for(int i=0;i<nbCells;i++)
1815 int sz=conni[i+1]-conni[i];
1817 newCI[n2oPtr[i]]=sz;
1820 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !";
1821 throw INTERP_KERNEL::Exception(oss.str().c_str());
1824 newConnI->computeOffsets2(); newCI=newConnI->getPointer();
1826 for(int i=0;i<nbCells;i++,conni++)
1828 int sz=conni[1]-conni[0];
1830 std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]);
1835 MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
1837 if(other->getType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED)
1838 throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !");
1839 const MEDCoupling1DGTUMesh *otherC=static_cast<const MEDCoupling1DGTUMesh *>(other);
1840 return Merge1DGTUMeshes(this,otherC);
1843 MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
1845 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
1846 ret->setCoords(getCoords());
1847 const int *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin();
1848 int nbCells=getNumberOfCells();//checkCoherency
1849 int geoType=(int)getCellModelEnum();
1850 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1);
1851 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::New(); cI->alloc(nbCells+1);
1852 int *cPtr=c->getPointer(),*ciPtr=cI->getPointer();
1854 for(int i=0;i<nbCells;i++,ciPtr++)
1856 int sz=nodalConnI[i+1]-nodalConnI[i];
1860 cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr);
1861 ciPtr[1]=ciPtr[0]+sz+1;
1865 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !";
1866 throw INTERP_KERNEL::Exception(oss.str().c_str());
1869 ret->setConnectivity(c,cI,true);
1874 * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes
1876 DataArrayInt *MEDCoupling1DGTUMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
1878 int nbOfCells=getNumberOfCells();
1879 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1880 ret->alloc(nbOfCells,1);
1885 void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1887 stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
1888 stream << " Mesh dimension : " << getMeshDimension() << ".";
1890 { stream << " No coordinates set !"; return ; }
1891 if(!_coords->isAllocated())
1892 { stream << " Coordinates set but not allocated !"; return ; }
1893 stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
1894 stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
1896 try { checkCoherency(); } catch(INTERP_KERNEL::Exception& e)
1898 stream << std::endl << "Nodal connectivity NOT set properly !\n";
1902 stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
1905 void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception)
1908 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
1909 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1911 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !");
1912 setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex());
1915 MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
1918 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
1919 const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1921 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
1922 std::vector<const MEDCoupling1DGTUMesh *> ms(2);
1925 return Merge1DGTUMeshesOnSameCoords(ms);
1928 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
1931 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
1932 ret->setCoords(_coords);
1933 DataArrayInt *c=0,*ci=0;
1934 MEDCouplingUMesh::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci);
1935 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
1936 ret->setNodalConnectivity(c,ci);
1940 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
1943 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
1944 ret->setCoords(_coords);
1945 DataArrayInt *c=0,*ci=0;
1946 MEDCouplingUMesh::ExtractFromIndexedArrays2(start,end,step,_conn,_conn_indx,c,ci);
1947 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
1948 ret->setNodalConnectivity(c,ci);
1952 void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception)
1954 checkFullyDefined();
1955 int nbOfNodes=getNumberOfNodes();
1956 int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
1957 revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
1958 std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
1959 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
1960 int nbOfCells=getNumberOfCells();
1961 int nbOfEltsInRevNodal=0;
1962 for(int eltId=0;eltId<nbOfCells;eltId++)
1964 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
1965 if(nbOfNodesPerCell>=0)
1967 for(int j=0;j<nbOfNodesPerCell;j++)
1969 int nodeId=conn[conni[eltId]+j];
1970 if(nodeId==-1) continue;
1971 if(nodeId>=0 && nodeId<nbOfNodes)
1973 nbOfEltsInRevNodal++;
1974 revNodalIndxPtr[nodeId+1]++;
1978 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
1979 throw INTERP_KERNEL::Exception(oss.str().c_str());
1985 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << "nodal connectivity is invalid !";
1986 throw INTERP_KERNEL::Exception(oss.str().c_str());
1989 std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
1990 conn=_conn->begin();
1991 int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
1992 revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
1993 std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
1994 for(int eltId=0;eltId<nbOfCells;eltId++)
1996 int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
1997 for(int j=0;j<nbOfNodesPerCell;j++)
1999 int nodeId=conn[conni[eltId]+j];
2001 *std::find_if(revNodalPtr+revNodalIndxPtr[nodeId],revNodalPtr+revNodalIndxPtr[nodeId+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
2006 void MEDCoupling1DGTUMesh::checkFullyDefined() const throw(INTERP_KERNEL::Exception)
2008 if(!((const DataArrayInt *)_conn) || !((const DataArrayInt *)_conn_indx) || !((const DataArrayDouble *)_coords))
2009 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined.");
2012 bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
2014 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !");
2018 * Finds nodes not used in any cell and returns an array giving a new id to every node
2019 * by excluding the unused nodes, for which the array holds -1. The result array is
2020 * a mapping in "Old to New" mode.
2021 * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
2022 * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
2023 * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
2024 * if the node is unused or a new id else. The caller is to delete this
2025 * array using decrRef() as it is no more needed.
2026 * \throw If the coordinates array is not set.
2027 * \throw If the nodal connectivity of cells is not defined.
2028 * \throw If the nodal connectivity includes an invalid id.
2030 DataArrayInt *MEDCoupling1DGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception)
2033 int nbOfNodes=getNumberOfNodes();
2034 int nbOfCells=getNumberOfCells();//checkCoherency
2035 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2036 ret->alloc(nbOfNodes,1);
2037 int *traducer=ret->getPointer();
2038 std::fill(traducer,traducer+nbOfNodes,-1);
2039 const int *conn=_conn->begin(),*conni(_conn_indx->begin());
2040 for(int i=0;i<nbOfCells;i++,conni++)
2042 int nbNodesPerCell=conni[1]-conni[0];
2043 for(int j=0;j<nbNodesPerCell;j++)
2045 int nodeId=conn[conni[0]+j];
2046 if(nodeId==-1) continue;
2047 if(nodeId>=0 && nodeId<nbOfNodes)
2051 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << nodeId << " not in [0," << nbOfNodes << ") !";
2052 throw INTERP_KERNEL::Exception(oss.str().c_str());
2056 nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
2057 std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
2062 * Changes ids of nodes within the nodal connectivity arrays according to a permutation
2063 * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
2064 * This method is a generalization of shiftNodeNumbersInConn().
2065 * \warning This method performs no check of validity of new ids. **Use it with care !**
2066 * \param [in] newNodeNumbersO2N - a permutation array, of length \a
2067 * this->getNumberOfNodes(), in "Old to New" mode.
2068 * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
2069 * \throw If the nodal connectivity of cells is not defined.
2071 void MEDCoupling1DGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
2073 getNumberOfCells();//only to check that all is well defined.
2075 int nbElemsIn=getNumberOfNodes();
2076 int nbOfTuples=_conn->getNumberOfTuples();
2077 int *pt=_conn->getPointer();
2078 for(int i=0;i<nbOfTuples;i++,pt++)
2080 if(*pt==-1) continue;
2081 if(*pt>=0 && *pt<nbElemsIn)
2082 *pt=newNodeNumbersO2N[*pt];
2085 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
2086 throw INTERP_KERNEL::Exception(oss.str().c_str());
2089 _conn->declareAsNew();
2095 * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
2096 * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
2097 * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
2098 * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
2100 * \param [in] begin input start of array of node ids.
2101 * \param [in] end input end of array of node ids.
2102 * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
2103 * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
2105 void MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
2107 int nbOfCells=getNumberOfCells();
2108 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
2110 int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
2111 std::vector<bool> fastFinder(sz,false);
2112 for(const int *work=begin;work!=end;work++)
2113 if(*work>=0 && *work<sz)
2114 fastFinder[*work]=true;
2115 const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2116 for(int i=0;i<nbOfCells;i++,conni++)
2118 int ref=0,nbOfHit=0;
2119 int nbNodesPerCell=conni[1]-conni[0];
2120 if(nbNodesPerCell>=0)
2122 for(int j=0;j<nbNodesPerCell;j++)
2124 int nodeId=conn[conni[0]+j];
2128 if(fastFinder[nodeId])
2135 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !";
2136 throw INTERP_KERNEL::Exception(oss.str().c_str());
2138 if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
2139 cellIdsKept->pushBackSilent(i);
2141 cellIdsKeptArr=cellIdsKept.retn();
2144 void MEDCoupling1DGTUMesh::allocateCells(int nbOfCells) throw(INTERP_KERNEL::Exception)
2147 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !");
2148 _conn=DataArrayInt::New();
2149 _conn->reserve(nbOfCells*3);
2150 _conn_indx=DataArrayInt::New();
2151 _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0);
2156 * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
2158 * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
2159 * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
2160 * \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
2161 * attached to \a this.
2162 * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
2164 void MEDCoupling1DGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) throw(INTERP_KERNEL::Exception)
2166 int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
2167 DataArrayInt *c(_conn),*c2(_conn_indx);
2171 if(pos==c->getNumberOfTuples())
2173 c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
2174 c2->pushBackSilent(pos+sz);
2178 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !";
2179 throw INTERP_KERNEL::Exception(oss.str().c_str());
2183 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !");
2186 void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex) throw(INTERP_KERNEL::Exception)
2189 nodalConn->incrRef();
2192 nodalConnIndex->incrRef();
2193 _conn_indx=nodalConnIndex;
2198 * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
2200 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivity() const throw(INTERP_KERNEL::Exception)
2202 const DataArrayInt *ret(_conn);
2203 return const_cast<DataArrayInt *>(ret);
2207 * \return DataArrayInt * - the internal reference to the nodal connectivity index. The caller is not reponsible to deallocate it.
2209 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const throw(INTERP_KERNEL::Exception)
2211 const DataArrayInt *ret(_conn_indx);
2212 return const_cast<DataArrayInt *>(ret);
2216 * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here".
2217 * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity).
2218 * Geometrically the returned mesh is equal to \a this. So if \a this is already packed, the return value is a shallow copy of \a this.
2220 * Whatever the status of pack of \a this, the coordinates array of the returned newly created instance is the same than those in \a this.
2222 * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal
2223 * connectivity arrays are different (false)
2224 * \return a new object to be managed by the caller.
2226 * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked
2228 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const throw(INTERP_KERNEL::Exception)
2230 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2231 DataArrayInt *nc=0,*nci=0;
2232 isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci);
2233 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ncs(nc),ncis(nci);
2234 ret->_conn=ncs; ret->_conn_indx=ncis;
2235 ret->setCoords(getCoords());
2240 * This method allows to compute, if needed, the packed nodal connectivity pair.
2241 * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges convered by nodal connectivity index array.
2242 * It is typically the case when nodalConnIndx starts with an id greater than 0, and finishes with id less than number of tuples in \c this->_conn.
2244 * If \a this looks packed (the front of nodal connectivity index equal to 0 and back of connectivity index equal to number of tuple of nodal connectivity array)
2245 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
2247 * If nodal connectivity index points to a subpart of nodal connectivity index the packed pair of arrays will be computed (new objects) and returned and false
2250 * This method return 3 elements.
2251 * \param [out] nodalConn - a pointer that can be equal to \a this->_conn if true is returned (general case). Whatever the value of return parameter
2252 * this pointer can be seen as a new object, that is to managed by the caller.
2253 * \param [out] nodalConnIndx - a pointer that can be equal to \a this->_conn_indx if true is returned (general case). Whatever the value of return parameter
2254 * this pointer can be seen as a new object, that is to managed by the caller.
2255 * \return bool - an indication of the content of the 2 output parameters. If true, \a this looks packed (general case), if true, \a this is not packed then
2256 * output parameters are newly created objects.
2258 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
2260 bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const throw(INTERP_KERNEL::Exception)
2262 if(isPacked())//performs the checkCoherency
2264 const DataArrayInt *c0(_conn),*c1(_conn_indx);
2265 nodalConn=const_cast<DataArrayInt *>(c0); nodalConnIndx=const_cast<DataArrayInt *>(c1);
2266 nodalConn->incrRef(); nodalConnIndx->incrRef();
2269 int bg=_conn_indx->front(),end=_conn_indx->back();
2270 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nc(_conn->selectByTupleId2(bg,end,1));
2271 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nci(_conn_indx->deepCpy());
2272 nci->applyLin(1,-bg);
2273 nodalConn=nc.retn(); nodalConnIndx=nci.retn();
2278 * If \a this looks packed (the front of nodal connectivity index equal to 0 and back of connectivity index equal to number of tuple of nodal connectivity array)
2279 * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
2280 * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned.
2281 * \return bool - true if \a this looks packed, false is not.
2283 * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
2285 bool MEDCoupling1DGTUMesh::isPacked() const throw(INTERP_KERNEL::Exception)
2288 return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples();
2291 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2) throw(INTERP_KERNEL::Exception)
2293 std::vector<const MEDCoupling1DGTUMesh *> tmp(2);
2294 tmp[0]=const_cast<MEDCoupling1DGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1DGTUMesh *>(mesh2);
2295 return Merge1DGTUMeshes(tmp);
2298 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
2300 std::size_t sz=a.size();
2302 return Merge1DGTUMeshesLL(a);
2303 for(std::size_t ii=0;ii<sz;ii++)
2306 std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::Merge1DGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
2307 throw INTERP_KERNEL::Exception(oss.str().c_str());
2309 const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
2310 for(std::size_t ii=0;ii<sz;ii++)
2311 if(&(a[ii]->getCellModel())!=cm)
2312 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !");
2313 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > bb(sz);
2314 std::vector< const MEDCoupling1DGTUMesh * > aa(sz);
2316 for(std::size_t i=0;i<sz && spaceDim==-3;i++)
2318 const MEDCoupling1DGTUMesh *cur=a[i];
2319 const DataArrayDouble *coo=cur->getCoords();
2321 spaceDim=coo->getNumberOfComponents();
2324 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !");
2325 for(std::size_t i=0;i<sz;i++)
2327 bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
2330 return Merge1DGTUMeshesLL(aa);
2333 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
2336 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !");
2337 std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
2339 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !");
2340 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
2341 std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
2342 int nbOfCells=(*it)->getNumberOfCells();
2343 const DataArrayDouble *coords=(*it)->getCoords();
2344 const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
2346 objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
2347 ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
2349 for(int i=1;it!=a.end();i++,it++)
2351 if(cm!=&((*it)->getCellModel()))
2352 throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
2353 (*it)->getNumberOfCells();//to check that all is OK
2354 objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
2355 ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
2356 if(coords!=(*it)->getCoords())
2357 throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !");
2359 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
2360 ret->setCoords(coords);
2361 ret->_conn=DataArrayInt::Aggregate(ncs);
2362 ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
2366 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
2371 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception)
2373 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2374 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1,tmp2;
2375 const DataArrayInt *nodalConn(_conn),*nodalConnI(_conn_indx);
2378 tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
2386 tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
2390 ret->_conn_indx=tmp2;
2394 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
2395 ret->setCoords(coords);
2398 ret->setCoords(_coords);