Back to index

salome-med  6.5.0
MEDCouplingExtrudedMesh.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 
00020 #include "MEDCouplingExtrudedMesh.hxx"
00021 #include "MEDCouplingUMesh.hxx"
00022 #include "MEDCouplingMemArray.hxx"
00023 #include "MEDCouplingFieldDouble.hxx"
00024 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
00025 #include "CellModel.hxx"
00026 
00027 #include "InterpolationUtils.hxx"
00028 
00029 #include <limits>
00030 #include <algorithm>
00031 #include <functional>
00032 #include <iterator>
00033 #include <sstream>
00034 #include <cmath>
00035 #include <list>
00036 #include <set>
00037 
00038 using namespace ParaMEDMEM;
00039 
00047 MEDCouplingExtrudedMesh *MEDCouplingExtrudedMesh::New(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId) throw(INTERP_KERNEL::Exception)
00048 {
00049   return new MEDCouplingExtrudedMesh(mesh3D,mesh2D,cell2DId);
00050 }
00051 
00056 MEDCouplingExtrudedMesh *MEDCouplingExtrudedMesh::New()
00057 {
00058   return new MEDCouplingExtrudedMesh;
00059 }
00060 
00061 MEDCouplingMeshType MEDCouplingExtrudedMesh::getType() const
00062 {
00063   return EXTRUDED;
00064 }
00065 
00070 void MEDCouplingExtrudedMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception)
00071 {
00072   const MEDCouplingExtrudedMesh *otherC=dynamic_cast<const MEDCouplingExtrudedMesh *>(other);
00073   if(!otherC)
00074     throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::copyTinyStringsFrom : meshes have not same type !");
00075   MEDCouplingMesh::copyTinyStringsFrom(other);
00076   _mesh2D->copyTinyStringsFrom(otherC->_mesh2D);
00077   _mesh1D->copyTinyStringsFrom(otherC->_mesh1D);
00078 }
00079 
00080 MEDCouplingExtrudedMesh::MEDCouplingExtrudedMesh(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId) throw(INTERP_KERNEL::Exception)
00081 try:_mesh2D(const_cast<MEDCouplingUMesh *>(mesh2D)),_mesh1D(MEDCouplingUMesh::New()),_mesh3D_ids(0),_cell_2D_id(cell2DId)
00082 {
00083   if(_mesh2D!=0)
00084     _mesh2D->incrRef();
00085   computeExtrusion(mesh3D);
00086   setName(mesh3D->getName());
00087 }
00088 catch(INTERP_KERNEL::Exception& e)
00089   {
00090     if(_mesh2D)
00091       _mesh2D->decrRef();
00092     if(_mesh1D)
00093       _mesh1D->decrRef();
00094     if(_mesh3D_ids)
00095       _mesh3D_ids->decrRef();
00096     throw e;
00097   }
00098 
00099 MEDCouplingExtrudedMesh::MEDCouplingExtrudedMesh():_mesh2D(0),_mesh1D(0),_mesh3D_ids(0),_cell_2D_id(-1)
00100 {
00101 }
00102 
00103 MEDCouplingExtrudedMesh::MEDCouplingExtrudedMesh(const MEDCouplingExtrudedMesh& other, bool deepCopy):MEDCouplingMesh(other),_cell_2D_id(other._cell_2D_id)
00104 {
00105   if(deepCopy)
00106     {
00107       _mesh2D=other._mesh2D->clone(true);
00108       _mesh1D=other._mesh1D->clone(true);
00109       _mesh3D_ids=other._mesh3D_ids->deepCpy();
00110     }
00111   else
00112     {
00113       _mesh2D=other._mesh2D;
00114       if(_mesh2D)
00115         _mesh2D->incrRef();
00116       _mesh1D=other._mesh1D;
00117       if(_mesh1D)
00118         _mesh1D->incrRef();
00119       _mesh3D_ids=other._mesh3D_ids;
00120       if(_mesh3D_ids)
00121         _mesh3D_ids->incrRef();
00122     }
00123 }
00124 
00125 int MEDCouplingExtrudedMesh::getNumberOfCells() const
00126 {
00127   return _mesh2D->getNumberOfCells()*_mesh1D->getNumberOfCells();
00128 }
00129 
00130 int MEDCouplingExtrudedMesh::getNumberOfNodes() const
00131 {
00132   return _mesh2D->getNumberOfNodes();
00133 }
00134 
00135 int MEDCouplingExtrudedMesh::getSpaceDimension() const
00136 {
00137   return 3;
00138 }
00139 
00140 int MEDCouplingExtrudedMesh::getMeshDimension() const
00141 {
00142   return 3;
00143 }
00144 
00145 MEDCouplingMesh *MEDCouplingExtrudedMesh::deepCpy() const
00146 {
00147   return clone(true);
00148 }
00149 
00150 MEDCouplingExtrudedMesh *MEDCouplingExtrudedMesh::clone(bool recDeepCpy) const
00151 {
00152   return new MEDCouplingExtrudedMesh(*this,recDeepCpy);
00153 }
00154 
00155 bool MEDCouplingExtrudedMesh::isEqual(const MEDCouplingMesh *other, double prec) const
00156 {
00157   const MEDCouplingExtrudedMesh *otherC=dynamic_cast<const MEDCouplingExtrudedMesh *>(other);
00158   if(!otherC)
00159     return false;
00160   if(!MEDCouplingMesh::isEqual(other,prec))
00161     return false;
00162   if(!_mesh2D->isEqual(otherC->_mesh2D,prec))
00163     return false;
00164   if(!_mesh1D->isEqual(otherC->_mesh1D,prec))
00165     return false;
00166   if(!_mesh3D_ids->isEqual(*otherC->_mesh3D_ids))
00167     return false;
00168   if(_cell_2D_id!=otherC->_cell_2D_id)
00169     return false;
00170   return true;
00171 }
00172 
00173 bool MEDCouplingExtrudedMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
00174 {
00175   const MEDCouplingExtrudedMesh *otherC=dynamic_cast<const MEDCouplingExtrudedMesh *>(other);
00176   if(!otherC)
00177     return false;
00178   if(!_mesh2D->isEqualWithoutConsideringStr(otherC->_mesh2D,prec))
00179     return false;
00180   if(!_mesh1D->isEqualWithoutConsideringStr(otherC->_mesh1D,prec))
00181     return false;
00182   if(!_mesh3D_ids->isEqualWithoutConsideringStr(*otherC->_mesh3D_ids))
00183     return false;
00184   if(_cell_2D_id!=otherC->_cell_2D_id)
00185     return false;
00186   return true;
00187 }
00188 
00189 void MEDCouplingExtrudedMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
00190                                                    DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception)
00191 {
00192   throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::checkDeepEquivalWith : not implemented yet !");
00193 }
00194 
00195 void MEDCouplingExtrudedMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
00196                                                               DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception)
00197 {
00198   throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::checkDeepEquivalOnSameNodesWith : not implemented yet !");
00199 }
00200 
00201 INTERP_KERNEL::NormalizedCellType MEDCouplingExtrudedMesh::getTypeOfCell(int cellId) const
00202 {
00203   const int *ids=_mesh3D_ids->getConstPointer();
00204   int nbOf3DCells=_mesh3D_ids->getNumberOfTuples();
00205   const int *where=std::find(ids,ids+nbOf3DCells,cellId);
00206   if(where==ids+nbOf3DCells)
00207     throw INTERP_KERNEL::Exception("Invalid cellId specified >= getNumberOfCells() !");
00208   int nbOfCells2D=_mesh2D->getNumberOfCells();
00209   int locId=((int)std::distance(ids,where))%nbOfCells2D;
00210   INTERP_KERNEL::NormalizedCellType tmp=_mesh2D->getTypeOfCell(locId);
00211   return INTERP_KERNEL::CellModel::GetCellModel(tmp).getExtrudedType();
00212 }
00213 
00214 std::set<INTERP_KERNEL::NormalizedCellType> MEDCouplingExtrudedMesh::getAllGeoTypes() const
00215 {
00216   const std::set<INTERP_KERNEL::NormalizedCellType>& ret2D=_mesh2D->getAllTypes();
00217   std::set<INTERP_KERNEL::NormalizedCellType> ret;
00218   for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator it=ret2D.begin();it!=ret2D.end();it++)
00219     ret.insert(INTERP_KERNEL::CellModel::GetCellModel(*it).getExtrudedType());
00220   return ret;
00221 }
00222 
00223 int MEDCouplingExtrudedMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
00224 {
00225   int ret=0;
00226   int nbOfCells2D=_mesh2D->getNumberOfCells();
00227   for(int i=0;i<nbOfCells2D;i++)
00228     {
00229       INTERP_KERNEL::NormalizedCellType t=_mesh2D->getTypeOfCell(i);
00230       if(INTERP_KERNEL::CellModel::GetCellModel(t).getExtrudedType()==type)
00231         ret++;
00232     }
00233   return ret*_mesh1D->getNumberOfCells();
00234 }
00235 
00236 void MEDCouplingExtrudedMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
00237 {
00238   int nbOfCells2D=_mesh2D->getNumberOfCells();
00239   int nbOfNodes2D=_mesh2D->getNumberOfNodes();
00240   int locId=cellId%nbOfCells2D;
00241   int lev=cellId/nbOfCells2D;
00242   std::vector<int> tmp,tmp2;
00243   _mesh2D->getNodeIdsOfCell(locId,tmp);
00244   tmp2=tmp;
00245   std::transform(tmp.begin(),tmp.end(),tmp.begin(),std::bind2nd(std::plus<int>(),nbOfNodes2D*lev));
00246   std::transform(tmp2.begin(),tmp2.end(),tmp2.begin(),std::bind2nd(std::plus<int>(),nbOfNodes2D*(lev+1)));
00247   conn.insert(conn.end(),tmp.begin(),tmp.end());
00248   conn.insert(conn.end(),tmp2.begin(),tmp2.end());
00249 }
00250 
00251 void MEDCouplingExtrudedMesh::getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const throw(INTERP_KERNEL::Exception)
00252 {
00253   int nbOfNodes2D=_mesh2D->getNumberOfNodes();
00254   int locId=nodeId%nbOfNodes2D;
00255   int lev=nodeId/nbOfNodes2D;
00256   std::vector<double> tmp,tmp2;
00257   _mesh2D->getCoordinatesOfNode(locId,tmp);
00258   tmp2=tmp;
00259   int spaceDim=_mesh1D->getSpaceDimension();
00260   const double *z=_mesh1D->getCoords()->getConstPointer();
00261   std::transform(tmp.begin(),tmp.end(),z+lev*spaceDim,tmp.begin(),std::plus<double>());
00262   std::transform(tmp2.begin(),tmp2.end(),z+(lev+1)*spaceDim,tmp2.begin(),std::plus<double>());
00263   coo.insert(coo.end(),tmp.begin(),tmp.end());
00264   coo.insert(coo.end(),tmp2.begin(),tmp2.end());
00265 }
00266 
00267 std::string MEDCouplingExtrudedMesh::simpleRepr() const
00268 {
00269   std::ostringstream ret;
00270   ret << "3D Extruded mesh from a 2D Surf Mesh with name : \"" << getName() << "\"\n";
00271   ret << "Description of mesh : \"" << getDescription() << "\"\n";
00272   int tmpp1,tmpp2;
00273   double tt=getTime(tmpp1,tmpp2);
00274   ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
00275   ret << "Iteration : " << tmpp1  << " Order : " << tmpp2 << "\n";
00276   ret << "Cell id where 1D mesh has been deduced : " << _cell_2D_id << "\n";
00277   ret << "Number of cells : " << getNumberOfCells() << "(" << _mesh2D->getNumberOfCells() << "x" << _mesh1D->getNumberOfCells() << ")\n";
00278   ret << "1D Mesh info : _____________________\n\n\n";
00279   ret << _mesh1D->simpleRepr();
00280   ret << "\n\n\n2D Mesh info : _____________________\n\n\n" << _mesh2D->simpleRepr() << "\n\n\n";
00281   return ret.str();
00282 }
00283 
00284 std::string MEDCouplingExtrudedMesh::advancedRepr() const
00285 {
00286   std::ostringstream ret;
00287   ret << "3D Extruded mesh from a 2D Surf Mesh with name : \"" << getName() << "\"\n";
00288   ret << "Description of mesh : \"" << getDescription() << "\"\n";
00289   int tmpp1,tmpp2;
00290   double tt=getTime(tmpp1,tmpp2);
00291   ret << "Time attached to the mesh (unit) : " << tt << " (" << getTimeUnit() << ")\n";
00292   ret << "Iteration : " << tmpp1  << " Order : " << tmpp2 << "\n";
00293   ret << "Cell id where 1D mesh has been deduced : " << _cell_2D_id << "\n";
00294   ret << "Number of cells : " << getNumberOfCells() << "(" << _mesh2D->getNumberOfCells() << "x" << _mesh1D->getNumberOfCells() << ")\n";
00295   ret << "1D Mesh info : _____________________\n\n\n";
00296   ret << _mesh1D->advancedRepr();
00297   ret << "\n\n\n2D Mesh info : _____________________\n\n\n" << _mesh2D->advancedRepr() << "\n\n\n";
00298   ret << "3D cell ids per level :\n";
00299   return ret.str();
00300 }
00301 
00302 void MEDCouplingExtrudedMesh::checkCoherency() const throw (INTERP_KERNEL::Exception)
00303 {
00304 }
00305 
00306 void MEDCouplingExtrudedMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
00307 {
00308   checkCoherency();
00309 }
00310 
00311 void MEDCouplingExtrudedMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
00312 {
00313   checkCoherency1(eps);
00314 }
00315 
00316 void MEDCouplingExtrudedMesh::getBoundingBox(double *bbox) const
00317 {
00318   double bbox2D[6];
00319   _mesh2D->getBoundingBox(bbox2D);
00320   const double *nodes1D=_mesh1D->getCoords()->getConstPointer();
00321   int nbOfNodes1D=_mesh1D->getNumberOfNodes();
00322   double bbox1DMin[3],bbox1DMax[3],tmp[3];
00323   std::fill(bbox1DMin,bbox1DMin+3,std::numeric_limits<double>::max());
00324   std::fill(bbox1DMax,bbox1DMax+3,-(std::numeric_limits<double>::max()));
00325   for(int i=0;i<nbOfNodes1D;i++)
00326     {
00327       std::transform(nodes1D+3*i,nodes1D+3*(i+1),bbox1DMin,bbox1DMin,static_cast<const double& (*)(const double&, const double&)>(std::min<double>));
00328       std::transform(nodes1D+3*i,nodes1D+3*(i+1),bbox1DMax,bbox1DMax,static_cast<const double& (*)(const double&, const double&)>(std::max<double>));
00329     }
00330   std::transform(bbox1DMax,bbox1DMax+3,bbox1DMin,tmp,std::minus<double>());
00331   int id=(int)std::distance(tmp,std::max_element(tmp,tmp+3));
00332   bbox[0]=bbox1DMin[0]; bbox[1]=bbox1DMax[0];
00333   bbox[2]=bbox1DMin[1]; bbox[3]=bbox1DMax[1];
00334   bbox[4]=bbox1DMin[2]; bbox[5]=bbox1DMax[2];
00335   bbox[2*id+1]+=tmp[id];
00336 }
00337 
00338 void MEDCouplingExtrudedMesh::updateTime() const
00339 {
00340   if(_mesh2D)
00341     {
00342       updateTimeWith(*_mesh2D);
00343     }
00344   if(_mesh1D)
00345     {
00346       updateTimeWith(*_mesh1D);
00347     }
00348 }
00349 
00350 void MEDCouplingExtrudedMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
00351 {
00352   throw INTERP_KERNEL::Exception("Functionnality of renumbering cells unavailable for ExtrudedMesh");
00353 }
00354 
00355 MEDCouplingUMesh *MEDCouplingExtrudedMesh::build3DUnstructuredMesh() const
00356 {
00357   MEDCouplingUMesh *ret=_mesh2D->buildExtrudedMesh(_mesh1D,0);
00358   const int *renum=_mesh3D_ids->getConstPointer();
00359   ret->renumberCells(renum,false);
00360   ret->setName(getName());
00361   return ret;
00362 }
00363 
00364 MEDCouplingUMesh *MEDCouplingExtrudedMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
00365 {
00366   return build3DUnstructuredMesh();
00367 }
00368 
00369 MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::getMeasureField(bool) const
00370 {
00371   std::string name="MeasureOfMesh_";
00372   name+=getName();
00373   MEDCouplingFieldDouble *ret2D=_mesh2D->getMeasureField(true);
00374   MEDCouplingFieldDouble *ret1D=_mesh1D->getMeasureField(true);
00375   const double *ret2DPtr=ret2D->getArray()->getConstPointer();
00376   const double *ret1DPtr=ret1D->getArray()->getConstPointer();
00377   int nbOf2DCells=_mesh2D->getNumberOfCells();
00378   int nbOf1DCells=_mesh1D->getNumberOfCells();
00379   int nbOf3DCells=nbOf2DCells*nbOf1DCells;
00380   const int *renum=_mesh3D_ids->getConstPointer();
00381   MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
00382   ret->setMesh(this);
00383   DataArrayDouble *da=DataArrayDouble::New();
00384   da->alloc(nbOf3DCells,1);
00385   double *retPtr=da->getPointer();
00386   for(int i=0;i<nbOf1DCells;i++)
00387     for(int j=0;j<nbOf2DCells;j++)
00388       retPtr[renum[i*nbOf2DCells+j]]=ret2DPtr[j]*ret1DPtr[i];
00389   ret->setArray(da);
00390   da->decrRef();
00391   ret->setName(name.c_str());
00392   ret2D->decrRef();
00393   ret1D->decrRef();
00394   return ret;
00395 }
00396 
00397 MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::getMeasureFieldOnNode(bool isAbs) const
00398 {
00399   //not implemented yet
00400   return 0;
00401 }
00402 
00403 MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::buildOrthogonalField() const
00404 {
00405   throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::buildOrthogonalField : This method has no sense for MEDCouplingExtrudedMesh that is 3D !");
00406 }
00407 
00408 int MEDCouplingExtrudedMesh::getCellContainingPoint(const double *pos, double eps) const
00409 {
00410   throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::getCellContainingPoint : not implemented yet !");
00411 }
00412 
00413 MEDCouplingExtrudedMesh::~MEDCouplingExtrudedMesh()
00414 {
00415   if(_mesh2D)
00416     _mesh2D->decrRef();
00417   if(_mesh1D)
00418     _mesh1D->decrRef();
00419   if(_mesh3D_ids)
00420     _mesh3D_ids->decrRef();
00421 }
00422 
00423 void MEDCouplingExtrudedMesh::computeExtrusion(const MEDCouplingUMesh *mesh3D) throw(INTERP_KERNEL::Exception)
00424 {
00425   const char errMsg1[]="2D mesh is empty unable to compute extrusion !";
00426   const char errMsg2[]="Coords between 2D and 3D meshes are not the same ! Try MEDCouplingPointSet::tryToShareSameCoords method";
00427   const char errMsg3[]="No chance to find extrusion pattern in mesh3D,mesh2D couple because nbCells3D%nbCells2D!=0 !";
00428   if(_mesh2D==0 || mesh3D==0)
00429     throw INTERP_KERNEL::Exception(errMsg1);
00430   if(_mesh2D->getCoords()!=mesh3D->getCoords())
00431     throw INTERP_KERNEL::Exception(errMsg2);
00432   if(mesh3D->getNumberOfCells()%_mesh2D->getNumberOfCells()!=0)
00433     throw INTERP_KERNEL::Exception(errMsg3);
00434   if(!_mesh3D_ids)
00435     _mesh3D_ids=DataArrayInt::New();
00436   if(!_mesh1D)
00437     _mesh1D=MEDCouplingUMesh::New();
00438   computeExtrusionAlg(mesh3D);
00439 }
00440 
00441 void MEDCouplingExtrudedMesh::build1DExtrusion(int idIn3DDesc, int newId, int nbOf1DLev, MEDCouplingUMesh *subMesh,
00442                                                const int *desc3D, const int *descIndx3D,
00443                                                const int *revDesc3D, const int *revDescIndx3D,
00444                                                bool computeMesh1D) throw(INTERP_KERNEL::Exception)
00445 {
00446   int nbOf2DCells=_mesh2D->getNumberOfCells();
00447   int start=revDescIndx3D[idIn3DDesc];
00448   int end=revDescIndx3D[idIn3DDesc+1];
00449   if(end-start!=1)
00450     {
00451       std::ostringstream ost; ost << "Invalid bases 2D mesh specified : 2D cell # " <<  idIn3DDesc;
00452       ost << " shared by more than 1 3D cell !!!";
00453       throw INTERP_KERNEL::Exception(ost.str().c_str());
00454     }
00455   int current3DCell=revDesc3D[start];
00456   int current2DCell=idIn3DDesc;
00457   int *mesh3DIDs=_mesh3D_ids->getPointer();
00458   mesh3DIDs[newId]=current3DCell;
00459   const int *conn2D=subMesh->getNodalConnectivity()->getConstPointer();
00460   const int *conn2DIndx=subMesh->getNodalConnectivityIndex()->getConstPointer();
00461   for(int i=1;i<nbOf1DLev;i++)
00462     {
00463       std::vector<int> conn(conn2D+conn2DIndx[current2DCell]+1,conn2D+conn2DIndx[current2DCell+1]);
00464       std::sort(conn.begin(),conn.end());
00465       if(computeMesh1D)
00466         computeBaryCenterOfFace(conn,i-1);
00467       current2DCell=findOppositeFaceOf(current2DCell,current3DCell,conn,
00468                                        desc3D,descIndx3D,conn2D,conn2DIndx);
00469       start=revDescIndx3D[current2DCell];
00470       end=revDescIndx3D[current2DCell+1];
00471       if(end-start!=2)
00472         {
00473           std::ostringstream ost; ost << "Expecting to have 2 3D cells attached to 2D cell " << current2DCell << "!";
00474           ost << " : Impossible or call tryToShareSameCoords method !";
00475           throw INTERP_KERNEL::Exception(ost.str().c_str());
00476         }
00477       if(revDesc3D[start]!=current3DCell)
00478         current3DCell=revDesc3D[start];
00479       else
00480         current3DCell=revDesc3D[start+1];
00481       mesh3DIDs[i*nbOf2DCells+newId]=current3DCell;
00482     }
00483   if(computeMesh1D)
00484     {
00485       std::vector<int> conn(conn2D+conn2DIndx[current2DCell]+1,conn2D+conn2DIndx[current2DCell+1]);
00486       std::sort(conn.begin(),conn.end());
00487       computeBaryCenterOfFace(conn,nbOf1DLev-1);
00488       current2DCell=findOppositeFaceOf(current2DCell,current3DCell,conn,
00489                                        desc3D,descIndx3D,conn2D,conn2DIndx);
00490       conn.clear();
00491       conn.insert(conn.end(),conn2D+conn2DIndx[current2DCell]+1,conn2D+conn2DIndx[current2DCell+1]);
00492       std::sort(conn.begin(),conn.end());
00493       computeBaryCenterOfFace(conn,nbOf1DLev);
00494     }
00495 }
00496 
00497 int MEDCouplingExtrudedMesh::findOppositeFaceOf(int current2DCell, int current3DCell, const std::vector<int>& connSorted,
00498                                                 const int *desc3D, const int *descIndx3D,
00499                                                 const int *conn2D, const int *conn2DIndx) throw(INTERP_KERNEL::Exception)
00500 {
00501   int start=descIndx3D[current3DCell];
00502   int end=descIndx3D[current3DCell+1];
00503   bool found=false;
00504   for(const int *candidate2D=desc3D+start;candidate2D!=desc3D+end && !found;candidate2D++)
00505     {
00506       if(*candidate2D!=current2DCell)
00507         {
00508           std::vector<int> conn2(conn2D+conn2DIndx[*candidate2D]+1,conn2D+conn2DIndx[*candidate2D+1]);
00509           std::sort(conn2.begin(),conn2.end());
00510           std::list<int> intersect;
00511           std::set_intersection(connSorted.begin(),connSorted.end(),conn2.begin(),conn2.end(),
00512                                 std::insert_iterator< std::list<int> >(intersect,intersect.begin()));
00513           if(intersect.empty())
00514             return *candidate2D;
00515         }
00516     }
00517   std::ostringstream ost; ost << "Impossible to find an opposite 2D face of face # " <<  current2DCell;
00518   ost << " in 3D cell # " << current3DCell << " : Impossible or call tryToShareSameCoords method !";
00519   throw INTERP_KERNEL::Exception(ost.str().c_str());
00520 }
00521 
00522 void MEDCouplingExtrudedMesh::computeBaryCenterOfFace(const std::vector<int>& nodalConnec, int lev1DId)
00523 {
00524   double *zoneToUpdate=_mesh1D->getCoords()->getPointer()+lev1DId*3;
00525   std::fill(zoneToUpdate,zoneToUpdate+3,0.);
00526   const double *coords=_mesh2D->getCoords()->getConstPointer();
00527   for(std::vector<int>::const_iterator iter=nodalConnec.begin();iter!=nodalConnec.end();iter++)
00528     std::transform(zoneToUpdate,zoneToUpdate+3,coords+3*(*iter),zoneToUpdate,std::plus<double>());
00529   std::transform(zoneToUpdate,zoneToUpdate+3,zoneToUpdate,std::bind2nd(std::multiplies<double>(),(double)(1./(int)nodalConnec.size())));
00530 }
00531 
00532 int MEDCouplingExtrudedMesh::FindCorrespCellByNodalConn(const std::vector<int>& nodalConnec, const int *revNodalPtr, const int *revNodalIndxPtr) throw(INTERP_KERNEL::Exception)
00533 {
00534   std::vector<int>::const_iterator iter=nodalConnec.begin();
00535   std::set<int> s1(revNodalPtr+revNodalIndxPtr[*iter],revNodalPtr+revNodalIndxPtr[*iter+1]);
00536   iter++;
00537   for(;iter!=nodalConnec.end();iter++)
00538     {
00539       std::set<int> s2(revNodalPtr+revNodalIndxPtr[*iter],revNodalPtr+revNodalIndxPtr[*iter+1]);
00540       std::set<int> s3;
00541       std::set_intersection(s1.begin(),s1.end(),s2.begin(),s2.end(),std::insert_iterator< std::set<int> >(s3,s3.end()));
00542       s1=s3;
00543     }
00544   if(s1.size()==1)
00545     return *(s1.begin());
00546   std::ostringstream ostr;
00547   ostr << "Cell with nodal connec : ";
00548   std::copy(nodalConnec.begin(),nodalConnec.end(),std::ostream_iterator<int>(ostr," "));
00549   ostr << " is not part of mesh";
00550   throw INTERP_KERNEL::Exception(ostr.str().c_str());
00551 }
00552 
00566 void MEDCouplingExtrudedMesh::Project1DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps,
00567                                               MEDCouplingUMesh *&m1r, MEDCouplingUMesh *&m2r, double *v) throw(INTERP_KERNEL::Exception)
00568 {
00569   if(m1->getSpaceDimension()!=3 || m1->getSpaceDimension()!=3)
00570     throw INTERP_KERNEL::Exception("Input meshes are expected to have a spaceDim==3 for Projec1D !");
00571   m1r=m1->clone(true);
00572   m2r=m2->clone(true);
00573   m1r->changeSpaceDimension(1);
00574   m2r->changeSpaceDimension(1);
00575   std::vector<int> c;
00576   std::vector<double> ref,ref2;
00577   m1->getNodeIdsOfCell(0,c);
00578   m1->getCoordinatesOfNode(c[0],ref);
00579   m1->getCoordinatesOfNode(c[1],ref2);
00580   std::transform(ref2.begin(),ref2.end(),ref.begin(),v,std::minus<double>());
00581   double n=INTERP_KERNEL::norm<3>(v);
00582   std::transform(v,v+3,v,std::bind2nd(std::multiplies<double>(),1/n));
00583   m1->project1D(&ref[0],v,eps,m1r->getCoords()->getPointer());
00584   m2->project1D(&ref[0],v,eps,m2r->getCoords()->getPointer());
00585   
00586 }
00587 
00588 void MEDCouplingExtrudedMesh::rotate(const double *center, const double *vector, double angle)
00589 {
00590   _mesh2D->rotate(center,vector,angle);
00591   _mesh1D->rotate(center,vector,angle);
00592 }
00593 
00594 void MEDCouplingExtrudedMesh::translate(const double *vector)
00595 {
00596   _mesh2D->translate(vector);
00597   _mesh1D->translate(vector);
00598 }
00599 
00600 void MEDCouplingExtrudedMesh::scale(const double *point, double factor)
00601 {
00602   _mesh2D->scale(point,factor);
00603   _mesh1D->scale(point,factor);
00604 }
00605 
00606 std::vector<int> MEDCouplingExtrudedMesh::getDistributionOfTypes() const throw(INTERP_KERNEL::Exception)
00607 {
00608   throw INTERP_KERNEL::Exception("Not implemented yet !");
00609 }
00610 
00611 DataArrayInt *MEDCouplingExtrudedMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
00612 {
00613   throw INTERP_KERNEL::Exception("Not implemented yet !");
00614 }
00615 
00616 void MEDCouplingExtrudedMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
00617 {
00618   throw INTERP_KERNEL::Exception("Not implemented yet !");
00619 }
00620 
00621 MEDCouplingMesh *MEDCouplingExtrudedMesh::buildPart(const int *start, const int *end) const
00622 {
00623   // not implemented yet !
00624   return 0;
00625 }
00626 
00627 MEDCouplingMesh *MEDCouplingExtrudedMesh::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const
00628 {
00629   // not implemented yet !
00630   return 0;
00631 }
00632 
00633 DataArrayInt *MEDCouplingExtrudedMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
00634 {
00635   throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::simplexize : unavailable for such a type of mesh : Extruded !");
00636 }
00637 
00638 MEDCouplingMesh *MEDCouplingExtrudedMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
00639 {
00640   // not implemented yet !
00641   return 0;
00642 }
00643 
00644 DataArrayDouble *MEDCouplingExtrudedMesh::getCoordinatesAndOwner() const
00645 {
00646   DataArrayDouble *arr2D=_mesh2D->getCoords();
00647   DataArrayDouble *arr1D=_mesh1D->getCoords();
00648   DataArrayDouble *ret=DataArrayDouble::New();
00649   ret->alloc(getNumberOfNodes(),3);
00650   int nbOf1DLev=_mesh1D->getNumberOfNodes();
00651   int nbOf2DNodes=_mesh2D->getNumberOfNodes();
00652   const double *ptSrc=arr2D->getConstPointer();
00653   double *pt=ret->getPointer();
00654   std::copy(ptSrc,ptSrc+3*nbOf2DNodes,pt);
00655   for(int i=1;i<nbOf1DLev;i++)
00656     {
00657       std::copy(ptSrc,ptSrc+3*nbOf2DNodes,pt+3*i*nbOf2DNodes);
00658       double vec[3];
00659       std::copy(arr1D->getConstPointer()+3*i,arr1D->getConstPointer()+3*(i+1),vec);
00660       std::transform(arr1D->getConstPointer()+3*(i-1),arr1D->getConstPointer()+3*i,vec,vec,std::minus<double>());
00661       for(int j=0;j<nbOf2DNodes;j++)
00662         std::transform(vec,vec+3,pt+3*(i*nbOf2DNodes+j),pt+3*(i*nbOf2DNodes+j),std::plus<double>());
00663     }
00664   return ret;
00665 }
00666 
00667 DataArrayDouble *MEDCouplingExtrudedMesh::getBarycenterAndOwner() const
00668 {
00669   //not yet implemented
00670   return 0;
00671 }
00672 
00673 void MEDCouplingExtrudedMesh::computeExtrusionAlg(const MEDCouplingUMesh *mesh3D) throw(INTERP_KERNEL::Exception)
00674 {
00675   _mesh3D_ids->alloc(mesh3D->getNumberOfCells(),1);
00676   int nbOf1DLev=mesh3D->getNumberOfCells()/_mesh2D->getNumberOfCells();
00677   _mesh1D->setMeshDimension(1);
00678   _mesh1D->allocateCells(nbOf1DLev);
00679   int tmpConn[2];
00680   for(int i=0;i<nbOf1DLev;i++)
00681     {
00682       tmpConn[0]=i;
00683       tmpConn[1]=i+1;
00684       _mesh1D->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,tmpConn);
00685     }
00686   _mesh1D->finishInsertingCells();
00687   DataArrayDouble *myCoords=DataArrayDouble::New();
00688   myCoords->alloc(nbOf1DLev+1,3);
00689   _mesh1D->setCoords(myCoords);
00690   myCoords->decrRef();
00691   DataArrayInt *desc,*descIndx,*revDesc,*revDescIndx;
00692   desc=DataArrayInt::New(); descIndx=DataArrayInt::New(); revDesc=DataArrayInt::New(); revDescIndx=DataArrayInt::New();
00693   MEDCouplingUMesh *subMesh=mesh3D->buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx);
00694   DataArrayInt *revNodal2D,*revNodalIndx2D;
00695   revNodal2D=DataArrayInt::New(); revNodalIndx2D=DataArrayInt::New();
00696   subMesh->getReverseNodalConnectivity(revNodal2D,revNodalIndx2D);
00697   const int *nodal2D=_mesh2D->getNodalConnectivity()->getConstPointer();
00698   const int *nodal2DIndx=_mesh2D->getNodalConnectivityIndex()->getConstPointer();
00699   const int *revNodal2DPtr=revNodal2D->getConstPointer();
00700   const int *revNodalIndx2DPtr=revNodalIndx2D->getConstPointer();
00701   const int *descP=desc->getConstPointer();
00702   const int *descIndxP=descIndx->getConstPointer();
00703   const int *revDescP=revDesc->getConstPointer();
00704   const int *revDescIndxP=revDescIndx->getConstPointer();
00705   //
00706   int nbOf2DCells=_mesh2D->getNumberOfCells();
00707   for(int i=0;i<nbOf2DCells;i++)
00708     {
00709       int idInSubMesh;
00710        std::vector<int> nodalConnec(nodal2D+nodal2DIndx[i]+1,nodal2D+nodal2DIndx[i+1]);
00711        try
00712         {
00713           idInSubMesh=FindCorrespCellByNodalConn(nodalConnec,revNodal2DPtr,revNodalIndx2DPtr);
00714         }
00715        catch(INTERP_KERNEL::Exception& e)
00716          {
00717            std::ostringstream ostr; ostr << "mesh2D cell # " << i << " is not part of any cell of 3D mesh !\n";
00718            ostr << e.what();
00719            throw INTERP_KERNEL::Exception(ostr.str().c_str());
00720          }
00721        build1DExtrusion(idInSubMesh,i,nbOf1DLev,subMesh,descP,descIndxP,revDescP,revDescIndxP,i==_cell_2D_id);
00722     }
00723   //
00724   revNodal2D->decrRef();
00725   revNodalIndx2D->decrRef();
00726   subMesh->decrRef();
00727   desc->decrRef();
00728   descIndx->decrRef();
00729   revDesc->decrRef();
00730   revDescIndx->decrRef();
00731 }
00732 
00733 void MEDCouplingExtrudedMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
00734 {
00735   std::vector<int> tinyInfo1;
00736   std::vector<std::string> ls1;
00737   std::vector<double> ls3;
00738   _mesh2D->getTinySerializationInformation(ls3,tinyInfo1,ls1);
00739   std::vector<int> tinyInfo2;
00740   std::vector<std::string> ls2;
00741   std::vector<double> ls4;
00742   _mesh1D->getTinySerializationInformation(ls4,tinyInfo2,ls2);
00743   tinyInfo.clear(); littleStrings.clear();
00744   tinyInfo.insert(tinyInfo.end(),tinyInfo1.begin(),tinyInfo1.end());
00745   littleStrings.insert(littleStrings.end(),ls1.begin(),ls1.end());
00746   tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
00747   littleStrings.insert(littleStrings.end(),ls2.begin(),ls2.end());
00748   tinyInfo.push_back(_cell_2D_id);
00749   tinyInfo.push_back((int)tinyInfo1.size());
00750   tinyInfo.push_back(_mesh3D_ids->getNbOfElems());
00751   littleStrings.push_back(getName());
00752   littleStrings.push_back(getDescription());
00753 }
00754 
00755 void MEDCouplingExtrudedMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
00756 {
00757   std::size_t sz=tinyInfo.size();
00758   int sz1=tinyInfo[sz-2];
00759   std::vector<int> ti1(tinyInfo.begin(),tinyInfo.begin()+sz1);
00760   std::vector<int> ti2(tinyInfo.begin()+sz1,tinyInfo.end()-3);
00761   MEDCouplingUMesh *um=MEDCouplingUMesh::New();
00762   DataArrayInt *a1tmp=DataArrayInt::New();
00763   DataArrayDouble *a2tmp=DataArrayDouble::New();
00764   int la1=0,la2=0;
00765   std::vector<std::string> ls1,ls2;
00766   um->resizeForUnserialization(ti1,a1tmp,a2tmp,ls1);
00767   la1+=a1tmp->getNbOfElems(); la2+=a2tmp->getNbOfElems();
00768   a1tmp->decrRef(); a2tmp->decrRef();
00769   a1tmp=DataArrayInt::New(); a2tmp=DataArrayDouble::New();
00770   um->resizeForUnserialization(ti2,a1tmp,a2tmp,ls2);
00771   la1+=a1tmp->getNbOfElems(); la2+=a2tmp->getNbOfElems();
00772   a1tmp->decrRef(); a2tmp->decrRef();
00773   um->decrRef();
00774   //
00775   a1->alloc(la1+tinyInfo[sz-1],1);
00776   a2->alloc(la2,1);
00777   littleStrings.resize(ls1.size()+ls2.size()+2);
00778 }
00779 
00780 void MEDCouplingExtrudedMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
00781 {
00782   a1=DataArrayInt::New(); a2=DataArrayDouble::New();
00783   DataArrayInt *a1_1=0,*a1_2=0;
00784   DataArrayDouble *a2_1=0,*a2_2=0;
00785   _mesh2D->serialize(a1_1,a2_1);
00786   _mesh1D->serialize(a1_2,a2_2);
00787   a1->alloc(a1_1->getNbOfElems()+a1_2->getNbOfElems()+_mesh3D_ids->getNbOfElems(),1);
00788   int *ptri=a1->getPointer();
00789   ptri=std::copy(a1_1->getConstPointer(),a1_1->getConstPointer()+a1_1->getNbOfElems(),ptri);
00790   a1_1->decrRef();
00791   ptri=std::copy(a1_2->getConstPointer(),a1_2->getConstPointer()+a1_2->getNbOfElems(),ptri);
00792   a1_2->decrRef();
00793   std::copy(_mesh3D_ids->getConstPointer(),_mesh3D_ids->getConstPointer()+_mesh3D_ids->getNbOfElems(),ptri);
00794   a2->alloc(a2_1->getNbOfElems()+a2_2->getNbOfElems(),1);
00795   double *ptrd=a2->getPointer();
00796   ptrd=std::copy(a2_1->getConstPointer(),a2_1->getConstPointer()+a2_1->getNbOfElems(),ptrd);
00797   a2_1->decrRef();
00798   std::copy(a2_2->getConstPointer(),a2_2->getConstPointer()+a2_2->getNbOfElems(),ptrd);
00799   a2_2->decrRef();
00800 }
00801 
00802 void MEDCouplingExtrudedMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector<std::string>& littleStrings)
00803 {
00804   setName(littleStrings[littleStrings.size()-2].c_str());
00805   setDescription(littleStrings.back().c_str());
00806   std::size_t sz=tinyInfo.size();
00807   int sz1=tinyInfo[sz-2];
00808   _cell_2D_id=tinyInfo[sz-3];
00809   std::vector<int> ti1(tinyInfo.begin(),tinyInfo.begin()+sz1);
00810   std::vector<int> ti2(tinyInfo.begin()+sz1,tinyInfo.end()-3);
00811   DataArrayInt *a1tmp=DataArrayInt::New();
00812   DataArrayDouble *a2tmp=DataArrayDouble::New();
00813   const int *a1Ptr=a1->getConstPointer();
00814   const double *a2Ptr=a2->getConstPointer();
00815   _mesh2D=MEDCouplingUMesh::New();
00816   std::vector<std::string> ls1,ls2;
00817   _mesh2D->resizeForUnserialization(ti1,a1tmp,a2tmp,ls1);
00818   std::copy(a2Ptr,a2Ptr+a2tmp->getNbOfElems(),a2tmp->getPointer());
00819   std::copy(a1Ptr,a1Ptr+a1tmp->getNbOfElems(),a1tmp->getPointer());
00820   a2Ptr+=a2tmp->getNbOfElems();
00821   a1Ptr+=a1tmp->getNbOfElems();
00822   ls2.insert(ls2.end(),littleStrings.begin(),littleStrings.begin()+ls1.size());
00823   std::vector<double> d1(1);
00824   _mesh2D->unserialization(d1,ti1,a1tmp,a2tmp,ls2);
00825   a1tmp->decrRef(); a2tmp->decrRef();
00826   //
00827   ls2.clear();
00828   ls2.insert(ls2.end(),littleStrings.begin()+ls1.size(),littleStrings.end()-2);
00829   _mesh1D=MEDCouplingUMesh::New();
00830   a1tmp=DataArrayInt::New(); a2tmp=DataArrayDouble::New();
00831   _mesh1D->resizeForUnserialization(ti2,a1tmp,a2tmp,ls1);
00832   std::copy(a2Ptr,a2Ptr+a2tmp->getNbOfElems(),a2tmp->getPointer());
00833   std::copy(a1Ptr,a1Ptr+a1tmp->getNbOfElems(),a1tmp->getPointer());
00834   a1Ptr+=a1tmp->getNbOfElems();
00835   _mesh1D->unserialization(d1,ti2,a1tmp,a2tmp,ls2);
00836   a1tmp->decrRef(); a2tmp->decrRef();
00837   //
00838   _mesh3D_ids=DataArrayInt::New();
00839   int szIds=(int)std::distance(a1Ptr,a1->getConstPointer()+a1->getNbOfElems());
00840   _mesh3D_ids->alloc(szIds,1);
00841   std::copy(a1Ptr,a1Ptr+szIds,_mesh3D_ids->getPointer());
00842 }
00843 
00844 void MEDCouplingExtrudedMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception)
00845 {
00846   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
00847   m->writeVTKLL(ofs,cellData,pointData);
00848 }
00849 
00850 std::string MEDCouplingExtrudedMesh::getVTKDataSetType() const throw(INTERP_KERNEL::Exception)
00851 {
00852   return _mesh2D->getVTKDataSetType();
00853 }