1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (CEA/DEN)
21 #include "MEDCouplingMappedExtrudedMesh.hxx"
22 #include "MEDCouplingUMesh.hxx"
23 #include "MEDCouplingCMesh.hxx"
24 #include "MEDCouplingMemArray.hxx"
25 #include "MEDCouplingFieldDouble.hxx"
27 #include "CellModel.hxx"
29 #include "InterpolationUtils.hxx"
40 using namespace MEDCoupling;
43 * Build an extruded mesh instance from 3D and 2D unstructured mesh lying on the \b same \b coords.
44 * @param mesh3D 3D unstructured mesh.
45 * @param mesh2D 2D unstructured mesh lying on the same coordinates than mesh3D. \b Warning mesh2D is \b not \b const
46 * because the mesh is aggregated and potentially modified by rotate or translate method.
47 * @param cell2DId Id of cell in mesh2D mesh where the computation of 1D mesh will be done.
49 MEDCouplingMappedExtrudedMesh *MEDCouplingMappedExtrudedMesh::New(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId)
51 return new MEDCouplingMappedExtrudedMesh(mesh3D,mesh2D,cell2DId);
54 MEDCouplingMappedExtrudedMesh *MEDCouplingMappedExtrudedMesh::New(const MEDCouplingCMesh *mesh3D)
56 return new MEDCouplingMappedExtrudedMesh(mesh3D);
60 * This constructor is here only for unserialisation process.
61 * This constructor is normally completely useless for end user.
63 MEDCouplingMappedExtrudedMesh *MEDCouplingMappedExtrudedMesh::New()
65 return new MEDCouplingMappedExtrudedMesh;
68 MEDCouplingMeshType MEDCouplingMappedExtrudedMesh::getType() const
73 std::size_t MEDCouplingMappedExtrudedMesh::getHeapMemorySizeWithoutChildren() const
75 return MEDCouplingMesh::getHeapMemorySizeWithoutChildren();
78 std::vector<const BigMemoryObject *> MEDCouplingMappedExtrudedMesh::getDirectChildrenWithNull() const
80 std::vector<const BigMemoryObject *> ret;
81 ret.push_back(_mesh2D);
82 ret.push_back(_mesh1D);
83 ret.push_back(_mesh3D_ids);
88 * This method copyies all tiny strings from other (name and components name).
89 * @throw if other and this have not same mesh type.
91 void MEDCouplingMappedExtrudedMesh::copyTinyStringsFrom(const MEDCouplingMesh *other)
93 const MEDCouplingMappedExtrudedMesh *otherC=dynamic_cast<const MEDCouplingMappedExtrudedMesh *>(other);
95 throw INTERP_KERNEL::Exception("MEDCouplingMappedExtrudedMesh::copyTinyStringsFrom : meshes have not same type !");
96 MEDCouplingMesh::copyTinyStringsFrom(other);
97 _mesh2D->copyTinyStringsFrom(otherC->_mesh2D);
98 _mesh1D->copyTinyStringsFrom(otherC->_mesh1D);
101 MEDCouplingMappedExtrudedMesh::MEDCouplingMappedExtrudedMesh(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId)
102 try:_mesh2D(const_cast<MEDCouplingUMesh *>(mesh2D)),_mesh1D(MEDCouplingUMesh::New()),_mesh3D_ids(0),_cell_2D_id(cell2DId)
104 if(_mesh2D.isNotNull())
106 computeExtrusion(mesh3D);
107 setName(mesh3D->getName()); setDescription(mesh3D->getDescription());
109 catch(INTERP_KERNEL::Exception& e)
114 MEDCouplingMappedExtrudedMesh::MEDCouplingMappedExtrudedMesh(const MEDCouplingCMesh *mesh3D):_mesh1D(MEDCouplingUMesh::New()),_mesh3D_ids(0),_cell_2D_id(0)
117 throw INTERP_KERNEL::Exception("MEDCouplingMappedExtrudedMesh contrct : null input pointer !");
118 if(mesh3D->getMeshDimension()!=3)
119 throw INTERP_KERNEL::Exception("MEDCouplingMappedExtrudedMesh contrct : input cart mesh must have dimension equal to 3 !");
120 MCAuto<MEDCouplingUMesh> umesh3D(mesh3D->buildUnstructured());
121 MCAuto<MEDCouplingCMesh> cmesh2D(MEDCouplingCMesh::New()); cmesh2D->setName(mesh3D->getName());
122 cmesh2D->setCoords(mesh3D->getCoordsAt(0),mesh3D->getCoordsAt(1));
123 _mesh2D=cmesh2D->buildUnstructured();
124 _mesh2D->setCoords(umesh3D->getCoords());
125 computeExtrusion(umesh3D);
126 setName(mesh3D->getName()); setDescription(mesh3D->getDescription());
129 MEDCouplingMappedExtrudedMesh::MEDCouplingMappedExtrudedMesh():_mesh2D(0),_mesh1D(0),_mesh3D_ids(0),_cell_2D_id(-1)
133 MEDCouplingMappedExtrudedMesh::MEDCouplingMappedExtrudedMesh(const MEDCouplingMappedExtrudedMesh& other, bool deepCpy):MEDCouplingMesh(other),_cell_2D_id(other._cell_2D_id)
137 _mesh2D=other._mesh2D->clone(true);
138 _mesh1D=other._mesh1D->clone(true);
139 _mesh3D_ids=other._mesh3D_ids->deepCopy();
143 _mesh2D=other._mesh2D;
144 _mesh1D=other._mesh1D;
145 _mesh3D_ids=other._mesh3D_ids;
149 std::size_t MEDCouplingMappedExtrudedMesh::getNumberOfCells() const
151 return _mesh2D->getNumberOfCells()*_mesh1D->getNumberOfCells();
154 int MEDCouplingMappedExtrudedMesh::getNumberOfNodes() const
156 return _mesh2D->getNumberOfNodes();
159 int MEDCouplingMappedExtrudedMesh::getSpaceDimension() const
164 int MEDCouplingMappedExtrudedMesh::getMeshDimension() const
169 MEDCouplingMappedExtrudedMesh *MEDCouplingMappedExtrudedMesh::deepCopy() const
174 MEDCouplingMappedExtrudedMesh *MEDCouplingMappedExtrudedMesh::clone(bool recDeepCpy) const
176 return new MEDCouplingMappedExtrudedMesh(*this,recDeepCpy);
179 const DataArrayDouble *MEDCouplingMappedExtrudedMesh::getDirectAccessOfCoordsArrIfInStructure() const
181 throw INTERP_KERNEL::Exception("MEDCouplingMappedExtrudedMesh::getDirectAccessOfCoordsArrIfInStructure : no direct acess of DataArrayDouble holding nodes !");
184 bool MEDCouplingMappedExtrudedMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
187 throw INTERP_KERNEL::Exception("MEDCouplingMappedExtrudedMesh::isEqualIfNotWhy : input other pointer is null !");
188 const MEDCouplingMappedExtrudedMesh *otherC=dynamic_cast<const MEDCouplingMappedExtrudedMesh *>(other);
189 std::ostringstream oss;
192 reason="mesh given in input is not castable in MEDCouplingMappedExtrudedMesh !";
195 if(!MEDCouplingMesh::isEqualIfNotWhy(other,prec,reason))
197 if(!_mesh2D->isEqualIfNotWhy(otherC->_mesh2D,prec,reason))
199 reason.insert(0,"Mesh2D unstructured meshes differ : ");
202 if(!_mesh1D->isEqualIfNotWhy(otherC->_mesh1D,prec,reason))
204 reason.insert(0,"Mesh1D unstructured meshes differ : ");
207 if(!_mesh3D_ids->isEqualIfNotWhy(*otherC->_mesh3D_ids,reason))
209 reason.insert(0,"Mesh3D ids DataArrayInt instances differ : ");
212 if(_cell_2D_id!=otherC->_cell_2D_id)
214 oss << "Cell 2D id of the two extruded mesh differ : this = " << _cell_2D_id << " other = " << otherC->_cell_2D_id;
221 bool MEDCouplingMappedExtrudedMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
223 const MEDCouplingMappedExtrudedMesh *otherC=dynamic_cast<const MEDCouplingMappedExtrudedMesh *>(other);
226 if(!_mesh2D->isEqualWithoutConsideringStr(otherC->_mesh2D,prec))
228 if(!_mesh1D->isEqualWithoutConsideringStr(otherC->_mesh1D,prec))
230 if(!_mesh3D_ids->isEqualWithoutConsideringStr(*otherC->_mesh3D_ids))
232 if(_cell_2D_id!=otherC->_cell_2D_id)
237 void MEDCouplingMappedExtrudedMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
238 DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const
240 throw INTERP_KERNEL::Exception("MEDCouplingMappedExtrudedMesh::checkDeepEquivalWith : not implemented yet !");
243 void MEDCouplingMappedExtrudedMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
244 DataArrayInt *&cellCor) const
246 throw INTERP_KERNEL::Exception("MEDCouplingMappedExtrudedMesh::checkDeepEquivalOnSameNodesWith : not implemented yet !");
249 INTERP_KERNEL::NormalizedCellType MEDCouplingMappedExtrudedMesh::getTypeOfCell(std::size_t cellId) const
251 const int *ids(_mesh3D_ids->begin());
252 std::size_t nbOf3DCells(_mesh3D_ids->getNumberOfTuples());
253 const int *where(std::find(ids,ids+nbOf3DCells,cellId));
254 if(where==ids+nbOf3DCells)
255 throw INTERP_KERNEL::Exception("Invalid cellId specified >= getNumberOfCells() !");
256 std::size_t nbOfCells2D(_mesh2D->getNumberOfCells());
257 std::size_t locId((std::distance(ids,where))%nbOfCells2D);
258 INTERP_KERNEL::NormalizedCellType tmp(_mesh2D->getTypeOfCell(locId));
259 return INTERP_KERNEL::CellModel::GetCellModel(tmp).getExtrudedType();
262 std::set<INTERP_KERNEL::NormalizedCellType> MEDCouplingMappedExtrudedMesh::getAllGeoTypes() const
264 std::set<INTERP_KERNEL::NormalizedCellType> ret2D(_mesh2D->getAllGeoTypes());
265 std::set<INTERP_KERNEL::NormalizedCellType> ret;
266 for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator it=ret2D.begin();it!=ret2D.end();it++)
267 ret.insert(INTERP_KERNEL::CellModel::GetCellModel(*it).getExtrudedType());
271 DataArrayInt *MEDCouplingMappedExtrudedMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
273 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(type));
274 INTERP_KERNEL::NormalizedCellType revExtTyp(cm.getReverseExtrudedType());
275 MCAuto<DataArrayInt> ret(DataArrayInt::New());
276 if(revExtTyp==INTERP_KERNEL::NORM_ERROR)
281 MCAuto<DataArrayInt> tmp(_mesh2D->giveCellsWithType(revExtTyp));
282 int nbOfLevs(_mesh1D->getNumberOfCells());
283 int nbOfCells2D(_mesh2D->getNumberOfCells());
284 int nbOfTuples(tmp->getNumberOfTuples());
285 ret->alloc(nbOfLevs*nbOfTuples,1);
286 int *pt(ret->getPointer());
287 for(int i=0;i<nbOfLevs;i++,pt+=nbOfTuples)
288 std::transform(tmp->begin(),tmp->end(),pt,std::bind2nd(std::plus<int>(),i*nbOfCells2D));
289 MCAuto<DataArrayInt> ret2(ret->renumberR(_mesh3D_ids->begin()));
294 DataArrayInt *MEDCouplingMappedExtrudedMesh::computeNbOfNodesPerCell() const
296 MCAuto<DataArrayInt> ret2D(_mesh2D->computeNbOfNodesPerCell());
297 int nbOfLevs(_mesh1D->getNumberOfCells());
298 int nbOfCells2D(_mesh2D->getNumberOfCells());
299 MCAuto<DataArrayInt> ret3D(DataArrayInt::New()); ret3D->alloc(nbOfLevs*nbOfCells2D,1);
300 int *pt(ret3D->getPointer());
301 for(int i=0;i<nbOfLevs;i++,pt+=nbOfCells2D)
302 std::copy(ret2D->begin(),ret2D->end(),pt);
303 ret3D->applyLin(2,0,0);
304 return ret3D->renumberR(_mesh3D_ids->begin());
307 DataArrayInt *MEDCouplingMappedExtrudedMesh::computeNbOfFacesPerCell() const
309 MCAuto<DataArrayInt> ret2D(_mesh2D->computeNbOfNodesPerCell());
310 int nbOfLevs(_mesh1D->getNumberOfCells());
311 int nbOfCells2D(_mesh2D->getNumberOfCells());
312 MCAuto<DataArrayInt> ret3D(DataArrayInt::New()); ret3D->alloc(nbOfLevs*nbOfCells2D,1);
313 int *pt(ret3D->getPointer());
314 for(int i=0;i<nbOfLevs;i++,pt+=nbOfCells2D)
315 std::copy(ret2D->begin(),ret2D->end(),pt);
316 ret3D->applyLin(2,2,0);
317 return ret3D->renumberR(_mesh3D_ids->begin());
320 DataArrayInt *MEDCouplingMappedExtrudedMesh::computeEffectiveNbOfNodesPerCell() const
322 return computeNbOfNodesPerCell();
325 std::size_t MEDCouplingMappedExtrudedMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
328 std::size_t nbOfCells2D(_mesh2D->getNumberOfCells());
329 for(std::size_t i=0;i<nbOfCells2D;i++)
331 INTERP_KERNEL::NormalizedCellType t(_mesh2D->getTypeOfCell(i));
332 if(INTERP_KERNEL::CellModel::GetCellModel(t).getExtrudedType()==type)
335 return ret*_mesh1D->getNumberOfCells();
338 void MEDCouplingMappedExtrudedMesh::getNodeIdsOfCell(std::size_t cellId, std::vector<int>& conn) const
340 int nbOfCells2D(_mesh2D->getNumberOfCells());
341 int nbOfNodes2D(_mesh2D->getNumberOfNodes());
342 int locId(cellId%nbOfCells2D);
343 int lev(cellId/nbOfCells2D);
344 std::vector<int> tmp,tmp2;
345 _mesh2D->getNodeIdsOfCell(locId,tmp);
347 std::transform(tmp.begin(),tmp.end(),tmp.begin(),std::bind2nd(std::plus<int>(),nbOfNodes2D*lev));
348 std::transform(tmp2.begin(),tmp2.end(),tmp2.begin(),std::bind2nd(std::plus<int>(),nbOfNodes2D*(lev+1)));
349 conn.insert(conn.end(),tmp.begin(),tmp.end());
350 conn.insert(conn.end(),tmp2.begin(),tmp2.end());
353 void MEDCouplingMappedExtrudedMesh::getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const
355 int nbOfNodes2D(_mesh2D->getNumberOfNodes());
356 int locId(nodeId%nbOfNodes2D);
357 int lev(nodeId/nbOfNodes2D);
358 std::vector<double> tmp,tmp2;
359 _mesh2D->getCoordinatesOfNode(locId,tmp);
361 int spaceDim(_mesh1D->getSpaceDimension());
362 const double *z(_mesh1D->getCoords()->begin());
363 std::transform(tmp.begin(),tmp.end(),z+lev*spaceDim,tmp.begin(),std::plus<double>());
364 std::transform(tmp2.begin(),tmp2.end(),z+(lev+1)*spaceDim,tmp2.begin(),std::plus<double>());
365 coo.insert(coo.end(),tmp.begin(),tmp.end());
366 coo.insert(coo.end(),tmp2.begin(),tmp2.end());
369 std::string MEDCouplingMappedExtrudedMesh::simpleRepr() const
371 std::ostringstream ret;
372 ret << "3D Extruded mesh from a 2D Surf Mesh with name : \"" << getName() << "\"\n";
373 ret << "Description of mesh : \"" << getDescription() << "\"\n";
375 double tt=getTime(tmpp1,tmpp2);
376 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
377 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
378 ret << "Cell id where 1D mesh has been deduced : " << _cell_2D_id << "\n";
379 ret << "Number of cells : " << getNumberOfCells() << "(" << _mesh2D->getNumberOfCells() << "x" << _mesh1D->getNumberOfCells() << ")\n";
380 ret << "1D Mesh info : _____________________\n\n\n";
381 ret << _mesh1D->simpleRepr();
382 ret << "\n\n\n2D Mesh info : _____________________\n\n\n" << _mesh2D->simpleRepr() << "\n\n\n";
386 std::string MEDCouplingMappedExtrudedMesh::advancedRepr() const
388 std::ostringstream ret;
389 ret << "3D Extruded mesh from a 2D Surf Mesh with name : \"" << getName() << "\"\n";
390 ret << "Description of mesh : \"" << getDescription() << "\"\n";
392 double tt=getTime(tmpp1,tmpp2);
393 ret << "Time attached to the mesh (unit) : " << tt << " (" << getTimeUnit() << ")\n";
394 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
395 ret << "Cell id where 1D mesh has been deduced : " << _cell_2D_id << "\n";
396 ret << "Number of cells : " << getNumberOfCells() << "(" << _mesh2D->getNumberOfCells() << "x" << _mesh1D->getNumberOfCells() << ")\n";
397 ret << "1D Mesh info : _____________________\n\n\n";
398 ret << _mesh1D->advancedRepr();
399 ret << "\n\n\n2D Mesh info : _____________________\n\n\n" << _mesh2D->advancedRepr() << "\n\n\n";
400 ret << "3D cell ids per level :\n";
404 void MEDCouplingMappedExtrudedMesh::checkConsistencyLight() const
408 void MEDCouplingMappedExtrudedMesh::checkConsistency(double eps) const
410 checkConsistencyLight();
413 void MEDCouplingMappedExtrudedMesh::getBoundingBox(double *bbox) const
416 _mesh2D->getBoundingBox(bbox2D);
417 const double *nodes1D(_mesh1D->getCoords()->begin());
418 int nbOfNodes1D(_mesh1D->getNumberOfNodes());
419 double bbox1DMin[3],bbox1DMax[3],tmp[3];
420 std::fill(bbox1DMin,bbox1DMin+3,std::numeric_limits<double>::max());
421 std::fill(bbox1DMax,bbox1DMax+3,-(std::numeric_limits<double>::max()));
422 for(int i=0;i<nbOfNodes1D;i++)
424 std::transform(nodes1D+3*i,nodes1D+3*(i+1),bbox1DMin,bbox1DMin,static_cast<const double& (*)(const double&, const double&)>(std::min<double>));
425 std::transform(nodes1D+3*i,nodes1D+3*(i+1),bbox1DMax,bbox1DMax,static_cast<const double& (*)(const double&, const double&)>(std::max<double>));
427 std::transform(bbox1DMax,bbox1DMax+3,bbox1DMin,tmp,std::minus<double>());
428 int id=(int)std::distance(tmp,std::max_element(tmp,tmp+3));
429 bbox[0]=bbox1DMin[0]; bbox[1]=bbox1DMax[0];
430 bbox[2]=bbox1DMin[1]; bbox[3]=bbox1DMax[1];
431 bbox[4]=bbox1DMin[2]; bbox[5]=bbox1DMax[2];
432 bbox[2*id+1]+=tmp[id];
435 void MEDCouplingMappedExtrudedMesh::updateTime() const
437 if(_mesh2D.isNotNull())
438 updateTimeWith(*_mesh2D);
439 if(_mesh1D.isNotNull())
440 updateTimeWith(*_mesh1D);
443 void MEDCouplingMappedExtrudedMesh::renumberCells(const int *old2NewBg, bool check)
445 throw INTERP_KERNEL::Exception("Functionnality of renumbering cells unavailable for ExtrudedMesh");
449 * \b WARNING in case of modif think to update MEDFileUMesh::New implementation !
450 * \sa MEDFileUMesh::New
452 MEDCouplingUMesh *MEDCouplingMappedExtrudedMesh::build3DUnstructuredMesh() const
454 MCAuto<MEDCouplingUMesh> mesh2DZC(_mesh2D->deepCopyConnectivityOnly());
455 mesh2DZC->zipCoords();
456 MCAuto<MEDCouplingUMesh> ret(mesh2DZC->buildExtrudedMesh(_mesh1D,0));
457 const int *renum(_mesh3D_ids->begin());
458 ret->renumberCells(renum,false);
459 ret->setName(getName());
464 * \b WARNING in case of modif think to update MEDFileUMesh::New implementation !
465 * \sa MEDFileUMesh::New
467 MEDCouplingUMesh *MEDCouplingMappedExtrudedMesh::buildUnstructured() const
469 return build3DUnstructuredMesh();
472 MEDCouplingFieldDouble *MEDCouplingMappedExtrudedMesh::getMeasureField(bool) const
474 std::string name="MeasureOfMesh_";
476 MCAuto<MEDCouplingFieldDouble> ret2D(_mesh2D->getMeasureField(true)),ret1D(_mesh1D->getMeasureField(true));
477 const double *ret2DPtr(ret2D->getArray()->begin());
478 const double *ret1DPtr(ret1D->getArray()->begin());
479 int nbOf2DCells(_mesh2D->getNumberOfCells()),nbOf1DCells(_mesh1D->getNumberOfCells()),nbOf3DCells(nbOf2DCells*nbOf1DCells);
480 const int *renum(_mesh3D_ids->begin());
481 MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME));
483 ret->synchronizeTimeWithMesh();
484 MCAuto<DataArrayDouble> da(DataArrayDouble::New());
485 da->alloc(nbOf3DCells,1);
486 double *retPtr(da->getPointer());
487 for(int i=0;i<nbOf1DCells;i++)
488 for(int j=0;j<nbOf2DCells;j++)
489 retPtr[renum[i*nbOf2DCells+j]]=ret2DPtr[j]*ret1DPtr[i];
495 MEDCouplingFieldDouble *MEDCouplingMappedExtrudedMesh::getMeasureFieldOnNode(bool isAbs) const
497 //not implemented yet
501 MEDCouplingFieldDouble *MEDCouplingMappedExtrudedMesh::buildOrthogonalField() const
503 throw INTERP_KERNEL::Exception("MEDCouplingMappedExtrudedMesh::buildOrthogonalField : This method has no sense for MEDCouplingMappedExtrudedMesh that is 3D !");
506 int MEDCouplingMappedExtrudedMesh::getCellContainingPoint(const double *pos, double eps) const
508 throw INTERP_KERNEL::Exception("MEDCouplingMappedExtrudedMesh::getCellContainingPoint : not implemented yet !");
511 void MEDCouplingMappedExtrudedMesh::getCellsContainingPoint(const double *pos, double eps, std::vector<int>& elts) const
513 throw INTERP_KERNEL::Exception("MEDCouplingMappedExtrudedMesh::getCellsContainingPoint : not implemented yet !");
516 MEDCouplingMappedExtrudedMesh::~MEDCouplingMappedExtrudedMesh()
520 void MEDCouplingMappedExtrudedMesh::computeExtrusion(const MEDCouplingUMesh *mesh3D)
522 const char errMsg1[]="2D mesh is empty unable to compute extrusion !";
523 const char errMsg2[]="Coords between 2D and 3D meshes are not the same ! Try MEDCouplingPointSet::tryToShareSameCoords method";
524 const char errMsg3[]="No chance to find extrusion pattern in mesh3D,mesh2D couple because nbCells3D%nbCells2D!=0 !";
525 if(_mesh2D.isNull() || mesh3D==0)
526 throw INTERP_KERNEL::Exception(errMsg1);
527 if(_mesh2D->getCoords()!=mesh3D->getCoords())
528 throw INTERP_KERNEL::Exception(errMsg2);
529 if(mesh3D->getNumberOfCells()%_mesh2D->getNumberOfCells()!=0)
530 throw INTERP_KERNEL::Exception(errMsg3);
531 if(_mesh3D_ids.isNull())
532 _mesh3D_ids=DataArrayInt::New();
534 _mesh1D=MEDCouplingUMesh::New();
535 computeExtrusionAlg(mesh3D);
538 void MEDCouplingMappedExtrudedMesh::build1DExtrusion(int idIn3DDesc, int newId, int nbOf1DLev, MEDCouplingUMesh *subMesh,
539 const int *desc3D, const int *descIndx3D,
540 const int *revDesc3D, const int *revDescIndx3D,
543 int nbOf2DCells(_mesh2D->getNumberOfCells());
544 int start(revDescIndx3D[idIn3DDesc]);
545 int end(revDescIndx3D[idIn3DDesc+1]);
548 std::ostringstream ost; ost << "Invalid bases 2D mesh specified : 2D cell # " << idIn3DDesc;
549 ost << " shared by more than 1 3D cell !!!";
550 throw INTERP_KERNEL::Exception(ost.str().c_str());
552 int current3DCell(revDesc3D[start]);
553 int current2DCell(idIn3DDesc);
554 int *mesh3DIDs(_mesh3D_ids->getPointer());
555 mesh3DIDs[newId]=current3DCell;
556 const int *conn2D(subMesh->getNodalConnectivity()->begin());
557 const int *conn2DIndx(subMesh->getNodalConnectivityIndex()->begin());
558 for(int i=1;i<nbOf1DLev;i++)
560 std::vector<int> conn(conn2D+conn2DIndx[current2DCell]+1,conn2D+conn2DIndx[current2DCell+1]);
561 std::sort(conn.begin(),conn.end());
563 computeBaryCenterOfFace(conn,i-1);
564 current2DCell=findOppositeFaceOf(current2DCell,current3DCell,conn,
565 desc3D,descIndx3D,conn2D,conn2DIndx);
566 start=revDescIndx3D[current2DCell];
567 end=revDescIndx3D[current2DCell+1];
570 std::ostringstream ost; ost << "Expecting to have 2 3D cells attached to 2D cell " << current2DCell << "!";
571 ost << " : Impossible or call tryToShareSameCoords method !";
572 throw INTERP_KERNEL::Exception(ost.str().c_str());
574 if(revDesc3D[start]!=current3DCell)
575 current3DCell=revDesc3D[start];
577 current3DCell=revDesc3D[start+1];
578 mesh3DIDs[i*nbOf2DCells+newId]=current3DCell;
582 std::vector<int> conn(conn2D+conn2DIndx[current2DCell]+1,conn2D+conn2DIndx[current2DCell+1]);
583 std::sort(conn.begin(),conn.end());
584 computeBaryCenterOfFace(conn,nbOf1DLev-1);
585 current2DCell=findOppositeFaceOf(current2DCell,current3DCell,conn,
586 desc3D,descIndx3D,conn2D,conn2DIndx);
588 conn.insert(conn.end(),conn2D+conn2DIndx[current2DCell]+1,conn2D+conn2DIndx[current2DCell+1]);
589 std::sort(conn.begin(),conn.end());
590 computeBaryCenterOfFace(conn,nbOf1DLev);
594 int MEDCouplingMappedExtrudedMesh::findOppositeFaceOf(int current2DCell, int current3DCell, const std::vector<int>& connSorted,
595 const int *desc3D, const int *descIndx3D,
596 const int *conn2D, const int *conn2DIndx)
598 int start(descIndx3D[current3DCell]);
599 int end(descIndx3D[current3DCell+1]);
601 for(const int *candidate2D=desc3D+start;candidate2D!=desc3D+end && !found;candidate2D++)
603 if(*candidate2D!=current2DCell)
605 std::vector<int> conn2(conn2D+conn2DIndx[*candidate2D]+1,conn2D+conn2DIndx[*candidate2D+1]);
606 std::sort(conn2.begin(),conn2.end());
607 std::list<int> intersect;
608 std::set_intersection(connSorted.begin(),connSorted.end(),conn2.begin(),conn2.end(),
609 std::insert_iterator< std::list<int> >(intersect,intersect.begin()));
610 if(intersect.empty())
614 std::ostringstream ost; ost << "Impossible to find an opposite 2D face of face # " << current2DCell;
615 ost << " in 3D cell # " << current3DCell << " : Impossible or call tryToShareSameCoords method !";
616 throw INTERP_KERNEL::Exception(ost.str().c_str());
619 void MEDCouplingMappedExtrudedMesh::computeBaryCenterOfFace(const std::vector<int>& nodalConnec, int lev1DId)
621 double *zoneToUpdate(_mesh1D->getCoords()->getPointer()+lev1DId*3);
622 std::fill(zoneToUpdate,zoneToUpdate+3,0.);
623 const double *coords(_mesh2D->getCoords()->begin());
624 for(std::vector<int>::const_iterator iter=nodalConnec.begin();iter!=nodalConnec.end();iter++)
625 std::transform(zoneToUpdate,zoneToUpdate+3,coords+3*(*iter),zoneToUpdate,std::plus<double>());
626 std::transform(zoneToUpdate,zoneToUpdate+3,zoneToUpdate,std::bind2nd(std::multiplies<double>(),(double)(1./(int)nodalConnec.size())));
629 int MEDCouplingMappedExtrudedMesh::FindCorrespCellByNodalConn(const std::vector<int>& nodalConnec, const int *revNodalPtr, const int *revNodalIndxPtr)
631 std::vector<int>::const_iterator iter=nodalConnec.begin();
632 std::set<int> s1(revNodalPtr+revNodalIndxPtr[*iter],revNodalPtr+revNodalIndxPtr[*iter+1]);
634 for(;iter!=nodalConnec.end();iter++)
636 std::set<int> s2(revNodalPtr+revNodalIndxPtr[*iter],revNodalPtr+revNodalIndxPtr[*iter+1]);
638 std::set_intersection(s1.begin(),s1.end(),s2.begin(),s2.end(),std::insert_iterator< std::set<int> >(s3,s3.end()));
642 return *(s1.begin());
643 std::ostringstream ostr;
644 ostr << "Cell with nodal connec : ";
645 std::copy(nodalConnec.begin(),nodalConnec.end(),std::ostream_iterator<int>(ostr," "));
646 ostr << " is not part of mesh";
647 throw INTERP_KERNEL::Exception(ostr.str().c_str());
651 * This method is callable on 1Dmeshes (meshDim==1 && spaceDim==3) returned by MEDCouplingMappedExtrudedMesh::getMesh1D typically.
652 * 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.
653 * 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
654 * are created ('m1r' and 'm2r') that can be used for interpolation.
655 * @param m1 input mesh with meshDim==1 and spaceDim==3
656 * @param m2 input mesh with meshDim==1 and spaceDim==3
657 * @param eps tolerance acceptable to determine compatibility
658 * @param m1r output mesh with ref count equal to 1 with meshDim==1 and spaceDim==1
659 * @param m2r output mesh with ref count equal to 1 with meshDim==1 and spaceDim==1
660 * @param v is the output normalized vector of the common direction of 'm1' and 'm2'
661 * @throw in case that m1 and m2 are not compatible each other.
663 void MEDCouplingMappedExtrudedMesh::Project1DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps,
664 MEDCouplingUMesh *&m1r, MEDCouplingUMesh *&m2r, double *v)
666 if(m1->getSpaceDimension()!=3 || m1->getSpaceDimension()!=3)
667 throw INTERP_KERNEL::Exception("Input meshes are expected to have a spaceDim==3 for Projec1D !");
670 m1r->changeSpaceDimension(1);
671 m2r->changeSpaceDimension(1);
673 std::vector<double> ref,ref2;
674 m1->getNodeIdsOfCell(0,c);
675 m1->getCoordinatesOfNode(c[0],ref);
676 m1->getCoordinatesOfNode(c[1],ref2);
677 std::transform(ref2.begin(),ref2.end(),ref.begin(),v,std::minus<double>());
678 double n=INTERP_KERNEL::norm<3>(v);
679 std::transform(v,v+3,v,std::bind2nd(std::multiplies<double>(),1/n));
680 m1->project1D(&ref[0],v,eps,m1r->getCoords()->getPointer());
681 m2->project1D(&ref[0],v,eps,m2r->getCoords()->getPointer());
684 void MEDCouplingMappedExtrudedMesh::rotate(const double *center, const double *vector, double angle)
686 _mesh2D->rotate(center,vector,angle);
687 _mesh1D->rotate(center,vector,angle);
690 void MEDCouplingMappedExtrudedMesh::translate(const double *vector)
692 _mesh2D->translate(vector);
693 _mesh1D->translate(vector);
696 void MEDCouplingMappedExtrudedMesh::scale(const double *point, double factor)
698 _mesh2D->scale(point,factor);
699 _mesh1D->scale(point,factor);
702 std::vector<int> MEDCouplingMappedExtrudedMesh::getDistributionOfTypes() const
704 throw INTERP_KERNEL::Exception("Not implemented yet !");
707 DataArrayInt *MEDCouplingMappedExtrudedMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const
709 throw INTERP_KERNEL::Exception("Not implemented yet !");
712 void MEDCouplingMappedExtrudedMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const
714 throw INTERP_KERNEL::Exception("Not implemented yet !");
717 MEDCouplingMesh *MEDCouplingMappedExtrudedMesh::buildPart(const int *start, const int *end) const
719 // not implemented yet !
723 MEDCouplingMesh *MEDCouplingMappedExtrudedMesh::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const
725 // not implemented yet !
729 DataArrayInt *MEDCouplingMappedExtrudedMesh::simplexize(int policy)
731 throw INTERP_KERNEL::Exception("MEDCouplingMappedExtrudedMesh::simplexize : unavailable for such a type of mesh : Extruded !");
734 MEDCouplingMesh *MEDCouplingMappedExtrudedMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
736 // not implemented yet !
740 DataArrayDouble *MEDCouplingMappedExtrudedMesh::getCoordinatesAndOwner() const
742 const DataArrayDouble *arr2D(_mesh2D->getCoords());
743 const DataArrayDouble *arr1D(_mesh1D->getCoords());
744 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
745 ret->alloc(getNumberOfNodes(),3);
746 int nbOf1DLev(_mesh1D->getNumberOfNodes());
747 int nbOf2DNodes(_mesh2D->getNumberOfNodes());
748 const double *ptSrc(arr2D->begin());
749 double *pt(ret->getPointer());
750 std::copy(ptSrc,ptSrc+3*nbOf2DNodes,pt);
751 for(int i=1;i<nbOf1DLev;i++)
753 std::copy(ptSrc,ptSrc+3*nbOf2DNodes,pt+3*i*nbOf2DNodes);
755 std::copy(arr1D->begin()+3*i,arr1D->begin()+3*(i+1),vec);
756 std::transform(arr1D->begin()+3*(i-1),arr1D->begin()+3*i,vec,vec,std::minus<double>());
757 for(int j=0;j<nbOf2DNodes;j++)
758 std::transform(vec,vec+3,pt+3*(i*nbOf2DNodes+j),pt+3*(i*nbOf2DNodes+j),std::plus<double>());
763 DataArrayDouble *MEDCouplingMappedExtrudedMesh::computeCellCenterOfMass() const
765 throw INTERP_KERNEL::Exception("MEDCouplingMappedExtrudedMesh::computeCellCenterOfMass : not yet implemented !");
768 DataArrayDouble *MEDCouplingMappedExtrudedMesh::computeIsoBarycenterOfNodesPerCell() const
770 throw INTERP_KERNEL::Exception("MEDCouplingMappedExtrudedMesh::computeIsoBarycenterOfNodesPerCell: not yet implemented !");
773 void MEDCouplingMappedExtrudedMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const
775 MCAuto<MEDCouplingUMesh> m(buildUnstructured());
776 m->getReverseNodalConnectivity(revNodal,revNodalIndx);
779 void MEDCouplingMappedExtrudedMesh::computeExtrusionAlg(const MEDCouplingUMesh *mesh3D)
781 _mesh3D_ids->alloc(mesh3D->getNumberOfCells(),1);
782 int nbOf1DLev(mesh3D->getNumberOfCells()/_mesh2D->getNumberOfCells());
783 _mesh1D->setMeshDimension(1);
784 _mesh1D->allocateCells(nbOf1DLev);
786 for(int i=0;i<nbOf1DLev;i++)
790 _mesh1D->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,tmpConn);
792 _mesh1D->finishInsertingCells();
793 DataArrayDouble *myCoords=DataArrayDouble::New();
794 myCoords->alloc(nbOf1DLev+1,3);
795 _mesh1D->setCoords(myCoords);
797 MCAuto<DataArrayInt> desc(DataArrayInt::New()),descIndx(DataArrayInt::New()),revDesc(DataArrayInt::New()),revDescIndx(DataArrayInt::New());
798 MCAuto<MEDCouplingUMesh> subMesh(mesh3D->buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx));
799 MCAuto<DataArrayInt> revNodal2D(DataArrayInt::New()),revNodalIndx2D(DataArrayInt::New());
800 subMesh->getReverseNodalConnectivity(revNodal2D,revNodalIndx2D);
801 const int *nodal2D(_mesh2D->getNodalConnectivity()->begin());
802 const int *nodal2DIndx(_mesh2D->getNodalConnectivityIndex()->begin());
803 const int *revNodal2DPtr(revNodal2D->begin());
804 const int *revNodalIndx2DPtr(revNodalIndx2D->begin());
805 const int *descP(desc->begin()),*descIndxP(descIndx->begin()),*revDescP(revDesc->begin()),*revDescIndxP(revDescIndx->begin());
807 int nbOf2DCells(_mesh2D->getNumberOfCells());
808 for(int i=0;i<nbOf2DCells;i++)
811 std::vector<int> nodalConnec(nodal2D+nodal2DIndx[i]+1,nodal2D+nodal2DIndx[i+1]);
814 idInSubMesh=FindCorrespCellByNodalConn(nodalConnec,revNodal2DPtr,revNodalIndx2DPtr);
816 catch(INTERP_KERNEL::Exception& e)
818 std::ostringstream ostr; ostr << "mesh2D cell # " << i << " is not part of any cell of 3D mesh !\n";
820 throw INTERP_KERNEL::Exception(ostr.str().c_str());
822 build1DExtrusion(idInSubMesh,i,nbOf1DLev,subMesh,descP,descIndxP,revDescP,revDescIndxP,i==_cell_2D_id);
826 void MEDCouplingMappedExtrudedMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
828 std::vector<int> tinyInfo1;
829 std::vector<std::string> ls1;
830 std::vector<double> ls3;
831 _mesh2D->getTinySerializationInformation(ls3,tinyInfo1,ls1);
832 std::vector<int> tinyInfo2;
833 std::vector<std::string> ls2;
834 std::vector<double> ls4;
835 _mesh1D->getTinySerializationInformation(ls4,tinyInfo2,ls2);
836 tinyInfo.clear(); littleStrings.clear();
837 tinyInfo.insert(tinyInfo.end(),tinyInfo1.begin(),tinyInfo1.end());
838 littleStrings.insert(littleStrings.end(),ls1.begin(),ls1.end());
839 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
840 littleStrings.insert(littleStrings.end(),ls2.begin(),ls2.end());
841 tinyInfo.push_back(_cell_2D_id);
842 tinyInfo.push_back((int)tinyInfo1.size());
843 tinyInfo.push_back(_mesh3D_ids->getNbOfElems());
844 littleStrings.push_back(getName());
845 littleStrings.push_back(getDescription());
848 void MEDCouplingMappedExtrudedMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
850 std::size_t sz=tinyInfo.size();
851 int sz1=tinyInfo[sz-2];
852 std::vector<int> ti1(tinyInfo.begin(),tinyInfo.begin()+sz1);
853 std::vector<int> ti2(tinyInfo.begin()+sz1,tinyInfo.end()-3);
854 MEDCouplingUMesh *um=MEDCouplingUMesh::New();
855 DataArrayInt *a1tmp=DataArrayInt::New();
856 DataArrayDouble *a2tmp=DataArrayDouble::New();
858 std::vector<std::string> ls1,ls2;
859 um->resizeForUnserialization(ti1,a1tmp,a2tmp,ls1);
860 la1+=a1tmp->getNbOfElems(); la2+=a2tmp->getNbOfElems();
861 a1tmp->decrRef(); a2tmp->decrRef();
862 a1tmp=DataArrayInt::New(); a2tmp=DataArrayDouble::New();
863 um->resizeForUnserialization(ti2,a1tmp,a2tmp,ls2);
864 la1+=a1tmp->getNbOfElems(); la2+=a2tmp->getNbOfElems();
865 a1tmp->decrRef(); a2tmp->decrRef();
868 a1->alloc(la1+tinyInfo[sz-1],1);
870 littleStrings.resize(ls1.size()+ls2.size()+2);
873 void MEDCouplingMappedExtrudedMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
875 a1=DataArrayInt::New(); a2=DataArrayDouble::New();
876 DataArrayInt *a1_1=0,*a1_2=0;
877 DataArrayDouble *a2_1=0,*a2_2=0;
878 _mesh2D->serialize(a1_1,a2_1);
879 _mesh1D->serialize(a1_2,a2_2);
880 a1->alloc(a1_1->getNbOfElems()+a1_2->getNbOfElems()+_mesh3D_ids->getNbOfElems(),1);
881 int *ptri=a1->getPointer();
882 ptri=std::copy(a1_1->begin(),a1_1->begin()+a1_1->getNbOfElems(),ptri);
884 ptri=std::copy(a1_2->begin(),a1_2->begin()+a1_2->getNbOfElems(),ptri);
886 std::copy(_mesh3D_ids->begin(),_mesh3D_ids->begin()+_mesh3D_ids->getNbOfElems(),ptri);
887 a2->alloc(a2_1->getNbOfElems()+a2_2->getNbOfElems(),1);
888 double *ptrd=a2->getPointer();
889 ptrd=std::copy(a2_1->begin(),a2_1->begin()+a2_1->getNbOfElems(),ptrd);
891 std::copy(a2_2->begin(),a2_2->begin()+a2_2->getNbOfElems(),ptrd);
895 void MEDCouplingMappedExtrudedMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector<std::string>& littleStrings)
897 setName(littleStrings[littleStrings.size()-2]);
898 setDescription(littleStrings.back());
899 std::size_t sz=tinyInfo.size();
900 int sz1=tinyInfo[sz-2];
901 _cell_2D_id=tinyInfo[sz-3];
902 std::vector<int> ti1(tinyInfo.begin(),tinyInfo.begin()+sz1);
903 std::vector<int> ti2(tinyInfo.begin()+sz1,tinyInfo.end()-3);
904 DataArrayInt *a1tmp=DataArrayInt::New();
905 DataArrayDouble *a2tmp=DataArrayDouble::New();
906 const int *a1Ptr=a1->begin();
907 const double *a2Ptr=a2->begin();
908 _mesh2D=MEDCouplingUMesh::New();
909 std::vector<std::string> ls1,ls2;
910 _mesh2D->resizeForUnserialization(ti1,a1tmp,a2tmp,ls1);
911 std::copy(a2Ptr,a2Ptr+a2tmp->getNbOfElems(),a2tmp->getPointer());
912 std::copy(a1Ptr,a1Ptr+a1tmp->getNbOfElems(),a1tmp->getPointer());
913 a2Ptr+=a2tmp->getNbOfElems();
914 a1Ptr+=a1tmp->getNbOfElems();
915 ls2.insert(ls2.end(),littleStrings.begin(),littleStrings.begin()+ls1.size());
916 std::vector<double> d1(1);
917 _mesh2D->unserialization(d1,ti1,a1tmp,a2tmp,ls2);
918 a1tmp->decrRef(); a2tmp->decrRef();
921 ls2.insert(ls2.end(),littleStrings.begin()+ls1.size(),littleStrings.end()-2);
922 _mesh1D=MEDCouplingUMesh::New();
923 a1tmp=DataArrayInt::New(); a2tmp=DataArrayDouble::New();
924 _mesh1D->resizeForUnserialization(ti2,a1tmp,a2tmp,ls1);
925 std::copy(a2Ptr,a2Ptr+a2tmp->getNbOfElems(),a2tmp->getPointer());
926 std::copy(a1Ptr,a1Ptr+a1tmp->getNbOfElems(),a1tmp->getPointer());
927 a1Ptr+=a1tmp->getNbOfElems();
928 _mesh1D->unserialization(d1,ti2,a1tmp,a2tmp,ls2);
929 a1tmp->decrRef(); a2tmp->decrRef();
931 _mesh3D_ids=DataArrayInt::New();
932 int szIds=(int)std::distance(a1Ptr,a1->begin()+a1->getNbOfElems());
933 _mesh3D_ids->alloc(szIds,1);
934 std::copy(a1Ptr,a1Ptr+szIds,_mesh3D_ids->getPointer());
937 void MEDCouplingMappedExtrudedMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const
939 MCAuto<MEDCouplingUMesh> m=buildUnstructured();
940 m->writeVTKLL(ofs,cellData,pointData,byteData);
943 void MEDCouplingMappedExtrudedMesh::reprQuickOverview(std::ostream& stream) const
945 stream << "MEDCouplingMappedExtrudedMesh C++ instance at " << this << ". Name : \"" << getName() << "\".";
948 std::string MEDCouplingMappedExtrudedMesh::getVTKFileExtension() const
950 return _mesh2D->getVTKFileExtension();
953 std::string MEDCouplingMappedExtrudedMesh::getVTKDataSetType() const
955 return _mesh2D->getVTKDataSetType();