2 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
3 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License.
10 // This library is distributed in the hope that it will be useful
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Lesser General Public License for more details.
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 // File : MEDMEM_Grid.hxx
22 // Created : Wed Dec 18 08:35:26 2002
23 // Descr : class containing structured mesh data
25 // Author : Edward AGAPOV (eap)
26 // Project : SALOME Pro
31 #include "MEDMEM_Grid.hxx"
32 #include "MEDMEM_CellModel.hxx"
33 #include "MEDMEM_SkyLineArray.hxx"
34 #include "MEDMEM_DriverFactory.hxx"
37 using namespace MEDMEM;
38 using namespace MED_EN;
40 //=======================================================================
42 //purpose : empty constructor
43 //=======================================================================
47 MESSAGE("A GRID CREATED");
50 //=======================================================================
52 ////purpose : array constructor
53 ////=======================================================================
54 GRID::GRID(const std::vector<std::vector<double> >& xyz_array,
55 const std::vector<std::string>& coord_name,
56 const std::vector<std::string>& coord_unit,
57 const med_grid_type type) : _gridType(type)
60 _is_default_gridType = false;
62 _spaceDimension = xyz_array.size();
63 _meshDimension = _spaceDimension; // PAL14482
65 // compute & set _numberOfNodes
67 for(int i=0;i!=xyz_array.size();++i)
68 NumberOfNodes*=xyz_array[i].size();
69 _numberOfNodes = NumberOfNodes ;
71 // create a non allocated COORDINATE
72 _coordinate = new COORDINATE(_spaceDimension, &coord_name[0], &coord_unit[0]);
73 string coordinateSystem = "UNDEFINED";
74 if( _gridType == MED_CARTESIAN)
75 coordinateSystem = "CARTESIAN";
76 else if ( _gridType == MED_POLAR)
77 coordinateSystem = "CYLINDRICAL";
78 _coordinate->setCoordinatesSystem(coordinateSystem);
81 if (_spaceDimension>=1)
83 _iArrayLength=xyz_array[0].size();
84 _iArray=new double[_iArrayLength];
85 std::copy(xyz_array[0].begin(),xyz_array[0].end(),_iArray);
87 if (_spaceDimension>=2)
89 _jArrayLength=xyz_array[1].size();
90 _jArray=new double[_jArrayLength];
91 std::copy(xyz_array[1].begin(),xyz_array[1].end(),_jArray);
93 if (_spaceDimension>=3)
95 _kArrayLength=xyz_array[2].size();
96 _kArray=new double[_kArrayLength];
97 std::copy(xyz_array[2].begin(),xyz_array[2].end(),_kArray);
100 _is_coordinates_filled = false;
101 _is_connectivity_filled = false;
105 //=======================================================================
107 //purpose : empty constructor
108 //=======================================================================
110 GRID::GRID(const med_grid_type type)
114 _is_default_gridType = false;
115 MESSAGE("A TYPED GRID CREATED");
118 //=======================================================================
120 //purpose : copying constructor
121 //=======================================================================
123 GRID::GRID(const GRID& otherGrid) {
127 //=======================================================================
129 //purpose : destructor
130 //=======================================================================
133 MESSAGE("GRID::~GRID() : Destroying the Grid");
134 if ( _iArray != (double* ) NULL) delete [] _iArray;
135 if ( _jArray != (double* ) NULL) delete [] _jArray;
136 if ( _kArray != (double* ) NULL) delete [] _kArray;
139 //=======================================================================
142 //=======================================================================
146 _gridType = MED_CARTESIAN;
147 _is_default_gridType = true;
149 _iArray = _jArray = _kArray = (double* ) NULL;
150 _iArrayLength = _jArrayLength = _kArrayLength = 0;
152 _is_coordinates_filled = false;
153 _is_connectivity_filled = false;
160 //=======================================================================
161 //function: operator=
162 //purpose : operator=
163 //=======================================================================
165 GRID & GRID::operator=(const GRID & otherGrid)
169 MESH::operator=(otherGrid);
173 //=======================================================================
175 //purpose : Create a GRID object using a MESH driver of type
176 // (MED_DRIVER, ....) associated with file <fileName>.
177 //=======================================================================
179 GRID::GRID(driverTypes driverType, const string & fileName,
180 const string & driverName)// : MESH(driverType, fileName, driverName)
182 const char * LOC ="GRID::GRID(driverTypes , const string & , const string &) : ";
187 GENDRIVER *myDriver=DRIVERFACTORY::buildDriverForMesh(driverType,fileName,this,driverName,MED_LECT);
188 int current = addDriver(*myDriver);
190 _drivers[current]->open();
191 _drivers[current]->read();
192 _drivers[current]->close();
200 return the GRID Geometric type, without computing all connectivity
202 const medGeometryElement * GRID::getTypes(medEntityMesh entity) const
204 static const medGeometryElement _gridGeometry[4]={MED_HEXA8,MED_QUAD4,MED_SEG2,MED_POINT1};
210 else if(entity==MED_FACE && _spaceDimension>2 )
212 else if(entity==MED_EDGE && _spaceDimension>1 )
214 else if(entity==MED_NODE && _spaceDimension>0)
217 throw MEDEXCEPTION(LOCALIZED("CONNECTIVITY::getGeometricTypes : Entity not defined !"));
218 return &_gridGeometry[i];
221 MED_EN::medGeometryElement * GRID::getTypesWithPoly(MED_EN::medEntityMesh Entity) const
223 int size=getNumberOfTypesWithPoly(Entity);
224 MED_EN::medGeometryElement *ret=new MED_EN::medGeometryElement[size];
225 memcpy(ret,getTypes(Entity),size*sizeof(MED_EN::medGeometryElement));
229 //=======================================================================
230 //function : fillMeshAfterRead
232 //=======================================================================
234 void GRID::fillMeshAfterRead()
236 // fill not only MESH (:-)
237 _is_coordinates_filled = false;
238 _is_connectivity_filled = false;
240 if (_gridType == MED_BODY_FITTED)
242 _is_coordinates_filled = true;
244 // nb of nodes in each direction is not known, set anything
245 // in order to be able to work anyhow
246 // INFOS("GRID::fillMeshAfterRead(): This stub must be removed");
247 // switch (_spaceDimension) {
249 // _iArrayLength = _numberOfNodes;
250 // _jArrayLength = 0;
251 // _kArrayLength = 0;
254 // _iArrayLength = 2;
255 // _jArrayLength = _numberOfNodes / _iArrayLength;
256 // _kArrayLength = 0;
259 // _iArrayLength = 2;
260 // _jArrayLength = _numberOfNodes / _iArrayLength / 2;
261 // _kArrayLength = _numberOfNodes / _iArrayLength / _jArrayLength;
263 //cout << "ARRAY LENGTHS: " << _iArrayLength << " " << _jArrayLength
264 // << " " << _kArrayLength << endl;
267 // int NbNodes = _iArrayLength;
268 // if (_jArrayLength)
269 // NbNodes *= _jArrayLength;
270 // if (_kArrayLength)
271 // NbNodes *= _kArrayLength;
272 // MESH::_numberOfNodes = NbNodes;
275 MESH::_meshDimension = MESH::_spaceDimension;
278 //=======================================================================
279 //function : fillCoordinates
281 //=======================================================================
283 void GRID::fillCoordinates() const
285 if (_is_coordinates_filled)
288 const char * LOC ="GRID::fillCoordinates()";
291 // if coordonate has not been allocated, perform shalow copy, transfer ownership of matrix
292 if(_coordinate->getSpaceDimension()*_coordinate->getNumberOfNodes() == 0)
293 _coordinate->setCoordinates(new MEDARRAY<double>(_spaceDimension,_numberOfNodes,MED_FULL_INTERLACE),true);
295 double* myCoord = const_cast <double *> ( _coordinate->getCoordinates(MED_FULL_INTERLACE) );
297 bool hasJ = _jArrayLength, hasK = _kArrayLength;
298 int J = hasJ ? _jArrayLength : 1;
299 int K = hasK ? _kArrayLength : 1;
300 //int nb, !! UNUSED VARIABLE !!
302 for (k=0; k < K; ++k) {
303 for (j=0; j < J; ++j) {
304 for (i=0; i < _iArrayLength; ++i) {
306 * myCoord = _iArray[ i ];
311 * myCoord = _jArray[ j ];
316 * myCoord = _kArray[ k ];
324 (const_cast <GRID *> (this))->_is_coordinates_filled = true;
328 //=======================================================================
329 //function : makeConnectivity
331 //=======================================================================
333 CONNECTIVITY * GRID::makeConnectivity (medEntityMesh Entity,
334 medGeometryElement Geometry,
338 const int * NodeNumbers)
341 CONNECTIVITY * Connectivity = new CONNECTIVITY(Entity) ;
342 Connectivity->_numberOfNodes = nbMeshNodes ;
343 Connectivity->_entityDimension = Geometry/100 ;
345 int numberOfGeometricType = 1;
346 Connectivity->_numberOfTypes = numberOfGeometricType;
348 Connectivity->_count = new int [numberOfGeometricType + 1] ;
349 Connectivity->_count[0] = 1;
350 Connectivity->_count[1] = 1 + NbEntities;
352 Connectivity->_type = new CELLMODEL [numberOfGeometricType];
353 Connectivity->_type[0] = CELLMODEL( Geometry ) ;
355 Connectivity->_geometricTypes = new medGeometryElement [ numberOfGeometricType ];
356 Connectivity->_geometricTypes[0] = Geometry;
358 // Connectivity->_nodal = new MEDSKYLINEARRAY() ;
359 int * skyLineArrayIndex = new int [NbEntities + 1];
360 int i, j, nbEntityNodes = Connectivity->_type[0].getNumberOfNodes();
361 for (i=0, j=1; i <= NbEntities; ++i, j += nbEntityNodes)
362 skyLineArrayIndex [ i ] = j;
364 // Connectivity->_nodal->setMEDSKYLINEARRAY (NbEntities, NbNodes,
365 //skyLineArrayIndex, NodeNumbers);
367 Connectivity->_nodal = new MEDSKYLINEARRAY (NbEntities, NbNodes,
368 skyLineArrayIndex, NodeNumbers);
370 delete [] skyLineArrayIndex;
372 // test connectivity right away
373 // for (med_int j = 0; j < numberOfGeometricType; j++)
375 // int node_number = Connectivity->_type[j].getNumberOfNodes();
376 // for (med_int k = Connectivity->_count[j]; k < Connectivity->_count[j+1]; k++)
377 // for (med_int local_node_number = 1 ; local_node_number < node_number+1; local_node_number++)
379 // cout << "MEDSKYLINEARRAY::getIJ(" << k << ", " << local_node_number << endl;
380 // med_int global_node = Connectivity->_nodal->getIJ(k,local_node_number) ;
381 // cout << "...= " << global_node << endl;
388 //=======================================================================
389 //function : fillConnectivity
390 //purpose : fill _coordinates and _connectivity of MESH if not yet done
391 //=======================================================================
393 void GRID::fillConnectivity() const
395 if (_is_connectivity_filled)
397 MESSAGE("GRID::fillConnectivity(): Already filled");
401 const char * LOC = "GRID::fillConnectivity() ";
404 int nbCells, nbFaces, nbEdges;
405 int nbCNodes, nbFNodes, nbENodes, nbMeshNodes;
406 int indexC, indexF, indexE;
407 int * nodeCNumbers, * nodeFNumbers, * nodeENumbers;
408 // about descending connectivity
409 int nbSub, nbRevSub, indexSub, indexRevSub, * subNumbers, * subRevNumbers;
411 bool hasFaces = _kArrayLength, hasEdges = _jArrayLength;
413 int iLenMin1 = _iArrayLength-1, jLenMin1 = _jArrayLength-1;
414 int kLenMin1 = _kArrayLength-1, ijLenMin1 = iLenMin1 * jLenMin1;
415 if (!hasEdges) jLenMin1 = 1;
416 if (!hasFaces) kLenMin1 = 1;
418 // nb of cells and of their connectivity nodes
420 nbCells = iLenMin1 * jLenMin1 * kLenMin1;
421 nbMeshNodes = _iArrayLength * (_jArrayLength ? _jArrayLength : 1) * (_kArrayLength ? _kArrayLength : 1);
422 nbCNodes = nbCells * 2 * (hasEdges ? 2 : 1) * (hasFaces ? 2 : 1);
423 nodeCNumbers = new int [ nbCNodes ];
425 // nb of faces and of their connectivity nodes
428 nbFaces = _iArrayLength * jLenMin1 * kLenMin1;
429 nbFaces += _jArrayLength * kLenMin1 * iLenMin1;
430 nbFaces += _kArrayLength * iLenMin1 * jLenMin1;
431 nbFNodes = nbFaces * 4;
432 nodeFNumbers = new int [ nbFNodes ];
434 nbFaces = nbFNodes = 0;
436 // nb of edges and of their connectivity nodes
439 if (_kArrayLength) { // 3d grid
440 nbEdges = iLenMin1 * _jArrayLength * _kArrayLength;
441 nbEdges += jLenMin1 * _kArrayLength * _iArrayLength;
442 nbEdges += kLenMin1 * _iArrayLength * _jArrayLength;
444 else if (_jArrayLength) { // 2d
445 nbEdges = iLenMin1 * _jArrayLength;
446 nbEdges += jLenMin1 * _iArrayLength;
448 nbENodes = nbEdges * 2;
449 nodeENumbers = new int [ nbENodes ];
451 nbEdges = nbENodes = 0;
453 // nb of descending connectivity Elements
458 nbRevSub = nbFaces * 2;
463 nbRevSub = nbEdges * 2;
465 subNumbers = new int [ nbSub ];
466 subRevNumbers = new int [ nbRevSub ];
467 for (int r=0; r<nbRevSub; ++r)
468 subRevNumbers[ r ] = 0;
470 int nSubI = 1, nSubJ, nSubK; // subelement numbers
473 nSubJ = getFaceNumber(2, 0, 0, 0);
474 nSubK = getFaceNumber(3, 0, 0, 0);
477 nSubJ = getEdgeNumber(2, 0, 0, 0);
480 // fill cell node numbers and descending element numbers
483 indexC = indexF = indexE = indexSub = indexRevSub = -1;
484 int iNode = 0, iCell = 0;
485 int ijLen = _iArrayLength * _jArrayLength;
486 int i, j, k, n1, n2, n3 ,n4;
488 int I = _iArrayLength;
489 int J = _jArrayLength ? _jArrayLength : 2; // pass at least once
490 int K = _kArrayLength ? _kArrayLength : 2;
491 // pass by all but last nodes in all directions
492 for (k = 1; k < K; ++k ) {
493 for (j = 1; j < J; ++j ) {
494 for (i = 1; i < I; ++i ) {
498 n1 = ++iNode; // iNode
500 nodeCNumbers [ ++indexC ] = n1;
501 nodeCNumbers [ ++indexC ] = n2;
503 if (hasEdges) { // at least 2d
506 nodeCNumbers [ ++indexC ] = n3;
507 nodeCNumbers [ ++indexC ] = n4;
509 if (hasFaces) { // 3d
510 nodeCNumbers [ ++indexC ] = n1 + ijLen;
511 nodeCNumbers [ ++indexC ] = n2 + ijLen;
512 nodeCNumbers [ ++indexC ] = n3 + ijLen;
513 nodeCNumbers [ ++indexC ] = n4 + ijLen;
520 subNumbers [ ++indexSub ] = n1;
521 subRevNumbers[ n3 ] = iCell;
522 subNumbers [ ++indexSub ] = n2;
523 subRevNumbers[ n4 ] = -iCell;
528 subNumbers [ ++indexSub ] = n1;
529 subRevNumbers[ n3 ] = iCell;
530 subNumbers [ ++indexSub ] = n2;
531 subRevNumbers[ n4 ] = -iCell;
536 subNumbers [ ++indexSub ] = n1;
537 subRevNumbers[ n3 ] = iCell;
538 subNumbers [ ++indexSub ] = n2;
539 subRevNumbers[ n4 ] = -iCell;
548 subNumbers [ ++indexSub ] = n1;
549 subRevNumbers[ n3 ] = iCell;
550 subNumbers [ ++indexSub ] = n2;
551 subRevNumbers[ n4 ] = -iCell;
556 subNumbers [ ++indexSub ] = n1;
557 subRevNumbers[ n3 ] = iCell;
558 subNumbers [ ++indexSub ] = n2;
559 subRevNumbers[ n4 ] = -iCell;
561 ++nSubI; ++nSubJ; ++nSubK;
563 ++iNode; // skip the last node in a row
569 iNode += I; // skip the whole last row
572 // fill face node numbers
574 int ax, AX = hasFaces ? 3 : 0;
575 for (ax = 1; ax <= AX; ++ax) {
583 case 1: --J; --K; break;
584 case 2: --K; --I; break;
587 for (k = 1; k <= K; ++k ) {
588 for (j = 1; j <= J; ++j ) {
589 for (i = 1; i <= I; ++i ) {
594 case 1: // nodes for faces normal to i direction
599 case 2: // nodes for faces normal to j direction
604 default: // nodes for faces normal to k direction
609 nodeFNumbers [ ++indexF ] = n1;
610 nodeFNumbers [ ++indexF ] = n2;
611 nodeFNumbers [ ++indexF ] = n3;
612 nodeFNumbers [ ++indexF ] = n4;
614 if (ax != 1) ++iNode;
616 if (ax != 2) iNode += _iArrayLength;
619 if (nbFNodes != indexF+1) {
620 throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Wrong nbFNodes : " \
621 << nbFNodes << " indexF : " << indexF ));
624 // fill edge node numbers
626 AX = hasEdges ? _spaceDimension : 0;
627 for (ax = 1; ax <= AX; ++ax) {
641 for (k = 1; k <= K; ++k ) {
642 for (j = 1; j <= J; ++j ) {
643 for (i = 1; i <= I; ++i ) {
648 case 1: // nodes for edges going along i direction
651 case 2: // nodes for edges going along j direction
652 n2 = n1 + _iArrayLength;
654 default: // nodes for edges going along k direction
657 nodeENumbers [ ++indexE ] = n1;
658 nodeENumbers [ ++indexE ] = n2;
660 if (ax == 1) ++iNode;
662 if (ax == 2) iNode += _iArrayLength;
665 if (nbENodes != indexE+1) {
666 throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Wrong nbFNodes : " \
667 << nbENodes << " indexE : " << indexE ));
671 CONNECTIVITY * CellCNCT, * FaceCNCT, * EdgeCNCT;
673 // make connectivity for CELL
675 medGeometryElement aCellGeometry;
676 if (_kArrayLength) aCellGeometry = MED_HEXA8;
677 else if (_jArrayLength) aCellGeometry = MED_QUAD4;
678 else aCellGeometry = MED_SEG2;
681 CellCNCT = makeConnectivity (MED_CELL, aCellGeometry, nbCells, nbCNodes, nbMeshNodes, nodeCNumbers);
683 delete [] nodeCNumbers;
687 // CellCNCT->_descending = new MEDSKYLINEARRAY() ;
688 int * skyLineArrayIndex = new int [nbCells + 1];
689 int nbEntitySub = CellCNCT->_type[0].getNumberOfConstituents(1);
690 for (i=0, j=1; i <= nbCells; ++i, j += nbEntitySub)
691 skyLineArrayIndex [ i ] = j;
692 // CellCNCT->_descending->setMEDSKYLINEARRAY (nbCells, nbSub,
693 // skyLineArrayIndex, subNumbers);
694 CellCNCT->_descending = new MEDSKYLINEARRAY (nbCells, nbSub,
697 delete [] skyLineArrayIndex;
699 delete [] subNumbers;
701 // reverse descending
703 // CellCNCT->_reverseDescendingConnectivity = new MEDSKYLINEARRAY() ;
705 int * skyLineArrayIndex = new int [nbSub + 1];
706 for (i=0, j=1; i <= nbSub; ++i, j += 2)
707 skyLineArrayIndex [ i ] = j;
708 // CellCNCT->_reverseDescendingConnectivity->setMEDSKYLINEARRAY
709 // (nbSub, nbRevSub, skyLineArrayIndex, subRevNumbers);
711 CellCNCT->_reverseDescendingConnectivity =
712 new MEDSKYLINEARRAY(nbSub, nbRevSub, skyLineArrayIndex, subRevNumbers);
714 delete [] skyLineArrayIndex;
716 delete [] subRevNumbers;
718 // make connectivity for FACE and/or EDGE
721 FaceCNCT = makeConnectivity (MED_FACE, MED_QUAD4, nbFaces, nbFNodes, nbMeshNodes, nodeFNumbers);
723 delete [] nodeFNumbers;
725 CellCNCT->_constituent = FaceCNCT;
728 EdgeCNCT = makeConnectivity (MED_EDGE, MED_SEG2, nbEdges, nbENodes, nbMeshNodes, nodeENumbers);
730 delete [] nodeENumbers;
733 FaceCNCT->_constituent = EdgeCNCT;
735 CellCNCT->_constituent = EdgeCNCT;
738 MESH::_connectivity = CellCNCT;
740 (const_cast <GRID *> (this))->_is_connectivity_filled = true;
745 //=======================================================================
746 //function : getArrayLength
747 //purpose : return array length. Axis = [1,2,3] meaning [i,j,k],
748 //=======================================================================
750 int GRID::getArrayLength( const int Axis ) const throw (MEDEXCEPTION)
753 case 1: return _iArrayLength;
754 case 2: return _jArrayLength;
755 case 3: return _kArrayLength;
757 throw MED_EXCEPTION ( LOCALIZED( STRING("GRID::getArrayLength ( ") << Axis << ")"));
762 //=======================================================================
763 //function : getArrayValue
764 //purpose : return i-th array component. Axis = [1,2,3] meaning [i,j,k],
765 // exception if Axis out of [1-3] range
766 // exception if i is out of range 0 <= i < getArrayLength(Axis);
767 //=======================================================================
769 const double GRID::getArrayValue (const int Axis, const int i) const throw (MEDEXCEPTION)
771 if (i < 0 || i >= getArrayLength(Axis))
773 ( LOCALIZED(STRING("GRID::getArrayValue ( ") << Axis << ", " << i << ")"));
776 case 1: return _iArray[ i ];
777 case 2: return _jArray[ i ];
778 default: return _kArray[ i ];
783 //=======================================================================
784 //function : getEdgeNumber
786 //=======================================================================
788 int GRID::getEdgeNumber(const int Axis, const int i, const int j, const int k)
789 const throw (MEDEXCEPTION)
791 const char * LOC = "GRID::getEdgeNumber(Axis, i,j,k) :";
795 int Len[4] = {0,_iArrayLength, _jArrayLength, _kArrayLength }, I=1, J=2, K=3;
796 int maxAxis = Len[ K ] ? 3 : 2;
798 if (Axis <= 0 || Axis > maxAxis)
799 throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "Axis out of range: " << Axis));
802 int Nb = 1 + i + j*Len[ I ] + k*Len[ J ]*Len[ K ];
808 if (Axis > 1) { // add all edges in i direction
810 Nb += Len[ I ]*Len[ J ]*Len[ K ];
813 if (Axis > 2) { // add all edges in j direction
815 Nb += Len[ I ]*Len[ J ]*Len[ K ];
823 //=======================================================================
824 //function : getFaceNumber
825 //purpose : return a NODE, EDGE, FACE, CELL number by its position in the grid.
826 // Axis [1,2,3] means one of directions: along i, j or k
827 // For Cell contituents (FACE or EDGE), Axis selects one of those having same (i,j,k):
828 // * a FACE which is normal to direction along given Axis;
829 // * an EDGE going along given Axis.
830 // Exception for Axis out of range
831 //=======================================================================
833 int GRID::getFaceNumber(const int Axis, const int i, const int j, const int k)
834 const throw (MEDEXCEPTION)
836 const char * LOC = "GRID::getFaceNumber(Axis, i,j,k) :";
840 // if (Axis <= 0 || Axis > 3)
841 if (Axis < 0 || Axis > 3)
842 throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "Axis = " << Axis));
844 int Len[4] = {0,_iArrayLength-1, _jArrayLength-1, _kArrayLength-1 }, I=1, J=2, K=3;
847 int Nb = 1 + i + j*Len[ I ] + k*Len[ J ]*Len[ K ];
850 if (Axis > 1) { // add all faces in i direction
852 Nb += Len[ I ]*Len[ J ]*Len[ K ];
855 if (Axis > 2) { // add all faces in j direction
857 Nb += Len[ I ]*Len[ J ]*Len[ K ];
865 //=======================================================================
866 //function : getNodePosition
868 //=======================================================================
870 void GRID::getNodePosition(const int Number, int& i, int& j, int& k) const
873 const char * LOC = "GRID::getNodePosition(Number, i,j,k) :";
877 if (Number <= 0 || Number > _numberOfNodes)
878 throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "Number is out of range: " << Number));
880 int Len[] = {_iArrayLength, _jArrayLength, _kArrayLength }, I=0, J=1;
881 // , K=2; !! UNUSED VARIABLE !!
883 int ijLen = Len[I] * Len[J]; // nb in a full k layer
884 int kLen = (Number - 1) % ijLen; // nb in the non full k layer
888 k = (Number - 1) / ijLen;
890 ////cout <<" NODE POS: " << Number << " - " << i << ", " << j << ", " << k << endl;
896 //=======================================================================
897 //function : getCellPosition
899 //=======================================================================
901 void GRID::getCellPosition(const int Number, int& i, int& j, int& k) const
904 const char * LOC = "GRID::getCellPosition(Number, i,j,k) :";
908 int Len[4] = {0,_iArrayLength-1, _jArrayLength-1, _kArrayLength-1 }, I=1, J=2;
909 // , K=3; !! UNUSED VARIABLE !!
911 // if (Number <= 0 || Number > getCellNumber(Len[I]-1, Len[J]-1, Len[K]-1))
912 // throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "Number is out of range: " << Number));
914 int ijLen = Len[I] * Len[J]; // nb in a full k layer
915 int kLen = (Number - 1) % ijLen; // nb in the non full k layer
919 k = (Number - 1) / ijLen;
924 //=======================================================================
925 //function : getEdgePosition
927 //=======================================================================
929 void GRID::getEdgePosition(const int Number, int& Axis, int& i, int& j, int& k)
930 const throw (MEDEXCEPTION)
932 const char * LOC = "GRID::getEdgePosition(Number, i,j,k) :";
937 throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "no edges in the grid: "));
940 throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "Number is out of range: " << Number));
942 int Len[4] = {0,_iArrayLength, _jArrayLength, _kArrayLength }, I=1, J=2, K=3;
945 int maxAxis = _kArrayLength ? 3 : 2;
947 for (Axis = 1; Axis <= maxAxis; ++Axis)
949 Len[Axis]--; // one less edge in Axis direction
951 // max edge number in Axis direction
952 int maxNb = getEdgeNumber (Axis, Len[I]-1, Len[J]-1, Len[K]-1);
969 int ijLen = Len[I] * Len[J]; // nb in a full k layer
970 int kLen = (theNb - 1) % ijLen; // nb in the non full k layer
973 k = (theNb - 1) / ijLen;
981 throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "Number is out of range: " << Number));
984 //=======================================================================
985 //function : getFacePosition
986 //purpose : return position (i,j,k) of an entity #Number
987 // Axis [1,2,3] means one of directions: along i, j or k
988 // For Cell contituents (FACE or EDGE), Axis selects one of those having same (i,j,k):
989 // * a FACE which is normal to direction along given Axis;
990 // * an EDGE going along given Axis.
991 // Exception for Number out of range
992 //=======================================================================
994 void GRID::getFacePosition(const int Number, int& Axis, int& i, int& j, int& k)
995 const throw (MEDEXCEPTION)
997 const char * LOC = "GRID::getFacePosition(Number, i,j,k) :";
1001 if (_kArrayLength == 0) {
1002 getCellPosition(Number, i, j, k);
1008 throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "no faces in the grid: "));
1011 throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "Number is out of range: " << Number));
1013 int Len[4] = {0,_iArrayLength-1, _jArrayLength-1, _kArrayLength-1 }, I=1, J=2, K=3;
1016 for (Axis = 1; Axis <= 3; ++Axis)
1020 // max face number in Axis direction
1021 int maxNb = getFaceNumber (Axis, Len[I]-1, Len[J]-1, Len[K]-1);
1038 int ijLen = Len[I] * Len[J]; // nb in a full k layer
1039 int kLen = (theNb - 1) % ijLen; // nb in the non full k layer
1042 k = (theNb - 1) / ijLen;
1050 throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "Number is out of range: " << Number));
1053 //=======================================================================
1054 //function : writeUnstructured
1055 //purpose : write a Grid as an Unstructured mesh
1056 //=======================================================================
1058 void GRID::writeUnstructured(int index, const string & driverName)
1060 const char * LOC = "GRID::writeUnstructured(int index=0, const string & driverName) : ";
1063 if ( _drivers[index] ) {
1068 _drivers[index]->open();
1069 if (driverName != "") _drivers[index]->setMeshName(driverName);
1070 _drivers[index]->write();
1071 _drivers[index]->close();
1076 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
1077 << "The index given is invalid, index must be between 0 and |"
1084 void GRID::read(int index)
1086 const char * LOC = "GRID::read(int index=0) : ";
1089 if (_drivers[index]) {
1090 _drivers[index]->open();
1091 _drivers[index]->read();
1092 _drivers[index]->close();
1095 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
1096 << "The index given is invalid, index must be between 0 and |"
1101 fillMeshAfterRead();