1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/
20 // File : MEDMEM_Grid.hxx
21 // Created : Wed Dec 18 08:35:26 2002
22 // Descr : class containing structured mesh data
24 // Author : Edward AGAPOV (eap)
25 // Project : SALOME Pro
27 // Copyright : Open CASCADE
31 #include "MEDMEM_Grid.hxx"
32 #include "MEDMEM_CellModel.hxx"
33 #include "MEDMEM_SkyLineArray.hxx"
36 using namespace MEDMEM;
37 using namespace MED_EN;
39 //=======================================================================
41 //purpose : empty constructor
42 //=======================================================================
46 MESSAGE("A GRID CREATED");
49 //=======================================================================
51 ////purpose : array constructor
52 ////=======================================================================
53 GRID::GRID(const std::vector<std::vector<double> >& xyz_array,const std::vector<std::string>& coord_name,
54 const std::vector<std::string>& coord_unit, const med_grid_type type) : _gridType(type)
56 _spaceDimension = xyz_array.size();
58 // compute & set _numberOfNodes
60 for(int i=0;i!=xyz_array.size();++i)
61 NumberOfNodes*=xyz_array[i].size();
62 _numberOfNodes = NumberOfNodes ;
64 // create a non allocated COORDINATE
65 _coordinate = new COORDINATE(_spaceDimension, &coord_name[0], &coord_unit[0]);
66 string coordinateSystem = "UNDEFINED";
67 if( _gridType == MED_CARTESIAN)
68 coordinateSystem = "CARTESIAN";
69 else if ( _gridType == MED_POLAR)
70 coordinateSystem = "CYLINDRICAL";
71 _coordinate->setCoordinatesSystem(coordinateSystem);
74 if (_spaceDimension>=1)
76 _iArrayLength=xyz_array[0].size();
77 _iArray=new double[_iArrayLength];
78 std::copy(xyz_array[0].begin(),xyz_array[0].end(),_iArray);
80 if (_spaceDimension>=2)
82 _jArrayLength=xyz_array[1].size();
83 _jArray=new double[_jArrayLength];
84 std::copy(xyz_array[1].begin(),xyz_array[1].end(),_jArray);
86 if (_spaceDimension>=3)
88 _kArrayLength=xyz_array[2].size();
89 _kArray=new double[_kArrayLength];
90 std::copy(xyz_array[2].begin(),xyz_array[2].end(),_kArray);
93 _is_coordinates_filled = false;
94 _is_connectivity_filled = false;
98 //=======================================================================
100 //purpose : empty constructor
101 //=======================================================================
103 GRID::GRID(const med_grid_type type)
107 MESSAGE("A TYPED GRID CREATED");
110 //=======================================================================
112 //purpose : copying constructor
113 //=======================================================================
115 GRID::GRID(const GRID& otherGrid) {
119 //=======================================================================
121 //purpose : destructor
122 //=======================================================================
125 MESSAGE("GRID::~GRID() : Destroying the Grid");
126 if ( _iArray != (double* ) NULL) delete [] _iArray;
127 if ( _jArray != (double* ) NULL) delete [] _jArray;
128 if ( _kArray != (double* ) NULL) delete [] _kArray;
131 //=======================================================================
134 //=======================================================================
138 _gridType = MED_CARTESIAN;
140 _iArray = _jArray = _kArray = (double* ) NULL;
141 _iArrayLength = _jArrayLength = _kArrayLength = 0;
143 _is_coordinates_filled = false;
144 _is_connectivity_filled = false;
151 //=======================================================================
152 //function: operator=
153 //purpose : operator=
154 //=======================================================================
156 GRID & GRID::operator=(const GRID & otherGrid)
160 MESH::operator=(otherGrid);
164 //=======================================================================
166 //purpose : Create a GRID object using a MESH driver of type
167 // (MED_DRIVER, ....) associated with file <fileName>.
168 //=======================================================================
170 GRID::GRID(driverTypes driverType, const string & fileName,
171 const string & driverName) : MESH(driverType, fileName, driverName)
173 const char * LOC ="GRID::GRID(driverTypes , const string & , const string &) : ";
180 // MESH(driverType,fileName,driverName);
182 // current = addDriver(driverType,fileName,driverName);
184 // switch(_drivers[current]->getAccessMode() ) {
186 // MESSAGE(LOC << "driverType must have a MED_RDWR accessMode");
187 // rmDriver(current);
191 // _drivers[current]->open();
192 // _drivers[current]->read();
193 // _drivers[current]->close();
195 // // fill some fields of MESH
196 // fillMeshAfterRead();
204 return the GRID Geometric type, without computing all connectivity
206 const medGeometryElement * GRID::getTypes(medEntityMesh entity) const
208 static const medGeometryElement _gridGeometry[4]={MED_HEXA8,MED_QUAD4,MED_SEG2,MED_POINT1};
214 else if(entity==MED_FACE && _spaceDimension>2 )
216 else if(entity==MED_EDGE && _spaceDimension>1 )
218 else if(entity==MED_NODE && _spaceDimension>0)
221 throw MEDEXCEPTION(LOCALIZED("CONNECTIVITY::getGeometricTypes : Entity not defined !"));
222 return &_gridGeometry[i];
225 MED_EN::medGeometryElement * GRID::getTypesWithPoly(MED_EN::medEntityMesh Entity) const
227 int size=getNumberOfTypesWithPoly(Entity);
228 MED_EN::medGeometryElement *ret=new MED_EN::medGeometryElement[size];
229 memcpy(ret,getTypes(Entity),size*sizeof(MED_EN::medGeometryElement));
233 //=======================================================================
234 //function : fillMeshAfterRead
236 //=======================================================================
238 void GRID::fillMeshAfterRead()
240 // fill not only MESH (:-)
241 _is_coordinates_filled = false;
242 _is_connectivity_filled = false;
244 if (_gridType == MED_BODY_FITTED)
246 _is_coordinates_filled = true;
248 // nb of nodes in each direction is not known, set anything
249 // in order to be able to work anyhow
250 // INFOS("GRID::fillMeshAfterRead(): This stub must be removed");
251 // switch (_spaceDimension) {
253 // _iArrayLength = _numberOfNodes;
254 // _jArrayLength = 0;
255 // _kArrayLength = 0;
258 // _iArrayLength = 2;
259 // _jArrayLength = _numberOfNodes / _iArrayLength;
260 // _kArrayLength = 0;
263 // _iArrayLength = 2;
264 // _jArrayLength = _numberOfNodes / _iArrayLength / 2;
265 // _kArrayLength = _numberOfNodes / _iArrayLength / _jArrayLength;
267 //cout << "ARRAY LENGTHS: " << _iArrayLength << " " << _jArrayLength
268 // << " " << _kArrayLength << endl;
271 // int NbNodes = _iArrayLength;
272 // if (_jArrayLength)
273 // NbNodes *= _jArrayLength;
274 // if (_kArrayLength)
275 // NbNodes *= _kArrayLength;
276 // MESH::_numberOfNodes = NbNodes;
279 MESH::_meshDimension = MESH::_spaceDimension;
282 //=======================================================================
283 //function : fillCoordinates
285 //=======================================================================
287 void GRID::fillCoordinates() const
289 if (_is_coordinates_filled)
292 const char * LOC ="GRID::fillCoordinates()";
295 // if coordonate has not been allocated, perform shalow copy, transfer ownership of matrix
296 if(_coordinate->getSpaceDimension()*_coordinate->getNumberOfNodes() == 0)
297 _coordinate->setCoordinates(new MEDARRAY<double>(_spaceDimension,_numberOfNodes,MED_FULL_INTERLACE),true);
299 double* myCoord = const_cast <double *> ( _coordinate->getCoordinates(MED_FULL_INTERLACE) );
301 bool hasJ = _jArrayLength, hasK = _kArrayLength;
302 int J = hasJ ? _jArrayLength : 1;
303 int K = hasK ? _kArrayLength : 1;
304 //int nb, !! UNUSED VARIABLE !!
306 for (k=0; k < K; ++k) {
307 for (j=0; j < J; ++j) {
308 for (i=0; i < _iArrayLength; ++i) {
310 * myCoord = _iArray[ i ];
315 * myCoord = _jArray[ j ];
320 * myCoord = _kArray[ k ];
328 (const_cast <GRID *> (this))->_is_coordinates_filled = true;
332 //=======================================================================
333 //function : makeConnectivity
335 //=======================================================================
337 CONNECTIVITY * GRID::makeConnectivity (medEntityMesh Entity,
338 medGeometryElement Geometry,
342 const int * NodeNumbers)
345 CONNECTIVITY * Connectivity = new CONNECTIVITY(Entity) ;
346 Connectivity->_numberOfNodes = nbMeshNodes ;
347 Connectivity->_entityDimension = Geometry/100 ;
349 int numberOfGeometricType = 1;
350 Connectivity->_numberOfTypes = numberOfGeometricType;
352 Connectivity->_count = new int [numberOfGeometricType + 1] ;
353 Connectivity->_count[0] = 1;
354 Connectivity->_count[1] = 1 + NbEntities;
356 Connectivity->_type = new CELLMODEL [numberOfGeometricType];
357 Connectivity->_type[0] = CELLMODEL( Geometry ) ;
359 Connectivity->_geometricTypes = new medGeometryElement [ numberOfGeometricType ];
360 Connectivity->_geometricTypes[0] = Geometry;
362 // Connectivity->_nodal = new MEDSKYLINEARRAY() ;
363 int * skyLineArrayIndex = new int [NbEntities + 1];
364 int i, j, nbEntityNodes = Connectivity->_type[0].getNumberOfNodes();
365 for (i=0, j=1; i <= NbEntities; ++i, j += nbEntityNodes)
366 skyLineArrayIndex [ i ] = j;
368 // Connectivity->_nodal->setMEDSKYLINEARRAY (NbEntities, NbNodes,
369 //skyLineArrayIndex, NodeNumbers);
371 Connectivity->_nodal = new MEDSKYLINEARRAY (NbEntities, NbNodes,
372 skyLineArrayIndex, NodeNumbers);
374 delete [] skyLineArrayIndex;
376 // test connectivity right away
377 // for (med_int j = 0; j < numberOfGeometricType; j++)
379 // int node_number = Connectivity->_type[j].getNumberOfNodes();
380 // for (med_int k = Connectivity->_count[j]; k < Connectivity->_count[j+1]; k++)
381 // for (med_int local_node_number = 1 ; local_node_number < node_number+1; local_node_number++)
383 // cout << "MEDSKYLINEARRAY::getIJ(" << k << ", " << local_node_number << endl;
384 // med_int global_node = Connectivity->_nodal->getIJ(k,local_node_number) ;
385 // cout << "...= " << global_node << endl;
392 //=======================================================================
393 //function : fillConnectivity
394 //purpose : fill _coordinates and _connectivity of MESH if not yet done
395 //=======================================================================
397 void GRID::fillConnectivity() const
399 if (_is_connectivity_filled)
401 MESSAGE("GRID::fillConnectivity(): Already filled");
405 const char * LOC = "GRID::fillConnectivity() ";
408 int nbCells, nbFaces, nbEdges;
409 int nbCNodes, nbFNodes, nbENodes, nbMeshNodes;
410 int indexC, indexF, indexE;
411 int * nodeCNumbers, * nodeFNumbers, * nodeENumbers;
412 // about descending connectivity
413 int nbSub, nbRevSub, indexSub, indexRevSub, * subNumbers, * subRevNumbers;
415 bool hasFaces = _kArrayLength, hasEdges = _jArrayLength;
417 int iLenMin1 = _iArrayLength-1, jLenMin1 = _jArrayLength-1;
418 int kLenMin1 = _kArrayLength-1, ijLenMin1 = iLenMin1 * jLenMin1;
419 if (!hasEdges) jLenMin1 = 1;
420 if (!hasFaces) kLenMin1 = 1;
422 // nb of cells and of their connectivity nodes
424 nbCells = iLenMin1 * jLenMin1 * kLenMin1;
425 nbMeshNodes = _iArrayLength * (_jArrayLength ? _jArrayLength : 1) * (_kArrayLength ? _kArrayLength : 1);
426 nbCNodes = nbCells * 2 * (hasEdges ? 2 : 1) * (hasFaces ? 2 : 1);
427 nodeCNumbers = new int [ nbCNodes ];
429 // nb of faces and of their connectivity nodes
432 nbFaces = _iArrayLength * jLenMin1 * kLenMin1;
433 nbFaces += _jArrayLength * kLenMin1 * iLenMin1;
434 nbFaces += _kArrayLength * iLenMin1 * jLenMin1;
435 nbFNodes = nbFaces * 4;
436 nodeFNumbers = new int [ nbFNodes ];
438 nbFaces = nbFNodes = 0;
440 // nb of edges and of their connectivity nodes
443 if (_kArrayLength) { // 3d grid
444 nbEdges = iLenMin1 * _jArrayLength * _kArrayLength;
445 nbEdges += jLenMin1 * _kArrayLength * _iArrayLength;
446 nbEdges += kLenMin1 * _iArrayLength * _jArrayLength;
448 else if (_jArrayLength) { // 2d
449 nbEdges = iLenMin1 * _jArrayLength;
450 nbEdges += jLenMin1 * _iArrayLength;
452 nbENodes = nbEdges * 2;
453 nodeENumbers = new int [ nbENodes ];
455 nbEdges = nbENodes = 0;
457 // nb of descending connectivity Elements
462 nbRevSub = nbFaces * 2;
467 nbRevSub = nbEdges * 2;
469 subNumbers = new int [ nbSub ];
470 subRevNumbers = new int [ nbRevSub ];
471 for (int r=0; r<nbRevSub; ++r)
472 subRevNumbers[ r ] = 0;
474 int nSubI = 1, nSubJ, nSubK; // subelement numbers
477 nSubJ = getFaceNumber(2, 0, 0, 0);
478 nSubK = getFaceNumber(3, 0, 0, 0);
481 nSubJ = getEdgeNumber(2, 0, 0, 0);
484 // fill cell node numbers and descending element numbers
487 indexC = indexF = indexE = indexSub = indexRevSub = -1;
488 int iNode = 0, iCell = 0;
489 int ijLen = _iArrayLength * _jArrayLength;
490 int i, j, k, n1, n2, n3 ,n4;
492 int I = _iArrayLength;
493 int J = _jArrayLength ? _jArrayLength : 2; // pass at least once
494 int K = _kArrayLength ? _kArrayLength : 2;
495 // pass by all but last nodes in all directions
496 for (k = 1; k < K; ++k ) {
497 for (j = 1; j < J; ++j ) {
498 for (i = 1; i < I; ++i ) {
502 n1 = ++iNode; // iNode
504 nodeCNumbers [ ++indexC ] = n1;
505 nodeCNumbers [ ++indexC ] = n2;
507 if (hasEdges) { // at least 2d
510 nodeCNumbers [ ++indexC ] = n3;
511 nodeCNumbers [ ++indexC ] = n4;
513 if (hasFaces) { // 3d
514 nodeCNumbers [ ++indexC ] = n1 + ijLen;
515 nodeCNumbers [ ++indexC ] = n2 + ijLen;
516 nodeCNumbers [ ++indexC ] = n3 + ijLen;
517 nodeCNumbers [ ++indexC ] = n4 + ijLen;
524 subNumbers [ ++indexSub ] = n1;
525 subRevNumbers[ n3 ] = iCell;
526 subNumbers [ ++indexSub ] = n2;
527 subRevNumbers[ n4 ] = -iCell;
532 subNumbers [ ++indexSub ] = n1;
533 subRevNumbers[ n3 ] = iCell;
534 subNumbers [ ++indexSub ] = n2;
535 subRevNumbers[ n4 ] = -iCell;
540 subNumbers [ ++indexSub ] = n1;
541 subRevNumbers[ n3 ] = iCell;
542 subNumbers [ ++indexSub ] = n2;
543 subRevNumbers[ n4 ] = -iCell;
552 subNumbers [ ++indexSub ] = n1;
553 subRevNumbers[ n3 ] = iCell;
554 subNumbers [ ++indexSub ] = n2;
555 subRevNumbers[ n4 ] = -iCell;
560 subNumbers [ ++indexSub ] = n1;
561 subRevNumbers[ n3 ] = iCell;
562 subNumbers [ ++indexSub ] = n2;
563 subRevNumbers[ n4 ] = -iCell;
565 ++nSubI; ++nSubJ; ++nSubK;
567 ++iNode; // skip the last node in a row
573 iNode += I; // skip the whole last row
576 // fill face node numbers
578 int ax, AX = hasFaces ? 3 : 0;
579 for (ax = 1; ax <= AX; ++ax) {
587 case 1: --J; --K; break;
588 case 2: --K; --I; break;
591 for (k = 1; k <= K; ++k ) {
592 for (j = 1; j <= J; ++j ) {
593 for (i = 1; i <= I; ++i ) {
598 case 1: // nodes for faces normal to i direction
603 case 2: // nodes for faces normal to j direction
608 default: // nodes for faces normal to k direction
613 nodeFNumbers [ ++indexF ] = n1;
614 nodeFNumbers [ ++indexF ] = n2;
615 nodeFNumbers [ ++indexF ] = n3;
616 nodeFNumbers [ ++indexF ] = n4;
618 if (ax != 1) ++iNode;
620 if (ax != 2) iNode += _iArrayLength;
623 if (nbFNodes != indexF+1) {
624 throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Wrong nbFNodes : " \
625 << nbFNodes << " indexF : " << indexF ));
628 // fill edge node numbers
630 AX = hasEdges ? _spaceDimension : 0;
631 for (ax = 1; ax <= AX; ++ax) {
645 for (k = 1; k <= K; ++k ) {
646 for (j = 1; j <= J; ++j ) {
647 for (i = 1; i <= I; ++i ) {
652 case 1: // nodes for edges going along i direction
655 case 2: // nodes for edges going along j direction
656 n2 = n1 + _iArrayLength;
658 default: // nodes for edges going along k direction
661 nodeENumbers [ ++indexE ] = n1;
662 nodeENumbers [ ++indexE ] = n2;
664 if (ax == 1) ++iNode;
666 if (ax == 2) iNode += _iArrayLength;
669 if (nbENodes != indexE+1) {
670 throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Wrong nbFNodes : " \
671 << nbENodes << " indexE : " << indexE ));
675 CONNECTIVITY * CellCNCT, * FaceCNCT, * EdgeCNCT;
677 // make connectivity for CELL
679 medGeometryElement aCellGeometry;
680 if (_kArrayLength) aCellGeometry = MED_HEXA8;
681 else if (_jArrayLength) aCellGeometry = MED_QUAD4;
682 else aCellGeometry = MED_SEG2;
685 CellCNCT = makeConnectivity (MED_CELL, aCellGeometry, nbCells, nbCNodes, nbMeshNodes, nodeCNumbers);
687 delete [] nodeCNumbers;
691 // CellCNCT->_descending = new MEDSKYLINEARRAY() ;
692 int * skyLineArrayIndex = new int [nbCells + 1];
693 int nbEntitySub = CellCNCT->_type[0].getNumberOfConstituents(1);
694 for (i=0, j=1; i <= nbCells; ++i, j += nbEntitySub)
695 skyLineArrayIndex [ i ] = j;
696 // CellCNCT->_descending->setMEDSKYLINEARRAY (nbCells, nbSub,
697 // skyLineArrayIndex, subNumbers);
698 CellCNCT->_descending = new MEDSKYLINEARRAY (nbCells, nbSub,
701 delete [] skyLineArrayIndex;
703 delete [] subNumbers;
705 // reverse descending
707 // CellCNCT->_reverseDescendingConnectivity = new MEDSKYLINEARRAY() ;
709 int * skyLineArrayIndex = new int [nbSub + 1];
710 for (i=0, j=1; i <= nbSub; ++i, j += 2)
711 skyLineArrayIndex [ i ] = j;
712 // CellCNCT->_reverseDescendingConnectivity->setMEDSKYLINEARRAY
713 // (nbSub, nbRevSub, skyLineArrayIndex, subRevNumbers);
715 CellCNCT->_reverseDescendingConnectivity =
716 new MEDSKYLINEARRAY(nbSub, nbRevSub, skyLineArrayIndex, subRevNumbers);
718 delete [] skyLineArrayIndex;
720 delete [] subRevNumbers;
722 // make connectivity for FACE and/or EDGE
725 FaceCNCT = makeConnectivity (MED_FACE, MED_QUAD4, nbFaces, nbFNodes, nbMeshNodes, nodeFNumbers);
727 delete [] nodeFNumbers;
729 CellCNCT->_constituent = FaceCNCT;
732 EdgeCNCT = makeConnectivity (MED_EDGE, MED_SEG2, nbEdges, nbENodes, nbMeshNodes, nodeENumbers);
734 delete [] nodeENumbers;
737 FaceCNCT->_constituent = EdgeCNCT;
739 CellCNCT->_constituent = EdgeCNCT;
742 MESH::_connectivity = CellCNCT;
744 (const_cast <GRID *> (this))->_is_connectivity_filled = true;
749 //=======================================================================
750 //function : getArrayLength
751 //purpose : return array length. Axis = [1,2,3] meaning [i,j,k],
752 //=======================================================================
754 int GRID::getArrayLength( const int Axis ) const throw (MEDEXCEPTION)
757 case 1: return _iArrayLength;
758 case 2: return _jArrayLength;
759 case 3: return _kArrayLength;
761 throw MED_EXCEPTION ( LOCALIZED( STRING("GRID::getArrayLength ( ") << Axis << ")"));
766 //=======================================================================
767 //function : getArrayValue
768 //purpose : return i-th array component. Axis = [1,2,3] meaning [i,j,k],
769 // exception if Axis out of [1-3] range
770 // exception if i is out of range 0 <= i < getArrayLength(Axis);
771 //=======================================================================
773 const double GRID::getArrayValue (const int Axis, const int i) const throw (MEDEXCEPTION)
775 if (i < 0 || i >= getArrayLength(Axis))
777 ( LOCALIZED(STRING("GRID::getArrayValue ( ") << Axis << ", " << i << ")"));
780 case 1: return _iArray[ i ];
781 case 2: return _jArray[ i ];
782 default: return _kArray[ i ];
787 //=======================================================================
788 //function : getEdgeNumber
790 //=======================================================================
792 int GRID::getEdgeNumber(const int Axis, const int i, const int j, const int k)
793 const throw (MEDEXCEPTION)
795 const char * LOC = "GRID::getEdgeNumber(Axis, i,j,k) :";
799 int Len[4] = {0,_iArrayLength, _jArrayLength, _kArrayLength }, I=1, J=2, K=3;
800 int maxAxis = Len[ K ] ? 3 : 2;
802 if (Axis <= 0 || Axis > maxAxis)
803 throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "Axis out of range: " << Axis));
806 int Nb = 1 + i + j*Len[ I ] + k*Len[ J ]*Len[ K ];
812 if (Axis > 1) { // add all edges in i direction
814 Nb += Len[ I ]*Len[ J ]*Len[ K ];
817 if (Axis > 2) { // add all edges in j direction
819 Nb += Len[ I ]*Len[ J ]*Len[ K ];
827 //=======================================================================
828 //function : getFaceNumber
829 //purpose : return a NODE, EDGE, FACE, CELL number by its position in the grid.
830 // Axis [1,2,3] means one of directions: along i, j or k
831 // For Cell contituents (FACE or EDGE), Axis selects one of those having same (i,j,k):
832 // * a FACE which is normal to direction along given Axis;
833 // * an EDGE going along given Axis.
834 // Exception for Axis out of range
835 //=======================================================================
837 int GRID::getFaceNumber(const int Axis, const int i, const int j, const int k)
838 const throw (MEDEXCEPTION)
840 const char * LOC = "GRID::getFaceNumber(Axis, i,j,k) :";
844 // if (Axis <= 0 || Axis > 3)
845 if (Axis < 0 || Axis > 3)
846 throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "Axis = " << Axis));
848 int Len[4] = {0,_iArrayLength-1, _jArrayLength-1, _kArrayLength-1 }, I=1, J=2, K=3;
851 int Nb = 1 + i + j*Len[ I ] + k*Len[ J ]*Len[ K ];
854 if (Axis > 1) { // add all faces in i direction
856 Nb += Len[ I ]*Len[ J ]*Len[ K ];
859 if (Axis > 2) { // add all faces in j direction
861 Nb += Len[ I ]*Len[ J ]*Len[ K ];
869 //=======================================================================
870 //function : getNodePosition
872 //=======================================================================
874 void GRID::getNodePosition(const int Number, int& i, int& j, int& k) const
877 const char * LOC = "GRID::getNodePosition(Number, i,j,k) :";
881 if (Number <= 0 || Number > _numberOfNodes)
882 throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "Number is out of range: " << Number));
884 int Len[] = {_iArrayLength, _jArrayLength, _kArrayLength }, I=0, J=1;
885 // , K=2; !! UNUSED VARIABLE !!
887 int ijLen = Len[I] * Len[J]; // nb in a full k layer
888 int kLen = (Number - 1) % ijLen; // nb in the non full k layer
892 k = (Number - 1) / ijLen;
894 ////cout <<" NODE POS: " << Number << " - " << i << ", " << j << ", " << k << endl;
900 //=======================================================================
901 //function : getCellPosition
903 //=======================================================================
905 void GRID::getCellPosition(const int Number, int& i, int& j, int& k) const
908 const char * LOC = "GRID::getCellPosition(Number, i,j,k) :";
912 int Len[4] = {0,_iArrayLength-1, _jArrayLength-1, _kArrayLength-1 }, I=1, J=2;
913 // , K=3; !! UNUSED VARIABLE !!
915 // if (Number <= 0 || Number > getCellNumber(Len[I]-1, Len[J]-1, Len[K]-1))
916 // throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "Number is out of range: " << Number));
918 int ijLen = Len[I] * Len[J]; // nb in a full k layer
919 int kLen = (Number - 1) % ijLen; // nb in the non full k layer
923 k = (Number - 1) / ijLen;
928 //=======================================================================
929 //function : getEdgePosition
931 //=======================================================================
933 void GRID::getEdgePosition(const int Number, int& Axis, int& i, int& j, int& k)
934 const throw (MEDEXCEPTION)
936 const char * LOC = "GRID::getEdgePosition(Number, i,j,k) :";
941 throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "no edges in the grid: "));
944 throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "Number is out of range: " << Number));
946 int Len[4] = {0,_iArrayLength, _jArrayLength, _kArrayLength }, I=1, J=2, K=3;
949 int maxAxis = _kArrayLength ? 3 : 2;
951 for (Axis = 1; Axis <= maxAxis; ++Axis)
953 Len[Axis]--; // one less edge in Axis direction
955 // max edge number in Axis direction
956 int maxNb = getEdgeNumber (Axis, Len[I]-1, Len[J]-1, Len[K]-1);
973 int ijLen = Len[I] * Len[J]; // nb in a full k layer
974 int kLen = (theNb - 1) % ijLen; // nb in the non full k layer
977 k = (theNb - 1) / ijLen;
985 throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "Number is out of range: " << Number));
988 //=======================================================================
989 //function : getFacePosition
990 //purpose : return position (i,j,k) of an entity #Number
991 // Axis [1,2,3] means one of directions: along i, j or k
992 // For Cell contituents (FACE or EDGE), Axis selects one of those having same (i,j,k):
993 // * a FACE which is normal to direction along given Axis;
994 // * an EDGE going along given Axis.
995 // Exception for Number out of range
996 //=======================================================================
998 void GRID::getFacePosition(const int Number, int& Axis, int& i, int& j, int& k)
999 const throw (MEDEXCEPTION)
1001 const char * LOC = "GRID::getFacePosition(Number, i,j,k) :";
1005 if (_kArrayLength == 0) {
1006 getCellPosition(Number, i, j, k);
1012 throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "no faces in the grid: "));
1015 throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "Number is out of range: " << Number));
1017 int Len[4] = {0,_iArrayLength-1, _jArrayLength-1, _kArrayLength-1 }, I=1, J=2, K=3;
1020 for (Axis = 1; Axis <= 3; ++Axis)
1024 // max face number in Axis direction
1025 int maxNb = getFaceNumber (Axis, Len[I]-1, Len[J]-1, Len[K]-1);
1042 int ijLen = Len[I] * Len[J]; // nb in a full k layer
1043 int kLen = (theNb - 1) % ijLen; // nb in the non full k layer
1046 k = (theNb - 1) / ijLen;
1054 throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "Number is out of range: " << Number));
1057 //=======================================================================
1058 //function : writeUnstructured
1059 //purpose : write a Grid as an Unstructured mesh
1060 //=======================================================================
1062 void GRID::writeUnstructured(int index, const string & driverName)
1064 const char * LOC = "GRID::writeUnstructured(int index=0, const string & driverName) : ";
1067 if ( _drivers[index] ) {
1072 _drivers[index]->open();
1073 if (driverName != "") _drivers[index]->setMeshName(driverName);
1074 _drivers[index]->write();
1075 _drivers[index]->close();
1080 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
1081 << "The index given is invalid, index must be between 0 and |"
1088 void GRID::read(int index)
1090 const char * LOC = "GRID::read(int index=0) : ";
1093 if (_drivers[index]) {
1094 _drivers[index]->open();
1095 _drivers[index]->read();
1096 _drivers[index]->close();
1099 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
1100 << "The index given is invalid, index must be between 0 and |"
1105 fillMeshAfterRead();