Salome HOME
1) Add CMake files to the dist rules (make dist)
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingUMeshDesc.cxx
1 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D
2 //
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.
7 //
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (CEA/DEN)
20
21 #include "MEDCouplingUMeshDesc.hxx"
22 #include "CellModel.hxx"
23 #include "MEDCouplingMemArray.hxx"
24
25 #include <limits>
26 #include <sstream>
27
28 using namespace ParaMEDMEM;
29
30 MEDCouplingUMeshDesc::MEDCouplingUMeshDesc():_mesh_dim(-2),_desc_connec(0),_desc_connec_index(0),
31                                              _nodal_connec_face(0),_nodal_connec_face_index(0)
32 {
33 }
34
35 MEDCouplingUMeshDesc::~MEDCouplingUMeshDesc()
36 {
37   if(_desc_connec)
38     _desc_connec->decrRef();
39   if(_desc_connec_index)
40     _desc_connec_index->decrRef();
41   if(_nodal_connec_face)
42     _nodal_connec_face->decrRef();
43   if(_nodal_connec_face_index)
44     _nodal_connec_face_index->decrRef();
45 }
46
47 MEDCouplingUMeshDesc *MEDCouplingUMeshDesc::New()
48 {
49   return new MEDCouplingUMeshDesc;
50 }
51
52 MEDCouplingUMeshDesc *MEDCouplingUMeshDesc::New(const char *meshName, int meshDim)
53 {
54   MEDCouplingUMeshDesc *ret=new MEDCouplingUMeshDesc;
55   ret->setName(meshName);
56   ret->setMeshDimension(meshDim);
57   return ret;
58 }
59
60 MEDCouplingMesh *MEDCouplingUMeshDesc::deepCpy() const
61 {
62   throw INTERP_KERNEL::Exception("Not implemented yet !");
63   return 0;
64 }
65
66 void MEDCouplingUMeshDesc::checkCoherency() const throw(INTERP_KERNEL::Exception)
67 {
68   for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator iter=_types.begin();iter!=_types.end();iter++)
69     {
70       if((int)INTERP_KERNEL::CellModel::GetCellModel(*iter).getDimension()!=_mesh_dim)
71         {
72           std::ostringstream message;
73           message << "MeshDesc invalid because dimension is " << _mesh_dim << " and there is presence of cell(s) with type " << (*iter);
74           throw INTERP_KERNEL::Exception(message.str().c_str());
75         }
76     }
77 }
78
79 void MEDCouplingUMeshDesc::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
80 {
81   checkCoherency();
82 }
83
84 void MEDCouplingUMeshDesc::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
85 {
86   checkCoherency1(eps);
87 }
88
89 void MEDCouplingUMeshDesc::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
90                                                 DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception)
91 {
92   throw INTERP_KERNEL::Exception("MEDCouplingUMeshDesc::checkDeepEquivalWith : not implemented yet !");
93 }
94
95 void MEDCouplingUMeshDesc::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
96                                                            DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception)
97 {
98   throw INTERP_KERNEL::Exception("MEDCouplingUMeshDesc::checkDeepEquivalOnSameNodesWith : not implemented yet !");
99 }
100
101 void MEDCouplingUMeshDesc::setMeshDimension(unsigned meshDim)
102 {
103   _mesh_dim=meshDim;
104   declareAsNew();
105 }
106
107 int MEDCouplingUMeshDesc::getNumberOfCells() const
108 {
109   if(_desc_connec_index)
110     return _desc_connec_index->getNumberOfTuples()-1;
111   else
112     throw INTERP_KERNEL::Exception("Unable to get number of cells because no connectivity specified !");
113 }
114
115 int MEDCouplingUMeshDesc::getNumberOfFaces() const
116 {
117   if(_nodal_connec_face_index)
118     return _nodal_connec_face_index->getNumberOfTuples()-1;
119   else
120     throw INTERP_KERNEL::Exception("Unable to get number of faces because no connectivity specified !");
121 }
122
123 int MEDCouplingUMeshDesc::getCellMeshLength() const
124 {
125   return _desc_connec->getNbOfElems();
126 }
127
128 int MEDCouplingUMeshDesc::getFaceMeshLength() const
129 {
130   return _nodal_connec_face->getNbOfElems();
131 }
132
133 INTERP_KERNEL::NormalizedCellType MEDCouplingUMeshDesc::getTypeOfCell(int cellId) const
134 {
135   const int *desc_connec=_desc_connec->getConstPointer();
136   const int *desc_connec_index=_desc_connec_index->getConstPointer();
137   return (INTERP_KERNEL::NormalizedCellType)desc_connec[desc_connec_index[cellId]+1];
138 }
139
140 std::set<INTERP_KERNEL::NormalizedCellType> MEDCouplingUMeshDesc::getAllGeoTypes() const
141 {
142   return _types;
143 }
144
145 int MEDCouplingUMeshDesc::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
146 {
147   const int *desc_connec=_desc_connec->getConstPointer();
148   const int *desc_connec_index=_desc_connec_index->getConstPointer();
149   int nbOfCells=getNumberOfCells();
150   int ret=0;
151   for(int i=0;i<nbOfCells;i++)
152     if((INTERP_KERNEL::NormalizedCellType) desc_connec[desc_connec_index[i]]==type)
153       ret++;
154   return ret;
155 }
156
157 void MEDCouplingUMeshDesc::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
158 {
159   throw INTERP_KERNEL::Exception("Not implemented yet !");
160 }
161
162 std::string MEDCouplingUMeshDesc::simpleRepr() const
163 {
164   std::string ret("Unstructured mesh with descending connectivity : ");
165   ret+=getName();
166   ret+="\n";
167   return ret;
168 }
169
170 std::string MEDCouplingUMeshDesc::advancedRepr() const
171 {
172   std::string ret("Unstructured mesh with descending connectivity : ");
173   ret+=getName();
174   ret+="\n";
175   return ret;
176 }
177
178 void MEDCouplingUMeshDesc::setConnectivity(DataArrayInt *descConn, DataArrayInt *descConnIndex, DataArrayInt *nodalFaceConn, DataArrayInt *nodalFaceConnIndx)
179 {
180   DataArrayInt::SetArrayIn(descConn,_desc_connec);
181   DataArrayInt::SetArrayIn(descConnIndex,_desc_connec_index);
182   DataArrayInt::SetArrayIn(nodalFaceConn,_nodal_connec_face);
183   DataArrayInt::SetArrayIn(nodalFaceConnIndx,_nodal_connec_face_index);
184   computeTypes();
185 }
186
187 std::vector<int> MEDCouplingUMeshDesc::getDistributionOfTypes() const throw(INTERP_KERNEL::Exception)
188 {
189   throw INTERP_KERNEL::Exception("Not implemented yet !");
190 }
191
192 DataArrayInt *MEDCouplingUMeshDesc::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
193 {
194   throw INTERP_KERNEL::Exception("Not implemented yet !");
195 }
196
197 void MEDCouplingUMeshDesc::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
198 {
199   throw INTERP_KERNEL::Exception("Not implemented yet !");
200 }
201
202 void MEDCouplingUMeshDesc::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
203 {
204   MEDCouplingPointSet::getTinySerializationInformation(tinyInfoD,tinyInfo,littleStrings);
205   tinyInfo.push_back(getMeshDimension());
206   tinyInfo.push_back(getNumberOfNodes());
207   tinyInfo.push_back(getNumberOfCells());
208   tinyInfo.push_back(getCellMeshLength());
209   tinyInfo.push_back(getNumberOfFaces());
210   tinyInfo.push_back(getFaceMeshLength());
211 }
212
213 bool MEDCouplingUMeshDesc::isEmptyMesh(const std::vector<int>& tinyInfo) const
214 {
215   return tinyInfo[5]<=0;
216 }
217
218 void MEDCouplingUMeshDesc::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
219 {
220   std::vector<int> tinyInfoTmp(tinyInfo.begin()+1,tinyInfo.end());
221   MEDCouplingPointSet::resizeForUnserialization(tinyInfoTmp,a1,a2,littleStrings);
222   a1->alloc(tinyInfo[5]+tinyInfo[4]+1+tinyInfo[7]+tinyInfo[6]+1,1);
223 }
224
225 void MEDCouplingUMeshDesc::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
226 {
227   MEDCouplingPointSet::serialize(a1,a2);
228   //
229   a1=DataArrayInt::New();
230   a1->alloc(getCellMeshLength()+getNumberOfCells()+1+getFaceMeshLength()+getNumberOfFaces()+1,1);
231   int *ptA1=a1->getPointer();
232   const int *descConn=_desc_connec->getConstPointer();
233   const int *descConnIndex=_desc_connec_index->getConstPointer();
234   const int *faceConn=_nodal_connec_face->getConstPointer();
235   const int *faceConnIndex=_nodal_connec_face_index->getConstPointer();
236   ptA1=std::copy(descConn,descConn+getCellMeshLength(),ptA1);
237   ptA1=std::copy(descConnIndex,descConnIndex+getNumberOfCells()+1,ptA1);
238   ptA1=std::copy(faceConn,faceConn+getFaceMeshLength(),ptA1);
239   std::copy(faceConnIndex,faceConnIndex+getNumberOfFaces()+1,ptA1);
240 }
241
242 void MEDCouplingUMeshDesc::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector<std::string>& littleStrings)
243 {
244   std::vector<int> tinyInfoTmp(tinyInfo.begin()+1,tinyInfo.end());
245   MEDCouplingPointSet::unserialization(tinyInfoD,tinyInfoTmp,a1,a2,littleStrings);
246   //
247   const int *recvBuffer=a1->getConstPointer();
248   DataArrayInt *descConn=DataArrayInt::New();
249   descConn->alloc(tinyInfo[5],1);
250   std::copy(recvBuffer,recvBuffer+tinyInfo[5],descConn->getPointer());
251   DataArrayInt *descConnIndex=DataArrayInt::New();
252   descConnIndex->alloc(tinyInfo[4]+1,1);
253   std::copy(recvBuffer+tinyInfo[5],recvBuffer+tinyInfo[5]+tinyInfo[4]+1,descConnIndex->getPointer());
254   DataArrayInt *faceConn=DataArrayInt::New();
255   faceConn->alloc(tinyInfo[7],1);
256   std::copy(recvBuffer+tinyInfo[5]+tinyInfo[4]+1,recvBuffer+tinyInfo[5]+tinyInfo[4]+1+tinyInfo[7],faceConn->getPointer());
257   DataArrayInt *faceConnIndex=DataArrayInt::New();
258   faceConnIndex->alloc(tinyInfo[6]+1,1);
259   std::copy(recvBuffer+tinyInfo[5]+tinyInfo[4]+1+tinyInfo[7],
260             recvBuffer+tinyInfo[5]+tinyInfo[5]+1+tinyInfo[7]+tinyInfo[6]+1,faceConnIndex->getPointer());
261   setConnectivity(descConn,descConnIndex,faceConn,faceConnIndex);
262   descConn->decrRef();
263   descConnIndex->decrRef();
264   faceConn->decrRef();
265   faceConnIndex->decrRef();
266   setMeshDimension(tinyInfo[2]);
267 }
268
269 void MEDCouplingUMeshDesc::getCellsInBoundingBox(const double *bbox, double eps, std::vector<int>& elems) const
270 {
271   int dim=getSpaceDimension();
272   double* elem_bb=new double[2*dim];
273   const int* conn      = _desc_connec->getConstPointer();
274   const int* conn_index= _desc_connec_index->getConstPointer();
275   const int* face      = _nodal_connec_face->getConstPointer();
276   const int* face_index= _nodal_connec_face_index->getConstPointer();
277   const double* coords = getCoords()->getConstPointer();
278   int nbOfCells=getNumberOfCells();
279   for ( int ielem=0; ielem<nbOfCells;ielem++ )
280     {
281       for (int i=0; i<dim; i++)
282         {
283           elem_bb[i*2]=std::numeric_limits<double>::max();
284           elem_bb[i*2+1]=-std::numeric_limits<double>::max();
285         }
286
287       for (int jface=conn_index[ielem]+1; jface<conn_index[ielem+1]; jface++)//+1 due to offset of cell type.
288         {
289           int iface=conn[jface];
290           for(int inode=face_index[iface]+1;inode<face_index[iface+1];inode++)
291             {
292               int node=face[inode];
293               for (int idim=0; idim<dim; idim++)
294                 {
295                   if ( coords[node*dim+idim] < elem_bb[idim*2] )
296                     {
297                       elem_bb[idim*2] = coords[node*dim+idim] ;
298                     }
299                   if ( coords[node*dim+idim] > elem_bb[idim*2+1] )
300                     {
301                       elem_bb[idim*2+1] = coords[node*dim+idim] ;
302                     }
303                 }
304             }
305         }
306       if (intersectsBoundingBox(elem_bb, bbox, dim, eps))
307         {
308           elems.push_back(ielem);
309         }
310     }
311   delete [] elem_bb;
312 }
313
314 void MEDCouplingUMeshDesc::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox &bbox, double eps, std::vector<int>& elems)
315 {
316   int dim=getSpaceDimension();
317   double* elem_bb=new double[2*dim];
318   const int* conn      = _desc_connec->getConstPointer();
319   const int* conn_index= _desc_connec_index->getConstPointer();
320   const int* face      = _nodal_connec_face->getConstPointer();
321   const int* face_index= _nodal_connec_face_index->getConstPointer();
322   const double* coords = getCoords()->getConstPointer();
323   int nbOfCells=getNumberOfCells();
324   for ( int ielem=0; ielem<nbOfCells;ielem++ )
325     {
326       for (int i=0; i<dim; i++)
327         {
328           elem_bb[i*2]=std::numeric_limits<double>::max();
329           elem_bb[i*2+1]=-std::numeric_limits<double>::max();
330         }
331
332       for (int jface=conn_index[ielem]+1; jface<conn_index[ielem+1]; jface++)//+1 due to offset of cell type.
333         {
334           int iface=conn[jface];
335           for(int inode=face_index[iface]+1;inode<face_index[iface+1];inode++)
336             {
337               int node=face[inode];
338               for (int idim=0; idim<dim; idim++)
339                 {
340                   if ( coords[node*dim+idim] < elem_bb[idim*2] )
341                     {
342                       elem_bb[idim*2] = coords[node*dim+idim] ;
343                     }
344                   if ( coords[node*dim+idim] > elem_bb[idim*2+1] )
345                     {
346                       elem_bb[idim*2+1] = coords[node*dim+idim] ;
347                     }
348                 }
349             }
350         }
351       if (intersectsBoundingBox(bbox, elem_bb, dim, eps))
352         {
353           elems.push_back(ielem);
354         }
355     }
356   delete [] elem_bb;
357 }
358
359 DataArrayInt *MEDCouplingUMeshDesc::mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes)
360 {
361   throw INTERP_KERNEL::Exception("Not implemented yet !");
362   areNodesMerged=false;
363   return 0;
364 }
365
366 DataArrayInt *MEDCouplingUMeshDesc::mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes)
367 {
368   throw INTERP_KERNEL::Exception("Not implemented yet !");
369   areNodesMerged=false;
370   return 0;
371 }
372
373 void MEDCouplingUMeshDesc::tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception)
374 {
375   throw INTERP_KERNEL::Exception("Not implemented yet !");
376 }
377
378 MEDCouplingPointSet *MEDCouplingUMeshDesc::buildPartOfMySelf2(int start, int end, int step, bool keepCoords) const throw(INTERP_KERNEL::Exception)
379 {
380   throw INTERP_KERNEL::Exception("Not implemented yet !");
381   return 0;
382 }
383
384 MEDCouplingPointSet *MEDCouplingUMeshDesc::buildPartOfMySelf(const int *start, const int *end, bool keepCoords) const
385 {
386   throw INTERP_KERNEL::Exception("Not implemented yet !");
387   return 0;
388 }
389
390 MEDCouplingPointSet *MEDCouplingUMeshDesc::buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const
391 {
392   throw INTERP_KERNEL::Exception("Not implemented yet !");
393   return 0;
394 }
395
396 MEDCouplingPointSet *MEDCouplingUMeshDesc::buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const
397 {
398   throw INTERP_KERNEL::Exception("Not implemented yet !");
399   return 0;
400 }
401
402 DataArrayInt *MEDCouplingUMeshDesc::simplexize(int policy) throw(INTERP_KERNEL::Exception)
403 {
404   throw INTERP_KERNEL::Exception("MEDCouplingUMeshDesc::simplexize : Not implemented yet !");
405 }
406
407 DataArrayInt *MEDCouplingUMeshDesc::findBoundaryNodes() const
408 {
409   throw INTERP_KERNEL::Exception("Not implemented yet !");
410 }
411
412 MEDCouplingPointSet *MEDCouplingUMeshDesc::buildBoundaryMesh(bool keepCoords) const
413 {
414   throw INTERP_KERNEL::Exception("Not implemented yet !");
415   return 0;
416 }
417
418 MEDCouplingUMesh *MEDCouplingUMeshDesc::buildUnstructured() const throw(INTERP_KERNEL::Exception)
419 {
420   throw INTERP_KERNEL::Exception("MEDCouplingUMeshDesc::buildUnstructured : not implemented yet !");
421 }
422
423 void MEDCouplingUMeshDesc::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
424 {
425   throw INTERP_KERNEL::Exception("Available for UMesh desc but not implemented yet !");
426 }
427
428 void MEDCouplingUMeshDesc::renumberNodes(const int *newNodeNumbers, int newNbOfNodes)
429 {
430   MEDCouplingPointSet::renumberNodes(newNodeNumbers,newNbOfNodes);
431   throw INTERP_KERNEL::Exception("Not implemented yet !");
432 }
433
434 MEDCouplingFieldDouble *MEDCouplingUMeshDesc::getMeasureField(bool isAbs) const
435 {
436   throw INTERP_KERNEL::Exception("Not implemented yet !");
437   return 0;
438 }
439
440 MEDCouplingFieldDouble *MEDCouplingUMeshDesc::getMeasureFieldOnNode(bool isAbs) const
441 {
442   throw INTERP_KERNEL::Exception("Not implemented yet !");
443   return 0;
444 }
445
446 MEDCouplingFieldDouble *MEDCouplingUMeshDesc::buildOrthogonalField() const
447 {
448   if(getMeshDimension()!=2)
449     throw INTERP_KERNEL::Exception("Expected a cmesh with meshDim == 2 !");
450   throw INTERP_KERNEL::Exception("Not implemented yet !");
451   return 0;
452 }
453
454 DataArrayInt *MEDCouplingUMeshDesc::zipCoordsTraducer()
455 {
456   throw INTERP_KERNEL::Exception("Not implemented yet !");
457   return 0;
458 }
459
460 void MEDCouplingUMeshDesc::computeTypes()
461 {
462   if(_desc_connec && _desc_connec_index)
463     {
464       _types.clear();
465       const int *conn=_desc_connec->getConstPointer();
466       const int *connIndex=_desc_connec_index->getConstPointer();
467       int nbOfElem=_desc_connec_index->getNbOfElems()-1;
468       for(const int *pt=connIndex;pt!=connIndex+nbOfElem;pt++)
469         _types.insert((INTERP_KERNEL::NormalizedCellType)conn[*pt]);
470     }
471 }
472
473 void MEDCouplingUMeshDesc::checkFullyDefined() const throw(INTERP_KERNEL::Exception)
474 {
475   if(!_desc_connec || !_desc_connec_index || !_nodal_connec_face || !_nodal_connec_face_index || !_coords)
476     throw INTERP_KERNEL::Exception("full connectivity and coordinates not set in unstructured mesh.");
477 }
478
479 MEDCouplingMesh *MEDCouplingUMeshDesc::mergeMyselfWith(const MEDCouplingMesh *other) const
480 {  
481   throw INTERP_KERNEL::Exception("Not implemented yet !");
482   return 0;
483 }
484
485 DataArrayDouble *MEDCouplingUMeshDesc::getBarycenterAndOwner() const
486 {
487   throw INTERP_KERNEL::Exception("Not implemented yet !");
488   return 0;
489 }
490
491 int MEDCouplingUMeshDesc::getCellContainingPoint(const double *pos, double eps) const
492 {
493   throw INTERP_KERNEL::Exception("MEDCouplingUMeshDesc::getCellContainingPoint : not implemented yet !");
494 }
495
496 void MEDCouplingUMeshDesc::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception)
497 {
498   throw INTERP_KERNEL::Exception("MEDCouplingUMeshDesc::writeVTKLL : not implemented yet !");
499 }
500
501 std::string MEDCouplingUMeshDesc::getVTKDataSetType() const throw(INTERP_KERNEL::Exception)
502 {
503   throw INTERP_KERNEL::Exception("MEDCouplingUMeshDesc::getVTKDataSetType : not implemented yet !");
504 }
505