Back to index

salome-med  6.5.0
MEDCouplingCMesh.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 "MEDCouplingCMesh.hxx"
00021 #include "MEDCouplingUMesh.hxx"
00022 #include "MEDCouplingMemArray.hxx"
00023 #include "MEDCouplingFieldDouble.hxx"
00024 
00025 #include <functional>
00026 #include <algorithm>
00027 #include <sstream>
00028 #include <numeric>
00029 
00030 using namespace ParaMEDMEM;
00031 
00032 MEDCouplingCMesh::MEDCouplingCMesh():_x_array(0),_y_array(0),_z_array(0)
00033 {
00034 }
00035 
00036 MEDCouplingCMesh::MEDCouplingCMesh(const MEDCouplingCMesh& other, bool deepCopy):MEDCouplingMesh(other)
00037 {
00038   if(deepCopy)
00039     {
00040       if(other._x_array)
00041         _x_array=other._x_array->deepCpy();
00042       else
00043         _x_array=0;
00044       if(other._y_array)
00045         _y_array=other._y_array->deepCpy();
00046       else
00047         _y_array=0;
00048       if(other._z_array)
00049         _z_array=other._z_array->deepCpy();
00050       else
00051         _z_array=0;
00052     }
00053   else
00054     {
00055       _x_array=other._x_array;
00056       if(_x_array)
00057         _x_array->incrRef();
00058       _y_array=other._y_array;
00059       if(_y_array)
00060         _y_array->incrRef();
00061       _z_array=other._z_array;
00062       if(_z_array)
00063         _z_array->incrRef();
00064     }
00065 }
00066 
00067 MEDCouplingCMesh::~MEDCouplingCMesh()
00068 {
00069   if(_x_array)
00070     _x_array->decrRef();
00071   if(_y_array)
00072     _y_array->decrRef();
00073   if(_z_array)
00074     _z_array->decrRef();
00075 }
00076 
00077 MEDCouplingCMesh *MEDCouplingCMesh::New()
00078 {
00079   return new MEDCouplingCMesh;
00080 }
00081 
00082 MEDCouplingMesh *MEDCouplingCMesh::deepCpy() const
00083 {
00084   return clone(true);
00085 }
00086 
00087 MEDCouplingCMesh *MEDCouplingCMesh::clone(bool recDeepCpy) const
00088 {
00089   return new MEDCouplingCMesh(*this,recDeepCpy);
00090 }
00091 
00092 void MEDCouplingCMesh::updateTime() const
00093 {
00094   if(_x_array)
00095     updateTimeWith(*_x_array);
00096   if(_y_array)
00097     updateTimeWith(*_y_array);
00098   if(_z_array)
00099     updateTimeWith(*_z_array);
00100 }
00101 
00106 void MEDCouplingCMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception)
00107 { 
00108   const MEDCouplingCMesh *otherC=dynamic_cast<const MEDCouplingCMesh *>(other);
00109   if(!otherC)
00110     throw INTERP_KERNEL::Exception("MEDCouplingCMesh::copyTinyStringsFrom : meshes have not same type !");
00111   MEDCouplingMesh::copyTinyStringsFrom(other);
00112   if(_x_array && otherC->_x_array)
00113     _x_array->copyStringInfoFrom(*otherC->_x_array);
00114   if(_y_array && otherC->_y_array)
00115     _y_array->copyStringInfoFrom(*otherC->_y_array);
00116   if(_z_array && otherC->_z_array)
00117     _z_array->copyStringInfoFrom(*otherC->_z_array);
00118 }
00119 
00120 bool MEDCouplingCMesh::isEqual(const MEDCouplingMesh *other, double prec) const
00121 {
00122   const MEDCouplingCMesh *otherC=dynamic_cast<const MEDCouplingCMesh *>(other);
00123   if(!otherC)
00124     return false;
00125   if(!MEDCouplingMesh::isEqual(other,prec))
00126     return false;
00127   const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
00128   const DataArrayDouble *otherArr[3]={otherC->_x_array,otherC->_y_array,otherC->_z_array};
00129   for(int i=0;i<3;i++)
00130     {
00131       if((thisArr[i]!=0 && otherArr[i]==0) || (thisArr[i]==0 && otherArr[i]!=0))
00132         return false;
00133       if(thisArr[i])
00134         if(!thisArr[i]->isEqual(*otherArr[i],prec))
00135           return false;
00136     }
00137   return true;
00138 }
00139 
00140 bool MEDCouplingCMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
00141 {
00142   const MEDCouplingCMesh *otherC=dynamic_cast<const MEDCouplingCMesh *>(other);
00143   if(!otherC)
00144     return false;
00145   const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
00146   const DataArrayDouble *otherArr[3]={otherC->_x_array,otherC->_y_array,otherC->_z_array};
00147   for(int i=0;i<3;i++)
00148     {
00149       if((thisArr[i]!=0 && otherArr[i]==0) || (thisArr[i]==0 && otherArr[i]!=0))
00150         return false;
00151       if(thisArr[i])
00152         if(!thisArr[i]->isEqualWithoutConsideringStr(*otherArr[i],prec))
00153           return false;
00154     }
00155   return true;
00156 }
00157 
00158 void MEDCouplingCMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
00159                                             DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception)
00160 {
00161   if(!isEqualWithoutConsideringStr(other,prec))
00162     throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkDeepEquivalWith : Meshes are not the same !");
00163 }
00164 
00169 void MEDCouplingCMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
00170                                                        DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception)
00171 {
00172   const MEDCouplingCMesh *otherC=dynamic_cast<const MEDCouplingCMesh *>(other);
00173   if(!otherC)
00174     throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkDeepEquivalOnSameNodesWith : other is NOT a cartesian mesh ! Impossible to check equivalence !");
00175 }
00176 
00177 void MEDCouplingCMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
00178 {
00179   const char msg0[]="Invalid ";
00180   const char msg1[]=" array ! Must contain more than 1 element.";
00181   const char msg2[]=" array ! Must be with only one component.";
00182   if(_x_array)
00183     {
00184       if(_x_array->getNbOfElems()<2)
00185         {
00186           std::ostringstream os; os << msg0 << 'X' << msg1;
00187           throw INTERP_KERNEL::Exception(os.str().c_str());
00188         }
00189       if(_x_array->getNumberOfComponents()!=1)
00190         {
00191           std::ostringstream os; os << msg0 << 'X' << msg2;
00192           throw INTERP_KERNEL::Exception(os.str().c_str());
00193         }
00194     }
00195   if(_y_array)
00196     {
00197       if(_y_array->getNbOfElems()<2)
00198         {
00199           std::ostringstream os; os << msg0 << 'Y' << msg1;
00200           throw INTERP_KERNEL::Exception(os.str().c_str());
00201         }
00202       if(_y_array->getNumberOfComponents()!=1)
00203         {
00204           std::ostringstream os; os << msg0 << 'Y' << msg2;
00205           throw INTERP_KERNEL::Exception(os.str().c_str());
00206         }
00207       
00208     }
00209   if(_z_array)
00210     {
00211       if(_z_array->getNbOfElems()<2)
00212         {
00213           std::ostringstream os; os << msg0 << 'Z' << msg1;
00214           throw INTERP_KERNEL::Exception(os.str().c_str());
00215         }
00216       if(_z_array->getNumberOfComponents()!=1)
00217         {
00218           std::ostringstream os; os << msg0 << 'Z' << msg2;
00219           throw INTERP_KERNEL::Exception(os.str().c_str());
00220         }
00221     }
00222 }
00223 
00224 void MEDCouplingCMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
00225 {
00226   checkCoherency();
00227   if(_x_array)
00228     _x_array->checkMonotonic(true, eps);
00229   if(_y_array)
00230     _y_array->checkMonotonic(true, eps);
00231   if(_z_array)
00232     _z_array->checkMonotonic(true, eps);
00233 }
00234 
00235 void MEDCouplingCMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
00236 {
00237   checkCoherency1(eps);
00238 }
00239 
00240 int MEDCouplingCMesh::getNumberOfCells() const
00241 {
00242   int ret=1;
00243   if(_x_array)
00244     ret*=_x_array->getNbOfElems()-1;
00245   if(_y_array)
00246     ret*=_y_array->getNbOfElems()-1;
00247   if(_z_array)
00248     ret*=_z_array->getNbOfElems()-1;
00249   return ret;
00250 }
00251 
00252 int MEDCouplingCMesh::getNumberOfNodes() const
00253 {
00254   int ret=1;
00255   if(_x_array)
00256     ret*=_x_array->getNbOfElems();
00257   if(_y_array)
00258     ret*=_y_array->getNbOfElems();
00259   if(_z_array)
00260     ret*=_z_array->getNbOfElems();
00261   return ret;
00262 }
00263 
00264 void MEDCouplingCMesh::getSplitCellValues(int *res) const
00265 {
00266   int spaceDim=getSpaceDimension();
00267   for(int l=0;l<spaceDim;l++)
00268     {
00269       int val=1;
00270       for(int p=0;p<spaceDim-l-1;p++)
00271         val*=getCoordsAt(p)->getNbOfElems()-1;
00272       res[spaceDim-l-1]=val;
00273     }
00274 }
00275 
00276 void MEDCouplingCMesh::getSplitNodeValues(int *res) const
00277 {
00278   int spaceDim=getSpaceDimension();
00279   for(int l=0;l<spaceDim;l++)
00280     {
00281       int val=1;
00282       for(int p=0;p<spaceDim-l-1;p++)
00283         val*=getCoordsAt(p)->getNbOfElems();
00284       res[spaceDim-l-1]=val;
00285     }
00286 }
00287 
00288 int MEDCouplingCMesh::getCellIdFromPos(int i, int j, int k) const
00289 {
00290   int tmp[3]={i,j,k};
00291   int tmp2[3];
00292   int spaceDim=getSpaceDimension();
00293   getSplitCellValues(tmp2);
00294   std::transform(tmp,tmp+spaceDim,tmp2,tmp,std::multiplies<int>());
00295   return std::accumulate(tmp,tmp+spaceDim,0);
00296 }
00297 
00298 int MEDCouplingCMesh::getNodeIdFromPos(int i, int j, int k) const
00299 {
00300   int tmp[3]={i,j,k};
00301   int tmp2[3];
00302   int spaceDim=getSpaceDimension();
00303   getSplitNodeValues(tmp2);
00304   std::transform(tmp,tmp+spaceDim,tmp2,tmp,std::multiplies<int>());
00305   return std::accumulate(tmp,tmp+spaceDim,0);
00306 }
00307 
00308 void MEDCouplingCMesh::GetPosFromId(int nodeId, int spaceDim, const int *split, int *res)
00309 {
00310   int work=nodeId;
00311   for(int i=spaceDim-1;i>=0;i--)
00312     {
00313       int pos=work/split[i];
00314       work=work%split[i];
00315       res[i]=pos;
00316     }
00317 }
00318 
00319 int MEDCouplingCMesh::getSpaceDimension() const
00320 {
00321   int ret=0;
00322   if(_x_array)
00323     ret++;
00324   if(_y_array)
00325     ret++;
00326   if(_z_array)
00327     ret++;
00328   return ret;
00329 }
00330 
00331 int MEDCouplingCMesh::getMeshDimension() const
00332 {
00333   return getSpaceDimension();
00334 }
00335 
00336 INTERP_KERNEL::NormalizedCellType MEDCouplingCMesh::getTypeOfCell(int cellId) const
00337 {
00338   switch(getMeshDimension())
00339     {
00340     case 3:
00341       return INTERP_KERNEL::NORM_HEXA8;
00342     case 2:
00343       return INTERP_KERNEL::NORM_QUAD4;
00344     case 1:
00345       return INTERP_KERNEL::NORM_SEG2;
00346     default:
00347       throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingCMesh::getTypeOfCell !");
00348     }
00349 }
00350 
00351 std::set<INTERP_KERNEL::NormalizedCellType> MEDCouplingCMesh::getAllGeoTypes() const
00352 {
00353   INTERP_KERNEL::NormalizedCellType ret;
00354   switch(getMeshDimension())
00355     {
00356     case 3:
00357       ret=INTERP_KERNEL::NORM_HEXA8;
00358       break;
00359     case 2:
00360       ret=INTERP_KERNEL::NORM_QUAD4;
00361       break;
00362     case 1:
00363       ret=INTERP_KERNEL::NORM_SEG2;
00364       break;
00365     default:
00366       throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingCMesh::getAllGeoTypes !");
00367     }
00368   std::set<INTERP_KERNEL::NormalizedCellType> ret2;
00369   ret2.insert(ret);
00370   return ret2;
00371 }
00372 
00373 int MEDCouplingCMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
00374 {
00375   int ret=getNumberOfCells();
00376   int dim=getMeshDimension();
00377   switch(type)
00378     {
00379     case INTERP_KERNEL::NORM_HEXA8:
00380       if(dim==3)
00381         return ret;
00382     case INTERP_KERNEL::NORM_QUAD4:
00383       if(dim==2)
00384         return ret;
00385     case INTERP_KERNEL::NORM_SEG2:
00386       if(dim==1)
00387         return ret;
00388     default:
00389       throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingCMesh::getTypeOfCell !");
00390     }
00391   return 0;
00392 }
00393 
00394 void MEDCouplingCMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
00395 {
00396   int spaceDim=getSpaceDimension();
00397   int tmpCell[3],tmpNode[3];
00398   getSplitCellValues(tmpCell);
00399   getSplitNodeValues(tmpNode);
00400   int tmp2[3];
00401   GetPosFromId(cellId,spaceDim,tmpCell,tmp2);
00402   switch(spaceDim)
00403     {
00404     case 1:
00405       conn.push_back(tmp2[0]); conn.push_back(tmp2[0]+1);
00406       break;
00407     case 2:
00408       conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1);
00409       conn.push_back((tmp2[1]+1)*(tmpCell[1]+1)+tmp2[0]+1); conn.push_back((tmp2[1]+1)*(tmpCell[1]+1)+tmp2[0]);
00410       break;
00411     case 3:
00412       conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+tmp2[2]*tmpNode[2]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1+tmp2[2]*tmpNode[2]);
00413       conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+1+tmp2[2]*tmpNode[2]); conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+tmp2[2]*tmpNode[2]);
00414       conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+(tmp2[2]+1)*tmpNode[2]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1+(tmp2[2]+1)*tmpNode[2]);
00415       conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+1+(tmp2[2]+1)*tmpNode[2]); conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+(tmp2[2]+1)*tmpNode[2]);
00416       break;
00417     default:
00418       throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeIdsOfCell : big problem spacedim must be in 1,2 or 3 !");
00419     };
00420 }
00421 
00422 void MEDCouplingCMesh::getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const throw(INTERP_KERNEL::Exception)
00423 {
00424   int tmp[3];
00425   int spaceDim=getSpaceDimension();
00426   getSplitNodeValues(tmp);
00427   const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)};
00428   int tmp2[3];
00429   GetPosFromId(nodeId,spaceDim,tmp,tmp2);
00430   for(int j=0;j<spaceDim;j++)
00431     if(tabs[j])
00432       coo.push_back(tabs[j]->getConstPointer()[tmp2[j]]);
00433 }
00434 
00435 std::string MEDCouplingCMesh::simpleRepr() const
00436 {
00437   std::ostringstream ret;
00438   ret << "Cartesian mesh with name : \"" << getName() << "\"\n";
00439   ret << "Description of mesh : \"" << getDescription() << "\"\n";
00440   int tmpp1,tmpp2;
00441   double tt=getTime(tmpp1,tmpp2);
00442   ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
00443   ret << "Iteration : " << tmpp1  << " Order : " << tmpp2 << "\n";
00444   ret << "Mesh and SpaceDimension dimension : " << getSpaceDimension() << "\n\nArrays :\n________\n\n";
00445   if(_x_array)
00446     {
00447       ret << "X Array :\n";
00448       _x_array->reprZipWithoutNameStream(ret);
00449     }
00450   if(_y_array)
00451     {
00452       ret << "Y Array :\n";
00453       _y_array->reprZipWithoutNameStream(ret);
00454     }
00455   if(_z_array)
00456     {
00457       ret << "Z Array :\n";
00458       _z_array->reprZipWithoutNameStream(ret);
00459     }
00460   return ret.str();
00461 }
00462 
00463 std::string MEDCouplingCMesh::advancedRepr() const
00464 {
00465   return simpleRepr();
00466 }
00467 
00468 const DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) const throw(INTERP_KERNEL::Exception)
00469 {
00470   switch(i)
00471     {
00472     case 0:
00473       return _x_array;
00474     case 1:
00475       return _y_array;
00476     case 2:
00477       return _z_array;
00478     default:
00479       throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2.");
00480     }
00481 }
00482 
00483 DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) throw(INTERP_KERNEL::Exception)
00484 {
00485   switch(i)
00486     {
00487     case 0:
00488       return _x_array;
00489     case 1:
00490       return _y_array;
00491     case 2:
00492       return _z_array;
00493     default:
00494       throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2.");
00495     }
00496 }
00497 
00498 void MEDCouplingCMesh::setCoordsAt(int i, const DataArrayDouble *arr) throw(INTERP_KERNEL::Exception)
00499 {
00500   DataArrayDouble **thisArr[3]={&_x_array,&_y_array,&_z_array};
00501   if(i<0 || i>2)
00502     throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2.");
00503   if(arr!=*(thisArr[i]))
00504     {
00505       if(*(thisArr[i]))
00506         (*(thisArr[i]))->decrRef();
00507       (*(thisArr[i]))=const_cast<DataArrayDouble *>(arr);
00508       if(*(thisArr[i]))
00509         (*(thisArr[i]))->incrRef();
00510       declareAsNew();
00511     }
00512 }
00513 
00514 void MEDCouplingCMesh::setCoords(const DataArrayDouble *coordsX, const DataArrayDouble *coordsY, const DataArrayDouble *coordsZ)
00515 {
00516   if(_x_array)
00517     _x_array->decrRef();
00518   _x_array=const_cast<DataArrayDouble *>(coordsX);
00519   if(_x_array)
00520     _x_array->incrRef();
00521   if(_y_array)
00522     _y_array->decrRef();
00523   _y_array=const_cast<DataArrayDouble *>(coordsY);
00524   if(_y_array)
00525     _y_array->incrRef();
00526   if(_z_array)
00527     _z_array->decrRef();
00528   _z_array=const_cast<DataArrayDouble *>(coordsZ);
00529   if(_z_array)
00530     _z_array->incrRef();
00531   declareAsNew();
00532 }
00533 
00537 std::vector<int> MEDCouplingCMesh::getDistributionOfTypes() const throw(INTERP_KERNEL::Exception)
00538 {
00539   //only one type of cell
00540   std::vector<int> ret(3);
00541   ret[0]=getTypeOfCell(0);
00542   ret[1]=getNumberOfCells();
00543   ret[2]=0; //ret[3*k+2]==0 because it has no sense here
00544   return ret;
00545 }
00546 
00550 DataArrayInt *MEDCouplingCMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
00551 {
00552   if(code.empty())
00553     throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : code is empty, should not !");
00554   std::size_t sz=code.size();
00555   if(sz!=3)
00556     throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : code should be of size 3 exactly !");
00557 
00558   int nbCells=getNumberOfCellsWithType((INTERP_KERNEL::NormalizedCellType)code[0]);
00559   if(code[2]==-1)
00560     {
00561       if(code[1]==nbCells)
00562         return 0;
00563       else
00564         throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : number of cells mismatch !");
00565     }
00566   else
00567     {
00568       if(code[2]<-1) 
00569         throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : code[2]<-1 mismatch !");
00570       if(code[2]>=(int)idsPerType.size()) 
00571         throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : code[2]>size idsPerType !");
00572       return idsPerType[code[2]]->deepCpy();
00573     }
00574 }
00575 
00579 void MEDCouplingCMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
00580 {
00581   int nbCells=getNumberOfCells();
00582   code.resize(3);
00583   code[0]=(int)getTypeOfCell(0);
00584   code[1]=nbCells;
00585   code[2]=0;
00586   idsInPflPerType.push_back(profile->deepCpy());
00587   idsPerType.push_back(profile->deepCpy());
00588 }
00589 
00590 MEDCouplingUMesh *MEDCouplingCMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
00591 {
00592   int spaceDim=getSpaceDimension();
00593   MEDCouplingUMesh *ret=MEDCouplingUMesh::New(getName(),spaceDim);
00594   DataArrayDouble *coords=getCoordinatesAndOwner();
00595   ret->setCoords(coords);
00596   coords->decrRef();
00597   switch(spaceDim)
00598     {
00599     case 1:
00600       fill1DUnstructuredMesh(ret);
00601       break;
00602     case 2:
00603       fill2DUnstructuredMesh(ret);
00604       break;
00605     case 3:
00606       fill3DUnstructuredMesh(ret);
00607       break;
00608     default:
00609       throw INTERP_KERNEL::Exception("MEDCouplingCMesh::buildUnstructured : big problem spacedim must be in 1,2 or 3 !");
00610     };
00611   return ret;
00612 }
00613 
00614 MEDCouplingMesh *MEDCouplingCMesh::buildPart(const int *start, const int *end) const
00615 {
00616   MEDCouplingUMesh *um=buildUnstructured();
00617   MEDCouplingMesh *ret=um->buildPart(start,end);
00618   um->decrRef();
00619   return ret;
00620 }
00621 
00622 MEDCouplingMesh *MEDCouplingCMesh::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const
00623 {
00624   MEDCouplingUMesh *um=buildUnstructured();
00625   MEDCouplingMesh *ret=um->buildPartAndReduceNodes(start,end,arr);
00626   um->decrRef();
00627   return ret;
00628 }
00629 
00630 DataArrayInt *MEDCouplingCMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
00631 {
00632   throw INTERP_KERNEL::Exception("MEDCouplingCMesh::simplexize : not available for Cartesian mesh !");
00633 }
00634 
00635 void MEDCouplingCMesh::getBoundingBox(double *bbox) const
00636 {
00637   int dim=getSpaceDimension();
00638   int j=0;
00639   for (int idim=0; idim<dim; idim++)
00640     {
00641       const DataArrayDouble *c=getCoordsAt(idim);
00642       if(c)
00643         {
00644           const double *coords=c->getConstPointer();
00645           int nb=c->getNbOfElems();
00646           bbox[2*j]=coords[0];
00647           bbox[2*j+1]=coords[nb-1];
00648           j++;
00649         }
00650     }
00651 }
00652 
00653 MEDCouplingFieldDouble *MEDCouplingCMesh::getMeasureField(bool isAbs) const
00654 {
00655   std::string name="MeasureOfMesh_";
00656   name+=getName();
00657   int nbelem=getNumberOfCells();
00658   MEDCouplingFieldDouble *field=MEDCouplingFieldDouble::New(ON_CELLS);
00659   field->setName(name.c_str());
00660   DataArrayDouble* array=DataArrayDouble::New();
00661   array->alloc(nbelem,1);
00662   double *area_vol=array->getPointer();
00663   field->setArray(array) ;
00664   array->decrRef();
00665   field->setMesh(const_cast<MEDCouplingCMesh *>(this));
00666   int tmp[3];
00667   getSplitCellValues(tmp);
00668   int dim=getSpaceDimension();
00669   const double **thisArr=new const double *[dim];
00670   const DataArrayDouble *thisArr2[3]={_x_array,_y_array,_z_array};
00671   for(int i=0;i<dim;i++)
00672     thisArr[i]=thisArr2[i]->getConstPointer();
00673   for(int icell=0;icell<nbelem;icell++)
00674     {
00675       int tmp2[3];
00676       GetPosFromId(icell,dim,tmp,tmp2);
00677       area_vol[icell]=1.;
00678       for(int i=0;i<dim;i++)
00679         area_vol[icell]*=thisArr[i][tmp2[i]+1]-thisArr[i][tmp2[i]];
00680     }
00681   delete [] thisArr;
00682   return field;
00683 }
00684 
00688 MEDCouplingFieldDouble *MEDCouplingCMesh::getMeasureFieldOnNode(bool isAbs) const
00689 {
00690   throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getMeasureFieldOnNode : not implemented yet !");
00691   //return 0;
00692 }
00693 
00694 MEDCouplingFieldDouble *MEDCouplingCMesh::buildOrthogonalField() const
00695 {
00696   if(getMeshDimension()!=2)
00697     throw INTERP_KERNEL::Exception("Expected a cmesh with meshDim == 2 !");
00698   MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
00699   DataArrayDouble *array=DataArrayDouble::New();
00700   int nbOfCells=getNumberOfCells();
00701   array->alloc(nbOfCells,3);
00702   double *vals=array->getPointer();
00703   for(int i=0;i<nbOfCells;i++)
00704     { vals[3*i]=0.; vals[3*i+1]=0.; vals[3*i+2]=1.; }
00705   ret->setArray(array);
00706   array->decrRef();
00707   ret->setMesh(this);
00708   return ret;
00709 }
00710 
00711 int MEDCouplingCMesh::getCellContainingPoint(const double *pos, double eps) const
00712 {
00713   int dim=getSpaceDimension();
00714   int ret=0;
00715   int coeff=1;
00716   for(int i=0;i<dim;i++)
00717     {
00718       const double *d=getCoordsAt(i)->getConstPointer();
00719       int nbOfNodes=getCoordsAt(i)->getNbOfElems();
00720       double ref=pos[i];
00721       const double *w=std::find_if(d,d+nbOfNodes,std::bind2nd(std::greater_equal<double>(),ref));
00722       int w2=(int)std::distance(d,w);
00723       if(w2<nbOfNodes)
00724         {
00725           if(w2==0)
00726             {
00727               if(ref>d[0]-eps)
00728                 w2=1;
00729               else
00730                 return -1;
00731             }
00732           ret+=coeff*(w2-1);
00733           coeff*=nbOfNodes-1;
00734         }
00735       else
00736         return -1;
00737     }
00738   return ret;
00739 }
00740 
00741 void MEDCouplingCMesh::rotate(const double *center, const double *vector, double angle)
00742 {
00743   throw INTERP_KERNEL::Exception("No rotation available on CMesh : Traduce it to StructuredMesh to apply it !");
00744 }
00745 
00746 void MEDCouplingCMesh::translate(const double *vector)
00747 {
00748   if(_x_array)
00749     std::transform(_x_array->getConstPointer(),_x_array->getConstPointer()+_x_array->getNbOfElems(),
00750                    _x_array->getPointer(),std::bind2nd(std::plus<double>(),vector[0]));
00751   if(_y_array)
00752     std::transform(_y_array->getConstPointer(),_y_array->getConstPointer()+_y_array->getNbOfElems(),
00753                    _y_array->getPointer(),std::bind2nd(std::plus<double>(),vector[1]));
00754   if(_z_array)
00755     std::transform(_z_array->getConstPointer(),_z_array->getConstPointer()+_z_array->getNbOfElems(),
00756                    _z_array->getPointer(),std::bind2nd(std::plus<double>(),vector[2]));
00757 }
00758 
00759 void MEDCouplingCMesh::scale(const double *point, double factor)
00760 {
00761   for(int i=0;i<3;i++)
00762     {
00763       DataArrayDouble *c=getCoordsAt(i);
00764       if(c)
00765         {
00766           double *coords=c->getPointer();
00767           int lgth=c->getNbOfElems();
00768           std::transform(coords,coords+lgth,coords,std::bind2nd(std::minus<double>(),point[i]));
00769           std::transform(coords,coords+lgth,coords,std::bind2nd(std::multiplies<double>(),factor));
00770           std::transform(coords,coords+lgth,coords,std::bind2nd(std::plus<double>(),point[i]));
00771           c->declareAsNew();
00772         }
00773     }
00774   updateTime();
00775 }
00776 
00777 MEDCouplingMesh *MEDCouplingCMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
00778 {
00779   //not implemented yet !
00780   return 0;
00781 }
00782 
00783 DataArrayDouble *MEDCouplingCMesh::getCoordinatesAndOwner() const
00784 {
00785   DataArrayDouble *ret=DataArrayDouble::New();
00786   int spaceDim=getSpaceDimension();
00787   int nbNodes=getNumberOfNodes();
00788   ret->alloc(nbNodes,spaceDim);
00789   double *pt=ret->getPointer();
00790   int tmp[3];
00791   getSplitNodeValues(tmp);
00792   const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)};
00793   const double *tabsPtr[3];
00794   for(int j=0;j<spaceDim;j++)
00795     {
00796       tabsPtr[j]=tabs[j]->getConstPointer();
00797       ret->setInfoOnComponent(j,tabs[j]->getInfoOnComponent(0).c_str());
00798     }
00799   int tmp2[3];
00800   for(int i=0;i<nbNodes;i++)
00801     {
00802       GetPosFromId(i,spaceDim,tmp,tmp2);
00803       for(int j=0;j<spaceDim;j++)
00804         pt[i*spaceDim+j]=tabsPtr[j][tmp2[j]];
00805     }
00806   return ret;
00807 }
00808 
00809 DataArrayDouble *MEDCouplingCMesh::getBarycenterAndOwner() const
00810 {
00811   DataArrayDouble *ret=DataArrayDouble::New();
00812   int spaceDim=getSpaceDimension();
00813   int nbCells=getNumberOfCells();
00814   ret->alloc(nbCells,spaceDim);
00815   double *pt=ret->getPointer();
00816   int tmp[3];
00817   getSplitCellValues(tmp);
00818   const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)};
00819   std::vector<double> tabsPtr[3];
00820   for(int j=0;j<spaceDim;j++)
00821     {
00822       int sz=tabs[j]->getNbOfElems()-1;
00823       ret->setInfoOnComponent(j,tabs[j]->getInfoOnComponent(0).c_str());
00824       const double *srcPtr=tabs[j]->getConstPointer();
00825       tabsPtr[j].insert(tabsPtr[j].end(),srcPtr,srcPtr+sz);
00826       std::transform(tabsPtr[j].begin(),tabsPtr[j].end(),srcPtr+1,tabsPtr[j].begin(),std::plus<double>());
00827       std::transform(tabsPtr[j].begin(),tabsPtr[j].end(),tabsPtr[j].begin(),std::bind2nd(std::multiplies<double>(),0.5));
00828     }
00829   int tmp2[3];
00830   for(int i=0;i<nbCells;i++)
00831     {
00832       GetPosFromId(i,spaceDim,tmp,tmp2);
00833       for(int j=0;j<spaceDim;j++)
00834         pt[i*spaceDim+j]=tabsPtr[j][tmp2[j]];
00835     }
00836   return ret;
00837 }
00838 
00839 void MEDCouplingCMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
00840 {
00841   throw INTERP_KERNEL::Exception("Functionnality of renumbering cell not available for CMesh !");
00842 }
00843 
00844 void MEDCouplingCMesh::fill1DUnstructuredMesh(MEDCouplingUMesh *m) const
00845 {
00846   const DataArrayDouble *c=getCoordsAt(0);
00847   int nbOfCells=c->getNbOfElems()-1;
00848   DataArrayInt *connI=DataArrayInt::New();
00849   connI->alloc(nbOfCells+1,1);
00850   int *ci=connI->getPointer();
00851   DataArrayInt *conn=DataArrayInt::New();
00852   conn->alloc(3*nbOfCells,1);
00853   ci[0]=0;
00854   int *cp=conn->getPointer();
00855   for(int i=0;i<nbOfCells;i++)
00856     {
00857       cp[3*i]=(int)INTERP_KERNEL::NORM_SEG2;
00858       cp[3*i+1]=i;
00859       cp[3*i+2]=i+1;
00860       ci[i+1]=3*(i+1);
00861     }
00862   m->setConnectivity(conn,connI,true);
00863   conn->decrRef();
00864   connI->decrRef();
00865 }
00866 
00867 void MEDCouplingCMesh::fill2DUnstructuredMesh(MEDCouplingUMesh *m) const
00868 {
00869   const DataArrayDouble *c1=getCoordsAt(0);
00870   const DataArrayDouble *c2=getCoordsAt(1);
00871   int n1=c1->getNbOfElems()-1;
00872   int n2=c2->getNbOfElems()-1;
00873   DataArrayInt *connI=DataArrayInt::New();
00874   connI->alloc(n1*n2+1,1);
00875   int *ci=connI->getPointer();
00876   DataArrayInt *conn=DataArrayInt::New();
00877   conn->alloc(5*n1*n2,1);
00878   ci[0]=0;
00879   int *cp=conn->getPointer();
00880   int pos=0;
00881   for(int j=0;j<n2;j++)
00882     for(int i=0;i<n1;i++,pos++)
00883       {
00884         cp[5*pos]=(int)INTERP_KERNEL::NORM_QUAD4;
00885         cp[5*pos+1]=i+1+j*(n1+1);
00886         cp[5*pos+2]=i+j*(n1+1);
00887         cp[5*pos+3]=i+(j+1)*(n1+1);
00888         cp[5*pos+4]=i+1+(j+1)*(n1+1);
00889         ci[pos+1]=5*(pos+1);
00890     }
00891   m->setConnectivity(conn,connI,true);
00892   conn->decrRef();
00893   connI->decrRef();
00894 }
00895 
00896 void MEDCouplingCMesh::fill3DUnstructuredMesh(MEDCouplingUMesh *m) const
00897 {
00898   const DataArrayDouble *c1=getCoordsAt(0);
00899   const DataArrayDouble *c2=getCoordsAt(1);
00900   const DataArrayDouble *c3=getCoordsAt(2);
00901   int n1=c1->getNbOfElems()-1;
00902   int n2=c2->getNbOfElems()-1;
00903   int n3=c3->getNbOfElems()-1;
00904   DataArrayInt *connI=DataArrayInt::New();
00905   connI->alloc(n1*n2*n3+1,1);
00906   int *ci=connI->getPointer();
00907   DataArrayInt *conn=DataArrayInt::New();
00908   conn->alloc(9*n1*n2*n3,1);
00909   ci[0]=0;
00910   int *cp=conn->getPointer();
00911   int pos=0;
00912   for(int k=0;k<n3;k++)
00913     for(int j=0;j<n2;j++)
00914       for(int i=0;i<n1;i++,pos++)
00915         {
00916           cp[9*pos]=(int)INTERP_KERNEL::NORM_HEXA8;
00917           int tmp=(n1+1)*(n2+1);
00918           cp[9*pos+1]=i+1+j*(n1+1)+k*tmp;
00919           cp[9*pos+2]=i+j*(n1+1)+k*tmp;
00920           cp[9*pos+3]=i+(j+1)*(n1+1)+k*tmp;
00921           cp[9*pos+4]=i+1+(j+1)*(n1+1)+k*tmp;
00922           cp[9*pos+5]=i+1+j*(n1+1)+(k+1)*tmp;
00923           cp[9*pos+6]=i+j*(n1+1)+(k+1)*tmp;
00924           cp[9*pos+7]=i+(j+1)*(n1+1)+(k+1)*tmp;
00925           cp[9*pos+8]=i+1+(j+1)*(n1+1)+(k+1)*tmp;
00926           ci[pos+1]=9*(pos+1);
00927         }
00928   m->setConnectivity(conn,connI,true);
00929   conn->decrRef();
00930   connI->decrRef();
00931 }
00932 
00933 void MEDCouplingCMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
00934 {
00935   int it,order;
00936   double time=getTime(it,order);
00937   tinyInfo.clear();
00938   tinyInfoD.clear();
00939   littleStrings.clear();
00940   littleStrings.push_back(getName());
00941   littleStrings.push_back(getDescription());
00942   littleStrings.push_back(getTimeUnit());
00943   const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
00944   for(int i=0;i<3;i++)
00945     {
00946       int val=-1;
00947       std::string st;
00948       if(thisArr[i])
00949         {
00950           val=thisArr[i]->getNumberOfTuples();
00951           st=thisArr[i]->getInfoOnComponent(0);
00952         }
00953       tinyInfo.push_back(val);
00954       littleStrings.push_back(st);
00955     }
00956   tinyInfo.push_back(it);
00957   tinyInfo.push_back(order);
00958   tinyInfoD.push_back(time);
00959 }
00960 
00961 void MEDCouplingCMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
00962 {
00963   a1->alloc(0,1);
00964   int sum=0;
00965   for(int i=0;i<3;i++)
00966     if(tinyInfo[i]!=-1)
00967       sum+=tinyInfo[i];
00968   a2->alloc(sum,1);
00969 }
00970 
00971 void MEDCouplingCMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
00972 {
00973   a1=DataArrayInt::New();
00974   a1->alloc(0,1);
00975   const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
00976   int sz=0;
00977   for(int i=0;i<3;i++)
00978     {
00979       if(thisArr[i])
00980         sz+=thisArr[i]->getNumberOfTuples();
00981     }
00982   a2=DataArrayDouble::New();
00983   a2->alloc(sz,1);
00984   double *a2Ptr=a2->getPointer();
00985   for(int i=0;i<3;i++)
00986     if(thisArr[i])
00987       a2Ptr=std::copy(thisArr[i]->getConstPointer(),thisArr[i]->getConstPointer()+thisArr[i]->getNumberOfTuples(),a2Ptr);
00988 }
00989 
00990 void MEDCouplingCMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
00991                                        const std::vector<std::string>& littleStrings)
00992 {
00993   setName(littleStrings[0].c_str());
00994   setDescription(littleStrings[1].c_str());
00995   setTimeUnit(littleStrings[2].c_str());
00996   DataArrayDouble **thisArr[3]={&_x_array,&_y_array,&_z_array};
00997   const double *data=a2->getConstPointer();
00998   for(int i=0;i<3;i++)
00999     {
01000       if(tinyInfo[i]!=-1)
01001         {
01002           (*(thisArr[i]))=DataArrayDouble::New();
01003           (*(thisArr[i]))->alloc(tinyInfo[i],1);
01004           (*(thisArr[i]))->setInfoOnComponent(0,littleStrings[i+3].c_str());
01005           std::copy(data,data+tinyInfo[i],(*(thisArr[i]))->getPointer());
01006           data+=tinyInfo[i];
01007         }
01008     }
01009   setTime(tinyInfoD[0],tinyInfo[3],tinyInfo[4]);
01010 }
01011 
01012 void MEDCouplingCMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception)
01013 {
01014   throw INTERP_KERNEL::Exception("MEDCouplingCMesh::writeVTKLL : not implemented yet !");
01015 }
01016 
01017 std::string MEDCouplingCMesh::getVTKDataSetType() const throw(INTERP_KERNEL::Exception)
01018 {
01019   return std::string("RectilinearGrid");
01020 }