1 // Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // File : MEDMEM_Grid.hxx
24 // Created : Wed Dec 18 08:35:26 2002
25 // Descr : class containing structured mesh data
26 // Author : Edward AGAPOV (eap)
27 // Project : SALOME Pro
30 #include "MEDMEM_Grid.hxx"
31 #include "MEDMEM_Meshing.hxx"
32 #include "MEDMEM_CellModel.hxx"
33 #include "MEDMEM_SkyLineArray.hxx"
34 #include "MEDMEM_DriverFactory.hxx"
39 using namespace MEDMEM;
40 using namespace MED_EN;
43 // Block defining the comments for the MEDMEM_ug documentation
47 \defgroup GRID_axes Information about axes
48 This group of methods retrieves information about the axes of the grid.
50 \defgroup GRID_connectivity Utility methods for defining element positions in the grid
51 These methods enable the user to convert a position on the grid to a global element number
53 \defgroup GRID_constructors Constructors
54 These methods are the different constructors for the grid objects.
60 const string* defaultStrings()
62 static const string str[3] = { "UNDEFINED", "UNDEFINED", "UNDEFINED" };
67 //=======================================================================
69 //purpose : empty constructor
70 //=======================================================================
74 MESSAGE_MED("A GRID CREATED");
77 //=======================================================================
79 ////purpose : array constructor
80 ////=======================================================================
83 \addtogroup GRID_constructors
88 * \brief Constructor specifying the axes of the grid
90 * This constructor describes the grid by specifying the location of the nodes on
91 each of the axis. The dimension of the grid is implicitly defined by the
92 size of vector \a xyz_array.
94 *\param xyz_array specifies the node coordinates for each direction
95 *\param coord_name names of the different coordinates
96 *\param coord_unit names of the different coordinate units
97 *\param type grid type (MED_POLAR, MED_CARTESIAN)
99 GRID::GRID(const std::vector<std::vector<double> >& xyz_array,
100 const std::vector<std::string>& coord_name,
101 const std::vector<std::string>& coord_unit,
102 const MED_EN::med_grid_type type)
106 _is_default_gridType = false;
108 _spaceDimension = xyz_array.size();
110 // create a non allocated COORDINATE
111 _coordinate = new COORDINATE(_spaceDimension, &coord_name[0], &coord_unit[0]);
112 string coordinateSystem = "UNDEFINED";
113 if( _gridType == MED_CARTESIAN)
114 coordinateSystem = "CARTESIAN";
115 else if ( _gridType == MED_POLAR)
116 coordinateSystem = "CYLINDRICAL";
117 _coordinate->setCoordinatesSystem(coordinateSystem);
120 if (_spaceDimension>=1)
122 _iArrayLength=xyz_array[0].size();
123 _iArray=new double[_iArrayLength];
124 std::copy(xyz_array[0].begin(),xyz_array[0].end(),_iArray);
126 if (_spaceDimension>=2)
128 _jArrayLength=xyz_array[1].size();
129 _jArray=new double[_jArrayLength];
130 std::copy(xyz_array[1].begin(),xyz_array[1].end(),_jArray);
132 if (_spaceDimension>=3)
134 _kArrayLength=xyz_array[2].size();
135 _kArray=new double[_kArrayLength];
136 std::copy(xyz_array[2].begin(),xyz_array[2].end(),_kArray);
140 //================================================================================
142 * \brief Reads a GRID form the file
143 * \param driverType - type of driver to read the specified file
144 * \param fileName - the file name to read
145 * \param driverName - name of a grid to read
147 //================================================================================
149 GRID::GRID(driverTypes driverType, const string & fileName, const string & driverName)
152 const char* LOC = "GRID::GRID(driverTypes , const string & , const string &) : ";
156 auto_ptr<GENDRIVER> myDriver (DRIVERFACTORY::buildDriverForMesh(driverType,fileName,this,driverName,RDONLY));
164 /*!\if MEDMEM_ug @} \endif */
166 //=======================================================================
168 //purpose : empty constructor
169 //=======================================================================
171 GRID::GRID(const MED_EN::med_grid_type type)
175 _is_default_gridType = false;
176 MESSAGE_MED("A TYPED GRID CREATED");
179 //=======================================================================
181 //purpose : copying constructor
182 //=======================================================================
184 GRID::GRID(const GRID& otherGrid) {
188 //=======================================================================
190 //purpose : destructor
191 //=======================================================================
194 MESSAGE_MED("GRID::~GRID() : Destroying the Grid");
195 if ( _coordinate ) delete _coordinate; _coordinate = 0;
196 if ( _iArray != (double* ) NULL) delete [] _iArray;
197 if ( _jArray != (double* ) NULL) delete [] _jArray;
198 if ( _kArray != (double* ) NULL) delete [] _kArray;
201 //=======================================================================
204 //=======================================================================
210 _gridType = MED_CARTESIAN;
211 _is_default_gridType = true;
213 _iArray = _jArray = _kArray = (double* ) NULL;
214 _iArrayLength = _jArrayLength = _kArrayLength = 0;
218 //================================================================================
220 * \brief Return true if contains no elements
222 //================================================================================
224 bool GRID::isEmpty() const
226 return !_iArrayLength && !_coordinate;
230 //=======================================================================
231 //function: operator=
232 //purpose : operator=
233 //=======================================================================
235 GRID & GRID::operator=(const GRID & otherGrid)
239 GMESH::operator=(otherGrid);
243 //=======================================================================
245 Returns true if mesh \a other has same
246 coordinates (to 1E-15 precision ) and same connectivity as the calling object.
247 Information like name or description is not taken into account
250 //=======================================================================
252 bool GRID::deepCompare(const GMESH& gother) const
254 if ( gother.getIsAGrid() != getIsAGrid())
256 const GRID& other = static_cast<const GRID&>( gother );
258 if ( getSpaceDimension() != other.getSpaceDimension() )
261 if ( _gridType != other._gridType )
264 if( bool( _coordinate) != bool(other._coordinate))
267 if ( _coordinate->getNumberOfNodes() > 0 )
269 if ( _coordinate->getNumberOfNodes() != other._coordinate->getNumberOfNodes() )
271 const int size = _coordinate->getNumberOfNodes() * getSpaceDimension();
272 const double* coord1=_coordinate->getCoordinates(MED_FULL_INTERLACE);
273 const double* coord2=other._coordinate->getCoordinates(MED_FULL_INTERLACE);
274 for(int i = 0 ; i < size; i++ )
275 if ( !(fabs(coord1[i]-coord2[i])<1e-15))
279 if ( _iArrayLength != other._iArrayLength )
281 if ( _jArrayLength != other._jArrayLength )
283 if ( _kArrayLength != other._kArrayLength )
286 if ( bool(_iArray) != bool(other._iArray) )
288 if ( bool(_jArray) != bool(other._jArray) )
290 if ( bool(_kArray) != bool(other._kArray) )
294 for ( int i = 0; i < _iArrayLength; ++i )
295 if ( !(fabs(_iArray[i]-other._iArray[i])<1e-15))
298 for ( int i = 0; i < _jArrayLength; ++i )
299 if ( !(fabs(_jArray[i]-other._jArray[i])<1e-15))
302 for ( int i = 0; i < _kArrayLength; ++i )
303 if ( !(fabs(_kArray[i]-other._kArray[i])<1e-15))
309 //================================================================================
311 * \brief print my contents
313 //================================================================================
315 void GRID::printMySelf(std::ostream &os) const
318 cout << "NOT IMPLEMENTED" << endl;
321 //================================================================================
323 * \brief Create an unstructured MESH. Call removeReference() after having finished using it!!!
325 //================================================================================
327 const MESH * GRID::convertInMESH() const
329 MESHING* mesh = new MESHING;
330 mesh->setName( getName() );
338 PointerOf< double > coords;
339 if ( _gridType == MED_BODY_FITTED )
343 (LOCALIZED("GRID::convertInMESH() : _coordinate of MED_BODY_FITTED GRID not defined !"));
344 coords.set( _coordinate->getCoordinates(MED_FULL_INTERLACE));
348 coords.set( getSpaceDimension() * getNumberOfNodes() );
349 double* coord = coords;
350 switch ( getSpaceDimension() )
353 for (k=0; k < _kArrayLength; ++k)
354 for (j=0; j < _jArrayLength; ++j)
355 for (i=0; i < _iArrayLength; ++i)
356 *coord++ = _iArray[i], *coord++ = _jArray[j], *coord++ = _kArray[k];
360 for (j=0; j < _jArrayLength; ++j)
361 for (i=0; i < _iArrayLength; ++i)
362 *coord++ = _iArray[i], *coord++ = _jArray[j];
370 mesh->setCoordinates( getSpaceDimension(),
372 (const double *) coords,
373 getCoordinatesSystem(),
374 MED_EN::MED_FULL_INTERLACE);
375 mesh->setCoordinatesNames( getCoordinatesNames() );
376 mesh->setCoordinatesUnits( getCoordinatesUnits() );
384 medEntityMesh subEntity;
386 mesh->setNumberOfTypes( getNumberOfTypes(MED_CELL), MED_CELL );
387 mesh->setTypes( getTypes( MED_CELL), MED_CELL );
388 int nbCells = getNumberOfElements( MED_CELL, MED_ALL_ELEMENTS );
389 mesh->setNumberOfElements( &nbCells, MED_CELL );
392 switch ( _spaceDimension )
395 for ( k = 0; k < _kArrayLength-1; ++k )
396 for ( j = 0; j < _jArrayLength-1; ++j )
397 for ( i = 0; i < _iArrayLength-1; ++i )
399 conn.push_back( getNodeNumber( i , j , k ));
400 conn.push_back( getNodeNumber( i , j+1, k ));
401 conn.push_back( getNodeNumber( i+1, j+1, k ));
402 conn.push_back( getNodeNumber( i+1, j , k ));
403 conn.push_back( getNodeNumber( i , j , k+1));
404 conn.push_back( getNodeNumber( i , j+1, k+1));
405 conn.push_back( getNodeNumber( i+1, j+1, k+1));
406 conn.push_back( getNodeNumber( i+1, j , k+1));
408 subEntity = MED_FACE;
412 for ( j = 0; j < _jArrayLength-1; ++j )
413 for ( i = 0; i < _iArrayLength-1; ++i )
415 int n1 = 1 + i + j*_iArrayLength;
416 conn.push_back( n1 );
417 conn.push_back( n1 + _iArrayLength );
418 conn.push_back( n1 + _iArrayLength + 1 );
419 conn.push_back( n1 + 1 );
421 subEntity = MED_EDGE;
425 for ( i = 0; i < _iArrayLength-1; ++i )
427 conn.push_back( i + 1 );
428 conn.push_back( i + 2 );
432 mesh->setConnectivity( MED_CELL, getTypes(MED_CELL)[0], &conn[0] );
438 if ( _spaceDimension > 1 )
440 mesh->setNumberOfTypes( getNumberOfTypes(subEntity), subEntity );
441 mesh->setTypes( getTypes( subEntity), subEntity );
442 int nbCells = getNumberOfElements( subEntity, MED_ALL_ELEMENTS );
443 mesh->setNumberOfElements( &nbCells, subEntity );
446 switch ( _spaceDimension )
451 for ( k = 0; k < _kArrayLength-1; ++k )
452 for ( j = 0; j < _jArrayLength-1; ++j )
453 for ( i = 0; i < _iArrayLength; ++i )
455 conn.push_back( getNodeNumber( i, j , k ));
456 conn.push_back( getNodeNumber( i, j , k+1));
457 conn.push_back( getNodeNumber( i, j+1, k+1));
458 conn.push_back( getNodeNumber( i, j+1, k ));
461 for ( k = 0; k < _kArrayLength-1; ++k )
462 for ( j = 0; j < _jArrayLength; ++j )
463 for ( i = 0; i < _iArrayLength-1; ++i )
465 conn.push_back( getNodeNumber( i , j, k ));
466 conn.push_back( getNodeNumber( i+1, j, k ));
467 conn.push_back( getNodeNumber( i+1, j, k+1));
468 conn.push_back( getNodeNumber( i , j, k+1));
471 for ( k = 0; k < _kArrayLength; ++k )
472 for ( j = 0; j < _jArrayLength-1; ++j )
473 for ( i = 0; i < _iArrayLength-1; ++i )
475 conn.push_back( getNodeNumber( i , j , k));
476 conn.push_back( getNodeNumber( i , j+1, k));
477 conn.push_back( getNodeNumber( i+1, j+1, k));
478 conn.push_back( getNodeNumber( i+1, j , k));
485 for ( j = 0; j < _jArrayLength; ++j )
486 for ( i = 0; i < _iArrayLength-1; ++i )
488 int n1 = 1 + i + j*_iArrayLength;
489 conn.push_back( n1 );
490 conn.push_back( n1 + 1 );
493 for ( j = 0; j < _jArrayLength-1; ++j )
494 for ( i = 0; i < _iArrayLength; ++i )
496 int n1 = 1 + i + j*_iArrayLength;
497 conn.push_back( n1 );
498 conn.push_back( n1 + _iArrayLength );
503 mesh->setConnectivity( subEntity, getTypes(subEntity)[0], &conn[0] );
506 // 3. Groups and Families
507 // -----------------------
509 const vector<GROUP*>* groups[] = { &_groupNode, &_groupCell, &_groupFace, &_groupEdge };
510 for ( i = 0; i < 4; ++i )
511 for ( j = 0; j < (int)groups[i]->size(); ++j )
512 mesh->addGroup( * groups[i]->at( j ));
517 //=======================================================================
519 return the GRID Geometric type, without computing all connectivity
521 //=======================================================================
523 const medGeometryElement * GRID::getTypes(MED_EN::medEntityMesh entity) const
525 static const medGeometryElement _gridGeometry[4]={MED_HEXA8,MED_QUAD4,MED_SEG2,MED_POINT1};
531 else if(entity==MED_FACE && _spaceDimension>2 )
533 else if(entity==MED_EDGE && _spaceDimension>1 )
535 else if(entity==MED_NODE && _spaceDimension>0)
538 throw MEDEXCEPTION(LOCALIZED("CONNECTIVITY::getGeometricTypes : Entity not defined !"));
539 return &_gridGeometry[i];
542 //=======================================================================
543 //function : getArrayLength
544 //purpose : return array length. Axis = [1,2,3] meaning [i,j,k],
545 //=======================================================================
547 \addtogroup GRID_axes
551 /*! Returns the number of nodes on axis number \a Axis (axis numbering starts at 1).
553 int GRID::getArrayLength( const int Axis ) const throw (MEDEXCEPTION)
556 case 1: return _iArrayLength;
557 case 2: return _jArrayLength;
558 case 3: return _kArrayLength;
560 throw MED_EXCEPTION ( LOCALIZED( STRING("GRID::getArrayLength ( ") << Axis << ")"));
565 //=======================================================================
566 //function : getArrayValue
567 //purpose : return i-th array component. Axis = [1,2,3] meaning [i,j,k],
568 // exception if Axis out of [1-3] range
569 // exception if i is out of range 0 <= i < getArrayLength(Axis);
570 //=======================================================================
572 Returns the value of node coordinate \a i on axis \a Axis.
574 const double GRID::getArrayValue (const int Axis, const int i) const throw (MEDEXCEPTION)
576 if (i < 0 || i >= getArrayLength(Axis))
578 ( LOCALIZED(STRING("GRID::getArrayValue ( ") << Axis << ", " << i << ")"));
581 case 1: return _iArray[ i ];
582 case 2: return _jArray[ i ];
583 default: return _kArray[ i ];
596 \addtogroup GRID_connectivity
602 \name Position to number conversion methods
603 \a getXXXNumber methods enable the user to convert an \f$ (i,j,k)\f$ position into a global number in the array.
605 Axis [1,2,3] means one of directions: along \a i, \a j or \a k.
606 For cell constituents (FACE or EDGE), Axis selects one of those having same \f$ (i, j, k )\f$ :
607 - a FACE which is normal to direction along given \a Axis;
608 - an EDGE going along given \a Axis.
609 \a i, \a j and \a k counts from zero.
611 Exception for \a Axis out of range.
612 For 2D grids, \a k is a dummy argument. */
614 //================================================================================
615 /*! Edge position to number conversion method*/
616 //================================================================================
618 int GRID::getEdgeNumber(const int Axis, const int i, const int j, const int k)
619 const throw (MEDEXCEPTION)
621 const char * LOC = "GRID::getEdgeNumber(Axis, i,j,k) :";
625 int Len[4] = {0,_iArrayLength, _jArrayLength, _kArrayLength }, I=1, J=2, K=3;
626 int maxAxis = Len[ K ] ? 3 : 2;
628 if (Axis <= 0 || Axis > maxAxis)
629 throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "Axis out of range: " << Axis));
632 int Nb = 1 + i + j*Len[ I ] + k*Len[ J ]*Len[ K ];
638 if (Axis > 1) { // add all edges in i direction
640 Nb += Len[ I ]*Len[ J ]*Len[ K ];
643 if (Axis > 2) { // add all edges in j direction
645 Nb += Len[ I ]*Len[ J ]*Len[ K ];
653 //================================================================================
655 Returns a NODE, EDGE, FACE, CELL number by its position in the grid.
656 Axis [1,2,3] means one of directions: along i, j or k
657 For Cell contituents (FACE or EDGE), Axis selects one of those having same (i,j,k):
658 - a FACE which is normal to direction along given Axis;
659 - an EDGE going along given Axis.
660 Exception for Axis out of range
662 //================================================================================
664 int GRID::getFaceNumber(const int Axis, const int i, const int j, const int k)
665 const throw (MEDEXCEPTION)
667 const char * LOC = "GRID::getFaceNumber(Axis, i,j,k) :";
671 // if (Axis <= 0 || Axis > 3)
672 if (Axis < 0 || Axis > 3)
673 throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "Axis = " << Axis));
675 int Len[4] = {0,_iArrayLength-1, _jArrayLength-1, _kArrayLength-1 }, I=1, J=2, K=3;
678 int Nb = 1 + i + j*Len[ I ] + k*Len[ I ]*Len[ J ];
681 if (Axis > 1) // add all faces nornal to i direction
682 Nb += ( Len[ I ]+1 )*Len[ J ]*Len[ K ];
684 if (Axis > 2) // add all faces nornal to j direction
685 Nb += Len[ I ]*( Len[ J ]+1 )*Len[ K ];
696 \name Number to position conversion methods
698 \a getXXXPosition functions enable the user to convert
699 a number into a \f$ (i,j,k) \f$ position.
700 Axis [1,2,3] means one of directions: along i, j or k
701 For Cell constituents (FACE or EDGE), Axis selects one of those having same (i,j,k):
702 - a FACE which is normal to direction along given Axis;
703 - an EDGE going along given Axis.
705 Exception for Number out of range.
708 //================================================================================
709 /*! Node number to position conversion method */
710 //================================================================================
712 void GRID::getNodePosition(const int Number, int& i, int& j, int& k) const
715 const char * LOC = "GRID::getNodePosition(Number, i,j,k) :";
719 if (Number <= 0 || Number > getNumberOfNodes() )
720 throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "Number is out of range: " << Number));
722 int Len[] = {_iArrayLength, _jArrayLength, _kArrayLength }, I=0, J=1;
723 // , K=2; !! UNUSED VARIABLE !!
725 int ijLen = Len[I] * Len[J]; // nb in a full k layer
726 int kLen = (Number - 1) % ijLen; // nb in the non full k layer
730 k = (Number - 1) / ijLen;
732 ////cout <<" NODE POS: " << Number << " - " << i << ", " << j << ", " << k << endl;
738 //=======================================================================
739 //function : getCellPosition
741 //=======================================================================
742 /*! Cell number to position conversion method */
743 void GRID::getCellPosition(const int Number, int& i, int& j, int& k) const
747 const char* LOC = "GRID::getCellPosition(Number, i,j,k) :";
750 int Len[4] = {0,_iArrayLength-1, _jArrayLength-1, _kArrayLength-1 }, I=1, J=2;
751 // , K=3; !! UNUSED VARIABLE !!
753 // if (Number <= 0 || Number > getCellNumber(Len[I]-1, Len[J]-1, Len[K]-1))
754 // throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "Number is out of range: " << Number));
756 int ijLen = Len[I] * Len[J]; // nb in a full k layer
757 int kLen = (Number - 1) % ijLen; // nb in the non full k layer
761 k = (Number - 1) / ijLen;
766 //=======================================================================
767 //function : getEdgePosition
769 //=======================================================================
770 /*! Edge number to poistion conversion method*/
771 void GRID::getEdgePosition(const int Number, int& Axis, int& i, int& j, int& k)
772 const throw (MEDEXCEPTION)
774 const char * LOC = "GRID::getEdgePosition(Number, i,j,k) :";
779 throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "no edges in the grid: "));
782 throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "Number is out of range: " << Number));
784 int Len[4] = {0,_iArrayLength, _jArrayLength, _kArrayLength }, I=1, J=2, K=3;
787 int maxAxis = _kArrayLength ? 3 : 2;
789 for (Axis = 1; Axis <= maxAxis; ++Axis)
791 Len[Axis]--; // one less edge in Axis direction
793 // max edge number in Axis direction
794 int maxNb = getEdgeNumber (Axis, Len[I]-1, Len[J]-1, Len[K]-1);
811 int ijLen = Len[I] * Len[J]; // nb in a full k layer
812 int kLen = (theNb - 1) % ijLen; // nb in the non full k layer
815 k = (theNb - 1) / ijLen;
823 throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "Number is out of range: " << Number));
826 //=======================================================================
827 //function : getFacePosition
828 //purpose : return position (i,j,k) of an entity #Number
829 // Axis [1,2,3] means one of directions: along i, j or k
830 // For Cell contituents (FACE or EDGE), Axis selects one of those having same (i,j,k):
831 // * a FACE which is normal to direction along given Axis;
832 // * an EDGE going along given Axis.
833 // Exception for Number out of range
834 //=======================================================================
835 /*! Face number to position convertion method*/
836 void GRID::getFacePosition(const int Number, int& Axis, int& i, int& j, int& k)
837 const throw (MEDEXCEPTION)
839 const char * LOC = "GRID::getFacePosition(Number, i,j,k) :";
843 if (_kArrayLength == 0) {
844 getCellPosition(Number, i, j, k);
850 throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "no faces in the grid: "));
853 throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "Number is out of range: " << Number));
855 int Len[4] = {0,_iArrayLength-1, _jArrayLength-1, _kArrayLength-1 }, I=1, J=2, K=3;
858 for (Axis = 1; Axis <= 3; ++Axis)
862 // max face number in Axis direction
863 int maxNb = getFaceNumber (Axis, Len[I]-1, Len[J]-1, Len[K]-1);
880 int ijLen = Len[I] * Len[J]; // nb in a full k layer
881 int kLen = (theNb - 1) % ijLen; // nb in the non full k layer
884 k = (theNb - 1) / ijLen;
892 throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "Number is out of range: " << Number));
901 //================================================================================
902 /*! Get the number of different geometric types for a given entity type.
904 medEntityMesh entity : MED_CELL, MED_FACE, MED_EDGE, MED_NODE,
908 //================================================================================
910 int GRID::getNumberOfTypes(MED_EN::medEntityMesh entity) const
912 MESSAGE_MED("GRID::getNumberOfTypes(medEntityMesh entity) : "<<entity);
913 return 1; // a grid has one type
916 //================================================================================
918 Return the number of element of given geometric type of given entity. Return 0 if query is not defined.
920 //================================================================================
922 int GRID::getNumberOfElements(MED_EN::medEntityMesh entity, MED_EN::medGeometryElement Type) const
924 int numberOfElements=0;
926 // Cas où le nombre d'éléments n'est pas nul
927 if (entity==MED_EN::MED_FACE && (Type==MED_EN::MED_QUAD4 || Type==MED_EN::MED_ALL_ELEMENTS) && getMeshDimension()>2)
929 (_iArrayLength-1)*(_jArrayLength-1)*(_kArrayLength )+
930 (_iArrayLength-1)*(_jArrayLength )*(_kArrayLength-1)+
931 (_iArrayLength )*(_jArrayLength-1)*(_kArrayLength-1);
933 else if (entity==MED_EN::MED_EDGE && (Type==MED_EN::MED_SEG2 || Type==MED_EN::MED_ALL_ELEMENTS))
934 if ( _spaceDimension==2)
935 numberOfElements=_iArrayLength*(_jArrayLength-1) + (_iArrayLength-1)*_jArrayLength;
936 else if ( _spaceDimension==1)
937 numberOfElements=_iArrayLength-1;
940 (_iArrayLength*(_jArrayLength-1) + (_iArrayLength-1)*_jArrayLength) * _kArrayLength +
941 _iArrayLength*_jArrayLength*(_kArrayLength-1);
943 else if (entity==MED_EN::MED_NODE && (Type==MED_EN::MED_NONE || Type==MED_EN::MED_ALL_ELEMENTS) && _spaceDimension>0)
944 numberOfElements=getNumberOfNodes();
946 else if (entity==MED_EN::MED_CELL && _spaceDimension==3 && (Type==MED_EN::MED_HEXA8 || Type==MED_EN::MED_ALL_ELEMENTS) )
947 numberOfElements=(_iArrayLength-1)*(_jArrayLength-1)*(_kArrayLength-1);
949 else if (entity==MED_EN::MED_CELL && _spaceDimension==2 && (Type==MED_EN::MED_QUAD4 || Type==MED_EN::MED_ALL_ELEMENTS))
950 numberOfElements=(_iArrayLength-1)*(_jArrayLength-1);
952 else if (entity==MED_EN::MED_CELL && _spaceDimension==1 && (Type==MED_EN::MED_SEG2 || Type==MED_EN::MED_ALL_ELEMENTS) )
953 numberOfElements=_iArrayLength-1;
955 MESSAGE_MED("GRID::getNumberOfElements - entity=" << entity << " Type=" << Type);
956 MESSAGE_MED("_spaceDimension=" << _spaceDimension << " numberOfElements=" << numberOfElements);
958 return numberOfElements;
961 //================================================================================
963 Return the geometric type of global element Number of entity Entity.
965 //================================================================================
967 MED_EN::medGeometryElement GRID::getElementType(MED_EN::medEntityMesh Entity,int Number) const
969 return getTypes(Entity)[0];
972 //================================================================================
974 * \brief Return mesh dimension
976 //================================================================================
978 int GRID::getMeshDimension() const
980 return getSpaceDimension();
983 //================================================================================
985 * \brief It is a grid
987 //================================================================================
989 bool GRID::getIsAGrid() const
994 //================================================================================
996 * \brief Return number of nodes
998 //================================================================================
1000 int GRID::getNumberOfNodes() const
1002 if ( _gridType == MED_EN::MED_BODY_FITTED )
1003 return _coordinate ? _coordinate->getNumberOfNodes() : 0;
1005 switch ( _spaceDimension )
1007 case 3: return _iArrayLength * _jArrayLength * _kArrayLength;
1008 case 2: return _iArrayLength * _jArrayLength;
1009 case 1: return _iArrayLength;
1014 //=======================================================================
1016 * Returns "CARTESIAN", "CYLINDRICAL" or "SPHERICAL"
1018 //=======================================================================
1020 std::string GRID::getCoordinatesSystem() const
1022 return _coordinate ? _coordinate->getCoordinatesSystem() : defaultStrings()[0];
1025 //=======================================================================
1027 * Returns an array with names of coordinates. \n
1033 //=======================================================================
1035 const std::string * GRID::getCoordinatesNames() const
1037 return _coordinate ? _coordinate->getCoordinatesNames() : defaultStrings();
1040 //=======================================================================
1042 * Returns an array with units of coordinates (cm, m, mm, ...)
1043 * It could be empty. We suppose we are IS (meter).
1045 //=======================================================================
1047 const std::string * GRID::getCoordinatesUnits() const
1049 return _coordinate ? _coordinate->getCoordinatesUnits() : defaultStrings();
1052 //=======================================================================
1054 Returns a support which reference all elements on the boundary of mesh.
1055 For a d-dimensional mesh, a boundary element is defined as a d-1 dimension
1056 element that is referenced by only one element in the full descending connectivity.
1058 This method can also return the list of nodes that belong to the boundary elements.
1060 WARNING: This method can recalculate descending connectivity from partial to full form,
1061 so that partial SUPPORT on d-1 dimension elements becomes invalid.
1063 \param Entity entity on which the boundary is desired. It has to be either \a MED_NODE or the
1064 d-1 dimension entity type (MED_FACE in 3D, MED_EDGE in 2D).
1066 //=======================================================================
1068 SUPPORT * GRID::getBoundaryElements(MED_EN::medEntityMesh Entity) const throw (MEDEXCEPTION)
1070 const char * LOC = "GMESH::getBoundaryElements() : " ;
1071 if ( _spaceDimension < 2 )
1072 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Not implemented in " << _spaceDimension <<"D space !"));
1074 if ( _gridType == MED_POLAR)
1075 throw MEDEXCEPTION("GRID::getBoundaryElements() : not implemented on MED_POLAR grig");
1078 medEntityMesh entityToParse=Entity;
1079 if(_spaceDimension == 3)
1080 if (Entity != MED_FACE)
1082 if(Entity==MED_NODE)
1083 entityToParse=MED_FACE;
1085 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Not defined in 3D mesh for entity "<<Entity<<" !"));
1087 if(_spaceDimension == 2)
1088 if(Entity != MED_EDGE)
1090 if(Entity==MED_NODE)
1091 entityToParse=MED_EDGE;
1093 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Not defined in 2D mesh for entity "<<Entity<<" !"));
1095 list<int> bnd_elems1, bnd_elems2;
1096 int numberOf = getNumberOfElements(entityToParse,MED_ALL_ELEMENTS) ;
1098 if ( _coordinate->getNumberOfNodes() > 0 ) // BODY FITTED
1100 throw MEDEXCEPTION("GRID::getBoundaryElements() : not implemented on BOBY FITTED grig");
1102 else if ( entityToParse == MED_FACE ) // 3D CARTESIAN
1104 const int nb_x = getArrayLength( 1 ) - 1;
1105 const int nb_y = getArrayLength( 2 ) - 1;
1106 const int nb_z = getArrayLength( 3 ) - 1;
1108 for ( int z = 0; z < nb_z; ++z )
1109 for ( int y = 0; y < nb_y; ++y )
1111 bnd_elems1.push_back( getFaceNumber( 1, 0, y, z ));
1112 bnd_elems2.push_back( getFaceNumber( 1, nb_x, y, z ));
1114 bnd_elems1.splice( bnd_elems1.end(), bnd_elems2 ); // to have ids in increasing order
1117 for ( int z = 0; z < nb_z; ++z )
1118 for ( int x = 0; x < nb_x; ++x )
1120 bnd_elems1.push_back( getFaceNumber( 2, x, 0, z ));
1121 bnd_elems2.push_back( getFaceNumber( 2, x, nb_y, z ));
1123 bnd_elems1.splice( bnd_elems1.end(), bnd_elems2 );
1126 for ( int y = 0; y < nb_y; ++y )
1127 for ( int x = 0; x < nb_x; ++x )
1129 bnd_elems1.push_back( getFaceNumber( 3, x, y, 0 ));
1130 bnd_elems2.push_back( getFaceNumber( 3, x, y, nb_z ));
1132 bnd_elems1.splice( bnd_elems1.end(), bnd_elems2 );
1136 const int nb_x = getArrayLength( 1 ) - 1;
1137 const int nb_y = getArrayLength( 2 ) - 1;
1139 for ( int x = 0; x < nb_x; ++x )
1141 bnd_elems1.push_back( getEdgeNumber( 1, x, 0 ));
1142 bnd_elems2.push_back( getEdgeNumber( 1, x, nb_y ));
1144 bnd_elems1.splice( bnd_elems1.end(), bnd_elems2 ); // to have ids in increasing order
1146 for ( int y = 0; y < nb_y; ++y )
1148 bnd_elems1.push_back( getEdgeNumber( 2, y, 0 ));
1149 bnd_elems2.push_back( getEdgeNumber( 2, y, nb_x ));
1151 bnd_elems1.splice( bnd_elems1.end(), bnd_elems2 );
1154 if ( bnd_elems1.empty() && numberOf != 0 )
1155 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"No boundary elements found by reverse descending connectivity for entity "<<Entity<<" !"));
1157 if ( Entity == MED_NODE )
1158 return buildSupportOnNodeFromElementList(bnd_elems1,entityToParse);
1160 return buildSupportOnElementsFromElementList(bnd_elems1,entityToParse);
1163 SUPPORT * GRID::getSkin(const SUPPORT * Support3D) throw (MEDEXCEPTION)
1165 throw MEDEXCEPTION("GRID::getSkin() : Not implemented yet");
1167 SUPPORT *GRID::buildSupportOnNodeFromElementList(const std::list<int>& listOfElt,
1168 MED_EN::medEntityMesh entity) const
1169 throw (MEDEXCEPTION)
1171 throw MEDEXCEPTION("GRID::buildSupportOnNodeFromElementList() : Not implemented yet");
1173 void GRID::fillSupportOnNodeFromElementList(const std::list<int>& listOfElt,
1174 SUPPORT * supportToFill) const
1175 throw (MEDEXCEPTION)
1177 throw MEDEXCEPTION("GRID::fillSupportOnNodeFromElementList() : Not implemented yet");
1180 FIELD<double>* GRID::getVolume (const SUPPORT * Support, bool isAbs) const
1181 throw (MEDEXCEPTION)
1183 throw MEDEXCEPTION("GRID::getVolume() : Not implemented yet");
1186 FIELD<double>* GRID::getArea (const SUPPORT * Support) const
1187 throw (MEDEXCEPTION)
1189 throw MEDEXCEPTION("GRID::getArea() : Not implemented yet");
1192 FIELD<double>* GRID::getLength (const SUPPORT * Support) const
1193 throw (MEDEXCEPTION)
1195 throw MEDEXCEPTION("GRID::getLength() : Not implemented yet");
1198 FIELD<double>* GRID::getNormal (const SUPPORT * Support) const
1199 throw (MEDEXCEPTION)
1201 throw MEDEXCEPTION("GRID::getNormal() : Not implemented yet");
1204 FIELD<double>* GRID::getBarycenter (const SUPPORT * Support) const
1205 throw (MEDEXCEPTION)
1207 throw MEDEXCEPTION("GRID::getBarycenter() : Not implemented yet");
1210 vector< vector<double> > GRID::getBoundingBox() const
1212 throw MEDEXCEPTION("GRID::getBoundingBox() : Not implemented yet");