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