Back to index

salome-med  6.5.0
MEDMEMTest_Connectivity.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 
00020 #include "MEDMEMTest.hxx"
00021 #include <cppunit/TestAssert.h>
00022 
00023 #include "MEDMEM_Connectivity.hxx"
00024 #include "MEDMEM_define.hxx"
00025 #include "MEDMEM_MedMeshDriver.hxx"
00026 #include "MEDMEM_Mesh.hxx"
00027 #include "MEDMEM_Family.hxx"
00028 
00029 #include <sstream>
00030 #include <cmath>
00031 
00032 // use this define to enable lines, execution of which leads to Segmentation Fault
00033 //#define ENABLE_FAULTS
00034 
00035 // use this define to enable CPPUNIT asserts and fails, showing bugs
00036 //#define ENABLE_FORCED_FAILURES
00037 
00038 using namespace std;
00039 using namespace MEDMEM;
00040 
00041 // #7: MEDMEM_Connectivity.hxx  }  MEDMEMTest_Connectivity.cxx
00042 
00116 static void checkConnectivity(CONNECTIVITY * myConnectivity,
00117                               int MeshDimension, int NumberOfNodes,
00118                               MED_EN::medEntityMesh Entity,
00119                               int NumberOfTypes)
00120 {
00121   int entityDim = myConnectivity->getEntityDimension();
00122   CPPUNIT_ASSERT_EQUAL(MeshDimension, entityDim);
00123 
00124   int nodesNb = myConnectivity->getNumberOf(MED_EN::MED_NODE, MED_EN::MED_NONE);
00125   CPPUNIT_ASSERT_EQUAL(NumberOfNodes, nodesNb); //?
00126 
00127   // MED_EN::MED_CELL
00128   MED_EN::medEntityMesh entity = myConnectivity->getEntity();
00129   CPPUNIT_ASSERT_EQUAL(Entity, entity);
00130 
00131   int typesNb = myConnectivity->getNumberOfTypes(Entity);
00132   CPPUNIT_ASSERT_EQUAL(NumberOfTypes, typesNb);
00133 
00134   const MED_EN::medGeometryElement * Types = myConnectivity->getGeometricTypes(Entity);
00135   CPPUNIT_ASSERT( Types );
00136 
00137   // TODO: implement some more checks
00138   int NumberOfElements;
00139   const int * connectivity;
00140   const int * connectivity_index;
00141   myConnectivity->calculateConnectivity(MED_EN::MED_DESCENDING, Entity);
00142   try {
00143     NumberOfElements = myConnectivity->getNumberOf(Entity, MED_EN::MED_ALL_ELEMENTS);
00144     connectivity = myConnectivity->getConnectivity(MED_EN::MED_DESCENDING, Entity,
00145                                                    MED_EN::MED_ALL_ELEMENTS);
00146     connectivity_index = myConnectivity->getConnectivityIndex(MED_EN::MED_DESCENDING, Entity);
00147   }
00148   catch (MEDEXCEPTION m) {
00149     CPPUNIT_FAIL(m.what());
00150   }
00151 
00152   // Get constituent entity type and quantity
00153   int NumberOfConstituents  = 0;
00154   string constituent;
00155   MED_EN::medEntityMesh constituentEntity;
00156 
00157   if (MeshDimension == 3) {
00158     constituent = "Face";
00159     constituentEntity = MED_EN::MED_FACE;
00160   }
00161 
00162   if (MeshDimension == 2) {
00163     constituent = "Edge";
00164     constituentEntity = MED_EN::MED_EDGE;
00165   }
00166 
00167   if (MeshDimension == 1) {
00168     MESSAGE_MED("ERROR : MeshDimension = 1 !");
00169     MESSAGE_MED("We could not see Reverse Descending Connectivity.");
00170     return;
00171   }
00172 
00173   myConnectivity->getReverseConnectivity(MED_EN::MED_DESCENDING, Entity);
00174   myConnectivity->getReverseConnectivityIndex(MED_EN::MED_DESCENDING, Entity);
00175 
00176   NumberOfConstituents = myConnectivity->getNumberOf(constituentEntity, MED_EN::MED_ALL_ELEMENTS);
00177   myConnectivity->getConnectivity(MED_EN::MED_NODAL, constituentEntity, MED_EN::MED_ALL_ELEMENTS);
00178   myConnectivity->getConnectivityIndex(MED_EN::MED_NODAL, constituentEntity);
00179 }
00180 
00182 // TEST 2: test_copie_connectivity.cxx //
00184 static void checkCopyConnectivity()
00185 {
00186   string filename = getResourceFile("pointe.med");
00187   string meshname = "maa1";
00188 
00189   //Construction d'un maillage
00190   MESH * myMesh = new MESH;
00191   myMesh->setName(meshname);
00192   MED_MESH_RDONLY_DRIVER myMeshDriver (filename, myMesh);
00193   myMeshDriver.setMeshName(meshname);
00194   myMeshDriver.open();
00195   myMeshDriver.read(); //A partir d'ici la connectivité est construite
00196   myMeshDriver.close();
00197 
00198   int aMeshDimension = myMesh->getMeshDimension();
00199   int aNumberOfNodes = myMesh->getNumberOfNodes();
00200 
00201   const CONNECTIVITY * myConnectivity0 = myMesh->getConnectivityptr();
00202   CONNECTIVITY * myConnectivity1 = const_cast<CONNECTIVITY *>(myConnectivity0);
00203 
00204   // DATA:
00205   MED_EN::medEntityMesh anEntity0 = myConnectivity0->getEntity();
00206 
00207   int nbOfTypes = myConnectivity0->getNumberOfTypes(anEntity0);
00208 
00209   checkConnectivity(myConnectivity1, aMeshDimension, aNumberOfNodes, anEntity0, nbOfTypes);
00210 
00211   ostringstream ostr1;
00212   ostr1 << *myConnectivity1;
00213   CPPUNIT_ASSERT(ostr1.str() != "");
00214 
00215   // COPY
00216   CONNECTIVITY * myConnectivity2 = new CONNECTIVITY(* myConnectivity0);
00217 
00218   // Compare
00219   CPPUNIT_ASSERT(myConnectivity2->deepCompare(*myConnectivity0));
00220 
00221   // Compare after deleting the initial connectivity
00222   myMesh->removeReference();
00223   myMesh = NULL;
00224   myConnectivity0 = NULL;
00225 
00226   MED_EN::medEntityMesh anEntity2 = myConnectivity2->getEntity();
00227   CPPUNIT_ASSERT_EQUAL(anEntity0, anEntity2);
00228 
00229   checkConnectivity(myConnectivity2, aMeshDimension, aNumberOfNodes, anEntity0, nbOfTypes);
00230 
00231   ostringstream ostr2;
00232   ostr2 << *myConnectivity2;
00233   CPPUNIT_ASSERT(ostr1.str() == ostr2.str());
00234 
00235   // ONE MORE COPY
00236   CONNECTIVITY * myConnectivity3 = new CONNECTIVITY(* myConnectivity2);
00237   delete myConnectivity2;
00238 
00239   MED_EN::medEntityMesh anEntity3 = myConnectivity3->getEntity();
00240   CPPUNIT_ASSERT_EQUAL(anEntity0, anEntity3);
00241 
00242   checkConnectivity(myConnectivity3, aMeshDimension, aNumberOfNodes, anEntity0, nbOfTypes);
00243 
00244   ostringstream ostr3;
00245   ostr3 << *myConnectivity3;
00246   CPPUNIT_ASSERT_EQUAL(ostr1.str(), ostr3.str());
00247 
00248   delete myConnectivity3;
00249 }
00250 
00251 static void createOrCheck (CONNECTIVITY * theC, string msg, bool create = false)
00252 {
00253   // Preconditions: Entity and NumberOfTypes
00254   CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, MED_EN::MED_CELL, theC->getEntity());
00255   CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 3, theC->getNumberOfTypes(MED_EN::MED_CELL));
00256 
00257   // EntityDimension
00258   if (create)
00259     // It would be good to set EntityDimension automatically for EDGEs and FACEs,
00260     // and warn about not set EntityDimension for CELLs
00261     // (or calculate it from given geometric types)
00262     theC->setEntityDimension(3);
00263   else
00264     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 3, theC->getEntityDimension());
00265 
00266   // NumberOfNodes
00267   int nbNodes = 20;
00268 
00269   if (create) {
00270     theC->setNumberOfNodes(nbNodes);
00271   }
00272   else {
00273     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nbNodes, theC->getNumberOf
00274                                  (MED_EN::MED_NODE, MED_EN::MED_NONE));
00275   }
00276 
00277   // GeometricTypes
00278   MED_EN::medGeometryElement aCellTypes[3] = {MED_EN::MED_PYRA5, MED_EN::MED_HEXA8,MED_EN::MED_POLYHEDRA};
00279 
00280   // this variable is needed in check mode (!create)
00281   // because of bug with getGlobalNumberingIndex() method (see below)
00282   bool triaFirst = true;
00283 
00284   if (create) {
00285     theC->setGeometricTypes(aCellTypes, MED_EN::MED_CELL);
00286     CPPUNIT_ASSERT_THROW(theC->setGeometricTypes(aCellTypes, MED_EN::MED_NODE), MEDEXCEPTION);
00287     CPPUNIT_ASSERT_THROW(theC->setGeometricTypes(aCellTypes, MED_EN::MED_FACE), MEDEXCEPTION);
00288     CPPUNIT_ASSERT_THROW(theC->setGeometricTypes(aCellTypes, MED_EN::MED_EDGE), MEDEXCEPTION);
00289   }
00290   else {
00291     // CELLS: theC
00292     const MED_EN::medGeometryElement * aCellTypesBack = theC->getGeometricTypes(MED_EN::MED_CELL);
00293     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, aCellTypes[0], aCellTypesBack[0]);
00294     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, aCellTypes[1], aCellTypesBack[1]);
00295 
00296     const CELLMODEL * aCellModels = theC->getCellsTypes(MED_EN::MED_CELL);
00297     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, aCellTypes[0], aCellModels[0].getType());
00298     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, aCellTypes[1], aCellModels[1].getType());
00299 
00300     string * aCellTypesNames = theC->getCellTypeNames(MED_EN::MED_CELL);
00301     CPPUNIT_ASSERT_MESSAGE(msg, aCellTypesNames[0] == "MED_PYRA5");
00302     CPPUNIT_ASSERT_MESSAGE(msg, aCellTypesNames[1] == "MED_HEXA8");
00303     delete [] aCellTypesNames;
00304 
00305     // FACES: theC->_constituent
00306     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 3, theC->getNumberOfTypes(MED_EN::MED_FACE));
00307     const MED_EN::medGeometryElement * aFaceTypesBack = theC->getGeometricTypes(MED_EN::MED_FACE);
00308     triaFirst = (aFaceTypesBack[0] == MED_EN::MED_TRIA3 && aFaceTypesBack[1] == MED_EN::MED_QUAD4);
00309     CPPUNIT_ASSERT_MESSAGE(msg, triaFirst || (aFaceTypesBack[1] == MED_EN::MED_TRIA3 &&
00310                                               aFaceTypesBack[0] == MED_EN::MED_QUAD4));
00311 
00312     const CELLMODEL * aFaceModels = theC->getCellsTypes(MED_EN::MED_FACE);
00313     bool case1 = (aFaceModels[0].getType() == MED_EN::MED_TRIA3 &&
00314                   aFaceModels[1].getType() == MED_EN::MED_QUAD4);
00315     bool case2 = (aFaceModels[1].getType() == MED_EN::MED_TRIA3 &&
00316                   aFaceModels[0].getType() == MED_EN::MED_QUAD4);
00317     CPPUNIT_ASSERT_MESSAGE(msg, case1 || case2);
00318 
00319     string * aFaceTypesNames = theC->getCellTypeNames(MED_EN::MED_FACE);
00320     CPPUNIT_ASSERT_MESSAGE(msg,
00321                            (aFaceTypesNames[0] == "MED_TRIA3" && aFaceTypesNames[1] == "MED_QUAD4") ||
00322                            (aFaceTypesNames[1] == "MED_TRIA3" && aFaceTypesNames[0] == "MED_QUAD4"));
00323     delete [] aFaceTypesNames;
00324     // EDGES: theC->_constituent->_constituent
00325     //CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1, theC->getNumberOfTypes(MED_EN::MED_EDGE));
00326     //const MED_EN::medGeometryElement * anEdgeTypesBack = theC->getGeometricTypes(MED_EN::MED_EDGE);
00327     //const CELLMODEL * anEdgeModels = theC->getCellsTypes(MED_EN::MED_EDGE);
00328 
00329     // invalid cases
00330     CPPUNIT_ASSERT(!theC->getGeometricTypes(MED_EN::MED_NODE));
00331     CPPUNIT_ASSERT(!theC->getGeometricTypes(MED_EN::MED_ALL_ENTITIES));
00332     CPPUNIT_ASSERT_THROW(theC->getCellsTypes(MED_EN::MED_NODE), MEDEXCEPTION);
00333     CPPUNIT_ASSERT_THROW(theC->getCellTypeNames(MED_EN::MED_ALL_ENTITIES), MEDEXCEPTION);
00334   }
00335 
00336   // 2 POLYHEDRA
00337   const int nbPolyhedron = 2;
00338   //const int nbPolyFaces = 14; // 13 unique
00339   const int nbPolyNodes = 52 + 14 - 2; // = 64
00340 
00341   int aPolyhedronIndex[nbPolyhedron + 1] = {1,33, 65};
00342 
00343   int aPolyhedronNodalConnectivity[nbPolyNodes] = {
00344     11,15,19,20,17,13,-1, 11,13,14,-1,  14,13,17,18,-1,  18,17,20,-1,  11,14,15,-1,  15,14,18,19,-1,  19,18,20,
00345     11,13,17,20,19,15,-1, 11,12,13,-1,  13,12,16,17,-1,  17,16,20,-1,  11,15,12,-1,  12,15,19,16,-1,  16,19,20};
00346 
00347   //          .11
00348   //
00349   //     13.---------.14
00350   //      /|\       /|
00351   //     / |  \    / |
00352   //    /  |    \ /  |
00353   // 12.---------.15 |
00354   //   |   |     |   |
00355   //   | 17.-----|---.18
00356   //   |  / \    |  /
00357   //   | /    \  | /
00358   //   |/       \|/
00359   // 16.---------.19
00360   //
00361   //          .20
00362 
00363   // Nodal Connectivity
00364   int countCells[4] = {1, 3, 4, 6}; // 2 PYRA5 and 1 HEXA8 and 2 POLYHEDRA
00365   int nodesCells_PYRA5[10] = {2,3,4,5,1, 6,7,8,9,10};
00366   int nodesCells_HEXA8[8] = {2,3,4,5, 6,7,8,9};
00367   const int nbClassicCells = countCells[2]-countCells[0];
00368 
00369   //          .1
00370   //
00371   //      3.---------.4
00372   //      /|        /|
00373   //     / |       / |
00374   //    /  |      /  |
00375   //  2.---------.5  |
00376   //   |   |     |   |
00377   //   |  7.-----|---.8
00378   //   |  /      |  /
00379   //   | /       | /
00380   //   |/        |/
00381   //  6.---------.9
00382   //
00383   //          .10
00384 
00385   // cells index will be: {1, 6, 11, 19}
00386 
00387   if (create) {
00388     theC->setCount(countCells, MED_EN::MED_CELL);
00389     theC->setNodal(nodesCells_PYRA5, MED_EN::MED_CELL, MED_EN::MED_PYRA5);
00390     theC->setNodal(nodesCells_HEXA8, MED_EN::MED_CELL, MED_EN::MED_HEXA8);
00391     theC->setNodal(aPolyhedronNodalConnectivity, MED_CELL, MED_POLYHEDRA, aPolyhedronIndex);
00392 
00393     // Invalid cases
00394     CPPUNIT_ASSERT_THROW(theC->setCount(countCells, MED_EN::MED_NODE), MEDEXCEPTION);
00395     CPPUNIT_ASSERT_THROW(theC->setCount(countCells, MED_EN::MED_EDGE), MEDEXCEPTION);
00396     CPPUNIT_ASSERT_THROW(theC->setCount(countCells, MED_EN::MED_FACE), MEDEXCEPTION);
00397 
00398     CPPUNIT_ASSERT_THROW(theC->setNodal(nodesCells_PYRA5, MED_EN::MED_FACE, MED_EN::MED_PYRA5), MEDEXCEPTION);
00399   }
00400   else {
00401     // CELLS(3D): theC
00402     CPPUNIT_ASSERT_MESSAGE(msg, theC->existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_CELL));
00403     CPPUNIT_ASSERT_MESSAGE(msg, theC->existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL));
00404 
00405     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 2, theC->getNumberOf(MED_EN::MED_CELL, MED_EN::MED_PYRA5));
00406     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1, theC->getNumberOf(MED_EN::MED_CELL, MED_EN::MED_HEXA8));
00407     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 2, theC->getNumberOf(MED_EN::MED_CELL, MED_EN::MED_POLYHEDRA));
00408     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 5, theC->getNumberOf(MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS));
00409 
00410     // sorted by geometric type (order is given by the typedef enum medGeometryElement)
00411     const int * countCellsBack = theC->getGlobalNumberingIndex(MED_EN::MED_CELL);
00412     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, countCells[0], countCellsBack[0]); // 1: always
00413     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, countCells[1], countCellsBack[1]); // 3: +2 PYRA5
00414     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, countCells[2], countCellsBack[2]); // 4: +1 HEXA8
00415     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, countCells[3], countCellsBack[3]); // 6: +2 POLYHEDRA
00416 
00417     // nodal connectivity length
00418     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 18+64, theC->getConnectivityLength(MED_EN::MED_NODAL, MED_EN::MED_CELL,
00419                                                                       MED_EN::MED_ALL_ELEMENTS));
00420 
00421     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 10, theC->getConnectivityLength(MED_EN::MED_NODAL, MED_EN::MED_CELL,
00422                                                                       MED_EN::MED_PYRA5));
00423 
00424     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg,  8, theC->getConnectivityLength(MED_EN::MED_NODAL, MED_EN::MED_CELL,
00425                                                                       MED_EN::MED_HEXA8));
00426     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg,  64, theC->getConnectivityLength(MED_EN::MED_NODAL, MED_EN::MED_CELL,
00427                                                                        MED_EN::MED_POLYHEDRA));
00428 
00429     // nodal connectivity index
00430     const int * connAllIndex = theC->getConnectivityIndex(MED_EN::MED_NODAL, MED_EN::MED_CELL);
00431     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg,  1, connAllIndex[0]);
00432     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg,  6, connAllIndex[1]); // +5 nodes of PYRA5
00433     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 11, connAllIndex[2]); // +5 nodes of PYRA5
00434     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 19, connAllIndex[3]); // +8 nodes of HEXA8
00435     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 19+32, connAllIndex[4]); // +32 nodes of POLYHEDRA
00436     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 19+64, connAllIndex[5]); // +32 nodes of POLYHEDRA
00437 
00438     // nodal connectivity
00439     const int * connAll = theC->getConnectivity(MED_EN::MED_NODAL, MED_EN::MED_CELL,
00440                                                 MED_EN::MED_ALL_ELEMENTS);
00441     const int * connPYRA5 = theC->getConnectivity(MED_EN::MED_NODAL, MED_EN::MED_CELL,
00442                                                   MED_EN::MED_PYRA5);
00443     const int * connHEXA8 = theC->getConnectivity(MED_EN::MED_NODAL, MED_EN::MED_CELL,
00444                                                   MED_EN::MED_HEXA8);
00445     const int * connPOLYH = theC->getConnectivity(MED_EN::MED_NODAL, MED_EN::MED_CELL,
00446                                                   MED_EN::MED_POLYHEDRA);
00447     for (int i = 0; i < 10; i++) {
00448       CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nodesCells_PYRA5[i], connPYRA5[i]);
00449       CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nodesCells_PYRA5[i], connAll[i]);
00450     }
00451     for (int i = 0; i < 8; i++) {
00452       CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nodesCells_HEXA8[i], connHEXA8[i]);
00453       CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nodesCells_HEXA8[i], connAll[10 + i]);
00454     }
00455     for (int i = 0; i < 64; i++) {
00456       CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, aPolyhedronNodalConnectivity[i], connPOLYH[i]);
00457       CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, aPolyhedronNodalConnectivity[i], connAll[18 + i]);
00458     }
00459 
00460     // descending connectivity length
00461     // 10 faces in 2 pyra
00462     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 10, theC->getConnectivityLength
00463                                  (MED_EN::MED_DESCENDING, MED_EN::MED_CELL, MED_EN::MED_PYRA5));
00464     // 6 faces in 1 hexa
00465     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg,  6, theC->getConnectivityLength
00466                                  (MED_EN::MED_DESCENDING, MED_EN::MED_CELL, MED_EN::MED_HEXA8));
00467     // 14 faces in 2 polyhedrons
00468     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg,  14, theC->getConnectivityLength
00469                                  (MED_EN::MED_DESCENDING, MED_EN::MED_CELL, MED_EN::MED_POLYHEDRA));
00470     // 10 + 6 + 14 faces
00471     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 30, theC->getConnectivityLength
00472                                  (MED_EN::MED_DESCENDING, MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS));
00473 
00474     // descending connectivity index
00475     const int * descAllIndex = theC->getConnectivityIndex(MED_EN::MED_DESCENDING, MED_EN::MED_CELL);
00476 
00477     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg,  1, descAllIndex[0]);
00478     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg,  6, descAllIndex[1]); // +5 faces of PYRA5
00479     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 11, descAllIndex[2]); // +5 faces of PYRA5
00480     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 17, descAllIndex[3]); // +6 faces of HEXA8
00481     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 24, descAllIndex[4]); // +7 faces of POLYHEDRA
00482     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 31, descAllIndex[5]); // +7 faces of POLYHEDRA
00483 
00484     // descending connectivity
00485     {
00486       const int * descAll = theC->getConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL,
00487                                                   MED_EN::MED_ALL_ELEMENTS);
00488       const int * descPYRA5 = theC->getConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL,
00489                                                     MED_EN::MED_PYRA5);
00490       const int * descHEXA8 = theC->getConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL,
00491                                                     MED_EN::MED_HEXA8);
00492       const int * descPOLYH = theC->getConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL,
00493                                                     MED_EN::MED_POLYHEDRA);
00494       for (int i = 0; i < 10; i++) {
00495         CPPUNIT_ASSERT_MESSAGE(msg, 0 < labs(descPYRA5[i]) && labs(descPYRA5[i]) < 16);
00496         CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, descAll[i], descPYRA5[i]);
00497       }
00498       for (int i = 0; i < 6; i++) {
00499         CPPUNIT_ASSERT_MESSAGE(msg, 0 < labs(descHEXA8[i]) && labs(descHEXA8[i]) < 16);
00500         CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, descAll[10 + i], descHEXA8[i]);
00501       }
00502       for (int i = 0; i < 14; i++) {
00503         CPPUNIT_ASSERT_MESSAGE(msg, 0 < labs(descPOLYH[i]) && labs(descPOLYH[i]) < 31);
00504         CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, descAll[16 + i], descPOLYH[i]);
00505       }
00506     }
00507 
00508     // FACES: theC->_constituent
00509     CPPUNIT_ASSERT_MESSAGE(msg, theC->existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_FACE));
00510     //CPPUNIT_ASSERT_MESSAGE(msg, theC->existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_FACE));
00511 
00512     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg,  8, theC->getNumberOf(MED_EN::MED_FACE, MED_EN::MED_TRIA3));
00513     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg,  6, theC->getNumberOf(MED_EN::MED_FACE, MED_EN::MED_QUAD4));
00514     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg,  13, theC->getNumberOf(MED_EN::MED_FACE, MED_EN::MED_POLYGON));
00515     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 27, theC->getNumberOf(MED_EN::MED_FACE, MED_EN::MED_ALL_ELEMENTS));
00516 
00517     // sorted by geometric type
00518     const int * countFacesBack = theC->getGlobalNumberingIndex(MED_EN::MED_FACE);
00519     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg,  1, countFacesBack[0]); // always
00520 
00521     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg,  9, countFacesBack[1]); // +8 TRIA3
00522 
00523     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 15, countFacesBack[2]); // 1+8+6
00524 
00525     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 28, countFacesBack[3]); // 1+8+6+13
00526 
00527     // nodal connectivity length // 8*3 + 6*4 + 46
00528     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 48+46, theC->getConnectivityLength(MED_EN::MED_NODAL, MED_EN::MED_FACE,
00529                                                                                   MED_EN::MED_ALL_ELEMENTS));
00530 
00531     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 24, theC->getConnectivityLength(MED_EN::MED_NODAL, MED_EN::MED_FACE,
00532                                                                       MED_EN::MED_TRIA3));
00533     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 24, theC->getConnectivityLength(MED_EN::MED_NODAL, MED_EN::MED_FACE,
00534                                                                       MED_EN::MED_QUAD4));
00535     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 46, theC->getConnectivityLength(MED_EN::MED_NODAL, MED_EN::MED_FACE,
00536                                                                                MED_EN::MED_POLYGON));
00537 
00538     // nodal connectivity index
00539     const int * connFaceAllIndex = theC->getConnectivityIndex(MED_EN::MED_NODAL, MED_EN::MED_FACE);
00540     {
00541       CPPUNIT_ASSERT(triaFirst);
00542       CPPUNIT_ASSERT_EQUAL_MESSAGE(msg,  1, connFaceAllIndex[0]);
00543       int typeChangeIndex = 8;
00544       int nbNodes1 = 3;
00545       int nbNodes2 = 4;
00546       CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 25, connFaceAllIndex[typeChangeIndex]); // + 3*8 or 4*6
00547       for (int i = 1; i < 14; i++) {
00548         if (i < typeChangeIndex)
00549           CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1 + i*nbNodes1, connFaceAllIndex[i]);
00550         else
00551           CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 25 + (i-typeChangeIndex)*nbNodes2, connFaceAllIndex[i]);
00552       }
00553       // + 3*8 nodes of TRIA3 + 4*6 nodes of QUAD4
00554       CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 49, connFaceAllIndex[14]);
00555     }
00556 
00557     // nodal connectivity
00558     const int * connFaceAll = theC->getConnectivity(MED_EN::MED_NODAL, MED_EN::MED_FACE,
00559                                                     MED_EN::MED_ALL_ELEMENTS);
00560     const int * connTRIA3 = theC->getConnectivity(MED_EN::MED_NODAL, MED_EN::MED_FACE,
00561                                                   MED_EN::MED_TRIA3);
00562     const int * connQUAD4 = theC->getConnectivity(MED_EN::MED_NODAL, MED_EN::MED_FACE,
00563                                                   MED_EN::MED_QUAD4);
00564     for (int i = 0; i < 24; i++) {
00565       CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, connFaceAll[   i], connTRIA3[i]);
00566       CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, connFaceAll[24+i], connQUAD4[i]);
00567     }
00568 
00569     // EDGES: theC->_constituent->_constituent
00570     //CPPUNIT_ASSERT_MESSAGE(msg, theC->existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_EDGE));
00571 
00572     // Invalid cases
00573     CPPUNIT_ASSERT_MESSAGE(msg, !theC->existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_NODE));
00574     CPPUNIT_ASSERT_MESSAGE(msg, !theC->existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_EDGE));
00575     CPPUNIT_ASSERT_MESSAGE(msg, !theC->existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_NODE));
00576     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 0, theC->getNumberOf(MED_EN::MED_CELL, MED_EN::MED_TETRA4));
00577     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 0, theC->getNumberOf(MED_EN::MED_CELL,
00578                                                                    MED_EN::MED_TETRA4));
00579     CPPUNIT_ASSERT_THROW(theC->getConnectivityLength(MED_EN::MED_NODAL, MED_EN::MED_CELL,
00580                                                      MED_EN::MED_TRIA3), MEDEXCEPTION);
00581     CPPUNIT_ASSERT_THROW(theC->getConnectivityLength(MED_EN::MED_DESCENDING, MED_EN::MED_CELL,
00582                                                      MED_EN::MED_NONE), MEDEXCEPTION);
00583     CPPUNIT_ASSERT_THROW(theC->getConnectivityLength(MED_EN::MED_NODAL, MED_EN::MED_CELL,
00584                                                      MED_EN::MED_POLYGON), MEDEXCEPTION);
00585   }
00586 
00587 
00588   if (create) {
00589   }
00590   else {
00591     // CELLS(3D): theC
00592     {
00593       CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 3, theC->getNumberOfTypes(MED_EN::MED_CELL));
00594 
00595       {
00596         const MED_EN::medGeometryElement * aCellTypesBack = theC->getGeometricTypes(MED_EN::MED_CELL);
00597         CPPUNIT_ASSERT_MESSAGE(msg, ((aCellTypesBack[0] == MED_EN::MED_PYRA5 &&
00598                                       aCellTypesBack[1] == MED_EN::MED_HEXA8) ||
00599                                      (aCellTypesBack[0] == MED_EN::MED_HEXA8 &&
00600                                       aCellTypesBack[1] == MED_EN::MED_PYRA5)));
00601         CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, MED_EN::MED_POLYHEDRA, aCellTypesBack[2]);
00602       }
00603 
00604       CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 2, theC->getNumberOf(MED_EN::MED_CELL,
00605                                                              MED_EN::MED_POLYHEDRA));
00606       //checking that 0 is returned if polygons are asked as cells instead of faces
00607       CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 0, theC->getNumberOf(MED_EN::MED_CELL,
00608                                                              MED_EN::MED_POLYGON));
00609 
00610 
00611       int nbCellAll = 5; // 2 (PYRA5) + 1 (HEXA8) + 2 (POLYHEDRA)
00612 
00613       CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nbCellAll, theC->getNumberOf
00614                                    (MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS));
00615 
00616 
00617       // first PYRA5 {1,2,3,4,5}
00618       {
00619         int len;
00620         const int * c1 = theC->getConnectivityOfAnElement
00621           (MED_EN::MED_NODAL, MED_EN::MED_CELL, /*Number*/1, len);
00622         CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 5, len);
00623         for (int i = 0; i < len; i++) {
00624           if (c1[i] < 1 || 5 < c1[i]) CPPUNIT_FAIL(msg);
00625         }
00626       }
00627 
00628       // first POLYHEDRA
00629       {
00630         int len;
00631         const int* con = 0;
00632         CPPUNIT_ASSERT_NO_THROW(con=theC->getConnectivityOfAnElement
00633                                 (MED_EN::MED_NODAL, MED_EN::MED_CELL, /*Number*/4, len));
00634         CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 32, len);
00635         for (int i = 0; i < len; i++)
00636           CPPUNIT_ASSERT_EQUAL_MESSAGE(msg,aPolyhedronNodalConnectivity[i],con[i]);
00637       }
00638 
00639       // cells descending connectivity
00640       for (int i = 1; i <= nbCellAll; i++) {
00641         int len;
00642         const int * ci = theC->getConnectivityOfAnElement
00643           (MED_EN::MED_DESCENDING, MED_EN::MED_CELL, /*Number*/i, len);
00644 
00645         MED_EN::medGeometryElement aCurElemType = theC->getElementType(MED_EN::MED_CELL, i);
00646 
00647         if (i <= 3) { // nb.standard cells = 3
00648           // sign of connectivity array value means element direction
00649           for (int j = 0; j < len; j++) {
00650             CPPUNIT_ASSERT_MESSAGE(msg, 0 < labs(ci[j]) && labs(ci[j]) <= 14); // nb.standard faces = 14
00651           }
00652         }
00653         else {
00654           CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, MED_EN::MED_POLYHEDRA, aCurElemType);
00655           for (int j = 0; j < len; j++) {
00656             CPPUNIT_ASSERT_MESSAGE(msg, 14 < labs(ci[j]) && labs(ci[j]) <= 27); // nb.polygons = 13
00657           }
00658         }
00659 
00660         switch (aCurElemType) {
00661         case MED_EN::MED_PYRA5:     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 5, len); break;
00662         case MED_EN::MED_HEXA8:     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 6, len); break;
00663         case MED_EN::MED_POLYHEDRA: CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 7, len); break;
00664         default:
00665           CPPUNIT_FAIL(msg); // wrong element type
00666         }
00667       }
00668 
00669       // Polyhedron-specific methods
00670       {
00671         CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 2, theC->getNumberOf(MED_EN::MED_CELL,
00672                                                                MED_EN::MED_POLYHEDRA));
00673 
00674         // getNodesOfPolyhedron
00675         int lenPolyh1nodes, lenPolyh2nodes; // nb of unique nodes
00676         int * polyh1nodes = theC->getNodesOfPolyhedron(/*polyhedronId*/3+1, lenPolyh1nodes);
00677         int * polyh2nodes = theC->getNodesOfPolyhedron(/*polyhedronId*/3+2, lenPolyh2nodes);
00678         CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 8, lenPolyh1nodes);
00679         CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 8, lenPolyh2nodes);
00680 
00681         set<int> polyh1nodesCheck;
00682         set<int> polyh2nodesCheck;
00683 
00684         polyh1nodesCheck.insert(11);
00685         polyh1nodesCheck.insert(13);
00686         polyh1nodesCheck.insert(14);
00687         polyh1nodesCheck.insert(15);
00688         polyh1nodesCheck.insert(17);
00689         polyh1nodesCheck.insert(18);
00690         polyh1nodesCheck.insert(19);
00691         polyh1nodesCheck.insert(20);
00692 
00693         polyh2nodesCheck.insert(11);
00694         polyh2nodesCheck.insert(12);
00695         polyh2nodesCheck.insert(13);
00696         polyh2nodesCheck.insert(15);
00697         polyh2nodesCheck.insert(16);
00698         polyh2nodesCheck.insert(17);
00699         polyh2nodesCheck.insert(19);
00700         polyh2nodesCheck.insert(20);
00701 
00702         for (int i = 0; i < 8; i++) {
00703           CPPUNIT_ASSERT_MESSAGE(msg, polyh1nodesCheck.count(polyh1nodes[i]));
00704           CPPUNIT_ASSERT_MESSAGE(msg, polyh2nodesCheck.count(polyh2nodes[i]));
00705         }
00706         delete [] polyh1nodes;
00707         delete [] polyh2nodes;
00708 
00709         // getNodesPerFaceOfPolyhedron
00710         int nbFaces1, nbFaces2;
00711         int *nbNodes1, *nbNodes2; // len = nb.faces (7)
00712         int ** polyh1nodesPerFace =
00713           theC->getNodesPerFaceOfPolyhedron(/*polyhedronId*/3+1, nbFaces1, nbNodes1);
00714         int ** polyh2nodesPerFace =
00715           theC->getNodesPerFaceOfPolyhedron(/*polyhedronId*/3+2, nbFaces2, nbNodes2);
00716 
00717         CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 7, nbFaces1);
00718         CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 7, nbFaces2);
00719 
00720         int nbNodesCheck [7] = {6,3,4,3,3,4,3};
00721         int startNode1 = aPolyhedronIndex[0] - 1;
00722         int startNode2 = aPolyhedronIndex[1] - 1;
00723         for (int i = 0; i < 7; i++) {
00724           CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nbNodesCheck[i], nbNodes1[i]);
00725           CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nbNodesCheck[i], nbNodes2[i]);
00726 
00727           for (int j = 0; j < nbNodesCheck[i]; j++) {
00728             CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, aPolyhedronNodalConnectivity[startNode1],
00729                                          polyh1nodesPerFace[i][j]);
00730             CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, aPolyhedronNodalConnectivity[startNode2],
00731                                          polyh2nodesPerFace[i][j]);
00732             startNode1++;
00733             startNode2++;
00734           }
00735           startNode1++;
00736           startNode2++;
00737         }
00738 
00739         delete [] nbNodes1;
00740         delete [] nbNodes2;
00741         delete [] polyh1nodesPerFace;
00742         delete [] polyh2nodesPerFace;
00743 
00744         // invalid polyhedron Id
00745 
00746         int lenPolyh3nodes;
00747         int nbFaces3;
00748         int *nbNodes3;
00749       
00750         CPPUNIT_ASSERT_THROW(theC->getNodesOfPolyhedron(1, lenPolyh3nodes), MEDEXCEPTION);
00751         CPPUNIT_ASSERT_THROW(theC->getNodesOfPolyhedron(3+3, lenPolyh3nodes), MEDEXCEPTION);
00752         CPPUNIT_ASSERT_THROW(theC->getNodesPerFaceOfPolyhedron
00753                              (/*polyhedronId*/1, nbFaces3, nbNodes3), MEDEXCEPTION);
00754         CPPUNIT_ASSERT_THROW(theC->getNodesPerFaceOfPolyhedron
00755                              (/*polyhedronId*/3+3, nbFaces3, nbNodes3), MEDEXCEPTION);
00756 
00757 
00758         // Descending
00759 
00760         // PolyhedronIndex: array of size (NumberOfPolyhedron + 1)
00761         const int* polyhDesceIndex = theC->getConnectivityIndex(MED_EN::MED_DESCENDING,MED_EN::MED_CELL);
00762         CPPUNIT_ASSERT_EQUAL_MESSAGE(msg,  polyhDesceIndex[nbClassicCells+0]+7, polyhDesceIndex[nbClassicCells+1]); // +7 faces
00763         CPPUNIT_ASSERT_EQUAL_MESSAGE(msg,  polyhDesceIndex[nbClassicCells+1]+7, polyhDesceIndex[nbClassicCells+2]); // +7 faces
00764 
00765         // Polyhedron Descending Connectivity: array of size (NumberOfPolyhedronFaces)
00766         const int* polyhDesceConn = theC->getConnectivity(MED_EN::MED_DESCENDING,MED_EN::MED_CELL,MED_EN::MED_POLYHEDRA);
00767         // 15,16,17,18,19,20,21, -15,22,23,24,25,26,27
00768         for (int i = 0; i < 14; i++) {
00769           // nb. poly faces = 13, because one face is common for two polyhedra
00770           // nb. standard faces < poly-face id <= 27 (27 = 14 + 13)
00771           CPPUNIT_ASSERT_MESSAGE(msg, 14 < labs(polyhDesceConn[i]) && labs(polyhDesceConn[i]) <= 27);
00772         }
00773       } // Polyhedron-specific methods
00774 
00775       // Polygon-specific methods
00776       {
00777         // Invalid cases: no polygons for MED_CELL in theC
00778         CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 0, theC->getNumberOf(MED_EN::MED_CELL,MED_EN::MED_POLYGON));
00779         CPPUNIT_ASSERT_THROW(theC->getConnectivity(MED_EN::MED_DESCENDING,
00780                                                    MED_EN::MED_CELL,MED_EN::MED_POLYGON), MEDEXCEPTION);
00781       }
00782     } // CELLS: theC
00783 
00784     // FACES: theC->_constituent
00785     {
00786       CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 3, theC->getNumberOfTypes(MED_EN::MED_FACE));
00787 
00788       const MED_EN::medGeometryElement * aFaceTypesBack = theC->getGeometricTypes(MED_EN::MED_FACE);
00789       CPPUNIT_ASSERT_MESSAGE(msg, ((aFaceTypesBack[0] == MED_EN::MED_TRIA3 &&
00790                                     aFaceTypesBack[1] == MED_EN::MED_QUAD4) ||
00791                                    (aFaceTypesBack[0] == MED_EN::MED_QUAD4 &&
00792                                     aFaceTypesBack[1] == MED_EN::MED_TRIA3)));
00793       CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, MED_EN::MED_POLYGON, aFaceTypesBack[2]);
00794 
00795       CPPUNIT_ASSERT_EQUAL_MESSAGE(msg,  0, theC->getNumberOf
00796                                    (MED_EN::MED_FACE, MED_EN::MED_POLYHEDRA));
00797 
00798       CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 13, theC->getNumberOf
00799                                    (MED_EN::MED_FACE, MED_EN::MED_POLYGON));
00800 
00801       int nbFaAll = 27; // 6 (QUAD4) + 8 (TRIA3) + 13 (POLYGON)
00802 
00803       CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nbFaAll, theC->getNumberOf
00804                                    (MED_EN::MED_FACE, MED_EN::MED_ALL_ELEMENTS));
00805 
00806 
00807       bool isHexagon = false;
00808       for (int i = 1; i <= nbFaAll; i++) {
00809         int len;
00810         const int * ci = theC->getConnectivityOfAnElement(MED_EN::MED_NODAL,
00811                                                                   MED_EN::MED_FACE, /*Number*/i, len);
00812         MED_EN::medGeometryElement aCurElemType = theC->getElementType(MED_EN::MED_FACE, i);
00813 
00814         if (len == 6) {
00815           CPPUNIT_ASSERT_MESSAGE(msg, !isHexagon); // because only one hexagon must exist
00816 
00817           // check nodes {11,15,19,20,17,13}
00818           int nij;
00819           for (int j = 0; j < len; j++) {
00820             nij = ci[j];
00821             CPPUNIT_ASSERT_MESSAGE(msg, nij==11 || nij==15 || nij==19 || nij==20 || nij==17 || nij==13);
00822           }
00823 
00824           isHexagon = true;
00825         }
00826 
00827         switch (aCurElemType) {
00828         case MED_EN::MED_TRIA3:   CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 3, len); break;
00829         case MED_EN::MED_QUAD4:   CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 4, len); break;
00830         case MED_EN::MED_POLYGON: CPPUNIT_ASSERT_MESSAGE(msg, len == 3 || len == 4 || len == 6); break;
00831         default:
00832           CPPUNIT_FAIL(msg); // wrong element type
00833         }
00834       }
00835       CPPUNIT_ASSERT_MESSAGE(msg, isHexagon); // hexagon must exist
00836 
00837       // Polygon-specific methods
00838       {
00839         CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 13, theC->getNumberOf(MED_EN::MED_FACE,MED_EN::MED_POLYGON));
00840 
00841         const int * pgIndx = theC->getConnectivityIndex(MED_EN::MED_NODAL, MED_EN::MED_FACE) + 8+6;
00842         CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 46, pgIndx[13]-pgIndx[0]);
00843 
00844         const int * pgConn = theC->getConnectivity(MED_EN::MED_NODAL, MED_EN::MED_FACE, MED_EN::MED_ALL_ELEMENTS);
00845 
00846         // face #  1: 11 15 19 20 17 13
00847         // face #  2: 11 13 14
00848         // face #  3: 14 13 17 18
00849         // face #  4: 18 17 20
00850         // face #  5: 11 14 15
00851         // face #  6: 15 14 18 19
00852         // face #  7: 19 18 20
00853         // face #  8: 11 12 13
00854         // face #  9: 13 12 16 17
00855         // face # 10: 17 16 20
00856         // face # 11: 11 15 12
00857         // face # 12: 12 15 19 16
00858         // face # 13: 16 19 20
00859 
00860         for (int i = 0; i < 13; i++) {
00861           int startNode = pgIndx[i];
00862           int finishNode = pgIndx[i+1];
00863           // check nodes uniqueness inside one polygon
00864           set<int> curNodes;
00865           for (int j = startNode; j < finishNode; j++) {
00866             CPPUNIT_ASSERT_MESSAGE(msg, (curNodes.insert(pgConn[j - 1])).second);
00867           }
00868         }
00869       }
00870     } // FACES: theC->_constituent
00871 
00872     // EDGES: theC->_constituent->_constituent
00873     //CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 2, theC->getNumberOfTypes(MED_EN::MED_EDGE));
00874   }
00875 
00876   if (create) {
00877     // force _constituent computation
00878     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 3, theC->getNumberOfTypes(MED_EN::MED_FACE));
00879 
00880 
00881     //N-2 Connectivity not supported in MEDMEM
00882     //CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1, theC->getNumberOfTypes(MED_EN::MED_EDGE));
00883 
00884   }
00885   else {
00886     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, MED_EN::MED_POLYHEDRA, theC->getPolyTypeRelativeTo());
00887 
00888     // The following methods are not recursive, i.e. they return types
00889     // of this connectivity, but do not return types of _constituent.
00890     // And these methods DO work with poly-types.
00891 
00892     // getType
00893     const CELLMODEL & aPYRA5_type = theC->getType(MED_EN::MED_PYRA5);
00894     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, MED_EN::MED_PYRA5, aPYRA5_type.getType());
00895     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 5, aPYRA5_type.getNumberOfVertexes());
00896 
00897     const CELLMODEL & aHEXA8_type = theC->getType(MED_EN::MED_HEXA8);
00898     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 8, aHEXA8_type.getNumberOfNodes());
00899     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 3, aHEXA8_type.getDimension());
00900     // nb. of sub-faces (nb. of constituents with dimension = 3 - 1)
00901     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 6, aHEXA8_type.getNumberOfConstituents(1));
00902 
00903     const CELLMODEL & aPOLYH_type = theC->getType(MED_EN::MED_POLYHEDRA);
00904     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 0, aPOLYH_type.getNumberOfNodes());
00905     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 3, aPOLYH_type.getDimension());
00906 
00907     CPPUNIT_ASSERT_THROW(theC->getType(MED_EN::MED_TRIA3), MEDEXCEPTION);
00908     CPPUNIT_ASSERT_THROW(theC->getType(MED_EN::MED_POLYGON), MEDEXCEPTION);
00909     CPPUNIT_ASSERT_THROW(theC->getType(MED_EN::MED_NONE), MEDEXCEPTION);
00910     CPPUNIT_ASSERT_THROW(theC->getType(MED_EN::MED_ALL_ELEMENTS), MEDEXCEPTION);
00911 
00912     // getNumberOfNodesInType
00913     int nbNodesInPYRA5 = theC->getNumberOfNodesInType(MED_EN::MED_PYRA5);
00914     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 5, nbNodesInPYRA5);
00915 
00916     CPPUNIT_ASSERT_THROW(theC->getNumberOfNodesInType(MED_EN::MED_TRIA3), MEDEXCEPTION);
00917     CPPUNIT_ASSERT_THROW(theC->getNumberOfNodesInType(MED_EN::MED_POLYGON), MEDEXCEPTION);
00918     CPPUNIT_ASSERT_THROW(theC->getNumberOfNodesInType(MED_EN::MED_NONE), MEDEXCEPTION);
00919 
00920     // getNumberOfSubCellInType
00921     int nbFacesInHEXA8 = theC->getNumberOfSubCellInType(MED_EN::MED_HEXA8);
00922     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 6, nbFacesInHEXA8);
00923 
00924     int nbFacesInPOLYH = theC->getNumberOfSubCellInType(MED_EN::MED_POLYHEDRA);
00925     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 0, nbFacesInPOLYH);
00926 
00927     CPPUNIT_ASSERT_THROW(theC->getNumberOfSubCellInType(MED_EN::MED_QUAD4), MEDEXCEPTION);
00928     CPPUNIT_ASSERT_THROW(theC->getNumberOfSubCellInType(MED_EN::MED_ALL_ELEMENTS), MEDEXCEPTION);
00929 
00930     // getValueIndex
00931     const int* nodalIndex = theC->getValueIndex(MED_EN::MED_NODAL);
00932     const int* desceIndex = theC->getValueIndex(MED_EN::MED_DESCENDING);
00933 
00934     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg,  1, nodalIndex[0]);
00935     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg,  6, nodalIndex[1]); // +5 nodes of PYRA5
00936     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 11, nodalIndex[2]); // +5 nodes of PYRA5
00937     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 19, nodalIndex[3]); // +8 nodes of HEXA8
00938 
00939     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg,  1, desceIndex[0]);
00940     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg,  6, desceIndex[1]); // +5 faces of PYRA5
00941     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 11, desceIndex[2]); // +5 faces of PYRA5
00942     CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 17, desceIndex[3]); // +6 faces of HEXA8
00943 
00944     // getValue
00945     const int* nodalValue = theC->getValue(MED_EN::MED_NODAL, MED_EN::MED_ALL_ELEMENTS);
00946     const int* nodalPYRA5 = theC->getValue(MED_EN::MED_NODAL, MED_EN::MED_PYRA5);
00947     const int* nodalHEXA8 = theC->getValue(MED_EN::MED_NODAL, MED_EN::MED_HEXA8);
00948 
00949     for (int i = 0; i < 10; i++) {
00950       CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nodesCells_PYRA5[i], nodalPYRA5[i]);
00951       CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nodesCells_PYRA5[i], nodalValue[i]);
00952     }
00953     for (int i = 0; i < 8; i++) {
00954       CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nodesCells_HEXA8[i], nodalHEXA8[i]);
00955       CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nodesCells_HEXA8[i], nodalValue[10 + i]);
00956     }
00957 
00958     const int* desceValue = theC->getValue(MED_EN::MED_DESCENDING, MED_EN::MED_ALL_ELEMENTS);
00959     const int* descePYRA5 = theC->getValue(MED_EN::MED_DESCENDING, MED_EN::MED_PYRA5);
00960     const int* desceHEXA8 = theC->getValue(MED_EN::MED_DESCENDING, MED_EN::MED_HEXA8);
00961 
00962     for (int i = 0; i < 10; i++) {
00963       CPPUNIT_ASSERT_MESSAGE(msg, 0 < labs(descePYRA5[i]) && labs(descePYRA5[i]) < 16);
00964 
00965       CPPUNIT_ASSERT_MESSAGE(msg, 0 < labs(desceValue[i]) && labs(desceValue[i]) < 16);
00966     }
00967     for (int i = 0; i < 6; i++) {
00968       CPPUNIT_ASSERT_MESSAGE(msg, 0 < labs(desceHEXA8[i]) && labs(desceHEXA8[i]) < 16);
00969       CPPUNIT_ASSERT_MESSAGE(msg, 0 < labs(desceValue[10 + i]) && labs(desceValue[10 + i]) < 16);
00970     }
00971 
00972     CPPUNIT_ASSERT_THROW(theC->getValue(MED_EN::MED_NODAL, MED_EN::MED_QUAD4), MEDEXCEPTION);
00973     CPPUNIT_ASSERT_THROW(theC->getValue(MED_EN::MED_NODAL, MED_EN::MED_POLYGON), MEDEXCEPTION);
00974     CPPUNIT_ASSERT_THROW(theC->getValue(MED_EN::MED_DESCENDING, MED_EN::MED_NONE), MEDEXCEPTION);
00975   }
00976 }
00977 
00978 void MEDMEMTest::testConnectivity()
00979 {
00981   // TEST 1: test_MEDMEM_PolyConnectivity.cxx //
00983   CONNECTIVITY myNodalConnectivity(1); // one type
00984   myNodalConnectivity.setEntityDimension(3);
00985 
00986   MED_EN::medGeometryElement types[] = { MED_EN::MED_POLYHEDRA };
00987 
00988   //POLYHEDRON
00989   const int NumberOfPolyhedron = 2;
00990   int PolyhedronIndex[NumberOfPolyhedron+1] = {1,47,91};
00991 
00992   //Nodal
00993   const int NumberOfFaces = 19;
00994   int PolyhedronNodalConnectivity[] ={1, 2, 3, 4, 5, 6, -1,// Polyhedron 1
00995                                       1, 7, 8, 2,       -1,
00996                                       2, 8, 9, 3,       -1,
00997                                       4, 3, 9, 10,      -1,
00998                                       5, 4, 10, 11,     -1,
00999                                       6, 5, 11, 12,     -1,
01000                                       1, 6, 12, 7,      -1,
01001                                       7, 12, 8,         -1,
01002                                       10, 9, 8, 12, 11,     
01003 
01004                                       13, 14, 15, 3, 2, -1,// Polyhedron 2
01005                                       13, 2, 8, 16,     -1,
01006                                       14, 13, 16, 17,   -1,
01007                                       15, 14, 17,       -1,
01008                                       15, 17, 18,       -1,
01009                                       15, 18, 9,        -1,
01010                                       3, 15, 9,         -1,
01011                                       2, 3, 9, 8,       -1,
01012                                       8, 9, 17, 16,     -1,
01013                                       9, 18, 17 };
01014 
01015   const int count[] = { 1, 1+NumberOfPolyhedron };
01016   myNodalConnectivity.setGeometricTypes( &types[0], MED_EN::MED_CELL );
01017   myNodalConnectivity.setCount( count, MED_EN::MED_CELL );
01018   myNodalConnectivity.setNodal( PolyhedronNodalConnectivity, MED_EN::MED_CELL,
01019                                 MED_EN::MED_POLYHEDRA, PolyhedronIndex);
01020 
01021   myNodalConnectivity.setNumberOfNodes(777);
01022   CPPUNIT_ASSERT_EQUAL(777, myNodalConnectivity.getNumberOf
01023                        (MED_EN::MED_NODE, MED_EN::MED_NONE));
01024 //   // Throws because _constituent is not calculated
01025 //   CPPUNIT_ASSERT_THROW(myNodalConnectivity.getNumberOf
01026 //                        (MED_EN::MED_FACE, MED_EN::MED_NONE), MEDEXCEPTION);
01027 
01028 //   // Returns zero, because EntityDimension is not set
01029 //   CPPUNIT_ASSERT_EQUAL(0, myNodalConnectivity.getNumberOf
01030 //                        (MED_EN::MED_CELL, MED_EN::MED_POLYGON));
01031 //   CPPUNIT_ASSERT_EQUAL(0, myNodalConnectivity.getNumberOf
01032 //                        (MED_EN::MED_CELL, MED_EN::MED_POLYHEDRA));
01033 
01034   // Throws because entity must differ from MED_NONE and MED_ALL_ELEMENTS
01035   CPPUNIT_ASSERT_THROW(myNodalConnectivity.getNumberOfNodesInType(MED_EN::MED_NONE), MEDEXCEPTION);
01036   CPPUNIT_ASSERT_THROW(myNodalConnectivity.getNumberOfNodesInType(MED_EN::MED_ALL_ELEMENTS), MEDEXCEPTION);
01037 
01038   // Throws because types are not defined
01039   CPPUNIT_ASSERT_THROW(myNodalConnectivity.getNumberOfNodesInType(MED_EN::MED_ALL_ELEMENTS), MEDEXCEPTION);
01040   CPPUNIT_ASSERT_THROW(myNodalConnectivity.getNumberOfNodesInType(MED_EN::MED_POLYGON), MEDEXCEPTION);
01041 
01042   // does not throw any more exception because 
01043   // it is now possible to work on meshes with only polyhedric elements
01044   CPPUNIT_ASSERT_NO_THROW(myNodalConnectivity.calculateConnectivity (MED_EN::MED_DESCENDING,
01045                                                                      MED_EN::MED_CELL));
01046 
01047   // existPolygonsConnectivity
01048   CPPUNIT_ASSERT(myNodalConnectivity.existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_FACE));
01049   CPPUNIT_ASSERT(!myNodalConnectivity.existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_FACE));
01050 
01051   // existPolyhedronConnectivity
01052   CPPUNIT_ASSERT(myNodalConnectivity.existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_CELL));
01053   CPPUNIT_ASSERT(myNodalConnectivity.existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL));
01054 
01055 
01056   // setEntityDimension
01057   // it contains cells of different dimension (2D and 3D)
01058   // We set here EntityDimension for good work of below methods
01059 
01060   CPPUNIT_ASSERT_EQUAL(MED_EN::MED_POLYHEDRA, myNodalConnectivity.getPolyTypeRelativeTo());
01061 
01062   // Poly types
01063   CPPUNIT_ASSERT_EQUAL(1, myNodalConnectivity.getNumberOfTypes(MED_EN::MED_CELL));
01064 
01065   CPPUNIT_ASSERT_EQUAL(1, myNodalConnectivity.getNumberOfTypes(MED_EN::MED_FACE));
01066 
01067   // getNumberOf
01068   CPPUNIT_ASSERT_EQUAL(NumberOfPolyhedron, myNodalConnectivity.getNumberOf
01069                        (MED_EN::MED_CELL, MED_EN::MED_POLYHEDRA));
01070   CPPUNIT_ASSERT_EQUAL(0, myNodalConnectivity.getNumberOf
01071                        (MED_EN::MED_CELL, MED_EN::MED_POLYGON));
01072   //Minus 1 because 2,3,8,9 is a given twice in connectivity
01073   CPPUNIT_ASSERT_EQUAL(NumberOfFaces-1, myNodalConnectivity.getNumberOf (MED_EN::MED_FACE,
01074                                                                          MED_EN::MED_POLYGON));
01075 
01076   // getConnectivityOfAnElement
01077   {
01078     //first polyhedron
01079     const int *ph1, *ph2;
01080     int len_ph1, len_ph2;
01081     CPPUNIT_ASSERT_NO_THROW(ph1 = myNodalConnectivity.getConnectivityOfAnElement
01082                             (MED_EN::MED_NODAL, MED_EN::MED_CELL, /*Number*/1, len_ph1));
01083     CPPUNIT_ASSERT_EQUAL( PolyhedronIndex[1]-PolyhedronIndex[0], len_ph1 );
01084     CPPUNIT_ASSERT( vector<int>( PolyhedronNodalConnectivity, PolyhedronNodalConnectivity + len_ph1) ==
01085                     vector<int>( ph1, ph1+len_ph1 ));
01086 
01087     //second polyhedron
01088     CPPUNIT_ASSERT_NO_THROW(ph2 = myNodalConnectivity.getConnectivityOfAnElement
01089                             (MED_EN::MED_NODAL, MED_EN::MED_CELL, /*Number*/2, len_ph2));
01090     CPPUNIT_ASSERT_EQUAL( PolyhedronIndex[2]-PolyhedronIndex[1], len_ph2 );
01091     CPPUNIT_ASSERT( vector<int>( PolyhedronNodalConnectivity + len_ph1, PolyhedronNodalConnectivity + len_ph1 + len_ph2) ==
01092                     vector<int>( ph2, ph2+len_ph2 ));
01093 
01094     // MED_DESCENDING
01095     //first polyhedron
01096     CPPUNIT_ASSERT_NO_THROW(ph1 = myNodalConnectivity.getConnectivityOfAnElement
01097                             (MED_EN::MED_DESCENDING, MED_EN::MED_CELL, /*Number*/1, len_ph1));
01098     CPPUNIT_ASSERT_EQUAL( 9, len_ph1 );
01099     const int faces1[] = { 1,2,3,4,5,6,7,8,9 };
01100     CPPUNIT_ASSERT( vector<int>( faces1, faces1 + len_ph1 ) ==
01101                     vector<int>( ph1, ph1+len_ph1 ));
01102 
01103     //second polyhedron
01104     CPPUNIT_ASSERT_NO_THROW(ph2 = myNodalConnectivity.getConnectivityOfAnElement
01105                             (MED_EN::MED_DESCENDING, MED_EN::MED_CELL, /*Number*/2, len_ph2));
01106     CPPUNIT_ASSERT_EQUAL( 10, len_ph2 );
01107     const int faces2[] = { 10,11,12,13,14,15,16,-3,17,18 };
01108     CPPUNIT_ASSERT( vector<int>( faces2, faces2 + len_ph2 ) ==
01109                     vector<int>( ph2, ph2+len_ph2 ));
01110   }
01111 
01112   // We reset here EntityDimension to check getConnectivityOfAnElement()
01113   //myNodalConnectivity.setEntityDimension(2);
01114 
01115   {
01116     const int *ph1, *ph2;
01117     int len_ph1, len_ph2;
01118     // first polygon
01119     CPPUNIT_ASSERT_NO_THROW(ph1 = myNodalConnectivity.getConnectivityOfAnElement
01120                             (MED_EN::MED_NODAL, MED_EN::MED_FACE, /*Number*/1, len_ph1));
01121     CPPUNIT_ASSERT_EQUAL( 6, len_ph1 );
01122     CPPUNIT_ASSERT( vector<int>( PolyhedronNodalConnectivity, PolyhedronNodalConnectivity + len_ph1) ==
01123                     vector<int>( ph1, ph1+len_ph1 ));
01124 
01125     // second polygon
01126     CPPUNIT_ASSERT_NO_THROW(ph2 = myNodalConnectivity.getConnectivityOfAnElement
01127                             (MED_EN::MED_NODAL, MED_EN::MED_FACE, /*Number*/2, len_ph2));
01128     CPPUNIT_ASSERT_EQUAL( 4, len_ph2 );
01129     CPPUNIT_ASSERT( vector<int>( PolyhedronNodalConnectivity + len_ph1 + 1, PolyhedronNodalConnectivity + len_ph1 + 1 + len_ph2) ==
01130                     vector<int>( ph2, ph2+len_ph2 ));
01131 
01132     // MED_DESCENDING
01133     // first polygon
01134     CPPUNIT_ASSERT_NO_THROW(ph1 = myNodalConnectivity.getConnectivityOfAnElement
01135                             (MED_EN::MED_DESCENDING, MED_EN::MED_FACE, /*Number*/1, len_ph1));
01136     CPPUNIT_ASSERT_EQUAL( 6, len_ph1 );
01137     const int edges1[6] = { 1,2,3,4,5,6 };
01138     CPPUNIT_ASSERT( vector<int>( edges1, edges1 + len_ph1 ) ==
01139                     vector<int>( ph1, ph1+len_ph1 ));
01140 
01141     // second polygon
01142     CPPUNIT_ASSERT_NO_THROW(ph2 = myNodalConnectivity.getConnectivityOfAnElement
01143                             (MED_EN::MED_DESCENDING, MED_EN::MED_FACE, /*Number*/2, len_ph2));
01144     CPPUNIT_ASSERT_EQUAL( 4, len_ph2 );
01145     const int edges2[4] = { 7,8,9,-1 };
01146     CPPUNIT_ASSERT( vector<int>( edges2, edges2 + len_ph2 ) ==
01147                     vector<int>( ph2, ph2+len_ph2 ));
01148   }
01149 
01151   // TEST 2 //
01153   checkCopyConnectivity();
01154 
01156   // TEST 3 //
01158 
01159   CONNECTIVITY *aCells1=new CONNECTIVITY(/*numberOfTypes*/2, /*Entity*/MED_EN::MED_CELL);
01160   CPPUNIT_ASSERT_EQUAL(MED_EN::MED_CELL, aCells1->getEntity());
01161   CPPUNIT_ASSERT_EQUAL(2, aCells1->getNumberOfTypes(MED_EN::MED_CELL));
01162   CPPUNIT_ASSERT_EQUAL(2, aCells1->getNumberOfTypes(MED_EN::MED_CELL));
01163 
01164   CONNECTIVITY aCells2 (/*numberOfTypes*/3/*, Entity=MED_EN::MED_CELL*/);
01165   CPPUNIT_ASSERT_EQUAL(MED_EN::MED_CELL, aCells2.getEntity());
01166   CPPUNIT_ASSERT_EQUAL(3, aCells2.getNumberOfTypes(MED_EN::MED_CELL));
01167   CPPUNIT_ASSERT_EQUAL(3, aCells2.getNumberOfTypes(MED_EN::MED_CELL));
01168 
01169   CONNECTIVITY * anEdges1 = new CONNECTIVITY(/*numberOfTypes*/1, /*Entity*/MED_EN::MED_EDGE);
01170   CPPUNIT_ASSERT_EQUAL(MED_EN::MED_EDGE, anEdges1->getEntity());
01171   CPPUNIT_ASSERT_EQUAL(1, anEdges1->getNumberOfTypes(MED_EN::MED_EDGE));
01172   CPPUNIT_ASSERT_EQUAL(1, anEdges1->getNumberOfTypes(MED_EN::MED_EDGE));
01173 
01174   CONNECTIVITY * anEdges2 = new CONNECTIVITY(/*numberOfTypes*/2, /*Entity*/MED_EN::MED_EDGE);
01175   CPPUNIT_ASSERT_EQUAL(MED_EN::MED_EDGE, anEdges2->getEntity());
01176   CPPUNIT_ASSERT_EQUAL(2, anEdges2->getNumberOfTypes(MED_EN::MED_EDGE));
01177   CPPUNIT_ASSERT_EQUAL(2, anEdges2->getNumberOfTypes(MED_EN::MED_EDGE));
01178 
01179   CONNECTIVITY * aFaces1 = new CONNECTIVITY(/*numberOfTypes*/2, /*Entity*/MED_EN::MED_FACE);
01180   CPPUNIT_ASSERT_EQUAL(MED_EN::MED_FACE, aFaces1->getEntity());
01181   CPPUNIT_ASSERT_EQUAL(2, aFaces1->getNumberOfTypes(MED_EN::MED_FACE));
01182   CPPUNIT_ASSERT_EQUAL(2, aFaces1->getNumberOfTypes(MED_EN::MED_FACE));
01183 
01184   // No need to delete anEdges1 and aFaces1, because they are owned by aCells1
01185   // (anEdges1 is owned by aFaces1 to be precise)
01186   // No need to delete anEdges2, because they are owned by aCells2
01187 
01188   // EntityDimension
01189   // It would be good to set EntityDimension automatically for EDGEs and FACEs,
01190   // and warn about not set EntityDimension for CELLs
01191   // (or calculate it by given geometric types)
01192   aCells1->setEntityDimension(3);
01193   aCells2.setEntityDimension(2); // for 2D mesh
01194   anEdges1->setEntityDimension(1);
01195   anEdges2->setEntityDimension(1);
01196   aFaces1->setEntityDimension(2);
01197 
01198   CPPUNIT_ASSERT_EQUAL(3, aCells1->getEntityDimension());
01199   CPPUNIT_ASSERT_EQUAL(2, aCells2.getEntityDimension());
01200   CPPUNIT_ASSERT_EQUAL(1, anEdges1->getEntityDimension());
01201   CPPUNIT_ASSERT_EQUAL(1, anEdges2->getEntityDimension());
01202   CPPUNIT_ASSERT_EQUAL(2, aFaces1->getEntityDimension());
01203 
01204   // getPolyTypeRelativeTo
01205   CPPUNIT_ASSERT_EQUAL(MED_EN::MED_POLYHEDRA, aCells1->getPolyTypeRelativeTo());
01206   CPPUNIT_ASSERT_EQUAL(MED_EN::MED_POLYGON  , aCells2.getPolyTypeRelativeTo());
01207   CPPUNIT_ASSERT_EQUAL(MED_EN::MED_POLYGON  , aFaces1->getPolyTypeRelativeTo());
01208   // because there is no poly types for edges (2D entities)
01209   CPPUNIT_ASSERT_THROW(anEdges1->getPolyTypeRelativeTo(), MEDEXCEPTION);
01210 
01211   // setConstituent
01212   CPPUNIT_ASSERT_THROW(aCells1->setConstituent(&aCells2), MEDEXCEPTION);
01213   CPPUNIT_ASSERT_THROW(aCells1->setConstituent(anEdges1), MEDEXCEPTION);
01214 
01215   aCells1->setConstituent(aFaces1);
01216   aCells1->setConstituent(anEdges1);
01217 
01218   CPPUNIT_ASSERT_EQUAL(1, aCells1->getNumberOfTypes(MED_EN::MED_EDGE));
01219   CPPUNIT_ASSERT_EQUAL(2, aCells1->getNumberOfTypes(MED_EN::MED_FACE));
01220 
01221   aCells2.setConstituent(anEdges2);
01222   CPPUNIT_ASSERT_EQUAL(2, aCells2.getNumberOfTypes(MED_EN::MED_EDGE));
01223 
01224   // setGeometricTypes
01225   MED_EN::medGeometryElement aCellTypes2D[3] = {MED_EN::MED_TRIA3, MED_EN::MED_QUAD4, MED_EN::MED_TRIA6};
01226   MED_EN::medGeometryElement aCellTypes3D[2] = {MED_EN::MED_PYRA5, MED_EN::MED_HEXA8};
01227   MED_EN::medGeometryElement anEdgeTypes1[1] = {MED_EN::MED_SEG2};
01228   MED_EN::medGeometryElement anEdgeTypes2[2] = {MED_EN::MED_SEG2, MED_EN::MED_SEG3};
01229   MED_EN::medGeometryElement aFaceTypes2[2] =
01230     {MED_EN::MED_TRIA3, MED_EN::MED_QUAD4};
01231 
01232   aCells1->setGeometricTypes(aCellTypes3D, MED_EN::MED_CELL);
01233   aCells1->setGeometricTypes(aFaceTypes2, MED_EN::MED_FACE);
01234   aCells1->setGeometricTypes(anEdgeTypes1, MED_EN::MED_EDGE);
01235   CPPUNIT_ASSERT_THROW(aCells1->setGeometricTypes(anEdgeTypes1, MED_EN::MED_NODE), MEDEXCEPTION);
01236 
01237   aCells2.setGeometricTypes(aCellTypes2D, MED_EN::MED_CELL);
01238   anEdges2->setGeometricTypes(anEdgeTypes2, MED_EN::MED_EDGE);
01239   CPPUNIT_ASSERT_THROW(aCells2.setGeometricTypes(aFaceTypes2, MED_EN::MED_FACE), MEDEXCEPTION);
01240 
01241   // setCount
01242   int countCell2D[4] = {1, 5, 6, 10};
01243   int countCell3D[3] = {1, 3, 4};
01244   int countEdges1[2] = {1, 21};
01245   int countEdges2[3] = {1, 13, 21};
01246   int countFaces1[3] = {1, 9, 15};
01247 
01248   aCells1->setCount(countCell3D, MED_EN::MED_CELL);
01249   aCells1->setCount(countEdges1, MED_EN::MED_EDGE);
01250   aCells1->setCount(countFaces1, MED_EN::MED_FACE);
01251   CPPUNIT_ASSERT_THROW(aCells1->setCount(countEdges1, MED_EN::MED_NODE), MEDEXCEPTION);
01252 
01253   aCells2.setCount(countCell2D, MED_EN::MED_CELL);
01254   aCells2.setCount(countEdges2, MED_EN::MED_EDGE);
01255   CPPUNIT_ASSERT_THROW(aCells2.setCount(countFaces1, MED_EN::MED_FACE), MEDEXCEPTION);
01256 
01257   // setNodal
01258 
01259   // aCells2
01260   int nodesCell2D_TRIA3[12] = {3,8,7, 10,7,13, 18,13,14, 11,14,8};
01261   int nodesCell2D_QUAD4[4] = {7,8,14,13};
01262   int nodesCell2D_TRIA6[24] = {1,2,3,7,10,6, 3,4,5,9,11,8, 11,15,20,19,18,14, 18,17,16,12,10,13};
01263 
01264   aCells2.setNodal(nodesCell2D_TRIA3, MED_EN::MED_CELL, MED_EN::MED_TRIA3);
01265   aCells2.setNodal(nodesCell2D_QUAD4, MED_EN::MED_CELL, MED_EN::MED_QUAD4);
01266   aCells2.setNodal(nodesCell2D_TRIA6, MED_EN::MED_CELL, MED_EN::MED_TRIA6);
01267 
01268   int nodesEdges2_SEG2[24] = {3,8, 8,11, 11,14, 14,18, 18,13, 13,10, 10,7,
01269                               7,3, 7,8, 8,14, 14,13, 13,7};
01270   int nodesEdges2_SEG3[24] = {1,2,3, 3,4,5, 5,9,11, 11,15,20,
01271                               20,19,18, 18,17,16, 16,12,10, 10,6,1};
01272 
01273   aCells2.setNodal(nodesEdges2_SEG2, MED_EN::MED_EDGE, MED_EN::MED_SEG2);
01274   aCells2.setNodal(nodesEdges2_SEG3, MED_EN::MED_EDGE, MED_EN::MED_SEG3);
01275 
01276   // aCells1
01277   int nodesCell3D_PYRA5[10] = {5,4,3,2,1, 6,7,8,9,10};
01278   int nodesCell3D_HEXA8[8] = {2,3,4,5, 6,7,8,9};
01279 
01280   aCells1->setNodal(nodesCell3D_PYRA5, MED_EN::MED_CELL, MED_EN::MED_PYRA5);
01281   aCells1->setNodal(nodesCell3D_HEXA8, MED_EN::MED_CELL, MED_EN::MED_HEXA8);
01282 
01283   int nodesFaces1_TRIA3[24] = {1,2,3, 1,3,4, 1,4,5, 1,5,2,
01284                                10,6,7, 10,7,8,  10,8,9, 10,9,6};
01285   int nodesFaces1_QUAD4[24] = {2,3,4,5, 6,7,8,9, 2,3,7,6, 5,4,8,9, 2,5,9,6, 3,4,8,7};
01286   // int nodesFaces1_TRIA6[6] = {11,12,13,14,15,16};
01287   // int nodesFaces1_QUAD8[8] = {15,14,13,17,18,19,20,21};
01288 
01289   aCells1->setNodal(nodesFaces1_TRIA3, MED_EN::MED_FACE, MED_EN::MED_TRIA3);
01290   aCells1->setNodal(nodesFaces1_QUAD4, MED_EN::MED_FACE, MED_EN::MED_QUAD4);
01291   //aCells1->setNodal(nodesFaces1_TRIA6, MED_EN::MED_FACE, MED_EN::MED_TRIA6);
01292   //aCells1->setNodal(nodesFaces1_QUAD8, MED_EN::MED_FACE, MED_EN::MED_QUAD8);
01293 
01294   int nodesEdges1_SEG2[40] = {1,2, 1,3, 1,4, 1,5, 10,6, 10,7, 10,8, 10,9,
01295                               2,3, 3,4, 4,5, 5,2,  6,7,  7,8,  8,9,  9,6,
01296                               2,6, 3,7, 4,8, 5,9};
01297 
01298   aCells1->setNodal(nodesEdges1_SEG2, MED_EN::MED_EDGE, MED_EN::MED_SEG2);
01299 
01300   // setNumberOfNodes
01301   aCells2.setNumberOfNodes(20);
01302   anEdges2->setNumberOfNodes(20);
01303 
01304   aCells1->setNumberOfNodes(10);
01305   anEdges1->setNumberOfNodes(10);
01306   aFaces1->setNumberOfNodes(10);
01307 
01308   // existConnectivity
01309   CPPUNIT_ASSERT(aCells1->existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_CELL));
01310   CPPUNIT_ASSERT(aCells1->existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_FACE));
01311   CPPUNIT_ASSERT(aCells1->existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_EDGE));
01312   CPPUNIT_ASSERT(!aCells1->existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_NODE));
01313 
01314   CPPUNIT_ASSERT(!aCells1->existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL));
01315   CPPUNIT_ASSERT(!aCells1->existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_FACE));
01316   CPPUNIT_ASSERT(!aCells1->existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_EDGE));
01317   CPPUNIT_ASSERT(!aCells1->existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_NODE));
01318 
01319   CPPUNIT_ASSERT(aCells2.existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_CELL));
01320   CPPUNIT_ASSERT(!aCells2.existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_FACE));
01321   CPPUNIT_ASSERT(aCells2.existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_EDGE));
01322   CPPUNIT_ASSERT(!aCells2.existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_NODE));
01323 
01324   CPPUNIT_ASSERT(!aCells2.existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL));
01325   CPPUNIT_ASSERT(!aCells2.existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_FACE));
01326   CPPUNIT_ASSERT(!aCells2.existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_EDGE));
01327   CPPUNIT_ASSERT(!aCells2.existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_NODE));
01328 
01329   // getConnectivityOfAnElement
01330   {
01331     int len_e1, len_e2, i;
01332     const int * nc_e1 = aCells1->getConnectivityOfAnElement
01333       (MED_EN::MED_NODAL, MED_EN::MED_CELL, /*Number*/1, len_e1);
01334     CPPUNIT_ASSERT_EQUAL(5, len_e1); // PYRA5 {1,2,3,4,5}
01335     for (i = 0; i < len_e1; i++) {
01336       if (nc_e1[i] < 1 || 5 < nc_e1[i])
01337         CPPUNIT_FAIL("Wrong node in element");
01338     }
01339 
01340     const int * nc_e2 = aCells2.getConnectivityOfAnElement
01341       (MED_EN::MED_NODAL, MED_EN::MED_CELL, /*Number*/2, len_e2);
01342     CPPUNIT_ASSERT_EQUAL(3, len_e2); // TRIA3 {7,10,13}
01343     for (i = 0; i < len_e2; i++) {
01344       if (nc_e2[i] != 7 && nc_e2[i] != 10 && nc_e2[i] != 13)
01345         CPPUNIT_FAIL("Wrong node in element");
01346     }
01347   }
01348 
01349   //  aCells1 (2 types)  |
01350   //     |               |
01351   //  aFaces1 (4 types)  |  aCells2 (3 types)
01352   //     |               |     |
01353   //  anEdges1 (1 type)  |  anEdges2 (2 types)
01354   
01355   MESH* mesh=new MESH; //updateFamily method requires a pointer to the mesh 
01356   mesh->setConnectivityptr(aCells1);
01357   // updateFamily
01358   {
01359     FAMILY *aFamilyOnFaces=new FAMILY;
01360     aFamilyOnFaces->setEntity(MED_EN::MED_FACE);
01361     aFamilyOnFaces->setMeshName("Mesh 1");
01362     aFamilyOnFaces->setMesh(mesh);
01363     mesh->removeReference();
01364     aFamilyOnFaces->setName("Support On Faces 1");
01365     //aFamilyOnFaces->setAll(true);
01366 
01367     int nbTypesFam1 = 2;
01368     MED_EN::medGeometryElement aSCTypes[4] = {MED_EN::MED_TRIA3, MED_EN::MED_QUAD4};
01369     int nbEltsSC[4] = {8,6};
01370     int indexSC[5] = {1,9,15}; // length = nb.types + 1
01371     int valueSC[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14}; // length = total nb. of elements
01372     //int nbTypesFam1 = 1;
01373     //MED_EN::medGeometryElement aSCTypes[1] = {MED_EN::MED_TRIA3};
01374     //int nbEltsSC[1] = {8};
01375     //int indexSC[2] = {1,9}; // length = nb.types + 1
01376     //int valueSC[8] = {1,3,5,7,9,11,13,15}; // length = total nb. of elements
01377 
01378     aFamilyOnFaces->setNumberOfGeometricType(nbTypesFam1);
01379     aFamilyOnFaces->setGeometricType(aSCTypes);
01380     aFamilyOnFaces->setNumberOfElements(nbEltsSC);
01381     aFamilyOnFaces->setNumber(indexSC, valueSC);
01382 
01383     vector<FAMILY*> aFamsOnFaces (1);
01384     aFamsOnFaces[0] = aFamilyOnFaces;
01385 
01386     // Attention!!! By default ENABLE_UPDATE_FAMILY is not defined!!!
01387     // I do not undestand, what this method should do
01388     // and what I must give to it to obtain good result
01389 
01390     CPPUNIT_ASSERT_NO_THROW(aCells1->updateFamily(aFamsOnFaces));
01391     aFamilyOnFaces->removeReference();
01392   }
01393 
01395   // TEST 4 //
01397   CONNECTIVITY * c1 = new CONNECTIVITY(/*numberOfTypes*/3, MED_EN::MED_CELL);
01398   createOrCheck(c1, "Creation", /*create*/true);
01399   createOrCheck(c1, "Check just created", /*create*/false);
01400 
01401   CONNECTIVITY * c2 = new CONNECTIVITY(*c1);
01402   createOrCheck(c2, "Check copy constructor", /*create*/false);
01403 
01404   // invertConnectivityForAFace
01405   int nbFacesC2 = c2->getNumberOf(MED_EN::MED_FACE, MED_EN::MED_ALL_ELEMENTS);
01406   for (int faceId = 1; faceId <= nbFacesC2; faceId++) {
01407 
01408     // this face nodal connectivity before inversion:
01409     int oldLen, newLen;
01410     const int * oldConn = c2->getConnectivityOfAnElement(MED_EN::MED_NODAL,
01411                                                          MED_EN::MED_FACE, faceId, oldLen);
01412 
01413     // descending connectivity before inversion:
01414     int before_NumberOfElements = c2->getNumberOf(MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS);
01415     const int * before_connectivity_shared =
01416       c2->getConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS);
01417     const int * before_connectivity_index =
01418       c2->getConnectivityIndex(MED_EN::MED_DESCENDING, MED_EN::MED_CELL);
01419 
01420     // copy connectivity, because the pointer, returned by getConnectivity,
01421     // will point to the same memory before and after inversion
01422     int lenDC = before_connectivity_index[before_NumberOfElements] - 1;
01423     int * before_connectivity = new int[lenDC];
01424     for (int i = 0; i < lenDC; i++)
01425       before_connectivity[i] = before_connectivity_shared[i];
01426 
01427     // reverse descending connectivity before inversion:
01428     const int * before_ReverseDescendingConnectivity_shared =
01429       c2->getReverseConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL);
01430     const int * before_ReverseDescendingConnectivityIndex =
01431       c2->getReverseConnectivityIndex(MED_EN::MED_DESCENDING, MED_EN::MED_CELL);
01432 
01433     int lenRDC = before_ReverseDescendingConnectivityIndex[nbFacesC2] - 1;
01434     int * before_ReverseDescendingConnectivity = new int[lenRDC];
01435     for (int i = 0; i < lenRDC; i++)
01436       before_ReverseDescendingConnectivity[i] = before_ReverseDescendingConnectivity_shared[i];
01437 
01438     // perform inversion
01439     int * newNodesForFace = new int[oldLen];
01440     if (oldLen == 3) {
01441       newNodesForFace[0] = oldConn[1];
01442       newNodesForFace[1] = oldConn[0];
01443       newNodesForFace[2] = oldConn[2];
01444     } else {
01445       newNodesForFace[0] = oldConn[2];
01446       newNodesForFace[1] = oldConn[1];
01447       newNodesForFace[2] = oldConn[0];
01448       newNodesForFace[3] = oldConn[3];
01449     }
01450     c2->invertConnectivityForAFace(faceId, newNodesForFace);
01451 
01452     // reverse descending connectivity after inversion:
01453     const int * after_ReverseDescendingConnectivity =
01454       c2->getReverseConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL);
01455     const int * after_ReverseDescendingConnectivityIndex =
01456       c2->getReverseConnectivityIndex(MED_EN::MED_DESCENDING, MED_EN::MED_CELL);
01457 
01458     // Faces, which are on bound (have one neighbouring), are not inverted.
01459     bool isOnBound = false;
01460 
01461     for (int i = 0; i < nbFacesC2; i++) {
01462       int plus = after_ReverseDescendingConnectivityIndex[i] - 1;
01463       // always two neighbourings
01464       if ((i + 1) == faceId) {
01465         // no second neighbouring
01466         isOnBound = (before_ReverseDescendingConnectivity[plus + 1] == 0);
01467       }
01468       if ((i + 1) == faceId && !isOnBound) {
01469         CPPUNIT_ASSERT_EQUAL(before_ReverseDescendingConnectivity[plus + 0],
01470                              after_ReverseDescendingConnectivity[plus + 1]);
01471         CPPUNIT_ASSERT_EQUAL(before_ReverseDescendingConnectivity[plus + 1],
01472                              after_ReverseDescendingConnectivity[plus + 0]);
01473       }
01474       else {
01475         CPPUNIT_ASSERT_EQUAL(before_ReverseDescendingConnectivity[plus + 0],
01476                              after_ReverseDescendingConnectivity[plus + 0]);
01477         CPPUNIT_ASSERT_EQUAL(before_ReverseDescendingConnectivity[plus + 1],
01478                              after_ReverseDescendingConnectivity[plus + 1]);
01479       }
01480     }
01481 
01482     // descending connectivity after inversion:
01483     int after_NumberOfElements = c2->getNumberOf(MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS);
01484     const int * after_connectivity =
01485       c2->getConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS);
01486     const int * after_connectivity_index =
01487       c2->getConnectivityIndex(MED_EN::MED_DESCENDING, MED_EN::MED_CELL);
01488 
01489     CPPUNIT_ASSERT_EQUAL(before_NumberOfElements, after_NumberOfElements);
01490 
01491     for (int j = 0; j < before_NumberOfElements; j++) {
01492       for (int k = after_connectivity_index[j]; k < after_connectivity_index[j+1]; k++) {
01493         if (labs(before_connectivity[k-1]) == faceId && !isOnBound) {
01494           CPPUNIT_ASSERT_EQUAL(before_connectivity[k-1], - after_connectivity[k-1]);
01495         }
01496         else {
01497           CPPUNIT_ASSERT_EQUAL(before_connectivity[k-1], after_connectivity[k-1]);
01498         }
01499       }
01500     }
01501 
01502     // this face nodal connectivity after inversion:
01503     if (!isOnBound) {
01504       const int * newConn = c2->getConnectivityOfAnElement(MED_EN::MED_NODAL,
01505                                                            MED_EN::MED_FACE, faceId, newLen);
01506       CPPUNIT_ASSERT_EQUAL(oldLen, newLen);
01507       for (int i = 0; i < newLen && i < 4; i++) {
01508         CPPUNIT_ASSERT_EQUAL(newNodesForFace[i], newConn[i]);
01509       }
01510     }
01511     delete [] newNodesForFace;
01512 
01513     delete [] before_connectivity;
01514     delete [] before_ReverseDescendingConnectivity;
01515 
01516     // ATTENTION: invertConnectivityForAFace() is not tested on polygons!!!
01517   }
01518 
01519 
01520   delete c1;
01521   delete c2;
01522 }