Back to index

salome-med  6.5.0
MEDMEMTest_Coordinate.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/Message.h>
00022 #include <cppunit/TestAssert.h>
00023 
00024 #include "MEDMEM_Array.hxx"
00025 #include "MEDMEM_Coordinate.hxx"
00026 
00027 #include <sstream>
00028 #include <cmath>
00029 
00030 // use this define to enable lines, execution of which leads to Segmentation Fault
00031 //#define ENABLE_FAULTS
00032 
00033 // use this define to enable CPPUNIT asserts and fails, showing bugs
00034 //#define ENABLE_FORCED_FAILURES
00035 
00036 using namespace std;
00037 using namespace MEDMEM;
00038 
00039 // #8: MEDMEM_Coordinate.hxx  }  MEDMEMTest_Coordinate.cxx
00040 
00073 void MEDMEMTest::testCoordinate()
00074 {
00076   // TEST 1: MEDMEM/tests/testUCoordinate.cxx //
00078   {
00079     const double pouieme = 0.009;
00080 
00081     int SpaceDim = 3;
00082     int NbOfNodes = 5;
00083 
00084     string * noms = new string[3];
00085     noms[0] = " X ";
00086     noms[1] = " Y ";
00087     noms[2] = " Z ";
00088 
00089     string  units[3];
00090     units[0] = " m ";
00091     units[1] = " m ";
00092     units[2] = " m ";
00093 
00094     int * numbers = new int[5];
00095     for (int i = 0; i < 5; i++) numbers[i] = 10 + i;
00096 
00097     double coor[15] = {0,0,0,0,0,1,0,1,0,1,0,0,0.5,0.5,0.5};
00098     CPPUNIT_ASSERT(SpaceDim * NbOfNodes == 15);
00099 
00100     double * coor1 = new double [SpaceDim*NbOfNodes];
00101     for (int k = 0; k < SpaceDim*NbOfNodes; k++)
00102       coor1[k] = coor[k];
00103 
00104     MEDARRAY<double>* CoordinateArray =
00105       new MEDARRAY<double>(coor1, SpaceDim, NbOfNodes, MED_EN::MED_FULL_INTERLACE);
00106     COORDINATE mycoo;
00107     CPPUNIT_ASSERT_NO_THROW(mycoo.setCoordinates(CoordinateArray));
00108 
00109     //--------------------------------------------------------------------//
00110     //                        Tests des methodes                          //
00111     //                                                                    //
00112     // - setCoordinatesNames                                              //
00113     // - setCoordinatesUnits                                              //
00114     // - setCoordinatesSystem                                             //
00115     // - setNodesNumbers                                                  //
00116     //                                                                    //
00117     //--------------------------------------------------------------------//
00118 
00119     CPPUNIT_ASSERT_NO_THROW(mycoo.setCoordinatesNames(noms));
00120     CPPUNIT_ASSERT_NO_THROW(mycoo.setCoordinatesUnits(units));
00121     CPPUNIT_ASSERT_NO_THROW(mycoo.setCoordinatesSystem("cartesien"));
00122     CPPUNIT_ASSERT_NO_THROW(mycoo.setNodesNumbers(numbers));
00123 
00124     //--------------------------------------------------------------------//
00125     //                        Tests des methodes                          //
00126     //                                                                    //
00127     // - getCoordinatesNames                                              //
00128     // - getCoordinatesUnits                                              //
00129     // - getCoordinatesUnit                                               //
00130     // - getCoordinatesSystem                                             //
00131     // - getNodesNumbers                                                  //
00132     //                                                                    //
00133     //--------------------------------------------------------------------//
00134     CPPUNIT_ASSERT_NO_THROW(CPPUNIT_ASSERT(mycoo.getCoordinatesSystem() == "cartesien"));
00135 
00136     const string * units2;
00137     try
00138     {
00139       units2 = mycoo.getCoordinatesUnits();
00140       for (int axe = 0; axe < SpaceDim; axe++) {
00141         string verif = mycoo.getCoordinateUnit(axe+1);
00142         CPPUNIT_ASSERT(verif == units2[axe]);
00143       }
00144     }
00145     catch (const std::exception &e)
00146     {
00147       CPPUNIT_FAIL(e.what());
00148     }
00149     catch (...)
00150     {
00151       CPPUNIT_FAIL("Unknown exception");
00152     }
00153 
00154     const string * noms2;
00155     try
00156     {
00157       noms2 = mycoo.getCoordinatesNames();
00158       for (int axe = 0; axe < SpaceDim; axe++) {
00159         string verif = mycoo.getCoordinateName(axe+1);
00160         CPPUNIT_ASSERT(verif == noms2[axe]);
00161       }
00162     }
00163     catch (const std::exception &e)
00164     {
00165       CPPUNIT_FAIL(e.what());
00166     }
00167     catch (...)
00168     {
00169       CPPUNIT_FAIL("Unknown exception");
00170     }
00171 
00172     try
00173     {
00174       const double * coor2 = mycoo.getCoordinates(MED_EN::MED_FULL_INTERLACE);
00175 
00176       for (int axe = 0; axe < SpaceDim; axe++) {
00177         const double * coor3 = mycoo.getCoordinateAxis(axe+1);
00178         for (int num = 0; num < NbOfNodes; num++) {
00179           const double d = mycoo.getCoordinate(num + 1, axe + 1);
00180           CPPUNIT_ASSERT(fabs(d - coor3[num                 ]) < pouieme);
00181           CPPUNIT_ASSERT(fabs(d - coor2[(num * SpaceDim)+axe]) < pouieme);
00182           CPPUNIT_ASSERT(fabs(d - coor [(num * SpaceDim)+axe]) < pouieme);
00183         }
00184       }
00185     }
00186     catch (const std::exception &e)
00187     {
00188       CPPUNIT_FAIL(e.what());
00189     }
00190     catch (...)
00191     {
00192       CPPUNIT_FAIL("Unknown exception");
00193     }
00194 
00195     delete [] noms;
00196     delete [] numbers;
00197     delete [] coor1;
00198 
00199     delete CoordinateArray;
00200   }
00201 
00203   // TEST 2: MEDMEM/test_copie_coordinate.cxx //
00205   {
00206     const int numberofNodes = 5;
00207     const int spaceDimension = 3;
00208     const MED_EN::medModeSwitch mode = MED_EN::MED_FULL_INTERLACE;
00209 
00210     //construction tableau MEDARRAY des coordonnées
00211     MEDARRAY<double> * myMedArray = new MEDARRAY<double>(spaceDimension, numberofNodes, mode);
00212     for (int i = 1; i <= myMedArray->getLengthValue(); i++) {
00213       for (int j = 1; j <= myMedArray->getLeadingValue(); j++)
00214         myMedArray->setIJ(i, j, (double) i*j);
00215     }
00216 
00217     //construction noms des coordonnées
00218     string * myCoordinatesNames = new string[spaceDimension];
00219     if (spaceDimension >= 1) myCoordinatesNames[0] = "x";
00220     if (spaceDimension >= 2) myCoordinatesNames[1] = "y";
00221     if (spaceDimension >= 3) myCoordinatesNames[2] = "z";
00222 
00223     //construction unités des coordonnées
00224     string * myCoordinatesUnits = new string[spaceDimension];
00225     if (spaceDimension >= 1) myCoordinatesUnits[0] = "m";
00226     if (spaceDimension >= 2) myCoordinatesUnits[1] = "m";
00227     if (spaceDimension >= 3) myCoordinatesUnits[2] = "m";
00228 
00229     //construction des indices des noeuds
00230     int * myNodeNumber = new int[numberofNodes];
00231     for (int i = 0; i < numberofNodes; i++)
00232       myNodeNumber[i] = numberofNodes - i - 1;
00233 
00234     //construction de l'objet COORDINATE
00235     COORDINATE * myCoordinate = new COORDINATE();
00236     myCoordinate->setCoordinates(myMedArray);
00237     myCoordinate->setCoordinatesNames(myCoordinatesNames);
00238     myCoordinate->setCoordinatesUnits(myCoordinatesUnits);
00239     myCoordinate->setNodesNumbers(myNodeNumber);
00240 
00241     delete myMedArray;
00242     delete[] myCoordinatesNames;
00243     delete[] myCoordinatesUnits;
00244     delete[] myNodeNumber;
00245 
00246     COORDINATE * myCoordinate2 = new COORDINATE(* myCoordinate);
00247     delete myCoordinate;
00248     myCoordinate = NULL;
00249 
00250     // check copied coordinate
00251     int _spaceDimension = myCoordinate2->getSpaceDimension();
00252     int _numberofNodes  = myCoordinate2->getNumberOfNodes();
00253     CPPUNIT_ASSERT(_spaceDimension == spaceDimension);
00254     CPPUNIT_ASSERT(_numberofNodes  == numberofNodes);
00255 
00256     for (int i = 1; i <= _numberofNodes; i++) {
00257       for (int j = 1; j <= _spaceDimension; j++) {
00258         CPPUNIT_ASSERT_DOUBLES_EQUAL(i*j, myCoordinate2->getCoordinate(i, j), 0.000001);
00259       }
00260     }
00261 
00262     CPPUNIT_ASSERT(myCoordinate2->getCoordinateName(1) == "x");
00263     CPPUNIT_ASSERT(myCoordinate2->getCoordinateName(2) == "y");
00264     CPPUNIT_ASSERT(myCoordinate2->getCoordinateName(3) == "z");
00265 
00266     CPPUNIT_ASSERT(myCoordinate2->getCoordinateUnit(1) == "m");
00267     CPPUNIT_ASSERT(myCoordinate2->getCoordinateUnit(2) == "m");
00268     CPPUNIT_ASSERT(myCoordinate2->getCoordinateUnit(3) == "m");
00269 
00270     for (int i = 0; i < _numberofNodes; i++)
00271       CPPUNIT_ASSERT(myCoordinate2->getNodesNumbers()[i] == _numberofNodes - i - 1);
00272 
00273     delete myCoordinate2;
00274   }
00275 
00277   // TEST 3 //
00279   {
00280     // COORDINATE(int SpaceDimension, int NumberOfNodes, MED_EN::medModeSwitch Mode);
00281     COORDINATE anEmptyC (2, 10, MED_EN::MED_FULL_INTERLACE);
00282     CPPUNIT_ASSERT(anEmptyC.getSpaceDimension() == 2);
00283     CPPUNIT_ASSERT(anEmptyC.getNumberOfNodes()  == 10);
00284     CPPUNIT_ASSERT(anEmptyC.getNodesNumbers() == NULL);
00285     // ?: how to fill it with coordinates?
00286     // 1. void setCoordinates(MEDARRAY<double> *Coordinate,bool shallowCopy=false);
00287     // but this way we can override all three constructor parameters
00288     // 2. void setCoordinates(const MED_EN::medModeSwitch Mode, const double *Coordinate);
00289     // in this case we can override Mode
00290 
00291 //#ifdef ENABLE_FAULTS
00292     // (BUG) Incoherence between setCoordinateName() and getCoordinateName()
00293     //anEmptyC.setCoordinateName("alpha", 1);
00294     //anEmptyC.setCoordinateName("betta", 2);
00295     // (BUG) Incoherence between setCoordinateUnit() and getCoordinateUnit()
00296     //anEmptyC.setCoordinateUnit("ttt", 1);
00297     //anEmptyC.setCoordinateUnit("sss", 2);
00298 //#else
00299     anEmptyC.setCoordinateName("alpha", 0);
00300     anEmptyC.setCoordinateName("betta", 1);
00301 
00302     anEmptyC.setCoordinateUnit("ttt", 0);
00303     anEmptyC.setCoordinateUnit("sss", 1);
00304 //#endif
00305 //#ifdef ENABLE_FORCED_FAILURES
00306     //CPPUNIT_FAIL("Incoherence between COORDINATE::setCoordinateName() and COORDINATE::getCoordinateName()");
00307     //CPPUNIT_FAIL("Incoherence between COORDINATE::setCoordinateUnit() and COORDINATE::getCoordinateUnit()");
00308 //#endif
00309 
00310     int len = 10 * 2;
00311     double * cc = new double[len];
00312     for (int i = 0; i < len; i++) {
00313       cc[i] = (double)(i + 1);
00314     }
00315     anEmptyC.setCoordinates(MED_EN::MED_NO_INTERLACE, cc);
00316 
00317     CPPUNIT_ASSERT(anEmptyC.getCoordinateName(1) == "alpha");
00318     CPPUNIT_ASSERT(anEmptyC.getCoordinateName(2) == "betta");
00319     CPPUNIT_ASSERT(anEmptyC.getCoordinateUnit(1) == "ttt");
00320     CPPUNIT_ASSERT(anEmptyC.getCoordinateUnit(2) == "sss");
00321     for (int nn = 1; nn <= 10; nn++) {
00322       for (int aa = 1; aa <= 2; aa++) {
00323         CPPUNIT_ASSERT_DOUBLES_EQUAL(nn + (aa - 1) * 10, anEmptyC.getCoordinate(nn, aa), 0.000001);
00324       }
00325     }
00326 
00327     CPPUNIT_ASSERT_THROW(anEmptyC.getCoordinate(0, 0), MEDEXCEPTION);
00328     CPPUNIT_ASSERT_THROW(anEmptyC.getCoordinate(10, 10), MEDEXCEPTION);
00329 
00330     MEDARRAY<double> mcc (cc, 2, 10, MED_EN::MED_FULL_INTERLACE, false, false);
00331     anEmptyC.setCoordinates(&mcc, false);
00332 
00333     // coordinates names and units are not changed
00334     CPPUNIT_ASSERT(anEmptyC.getCoordinateName(1) == "alpha");
00335     CPPUNIT_ASSERT(anEmptyC.getCoordinateName(2) == "betta");
00336     CPPUNIT_ASSERT(anEmptyC.getCoordinateUnit(1) == "ttt");
00337     CPPUNIT_ASSERT(anEmptyC.getCoordinateUnit(2) == "sss");
00338     for (int nn = 1; nn <= 10; nn++) {
00339       for (int aa = 1; aa <= 2; aa++) {
00340         // coordinates changed
00341         CPPUNIT_ASSERT_DOUBLES_EQUAL((nn - 1) * 2 + aa, anEmptyC.getCoordinate(nn, aa), 0.000001);
00342       }
00343     }
00344 
00345     delete [] cc;
00346 
00347 //#ifdef ENABLE_FAULTS
00348     // (BUG) Segmentation Fault or Hang up after anEmptyC and mcc destruction,
00349     // because array will be owned by two pointers (in mcc and in anEmptyC) after this call
00350     //???skl anEmptyC.setCoordinates(&mcc, true);
00351     // In other case (if we dynamically allocate mcc and do not free it) we will have memory leak.
00352 //#endif
00353 //#ifdef ENABLE_FORCED_FAILURES
00354     //CPPUNIT_FAIL("Bug in COORDINATE::setCoordinates() in shallow copy mode");
00355 //#endif
00356   }
00357 
00359   // TEST 4 //
00361   {
00362     // COORDINATE(int SpaceDimension,const string * CoordinateName, const string * CoordinateUnit);
00363     string cnames [3] = {"al", "be", "ga"};
00364     string cunits [3] = {"kg", "mm", "s2"};
00365     COORDINATE anEmptyA (3, cnames, cunits);
00366 
00367     CPPUNIT_ASSERT(anEmptyA.getCoordinateName(1) == "al");
00368     CPPUNIT_ASSERT(anEmptyA.getCoordinateName(2) == "be");
00369     CPPUNIT_ASSERT(anEmptyA.getCoordinateName(3) == "ga");
00370 
00371     CPPUNIT_ASSERT(anEmptyA.getCoordinateUnit(1) == "kg");
00372     CPPUNIT_ASSERT(anEmptyA.getCoordinateUnit(2) == "mm");
00373     CPPUNIT_ASSERT(anEmptyA.getCoordinateUnit(3) == "s2");
00374 
00375     CPPUNIT_ASSERT_EQUAL(anEmptyA.getSpaceDimension(), 0);
00376     CPPUNIT_ASSERT_EQUAL(anEmptyA.getNumberOfNodes(),  0);
00377 
00378     MEDARRAY<double> mcc (3, 7, MED_EN::MED_NO_INTERLACE);
00379     { vector<double> val(3*7,0); // avoid usage of not initialized memory
00380       mcc.set(MED_EN::MED_NO_INTERLACE, &val[0]); }
00381     anEmptyA.setCoordinates(&mcc, false);
00382 
00383     CPPUNIT_ASSERT_EQUAL(anEmptyA.getSpaceDimension(), 3);
00384     CPPUNIT_ASSERT_EQUAL(anEmptyA.getNumberOfNodes(),  7);
00385 
00386     CPPUNIT_ASSERT(anEmptyA.getCoordinateName(1) == "al");
00387     CPPUNIT_ASSERT(anEmptyA.getCoordinateName(2) == "be");
00388     CPPUNIT_ASSERT(anEmptyA.getCoordinateName(3) == "ga");
00389 
00390     CPPUNIT_ASSERT(anEmptyA.getCoordinateUnit(1) == "kg");
00391     CPPUNIT_ASSERT(anEmptyA.getCoordinateUnit(2) == "mm");
00392     CPPUNIT_ASSERT(anEmptyA.getCoordinateUnit(3) == "s2");
00393 
00394     CPPUNIT_ASSERT_THROW(anEmptyA.getCoordinate(-1, 0), MEDEXCEPTION);
00395     CPPUNIT_ASSERT_THROW(anEmptyA.getCoordinate(10, 10), MEDEXCEPTION);
00396 
00397     // No COORDINATE::operator=, but this is compilable
00398     // good
00399     //COORDINATE anEmptyB;
00400     //COORDINATE anEmptyD (3, cnames, cunits);
00401     //anEmptyB = anEmptyD;
00402     //CPPUNIT_ASSERT(anEmptyB.getCoordinateName(1) == "al");
00403 
00404     // bad (assert fails)
00405     //COORDINATE anEmptyB;
00406     // Object, created in this line, is destructed right after it.
00407     //anEmptyB = COORDINATE(3, cnames, cunits);
00408     // Now a pointer _coordinateName inside anEmptyB points to a desallocated memory zone
00409     //CPPUNIT_ASSERT(anEmptyB.getCoordinateName(1) == "al");
00410   }
00411 }