1 // Copyright (C) 2007-2012 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 "MEDCouplingExtrudedMesh.hxx"
22 #include "MEDCouplingUMesh.hxx"
23 #include "MEDCouplingMemArray.hxx"
24 #include "MEDCouplingFieldDouble.hxx"
25 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
26 #include "CellModel.hxx"
28 #include "InterpolationUtils.hxx"
39 using namespace ParaMEDMEM;
42 * Build an extruded mesh instance from 3D and 2D unstructured mesh lying on the \b same \b coords.
43 * @param mesh3D 3D unstructured mesh.
44 * @param mesh2D 2D unstructured mesh lying on the same coordinates than mesh3D. \b Warning mesh2D is \b not \b const
45 * because the mesh is aggregated and potentially modified by rotate or translate method.
46 * @param cell2DId Id of cell in mesh2D mesh where the computation of 1D mesh will be done.
48 MEDCouplingExtrudedMesh *MEDCouplingExtrudedMesh::New(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId) throw(INTERP_KERNEL::Exception)
50 return new MEDCouplingExtrudedMesh(mesh3D,mesh2D,cell2DId);
54 * This constructor is here only for unserialisation process.
55 * This constructor is normally completely useless for end user.
57 MEDCouplingExtrudedMesh *MEDCouplingExtrudedMesh::New()
59 return new MEDCouplingExtrudedMesh;
62 MEDCouplingMeshType MEDCouplingExtrudedMesh::getType() const
67 std::size_t MEDCouplingExtrudedMesh::getHeapMemorySize() const
71 ret+=_mesh2D->getHeapMemorySize();
73 ret+=_mesh1D->getHeapMemorySize();
75 ret+=_mesh3D_ids->getHeapMemorySize();
76 return MEDCouplingMesh::getHeapMemorySize()+ret;
80 * This method copyies all tiny strings from other (name and components name).
81 * @throw if other and this have not same mesh type.
83 void MEDCouplingExtrudedMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception)
85 const MEDCouplingExtrudedMesh *otherC=dynamic_cast<const MEDCouplingExtrudedMesh *>(other);
87 throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::copyTinyStringsFrom : meshes have not same type !");
88 MEDCouplingMesh::copyTinyStringsFrom(other);
89 _mesh2D->copyTinyStringsFrom(otherC->_mesh2D);
90 _mesh1D->copyTinyStringsFrom(otherC->_mesh1D);
93 MEDCouplingExtrudedMesh::MEDCouplingExtrudedMesh(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId) throw(INTERP_KERNEL::Exception)
94 try:_mesh2D(const_cast<MEDCouplingUMesh *>(mesh2D)),_mesh1D(MEDCouplingUMesh::New()),_mesh3D_ids(0),_cell_2D_id(cell2DId)
98 computeExtrusion(mesh3D);
99 setName(mesh3D->getName());
101 catch(INTERP_KERNEL::Exception& e)
108 _mesh3D_ids->decrRef();
112 MEDCouplingExtrudedMesh::MEDCouplingExtrudedMesh():_mesh2D(0),_mesh1D(0),_mesh3D_ids(0),_cell_2D_id(-1)
116 MEDCouplingExtrudedMesh::MEDCouplingExtrudedMesh(const MEDCouplingExtrudedMesh& other, bool deepCopy):MEDCouplingMesh(other),_cell_2D_id(other._cell_2D_id)
120 _mesh2D=other._mesh2D->clone(true);
121 _mesh1D=other._mesh1D->clone(true);
122 _mesh3D_ids=other._mesh3D_ids->deepCpy();
126 _mesh2D=other._mesh2D;
129 _mesh1D=other._mesh1D;
132 _mesh3D_ids=other._mesh3D_ids;
134 _mesh3D_ids->incrRef();
138 int MEDCouplingExtrudedMesh::getNumberOfCells() const
140 return _mesh2D->getNumberOfCells()*_mesh1D->getNumberOfCells();
143 int MEDCouplingExtrudedMesh::getNumberOfNodes() const
145 return _mesh2D->getNumberOfNodes();
148 int MEDCouplingExtrudedMesh::getSpaceDimension() const
153 int MEDCouplingExtrudedMesh::getMeshDimension() const
158 MEDCouplingMesh *MEDCouplingExtrudedMesh::deepCpy() const
163 MEDCouplingExtrudedMesh *MEDCouplingExtrudedMesh::clone(bool recDeepCpy) const
165 return new MEDCouplingExtrudedMesh(*this,recDeepCpy);
168 bool MEDCouplingExtrudedMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
171 throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::isEqualIfNotWhy : input other pointer is null !");
172 const MEDCouplingExtrudedMesh *otherC=dynamic_cast<const MEDCouplingExtrudedMesh *>(other);
173 std::ostringstream oss;
176 reason="mesh given in input is not castable in MEDCouplingExtrudedMesh !";
179 if(!MEDCouplingMesh::isEqualIfNotWhy(other,prec,reason))
181 if(!_mesh2D->isEqualIfNotWhy(otherC->_mesh2D,prec,reason))
183 reason.insert(0,"Mesh2D unstructured meshes differ : ");
186 if(!_mesh1D->isEqualIfNotWhy(otherC->_mesh1D,prec,reason))
188 reason.insert(0,"Mesh1D unstructured meshes differ : ");
191 if(!_mesh3D_ids->isEqualIfNotWhy(*otherC->_mesh3D_ids,reason))
193 reason.insert(0,"Mesh3D ids DataArrayInt instances differ : ");
196 if(_cell_2D_id!=otherC->_cell_2D_id)
198 oss << "Cell 2D id of the two extruded mesh differ : this = " << _cell_2D_id << " other = " << otherC->_cell_2D_id;
205 bool MEDCouplingExtrudedMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
207 const MEDCouplingExtrudedMesh *otherC=dynamic_cast<const MEDCouplingExtrudedMesh *>(other);
210 if(!_mesh2D->isEqualWithoutConsideringStr(otherC->_mesh2D,prec))
212 if(!_mesh1D->isEqualWithoutConsideringStr(otherC->_mesh1D,prec))
214 if(!_mesh3D_ids->isEqualWithoutConsideringStr(*otherC->_mesh3D_ids))
216 if(_cell_2D_id!=otherC->_cell_2D_id)
221 void MEDCouplingExtrudedMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
222 DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception)
224 throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::checkDeepEquivalWith : not implemented yet !");
227 void MEDCouplingExtrudedMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
228 DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception)
230 throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::checkDeepEquivalOnSameNodesWith : not implemented yet !");
233 INTERP_KERNEL::NormalizedCellType MEDCouplingExtrudedMesh::getTypeOfCell(int cellId) const
235 const int *ids=_mesh3D_ids->getConstPointer();
236 int nbOf3DCells=_mesh3D_ids->getNumberOfTuples();
237 const int *where=std::find(ids,ids+nbOf3DCells,cellId);
238 if(where==ids+nbOf3DCells)
239 throw INTERP_KERNEL::Exception("Invalid cellId specified >= getNumberOfCells() !");
240 int nbOfCells2D=_mesh2D->getNumberOfCells();
241 int locId=((int)std::distance(ids,where))%nbOfCells2D;
242 INTERP_KERNEL::NormalizedCellType tmp=_mesh2D->getTypeOfCell(locId);
243 return INTERP_KERNEL::CellModel::GetCellModel(tmp).getExtrudedType();
246 std::set<INTERP_KERNEL::NormalizedCellType> MEDCouplingExtrudedMesh::getAllGeoTypes() const
248 const std::set<INTERP_KERNEL::NormalizedCellType>& ret2D=_mesh2D->getAllTypes();
249 std::set<INTERP_KERNEL::NormalizedCellType> ret;
250 for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator it=ret2D.begin();it!=ret2D.end();it++)
251 ret.insert(INTERP_KERNEL::CellModel::GetCellModel(*it).getExtrudedType());
255 int MEDCouplingExtrudedMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
258 int nbOfCells2D=_mesh2D->getNumberOfCells();
259 for(int i=0;i<nbOfCells2D;i++)
261 INTERP_KERNEL::NormalizedCellType t=_mesh2D->getTypeOfCell(i);
262 if(INTERP_KERNEL::CellModel::GetCellModel(t).getExtrudedType()==type)
265 return ret*_mesh1D->getNumberOfCells();
268 void MEDCouplingExtrudedMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
270 int nbOfCells2D=_mesh2D->getNumberOfCells();
271 int nbOfNodes2D=_mesh2D->getNumberOfNodes();
272 int locId=cellId%nbOfCells2D;
273 int lev=cellId/nbOfCells2D;
274 std::vector<int> tmp,tmp2;
275 _mesh2D->getNodeIdsOfCell(locId,tmp);
277 std::transform(tmp.begin(),tmp.end(),tmp.begin(),std::bind2nd(std::plus<int>(),nbOfNodes2D*lev));
278 std::transform(tmp2.begin(),tmp2.end(),tmp2.begin(),std::bind2nd(std::plus<int>(),nbOfNodes2D*(lev+1)));
279 conn.insert(conn.end(),tmp.begin(),tmp.end());
280 conn.insert(conn.end(),tmp2.begin(),tmp2.end());
283 void MEDCouplingExtrudedMesh::getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const throw(INTERP_KERNEL::Exception)
285 int nbOfNodes2D=_mesh2D->getNumberOfNodes();
286 int locId=nodeId%nbOfNodes2D;
287 int lev=nodeId/nbOfNodes2D;
288 std::vector<double> tmp,tmp2;
289 _mesh2D->getCoordinatesOfNode(locId,tmp);
291 int spaceDim=_mesh1D->getSpaceDimension();
292 const double *z=_mesh1D->getCoords()->getConstPointer();
293 std::transform(tmp.begin(),tmp.end(),z+lev*spaceDim,tmp.begin(),std::plus<double>());
294 std::transform(tmp2.begin(),tmp2.end(),z+(lev+1)*spaceDim,tmp2.begin(),std::plus<double>());
295 coo.insert(coo.end(),tmp.begin(),tmp.end());
296 coo.insert(coo.end(),tmp2.begin(),tmp2.end());
299 std::string MEDCouplingExtrudedMesh::simpleRepr() const
301 std::ostringstream ret;
302 ret << "3D Extruded mesh from a 2D Surf Mesh with name : \"" << getName() << "\"\n";
303 ret << "Description of mesh : \"" << getDescription() << "\"\n";
305 double tt=getTime(tmpp1,tmpp2);
306 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
307 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
308 ret << "Cell id where 1D mesh has been deduced : " << _cell_2D_id << "\n";
309 ret << "Number of cells : " << getNumberOfCells() << "(" << _mesh2D->getNumberOfCells() << "x" << _mesh1D->getNumberOfCells() << ")\n";
310 ret << "1D Mesh info : _____________________\n\n\n";
311 ret << _mesh1D->simpleRepr();
312 ret << "\n\n\n2D Mesh info : _____________________\n\n\n" << _mesh2D->simpleRepr() << "\n\n\n";
316 std::string MEDCouplingExtrudedMesh::advancedRepr() const
318 std::ostringstream ret;
319 ret << "3D Extruded mesh from a 2D Surf Mesh with name : \"" << getName() << "\"\n";
320 ret << "Description of mesh : \"" << getDescription() << "\"\n";
322 double tt=getTime(tmpp1,tmpp2);
323 ret << "Time attached to the mesh (unit) : " << tt << " (" << getTimeUnit() << ")\n";
324 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
325 ret << "Cell id where 1D mesh has been deduced : " << _cell_2D_id << "\n";
326 ret << "Number of cells : " << getNumberOfCells() << "(" << _mesh2D->getNumberOfCells() << "x" << _mesh1D->getNumberOfCells() << ")\n";
327 ret << "1D Mesh info : _____________________\n\n\n";
328 ret << _mesh1D->advancedRepr();
329 ret << "\n\n\n2D Mesh info : _____________________\n\n\n" << _mesh2D->advancedRepr() << "\n\n\n";
330 ret << "3D cell ids per level :\n";
334 void MEDCouplingExtrudedMesh::checkCoherency() const throw (INTERP_KERNEL::Exception)
338 void MEDCouplingExtrudedMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
343 void MEDCouplingExtrudedMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
345 checkCoherency1(eps);
348 void MEDCouplingExtrudedMesh::getBoundingBox(double *bbox) const
351 _mesh2D->getBoundingBox(bbox2D);
352 const double *nodes1D=_mesh1D->getCoords()->getConstPointer();
353 int nbOfNodes1D=_mesh1D->getNumberOfNodes();
354 double bbox1DMin[3],bbox1DMax[3],tmp[3];
355 std::fill(bbox1DMin,bbox1DMin+3,std::numeric_limits<double>::max());
356 std::fill(bbox1DMax,bbox1DMax+3,-(std::numeric_limits<double>::max()));
357 for(int i=0;i<nbOfNodes1D;i++)
359 std::transform(nodes1D+3*i,nodes1D+3*(i+1),bbox1DMin,bbox1DMin,static_cast<const double& (*)(const double&, const double&)>(std::min<double>));
360 std::transform(nodes1D+3*i,nodes1D+3*(i+1),bbox1DMax,bbox1DMax,static_cast<const double& (*)(const double&, const double&)>(std::max<double>));
362 std::transform(bbox1DMax,bbox1DMax+3,bbox1DMin,tmp,std::minus<double>());
363 int id=(int)std::distance(tmp,std::max_element(tmp,tmp+3));
364 bbox[0]=bbox1DMin[0]; bbox[1]=bbox1DMax[0];
365 bbox[2]=bbox1DMin[1]; bbox[3]=bbox1DMax[1];
366 bbox[4]=bbox1DMin[2]; bbox[5]=bbox1DMax[2];
367 bbox[2*id+1]+=tmp[id];
370 void MEDCouplingExtrudedMesh::updateTime() const
374 updateTimeWith(*_mesh2D);
378 updateTimeWith(*_mesh1D);
382 void MEDCouplingExtrudedMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
384 throw INTERP_KERNEL::Exception("Functionnality of renumbering cells unavailable for ExtrudedMesh");
387 MEDCouplingUMesh *MEDCouplingExtrudedMesh::build3DUnstructuredMesh() const
389 MEDCouplingUMesh *ret=_mesh2D->buildExtrudedMesh(_mesh1D,0);
390 const int *renum=_mesh3D_ids->getConstPointer();
391 ret->renumberCells(renum,false);
392 ret->setName(getName());
396 MEDCouplingUMesh *MEDCouplingExtrudedMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
398 return build3DUnstructuredMesh();
401 MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::getMeasureField(bool) const
403 std::string name="MeasureOfMesh_";
405 MEDCouplingFieldDouble *ret2D=_mesh2D->getMeasureField(true);
406 MEDCouplingFieldDouble *ret1D=_mesh1D->getMeasureField(true);
407 const double *ret2DPtr=ret2D->getArray()->getConstPointer();
408 const double *ret1DPtr=ret1D->getArray()->getConstPointer();
409 int nbOf2DCells=_mesh2D->getNumberOfCells();
410 int nbOf1DCells=_mesh1D->getNumberOfCells();
411 int nbOf3DCells=nbOf2DCells*nbOf1DCells;
412 const int *renum=_mesh3D_ids->getConstPointer();
413 MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
415 ret->synchronizeTimeWithMesh();
416 DataArrayDouble *da=DataArrayDouble::New();
417 da->alloc(nbOf3DCells,1);
418 double *retPtr=da->getPointer();
419 for(int i=0;i<nbOf1DCells;i++)
420 for(int j=0;j<nbOf2DCells;j++)
421 retPtr[renum[i*nbOf2DCells+j]]=ret2DPtr[j]*ret1DPtr[i];
424 ret->setName(name.c_str());
430 MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::getMeasureFieldOnNode(bool isAbs) const
432 //not implemented yet
436 MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::buildOrthogonalField() const
438 throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::buildOrthogonalField : This method has no sense for MEDCouplingExtrudedMesh that is 3D !");
441 int MEDCouplingExtrudedMesh::getCellContainingPoint(const double *pos, double eps) const
443 throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::getCellContainingPoint : not implemented yet !");
446 MEDCouplingExtrudedMesh::~MEDCouplingExtrudedMesh()
453 _mesh3D_ids->decrRef();
456 void MEDCouplingExtrudedMesh::computeExtrusion(const MEDCouplingUMesh *mesh3D) throw(INTERP_KERNEL::Exception)
458 const char errMsg1[]="2D mesh is empty unable to compute extrusion !";
459 const char errMsg2[]="Coords between 2D and 3D meshes are not the same ! Try MEDCouplingPointSet::tryToShareSameCoords method";
460 const char errMsg3[]="No chance to find extrusion pattern in mesh3D,mesh2D couple because nbCells3D%nbCells2D!=0 !";
461 if(_mesh2D==0 || mesh3D==0)
462 throw INTERP_KERNEL::Exception(errMsg1);
463 if(_mesh2D->getCoords()!=mesh3D->getCoords())
464 throw INTERP_KERNEL::Exception(errMsg2);
465 if(mesh3D->getNumberOfCells()%_mesh2D->getNumberOfCells()!=0)
466 throw INTERP_KERNEL::Exception(errMsg3);
468 _mesh3D_ids=DataArrayInt::New();
470 _mesh1D=MEDCouplingUMesh::New();
471 computeExtrusionAlg(mesh3D);
474 void MEDCouplingExtrudedMesh::build1DExtrusion(int idIn3DDesc, int newId, int nbOf1DLev, MEDCouplingUMesh *subMesh,
475 const int *desc3D, const int *descIndx3D,
476 const int *revDesc3D, const int *revDescIndx3D,
477 bool computeMesh1D) throw(INTERP_KERNEL::Exception)
479 int nbOf2DCells=_mesh2D->getNumberOfCells();
480 int start=revDescIndx3D[idIn3DDesc];
481 int end=revDescIndx3D[idIn3DDesc+1];
484 std::ostringstream ost; ost << "Invalid bases 2D mesh specified : 2D cell # " << idIn3DDesc;
485 ost << " shared by more than 1 3D cell !!!";
486 throw INTERP_KERNEL::Exception(ost.str().c_str());
488 int current3DCell=revDesc3D[start];
489 int current2DCell=idIn3DDesc;
490 int *mesh3DIDs=_mesh3D_ids->getPointer();
491 mesh3DIDs[newId]=current3DCell;
492 const int *conn2D=subMesh->getNodalConnectivity()->getConstPointer();
493 const int *conn2DIndx=subMesh->getNodalConnectivityIndex()->getConstPointer();
494 for(int i=1;i<nbOf1DLev;i++)
496 std::vector<int> conn(conn2D+conn2DIndx[current2DCell]+1,conn2D+conn2DIndx[current2DCell+1]);
497 std::sort(conn.begin(),conn.end());
499 computeBaryCenterOfFace(conn,i-1);
500 current2DCell=findOppositeFaceOf(current2DCell,current3DCell,conn,
501 desc3D,descIndx3D,conn2D,conn2DIndx);
502 start=revDescIndx3D[current2DCell];
503 end=revDescIndx3D[current2DCell+1];
506 std::ostringstream ost; ost << "Expecting to have 2 3D cells attached to 2D cell " << current2DCell << "!";
507 ost << " : Impossible or call tryToShareSameCoords method !";
508 throw INTERP_KERNEL::Exception(ost.str().c_str());
510 if(revDesc3D[start]!=current3DCell)
511 current3DCell=revDesc3D[start];
513 current3DCell=revDesc3D[start+1];
514 mesh3DIDs[i*nbOf2DCells+newId]=current3DCell;
518 std::vector<int> conn(conn2D+conn2DIndx[current2DCell]+1,conn2D+conn2DIndx[current2DCell+1]);
519 std::sort(conn.begin(),conn.end());
520 computeBaryCenterOfFace(conn,nbOf1DLev-1);
521 current2DCell=findOppositeFaceOf(current2DCell,current3DCell,conn,
522 desc3D,descIndx3D,conn2D,conn2DIndx);
524 conn.insert(conn.end(),conn2D+conn2DIndx[current2DCell]+1,conn2D+conn2DIndx[current2DCell+1]);
525 std::sort(conn.begin(),conn.end());
526 computeBaryCenterOfFace(conn,nbOf1DLev);
530 int MEDCouplingExtrudedMesh::findOppositeFaceOf(int current2DCell, int current3DCell, const std::vector<int>& connSorted,
531 const int *desc3D, const int *descIndx3D,
532 const int *conn2D, const int *conn2DIndx) throw(INTERP_KERNEL::Exception)
534 int start=descIndx3D[current3DCell];
535 int end=descIndx3D[current3DCell+1];
537 for(const int *candidate2D=desc3D+start;candidate2D!=desc3D+end && !found;candidate2D++)
539 if(*candidate2D!=current2DCell)
541 std::vector<int> conn2(conn2D+conn2DIndx[*candidate2D]+1,conn2D+conn2DIndx[*candidate2D+1]);
542 std::sort(conn2.begin(),conn2.end());
543 std::list<int> intersect;
544 std::set_intersection(connSorted.begin(),connSorted.end(),conn2.begin(),conn2.end(),
545 std::insert_iterator< std::list<int> >(intersect,intersect.begin()));
546 if(intersect.empty())
550 std::ostringstream ost; ost << "Impossible to find an opposite 2D face of face # " << current2DCell;
551 ost << " in 3D cell # " << current3DCell << " : Impossible or call tryToShareSameCoords method !";
552 throw INTERP_KERNEL::Exception(ost.str().c_str());
555 void MEDCouplingExtrudedMesh::computeBaryCenterOfFace(const std::vector<int>& nodalConnec, int lev1DId)
557 double *zoneToUpdate=_mesh1D->getCoords()->getPointer()+lev1DId*3;
558 std::fill(zoneToUpdate,zoneToUpdate+3,0.);
559 const double *coords=_mesh2D->getCoords()->getConstPointer();
560 for(std::vector<int>::const_iterator iter=nodalConnec.begin();iter!=nodalConnec.end();iter++)
561 std::transform(zoneToUpdate,zoneToUpdate+3,coords+3*(*iter),zoneToUpdate,std::plus<double>());
562 std::transform(zoneToUpdate,zoneToUpdate+3,zoneToUpdate,std::bind2nd(std::multiplies<double>(),(double)(1./(int)nodalConnec.size())));
565 int MEDCouplingExtrudedMesh::FindCorrespCellByNodalConn(const std::vector<int>& nodalConnec, const int *revNodalPtr, const int *revNodalIndxPtr) throw(INTERP_KERNEL::Exception)
567 std::vector<int>::const_iterator iter=nodalConnec.begin();
568 std::set<int> s1(revNodalPtr+revNodalIndxPtr[*iter],revNodalPtr+revNodalIndxPtr[*iter+1]);
570 for(;iter!=nodalConnec.end();iter++)
572 std::set<int> s2(revNodalPtr+revNodalIndxPtr[*iter],revNodalPtr+revNodalIndxPtr[*iter+1]);
574 std::set_intersection(s1.begin(),s1.end(),s2.begin(),s2.end(),std::insert_iterator< std::set<int> >(s3,s3.end()));
578 return *(s1.begin());
579 std::ostringstream ostr;
580 ostr << "Cell with nodal connec : ";
581 std::copy(nodalConnec.begin(),nodalConnec.end(),std::ostream_iterator<int>(ostr," "));
582 ostr << " is not part of mesh";
583 throw INTERP_KERNEL::Exception(ostr.str().c_str());
587 * This method is callable on 1Dmeshes (meshDim==1 && spaceDim==3) returned by MEDCouplingExtrudedMesh::getMesh1D typically.
588 * These 1Dmeshes (meshDim==1 && spaceDim==3) have a special semantic because these meshes do not specify a static location but a translation along a path.
589 * This method checks that 'm1' and 'm2' are compatible, if not an exception is thrown. In case these meshes ('m1' and 'm2') are compatible 2 corresponding meshes
590 * are created ('m1r' and 'm2r') that can be used for interpolation.
591 * @param m1 input mesh with meshDim==1 and spaceDim==3
592 * @param m2 input mesh with meshDim==1 and spaceDim==3
593 * @param eps tolerance acceptable to determine compatibility
594 * @param m1r output mesh with ref count equal to 1 with meshDim==1 and spaceDim==1
595 * @param m2r output mesh with ref count equal to 1 with meshDim==1 and spaceDim==1
596 * @param v is the output normalized vector of the common direction of 'm1' and 'm2'
597 * @throw in case that m1 and m2 are not compatible each other.
599 void MEDCouplingExtrudedMesh::Project1DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps,
600 MEDCouplingUMesh *&m1r, MEDCouplingUMesh *&m2r, double *v) throw(INTERP_KERNEL::Exception)
602 if(m1->getSpaceDimension()!=3 || m1->getSpaceDimension()!=3)
603 throw INTERP_KERNEL::Exception("Input meshes are expected to have a spaceDim==3 for Projec1D !");
606 m1r->changeSpaceDimension(1);
607 m2r->changeSpaceDimension(1);
609 std::vector<double> ref,ref2;
610 m1->getNodeIdsOfCell(0,c);
611 m1->getCoordinatesOfNode(c[0],ref);
612 m1->getCoordinatesOfNode(c[1],ref2);
613 std::transform(ref2.begin(),ref2.end(),ref.begin(),v,std::minus<double>());
614 double n=INTERP_KERNEL::norm<3>(v);
615 std::transform(v,v+3,v,std::bind2nd(std::multiplies<double>(),1/n));
616 m1->project1D(&ref[0],v,eps,m1r->getCoords()->getPointer());
617 m2->project1D(&ref[0],v,eps,m2r->getCoords()->getPointer());
621 void MEDCouplingExtrudedMesh::rotate(const double *center, const double *vector, double angle)
623 _mesh2D->rotate(center,vector,angle);
624 _mesh1D->rotate(center,vector,angle);
627 void MEDCouplingExtrudedMesh::translate(const double *vector)
629 _mesh2D->translate(vector);
630 _mesh1D->translate(vector);
633 void MEDCouplingExtrudedMesh::scale(const double *point, double factor)
635 _mesh2D->scale(point,factor);
636 _mesh1D->scale(point,factor);
639 std::vector<int> MEDCouplingExtrudedMesh::getDistributionOfTypes() const throw(INTERP_KERNEL::Exception)
641 throw INTERP_KERNEL::Exception("Not implemented yet !");
644 DataArrayInt *MEDCouplingExtrudedMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
646 throw INTERP_KERNEL::Exception("Not implemented yet !");
649 void MEDCouplingExtrudedMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
651 throw INTERP_KERNEL::Exception("Not implemented yet !");
654 MEDCouplingMesh *MEDCouplingExtrudedMesh::buildPart(const int *start, const int *end) const
656 // not implemented yet !
660 MEDCouplingMesh *MEDCouplingExtrudedMesh::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const
662 // not implemented yet !
666 DataArrayInt *MEDCouplingExtrudedMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
668 throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::simplexize : unavailable for such a type of mesh : Extruded !");
671 MEDCouplingMesh *MEDCouplingExtrudedMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
673 // not implemented yet !
677 DataArrayDouble *MEDCouplingExtrudedMesh::getCoordinatesAndOwner() const
679 DataArrayDouble *arr2D=_mesh2D->getCoords();
680 DataArrayDouble *arr1D=_mesh1D->getCoords();
681 DataArrayDouble *ret=DataArrayDouble::New();
682 ret->alloc(getNumberOfNodes(),3);
683 int nbOf1DLev=_mesh1D->getNumberOfNodes();
684 int nbOf2DNodes=_mesh2D->getNumberOfNodes();
685 const double *ptSrc=arr2D->getConstPointer();
686 double *pt=ret->getPointer();
687 std::copy(ptSrc,ptSrc+3*nbOf2DNodes,pt);
688 for(int i=1;i<nbOf1DLev;i++)
690 std::copy(ptSrc,ptSrc+3*nbOf2DNodes,pt+3*i*nbOf2DNodes);
692 std::copy(arr1D->getConstPointer()+3*i,arr1D->getConstPointer()+3*(i+1),vec);
693 std::transform(arr1D->getConstPointer()+3*(i-1),arr1D->getConstPointer()+3*i,vec,vec,std::minus<double>());
694 for(int j=0;j<nbOf2DNodes;j++)
695 std::transform(vec,vec+3,pt+3*(i*nbOf2DNodes+j),pt+3*(i*nbOf2DNodes+j),std::plus<double>());
700 DataArrayDouble *MEDCouplingExtrudedMesh::getBarycenterAndOwner() const
702 //not yet implemented
706 void MEDCouplingExtrudedMesh::computeExtrusionAlg(const MEDCouplingUMesh *mesh3D) throw(INTERP_KERNEL::Exception)
708 _mesh3D_ids->alloc(mesh3D->getNumberOfCells(),1);
709 int nbOf1DLev=mesh3D->getNumberOfCells()/_mesh2D->getNumberOfCells();
710 _mesh1D->setMeshDimension(1);
711 _mesh1D->allocateCells(nbOf1DLev);
713 for(int i=0;i<nbOf1DLev;i++)
717 _mesh1D->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,tmpConn);
719 _mesh1D->finishInsertingCells();
720 DataArrayDouble *myCoords=DataArrayDouble::New();
721 myCoords->alloc(nbOf1DLev+1,3);
722 _mesh1D->setCoords(myCoords);
724 DataArrayInt *desc,*descIndx,*revDesc,*revDescIndx;
725 desc=DataArrayInt::New(); descIndx=DataArrayInt::New(); revDesc=DataArrayInt::New(); revDescIndx=DataArrayInt::New();
726 MEDCouplingUMesh *subMesh=mesh3D->buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx);
727 DataArrayInt *revNodal2D,*revNodalIndx2D;
728 revNodal2D=DataArrayInt::New(); revNodalIndx2D=DataArrayInt::New();
729 subMesh->getReverseNodalConnectivity(revNodal2D,revNodalIndx2D);
730 const int *nodal2D=_mesh2D->getNodalConnectivity()->getConstPointer();
731 const int *nodal2DIndx=_mesh2D->getNodalConnectivityIndex()->getConstPointer();
732 const int *revNodal2DPtr=revNodal2D->getConstPointer();
733 const int *revNodalIndx2DPtr=revNodalIndx2D->getConstPointer();
734 const int *descP=desc->getConstPointer();
735 const int *descIndxP=descIndx->getConstPointer();
736 const int *revDescP=revDesc->getConstPointer();
737 const int *revDescIndxP=revDescIndx->getConstPointer();
739 int nbOf2DCells=_mesh2D->getNumberOfCells();
740 for(int i=0;i<nbOf2DCells;i++)
743 std::vector<int> nodalConnec(nodal2D+nodal2DIndx[i]+1,nodal2D+nodal2DIndx[i+1]);
746 idInSubMesh=FindCorrespCellByNodalConn(nodalConnec,revNodal2DPtr,revNodalIndx2DPtr);
748 catch(INTERP_KERNEL::Exception& e)
750 std::ostringstream ostr; ostr << "mesh2D cell # " << i << " is not part of any cell of 3D mesh !\n";
752 throw INTERP_KERNEL::Exception(ostr.str().c_str());
754 build1DExtrusion(idInSubMesh,i,nbOf1DLev,subMesh,descP,descIndxP,revDescP,revDescIndxP,i==_cell_2D_id);
757 revNodal2D->decrRef();
758 revNodalIndx2D->decrRef();
763 revDescIndx->decrRef();
766 void MEDCouplingExtrudedMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
768 std::vector<int> tinyInfo1;
769 std::vector<std::string> ls1;
770 std::vector<double> ls3;
771 _mesh2D->getTinySerializationInformation(ls3,tinyInfo1,ls1);
772 std::vector<int> tinyInfo2;
773 std::vector<std::string> ls2;
774 std::vector<double> ls4;
775 _mesh1D->getTinySerializationInformation(ls4,tinyInfo2,ls2);
776 tinyInfo.clear(); littleStrings.clear();
777 tinyInfo.insert(tinyInfo.end(),tinyInfo1.begin(),tinyInfo1.end());
778 littleStrings.insert(littleStrings.end(),ls1.begin(),ls1.end());
779 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
780 littleStrings.insert(littleStrings.end(),ls2.begin(),ls2.end());
781 tinyInfo.push_back(_cell_2D_id);
782 tinyInfo.push_back((int)tinyInfo1.size());
783 tinyInfo.push_back(_mesh3D_ids->getNbOfElems());
784 littleStrings.push_back(getName());
785 littleStrings.push_back(getDescription());
788 void MEDCouplingExtrudedMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
790 std::size_t sz=tinyInfo.size();
791 int sz1=tinyInfo[sz-2];
792 std::vector<int> ti1(tinyInfo.begin(),tinyInfo.begin()+sz1);
793 std::vector<int> ti2(tinyInfo.begin()+sz1,tinyInfo.end()-3);
794 MEDCouplingUMesh *um=MEDCouplingUMesh::New();
795 DataArrayInt *a1tmp=DataArrayInt::New();
796 DataArrayDouble *a2tmp=DataArrayDouble::New();
798 std::vector<std::string> ls1,ls2;
799 um->resizeForUnserialization(ti1,a1tmp,a2tmp,ls1);
800 la1+=a1tmp->getNbOfElems(); la2+=a2tmp->getNbOfElems();
801 a1tmp->decrRef(); a2tmp->decrRef();
802 a1tmp=DataArrayInt::New(); a2tmp=DataArrayDouble::New();
803 um->resizeForUnserialization(ti2,a1tmp,a2tmp,ls2);
804 la1+=a1tmp->getNbOfElems(); la2+=a2tmp->getNbOfElems();
805 a1tmp->decrRef(); a2tmp->decrRef();
808 a1->alloc(la1+tinyInfo[sz-1],1);
810 littleStrings.resize(ls1.size()+ls2.size()+2);
813 void MEDCouplingExtrudedMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
815 a1=DataArrayInt::New(); a2=DataArrayDouble::New();
816 DataArrayInt *a1_1=0,*a1_2=0;
817 DataArrayDouble *a2_1=0,*a2_2=0;
818 _mesh2D->serialize(a1_1,a2_1);
819 _mesh1D->serialize(a1_2,a2_2);
820 a1->alloc(a1_1->getNbOfElems()+a1_2->getNbOfElems()+_mesh3D_ids->getNbOfElems(),1);
821 int *ptri=a1->getPointer();
822 ptri=std::copy(a1_1->getConstPointer(),a1_1->getConstPointer()+a1_1->getNbOfElems(),ptri);
824 ptri=std::copy(a1_2->getConstPointer(),a1_2->getConstPointer()+a1_2->getNbOfElems(),ptri);
826 std::copy(_mesh3D_ids->getConstPointer(),_mesh3D_ids->getConstPointer()+_mesh3D_ids->getNbOfElems(),ptri);
827 a2->alloc(a2_1->getNbOfElems()+a2_2->getNbOfElems(),1);
828 double *ptrd=a2->getPointer();
829 ptrd=std::copy(a2_1->getConstPointer(),a2_1->getConstPointer()+a2_1->getNbOfElems(),ptrd);
831 std::copy(a2_2->getConstPointer(),a2_2->getConstPointer()+a2_2->getNbOfElems(),ptrd);
835 void MEDCouplingExtrudedMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector<std::string>& littleStrings)
837 setName(littleStrings[littleStrings.size()-2].c_str());
838 setDescription(littleStrings.back().c_str());
839 std::size_t sz=tinyInfo.size();
840 int sz1=tinyInfo[sz-2];
841 _cell_2D_id=tinyInfo[sz-3];
842 std::vector<int> ti1(tinyInfo.begin(),tinyInfo.begin()+sz1);
843 std::vector<int> ti2(tinyInfo.begin()+sz1,tinyInfo.end()-3);
844 DataArrayInt *a1tmp=DataArrayInt::New();
845 DataArrayDouble *a2tmp=DataArrayDouble::New();
846 const int *a1Ptr=a1->getConstPointer();
847 const double *a2Ptr=a2->getConstPointer();
848 _mesh2D=MEDCouplingUMesh::New();
849 std::vector<std::string> ls1,ls2;
850 _mesh2D->resizeForUnserialization(ti1,a1tmp,a2tmp,ls1);
851 std::copy(a2Ptr,a2Ptr+a2tmp->getNbOfElems(),a2tmp->getPointer());
852 std::copy(a1Ptr,a1Ptr+a1tmp->getNbOfElems(),a1tmp->getPointer());
853 a2Ptr+=a2tmp->getNbOfElems();
854 a1Ptr+=a1tmp->getNbOfElems();
855 ls2.insert(ls2.end(),littleStrings.begin(),littleStrings.begin()+ls1.size());
856 std::vector<double> d1(1);
857 _mesh2D->unserialization(d1,ti1,a1tmp,a2tmp,ls2);
858 a1tmp->decrRef(); a2tmp->decrRef();
861 ls2.insert(ls2.end(),littleStrings.begin()+ls1.size(),littleStrings.end()-2);
862 _mesh1D=MEDCouplingUMesh::New();
863 a1tmp=DataArrayInt::New(); a2tmp=DataArrayDouble::New();
864 _mesh1D->resizeForUnserialization(ti2,a1tmp,a2tmp,ls1);
865 std::copy(a2Ptr,a2Ptr+a2tmp->getNbOfElems(),a2tmp->getPointer());
866 std::copy(a1Ptr,a1Ptr+a1tmp->getNbOfElems(),a1tmp->getPointer());
867 a1Ptr+=a1tmp->getNbOfElems();
868 _mesh1D->unserialization(d1,ti2,a1tmp,a2tmp,ls2);
869 a1tmp->decrRef(); a2tmp->decrRef();
871 _mesh3D_ids=DataArrayInt::New();
872 int szIds=(int)std::distance(a1Ptr,a1->getConstPointer()+a1->getNbOfElems());
873 _mesh3D_ids->alloc(szIds,1);
874 std::copy(a1Ptr,a1Ptr+szIds,_mesh3D_ids->getPointer());
877 void MEDCouplingExtrudedMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception)
879 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
880 m->writeVTKLL(ofs,cellData,pointData);
883 std::string MEDCouplingExtrudedMesh::getVTKDataSetType() const throw(INTERP_KERNEL::Exception)
885 return _mesh2D->getVTKDataSetType();