1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "MEDMEMTest.hxx"
21 #include <cppunit/Message.h>
22 #include <cppunit/TestAssert.h>
24 #include "MEDMEM_Array.hxx"
25 #include "MEDMEM_Coordinate.hxx"
30 // use this define to enable lines, execution of which leads to Segmentation Fault
31 //#define ENABLE_FAULTS
33 // use this define to enable CPPUNIT asserts and fails, showing bugs
34 //#define ENABLE_FORCED_FAILURES
37 using namespace MEDMEM;
39 // #8: MEDMEM_Coordinate.hxx } MEDMEMTest_Coordinate.cxx
42 * Check methods (23), defined in MEDMEM_Coordinate.hxx:
45 * (+) COORDINATE(int SpaceDimension, int NumberOfNodes, MED_EN::medModeSwitch Mode);
46 * (+) COORDINATE(int SpaceDimension,const string * CoordinateName, const string * CoordinateUnit);
47 * (+) COORDINATE(const COORDINATE & m);
48 * (+) virtual ~COORDINATE();
49 * (+) void setCoordinates(MEDARRAY<double> *Coordinate,bool shallowCopy=false);
50 * (+) void setCoordinates(const MED_EN::medModeSwitch Mode, const double *Coordinate);
51 * (+) void setCoordinatesNames(const string * CoordinateName);
52 * (+) void setCoordinateName(const string CoordinateName, const int i);
53 * (+) void setCoordinatesUnits(const string * CoordinateUnit);
54 * (+) void setCoordinateUnit(const string CoordinateUnit, const int i);
55 * (+) void setCoordinatesSystem(const string CoordinateSystem);
56 * (+) void setNodesNumbers(const int * NodeNumber);
57 * (+) int getSpaceDimension() const;
58 * (+) int getNumberOfNodes() const;
59 * (+) virtual const int* getNodesNumbers() const;
60 * (+) string getCoordinatesSystem() const;
61 * (+) virtual const double * getCoordinates(MED_EN::medModeSwitch Mode);
62 * (+) virtual double getCoordinate(int Number,int Axis);
63 * (+) virtual const double * getCoordinateAxis(int Axis);
64 * (+) const string * getCoordinatesNames() const;
65 * (+) string getCoordinateName(int Axis) const;
66 * (+) const string * getCoordinatesUnits() const;
67 * (+) string getCoordinateUnit(int Axis) const;
70 * Use code of MEDMEM/tests/testUCoordinate.cxx
71 * MEDMEM/test_copie_coordinate.cxx
73 void MEDMEMTest::testCoordinate()
75 //////////////////////////////////////////////
76 // TEST 1: MEDMEM/tests/testUCoordinate.cxx //
77 //////////////////////////////////////////////
79 const double pouieme = 0.009;
84 string * noms = new string[3];
94 int * numbers = new int[5];
95 for (int i = 0; i < 5; i++) numbers[i] = 10 + i;
97 double coor[15] = {0,0,0,0,0,1,0,1,0,1,0,0,0.5,0.5,0.5};
98 CPPUNIT_ASSERT(SpaceDim * NbOfNodes == 15);
100 double * coor1 = new double [SpaceDim*NbOfNodes];
101 for (int k = 0; k < SpaceDim*NbOfNodes; k++)
104 MEDARRAY<double>* CoordinateArray =
105 new MEDARRAY<double>(coor1, SpaceDim, NbOfNodes, MED_EN::MED_FULL_INTERLACE);
107 CPPUNIT_ASSERT_NO_THROW(mycoo.setCoordinates(CoordinateArray));
109 //--------------------------------------------------------------------//
110 // Tests des methodes //
112 // - setCoordinatesNames //
113 // - setCoordinatesUnits //
114 // - setCoordinatesSystem //
115 // - setNodesNumbers //
117 //--------------------------------------------------------------------//
119 CPPUNIT_ASSERT_NO_THROW(mycoo.setCoordinatesNames(noms));
120 CPPUNIT_ASSERT_NO_THROW(mycoo.setCoordinatesUnits(units));
121 CPPUNIT_ASSERT_NO_THROW(mycoo.setCoordinatesSystem("cartesien"));
122 CPPUNIT_ASSERT_NO_THROW(mycoo.setNodesNumbers(numbers));
124 //--------------------------------------------------------------------//
125 // Tests des methodes //
127 // - getCoordinatesNames //
128 // - getCoordinatesUnits //
129 // - getCoordinatesUnit //
130 // - getCoordinatesSystem //
131 // - getNodesNumbers //
133 //--------------------------------------------------------------------//
134 CPPUNIT_ASSERT_NO_THROW(CPPUNIT_ASSERT(mycoo.getCoordinatesSystem() == "cartesien"));
136 const string * units2;
139 units2 = mycoo.getCoordinatesUnits();
140 for (int axe = 0; axe < SpaceDim; axe++) {
141 string verif = mycoo.getCoordinateUnit(axe+1);
142 CPPUNIT_ASSERT(verif == units2[axe]);
145 catch (const std::exception &e)
147 CPPUNIT_FAIL(e.what());
151 CPPUNIT_FAIL("Unknown exception");
154 const string * noms2;
157 noms2 = mycoo.getCoordinatesNames();
158 for (int axe = 0; axe < SpaceDim; axe++) {
159 string verif = mycoo.getCoordinateName(axe+1);
160 CPPUNIT_ASSERT(verif == noms2[axe]);
163 catch (const std::exception &e)
165 CPPUNIT_FAIL(e.what());
169 CPPUNIT_FAIL("Unknown exception");
174 const double * coor2 = mycoo.getCoordinates(MED_EN::MED_FULL_INTERLACE);
176 for (int axe = 0; axe < SpaceDim; axe++) {
177 const double * coor3 = mycoo.getCoordinateAxis(axe+1);
178 for (int num = 0; num < NbOfNodes; num++) {
179 const double d = mycoo.getCoordinate(num + 1, axe + 1);
180 CPPUNIT_ASSERT(fabs(d - coor3[num ]) < pouieme);
181 CPPUNIT_ASSERT(fabs(d - coor2[(num * SpaceDim)+axe]) < pouieme);
182 CPPUNIT_ASSERT(fabs(d - coor [(num * SpaceDim)+axe]) < pouieme);
186 catch (const std::exception &e)
188 CPPUNIT_FAIL(e.what());
192 CPPUNIT_FAIL("Unknown exception");
199 delete CoordinateArray;
202 //////////////////////////////////////////////
203 // TEST 2: MEDMEM/test_copie_coordinate.cxx //
204 //////////////////////////////////////////////
206 const int numberofNodes = 5;
207 const int spaceDimension = 3;
208 const MED_EN::medModeSwitch mode = MED_EN::MED_FULL_INTERLACE;
210 //construction tableau MEDARRAY des coordonnées
211 MEDARRAY<double> * myMedArray = new MEDARRAY<double>(spaceDimension, numberofNodes, mode);
212 for (int i = 1; i <= myMedArray->getLengthValue(); i++) {
213 for (int j = 1; j <= myMedArray->getLeadingValue(); j++)
214 myMedArray->setIJ(i, j, (double) i*j);
217 //construction noms des coordonnées
218 string * myCoordinatesNames = new string[spaceDimension];
219 if (spaceDimension >= 1) myCoordinatesNames[0] = "x";
220 if (spaceDimension >= 2) myCoordinatesNames[1] = "y";
221 if (spaceDimension >= 3) myCoordinatesNames[2] = "z";
223 //construction unités des coordonnées
224 string * myCoordinatesUnits = new string[spaceDimension];
225 if (spaceDimension >= 1) myCoordinatesUnits[0] = "m";
226 if (spaceDimension >= 2) myCoordinatesUnits[1] = "m";
227 if (spaceDimension >= 3) myCoordinatesUnits[2] = "m";
229 //construction des indices des noeuds
230 int * myNodeNumber = new int[numberofNodes];
231 for (int i = 0; i < numberofNodes; i++)
232 myNodeNumber[i] = numberofNodes - i - 1;
234 //construction de l'objet COORDINATE
235 COORDINATE * myCoordinate = new COORDINATE();
236 myCoordinate->setCoordinates(myMedArray);
237 myCoordinate->setCoordinatesNames(myCoordinatesNames);
238 myCoordinate->setCoordinatesUnits(myCoordinatesUnits);
239 myCoordinate->setNodesNumbers(myNodeNumber);
242 delete[] myCoordinatesNames;
243 delete[] myCoordinatesUnits;
244 delete[] myNodeNumber;
246 COORDINATE * myCoordinate2 = new COORDINATE(* myCoordinate);
250 // check copied coordinate
251 int _spaceDimension = myCoordinate2->getSpaceDimension();
252 int _numberofNodes = myCoordinate2->getNumberOfNodes();
253 CPPUNIT_ASSERT(_spaceDimension == spaceDimension);
254 CPPUNIT_ASSERT(_numberofNodes == numberofNodes);
256 for (int i = 1; i <= _numberofNodes; i++) {
257 for (int j = 1; j <= _spaceDimension; j++) {
258 CPPUNIT_ASSERT_DOUBLES_EQUAL(i*j, myCoordinate2->getCoordinate(i, j), 0.000001);
262 CPPUNIT_ASSERT(myCoordinate2->getCoordinateName(1) == "x");
263 CPPUNIT_ASSERT(myCoordinate2->getCoordinateName(2) == "y");
264 CPPUNIT_ASSERT(myCoordinate2->getCoordinateName(3) == "z");
266 CPPUNIT_ASSERT(myCoordinate2->getCoordinateUnit(1) == "m");
267 CPPUNIT_ASSERT(myCoordinate2->getCoordinateUnit(2) == "m");
268 CPPUNIT_ASSERT(myCoordinate2->getCoordinateUnit(3) == "m");
270 for (int i = 0; i < _numberofNodes; i++)
271 CPPUNIT_ASSERT(myCoordinate2->getNodesNumbers()[i] == _numberofNodes - i - 1);
273 delete myCoordinate2;
280 // COORDINATE(int SpaceDimension, int NumberOfNodes, MED_EN::medModeSwitch Mode);
281 COORDINATE anEmptyC (2, 10, MED_EN::MED_FULL_INTERLACE);
282 CPPUNIT_ASSERT(anEmptyC.getSpaceDimension() == 2);
283 CPPUNIT_ASSERT(anEmptyC.getNumberOfNodes() == 10);
284 CPPUNIT_ASSERT(anEmptyC.getNodesNumbers() == NULL);
285 // ?: how to fill it with coordinates?
286 // 1. void setCoordinates(MEDARRAY<double> *Coordinate,bool shallowCopy=false);
287 // but this way we can override all three constructor parameters
288 // 2. void setCoordinates(const MED_EN::medModeSwitch Mode, const double *Coordinate);
289 // in this case we can override Mode
291 //#ifdef ENABLE_FAULTS
292 // (BUG) Incoherence between setCoordinateName() and getCoordinateName()
293 //anEmptyC.setCoordinateName("alpha", 1);
294 //anEmptyC.setCoordinateName("betta", 2);
295 // (BUG) Incoherence between setCoordinateUnit() and getCoordinateUnit()
296 //anEmptyC.setCoordinateUnit("ttt", 1);
297 //anEmptyC.setCoordinateUnit("sss", 2);
299 anEmptyC.setCoordinateName("alpha", 0);
300 anEmptyC.setCoordinateName("betta", 1);
302 anEmptyC.setCoordinateUnit("ttt", 0);
303 anEmptyC.setCoordinateUnit("sss", 1);
305 //#ifdef ENABLE_FORCED_FAILURES
306 //CPPUNIT_FAIL("Incoherence between COORDINATE::setCoordinateName() and COORDINATE::getCoordinateName()");
307 //CPPUNIT_FAIL("Incoherence between COORDINATE::setCoordinateUnit() and COORDINATE::getCoordinateUnit()");
311 double * cc = new double[len];
312 for (int i = 0; i < len; i++) {
313 cc[i] = (double)(i + 1);
315 anEmptyC.setCoordinates(MED_EN::MED_NO_INTERLACE, cc);
317 CPPUNIT_ASSERT(anEmptyC.getCoordinateName(1) == "alpha");
318 CPPUNIT_ASSERT(anEmptyC.getCoordinateName(2) == "betta");
319 CPPUNIT_ASSERT(anEmptyC.getCoordinateUnit(1) == "ttt");
320 CPPUNIT_ASSERT(anEmptyC.getCoordinateUnit(2) == "sss");
321 for (int nn = 1; nn <= 10; nn++) {
322 for (int aa = 1; aa <= 2; aa++) {
323 CPPUNIT_ASSERT_DOUBLES_EQUAL(nn + (aa - 1) * 10, anEmptyC.getCoordinate(nn, aa), 0.000001);
327 CPPUNIT_ASSERT_THROW(anEmptyC.getCoordinate(0, 0), MEDEXCEPTION);
328 CPPUNIT_ASSERT_THROW(anEmptyC.getCoordinate(10, 10), MEDEXCEPTION);
330 MEDARRAY<double> mcc (cc, 2, 10, MED_EN::MED_FULL_INTERLACE, false, false);
331 anEmptyC.setCoordinates(&mcc, false);
333 // coordinates names and units are not changed
334 CPPUNIT_ASSERT(anEmptyC.getCoordinateName(1) == "alpha");
335 CPPUNIT_ASSERT(anEmptyC.getCoordinateName(2) == "betta");
336 CPPUNIT_ASSERT(anEmptyC.getCoordinateUnit(1) == "ttt");
337 CPPUNIT_ASSERT(anEmptyC.getCoordinateUnit(2) == "sss");
338 for (int nn = 1; nn <= 10; nn++) {
339 for (int aa = 1; aa <= 2; aa++) {
340 // coordinates changed
341 CPPUNIT_ASSERT_DOUBLES_EQUAL((nn - 1) * 2 + aa, anEmptyC.getCoordinate(nn, aa), 0.000001);
347 //#ifdef ENABLE_FAULTS
348 // (BUG) Segmentation Fault or Hang up after anEmptyC and mcc destruction,
349 // because array will be owned by two pointers (in mcc and in anEmptyC) after this call
350 //???skl anEmptyC.setCoordinates(&mcc, true);
351 // In other case (if we dynamically allocate mcc and do not free it) we will have memory leak.
353 //#ifdef ENABLE_FORCED_FAILURES
354 //CPPUNIT_FAIL("Bug in COORDINATE::setCoordinates() in shallow copy mode");
362 // COORDINATE(int SpaceDimension,const string * CoordinateName, const string * CoordinateUnit);
363 string cnames [3] = {"al", "be", "ga"};
364 string cunits [3] = {"kg", "mm", "s2"};
365 COORDINATE anEmptyA (3, cnames, cunits);
367 CPPUNIT_ASSERT(anEmptyA.getCoordinateName(1) == "al");
368 CPPUNIT_ASSERT(anEmptyA.getCoordinateName(2) == "be");
369 CPPUNIT_ASSERT(anEmptyA.getCoordinateName(3) == "ga");
371 CPPUNIT_ASSERT(anEmptyA.getCoordinateUnit(1) == "kg");
372 CPPUNIT_ASSERT(anEmptyA.getCoordinateUnit(2) == "mm");
373 CPPUNIT_ASSERT(anEmptyA.getCoordinateUnit(3) == "s2");
375 CPPUNIT_ASSERT_EQUAL(anEmptyA.getSpaceDimension(), 0);
376 CPPUNIT_ASSERT_EQUAL(anEmptyA.getNumberOfNodes(), 0);
378 MEDARRAY<double> mcc (3, 7, MED_EN::MED_NO_INTERLACE);
379 { vector<double> val(3*7,0); // avoid usage of not initialized memory
380 mcc.set(MED_EN::MED_NO_INTERLACE, &val[0]); }
381 anEmptyA.setCoordinates(&mcc, false);
383 CPPUNIT_ASSERT_EQUAL(anEmptyA.getSpaceDimension(), 3);
384 CPPUNIT_ASSERT_EQUAL(anEmptyA.getNumberOfNodes(), 7);
386 CPPUNIT_ASSERT(anEmptyA.getCoordinateName(1) == "al");
387 CPPUNIT_ASSERT(anEmptyA.getCoordinateName(2) == "be");
388 CPPUNIT_ASSERT(anEmptyA.getCoordinateName(3) == "ga");
390 CPPUNIT_ASSERT(anEmptyA.getCoordinateUnit(1) == "kg");
391 CPPUNIT_ASSERT(anEmptyA.getCoordinateUnit(2) == "mm");
392 CPPUNIT_ASSERT(anEmptyA.getCoordinateUnit(3) == "s2");
394 CPPUNIT_ASSERT_THROW(anEmptyA.getCoordinate(-1, 0), MEDEXCEPTION);
395 CPPUNIT_ASSERT_THROW(anEmptyA.getCoordinate(10, 10), MEDEXCEPTION);
397 // No COORDINATE::operator=, but this is compilable
399 //COORDINATE anEmptyB;
400 //COORDINATE anEmptyD (3, cnames, cunits);
401 //anEmptyB = anEmptyD;
402 //CPPUNIT_ASSERT(anEmptyB.getCoordinateName(1) == "al");
404 // bad (assert fails)
405 //COORDINATE anEmptyB;
406 // Object, created in this line, is destructed right after it.
407 //anEmptyB = COORDINATE(3, cnames, cunits);
408 // Now a pointer _coordinateName inside anEmptyB points to a desallocated memory zone
409 //CPPUNIT_ASSERT(anEmptyB.getCoordinateName(1) == "al");