Salome HOME
Merge from BR_V5_DEV 16Feb09
[modules/med.git] / src / MEDMEMCppTest / MEDMEMTest_AsciiFieldDriver.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 #include "MEDMEMTest.hxx"
23 #include <cppunit/TestAssert.h>
24
25 #include "MEDMEM_Compatibility21_22.hxx"
26 #include "MEDMEM_AsciiFieldDriver.hxx"
27 #include "MEDMEM_STRING.hxx"
28
29 #include <stdio.h>
30
31 #include <sstream>
32 #include <fstream>
33 #include <cmath>
34
35 // use this define to enable lines, execution of which leads to Segmentation Fault
36 //#define ENABLE_FAULTS
37
38 // use this define to enable CPPUNIT asserts and fails, showing bugs
39 //#define ENABLE_FORCED_FAILURES
40
41 using namespace std;
42 using namespace MEDMEM;
43
44 // #4: MEDMEM_AsciiFieldDriver.hxx  }  MEDMEMTest_AsciiFieldDriver.cxx
45
46 /*!
47  *  Check methods (8), defined in MEDMEM_AsciiFieldDriver.hxx:
48  *
49  *  (+)     template<int N,unsigned int CODE> void fill(double *a, const double *b)
50  *  (+)     template<int N> bool compare(const double* a, const double* b)
51  *  (+)     template<> void fill<-1,0x3>(double *a, const double *b);
52  *  (+)     template<> bool compare<-1>(const double *a, const double *b);
53  *
54  *  template <class T, int SPACEDIMENSION, unsigned int SORTSTRATEGY>
55  *  class SDForSorting {
56  *   (+)     SDForSorting(const double *coords, const T* comp, int nbComponents);
57  *   (+)     SDForSorting(const SDForSorting& other);
58  *   (+)     ~SDForSorting();
59  *   (+)     bool operator< (const SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY>& other) const;
60  *   (+)     void writeLine(ofstream& file) const;
61  *  }
62  *
63  *  template <class T>
64  *  class ASCII_FIELD_DRIVER : public GENDRIVER {
65  *
66  *           //MUST BE PRIVATE as there is no possibility to set _ptrField after this constructor usage
67  *   (-)     template <class INTERLACING_TAG> ASCII_FIELD_DRIVER();
68  *
69  *   (+)     template <class INTERLACING_TAG>
70  *           ASCII_FIELD_DRIVER(const string & fileName, FIELD<T,INTERLACING_TAG> * ptrField,
71  *                              MED_EN::med_sort_direc direction=MED_EN::ASCENDING, const char *priority="");
72  *   (+)     ASCII_FIELD_DRIVER(const ASCII_FIELD_DRIVER<T>& other);
73  *   (+)     void open() throw (MEDEXCEPTION);
74  *   (+)     void close();
75  *   (+)     void read (void) throw (MEDEXCEPTION);
76  *   (+)     void write(void) const throw (MEDEXCEPTION);
77  *   (+)     GENDRIVER* copy() const;
78  *  }
79  */
80 void MEDMEMTest::testAsciiFieldDriver()
81 {
82   // read a mesh from a MED file
83   string datadir   = getenv("MED_ROOT_DIR");
84   string tmp_dir   = getenv("TMP") ? getenv("TMP") : "/tmp";
85   string filename  = datadir + "/share/salome/resources/med/pointe.med";
86   string meshname  = "maa1";
87   string fieldname = "fieldcelldoublescalar";
88
89   if (tmp_dir == "")
90     tmp_dir = "/tmp";
91   string anyfile1  = tmp_dir + "/anyfile1";
92   string SDFfilename = tmp_dir + "/myfile";
93   ofstream aFile(SDFfilename.c_str());
94
95   // To remove tmp files from disk
96   MEDMEMTest_TmpFilesRemover aRemover;
97   aRemover.Register(anyfile1);
98   aRemover.Register(SDFfilename);
99
100   //Test SDForSorting class
101   {
102     double coord_1[10] = { 1.0, 2.0,
103                            -1.0, 2.0,
104                            3.6, -8.7,
105                            10.0, -10.0,
106                            12.3, 9.3};
107
108     int comp_1[5] = {1, 3, 5, 7, 9};
109     SDForSorting<int, 2, 48> aSDF_1(coord_1, comp_1, 5);
110
111     SDForSorting<int, 2, 48> aSDFCpy_1 = SDForSorting<int, 2, 48>(aSDF_1);
112     CPPUNIT_ASSERT_EQUAL(aSDFCpy_1 < aSDF_1, false);
113     CPPUNIT_ASSERT_NO_THROW(aSDF_1.writeLine(aFile));
114   }
115
116   // Why functions
117   // template<> void MEDMEM::fill<-1,0x3>(double *a, const double *b)
118   // and
119   // template<> bool MEDMEM::compare<-1>(const double *a, const double *b)
120   // declared in MEDMEM_AsciiFieldDriver.hxx,
121   // are implemented in MEDMEM_DriverFactory.cxx?
122
123   // template<int N,unsigned int CODE> void fill(double *a, const double *b)
124   {
125     // 0x3 = 110000
126     double aa[3];
127     double bb[3] = {1,2,3};
128
129     fill<2,198>(aa, bb); // ZYX // 11000110 // 012
130     //MEDMEMTest_DumpArray<double>(cout, aa, 3, "aa filled with ZYX");
131     CPPUNIT_ASSERT_EQUAL(aa[0], bb[0]);
132     CPPUNIT_ASSERT_EQUAL(aa[1], bb[1]);
133     CPPUNIT_ASSERT_EQUAL(aa[2], bb[2]);
134
135     fill<2,210>(aa, bb); // ZXY // 11010010 // 102
136     //MEDMEMTest_DumpArray<double>(cout, aa, 3, "aa filled with ZXY");
137     CPPUNIT_ASSERT_EQUAL(aa[0], bb[1]);
138     CPPUNIT_ASSERT_EQUAL(aa[1], bb[0]);
139     CPPUNIT_ASSERT_EQUAL(aa[2], bb[2]);
140
141     fill<2,228>(aa, bb); // XYZ // 11100100 // 210
142     //MEDMEMTest_DumpArray<double>(cout, aa, 3, "aa filled with XYZ");
143     CPPUNIT_ASSERT_EQUAL(aa[0], bb[2]);
144     CPPUNIT_ASSERT_EQUAL(aa[1], bb[1]);
145     CPPUNIT_ASSERT_EQUAL(aa[2], bb[0]);
146   }
147
148   printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
149   printf("1\n");
150   printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
151   // template<int N> bool compare(const double* a, const double* b)
152   {
153     {
154       // aa < bb
155       double aa[8] = {1,1,1,1,1,1,1,1};
156       double bb[8] = {1,1,1,1,1,1,1,2};
157       CPPUNIT_ASSERT(compare<7>(aa, bb));
158     }
159
160     {
161       // aa < bb
162       double aa[8] = {1,1,1,1,1,1,1,1};
163       double bb[8] = {2,1,1,1,1,1,1,1};
164       CPPUNIT_ASSERT(compare<7>(aa, bb));
165     }
166
167     {
168       // aa > bb
169       double aa[8] = {2,1,1,1,1,1,1,1};
170       double bb[8] = {1,1,1,1,1,1,1,1};
171       CPPUNIT_ASSERT(!compare<7>(aa, bb));
172     }
173
174     {
175       // aa == bb
176       double aa[8] = {1,1,1,1,1,1,1,1};
177       double bb[8] = {1,1,1,1,1,1,1,1};
178       CPPUNIT_ASSERT(!compare<7>(aa, bb));
179     }
180
181     {
182       // compare<-1>
183       double aa[8] = {2,1,1,1,1,1,1,1};
184       double bb[8] = {1,1,1,1,1,1,1,1};
185       CPPUNIT_ASSERT(!compare<-1>(aa, bb));
186     }
187   }
188
189   // Test ASCII_FIELD_DRIVER
190   FIELD<double> * aField1 = new FIELD<double> (MED_DRIVER, filename, fieldname);
191   const SUPPORT * aSupport = aField1->getSupport();
192   MESH * aMesh = new MESH (MED_DRIVER, filename, aSupport->getMeshName());
193   aSupport->setMesh(aMesh);
194
195   // create an ASCII driver for a field
196   ASCII_FIELD_DRIVER<double> * aDriver1 =
197     new ASCII_FIELD_DRIVER<double> (anyfile1, aField1, MED_EN::ASCENDING, "");
198   CPPUNIT_ASSERT(aDriver1);
199
200   CPPUNIT_ASSERT(aDriver1->getFileName() == anyfile1);
201   CPPUNIT_ASSERT(aDriver1->getAccessMode() == MED_EN::WRONLY);
202
203   // and write the field on disk
204
205   // must throw because the file is not opened
206
207   CPPUNIT_ASSERT_THROW(aDriver1->write(), MEDEXCEPTION);
208
209   aDriver1->open();
210
211   // must throw because the file is opened
212   CPPUNIT_ASSERT_THROW(aDriver1->setFileName("anyfile2"), MEDEXCEPTION);
213   CPPUNIT_ASSERT_THROW(aDriver1->setFileName(anyfile1), MEDEXCEPTION);
214
215   CPPUNIT_ASSERT_THROW(aDriver1->open(), MEDEXCEPTION);
216
217
218   // must throw because it is a writeonly driver
219   CPPUNIT_ASSERT_THROW(aDriver1->read(), MEDEXCEPTION);
220
221   aDriver1->write();
222   aDriver1->close();
223
224   // must throw because the file is not opened
225
226   CPPUNIT_ASSERT_THROW(aDriver1->write(), MEDEXCEPTION);
227
228   //CPPUNIT_ASSERT_THROW(aDriver1->close(), MEDEXCEPTION);
229   CPPUNIT_ASSERT_NO_THROW(aDriver1->close()); // do not make troubles to the user
230
231   // check priority definition
232   int spaceDimension = aMesh->getSpaceDimension();
233   if (spaceDimension == 3) {
234     // good
235     CPPUNIT_ASSERT_NO_THROW(ASCII_FIELD_DRIVER<double> aDriver2
236                             ("anyfile2", aField1, MED_EN::ASCENDING, "XYZ"));
237     // too long
238     CPPUNIT_ASSERT_THROW(ASCII_FIELD_DRIVER<double> aDriver3
239                          ("anyfile3", aField1, MED_EN::ASCENDING, "XYZX"), MEDEXCEPTION);
240     // too short
241     CPPUNIT_ASSERT_THROW(ASCII_FIELD_DRIVER<double> aDriver4
242                          ("anyfile4", aField1, MED_EN::ASCENDING, "XY"), MEDEXCEPTION);
243     // invalid
244 //#ifdef ENABLE_FORCED_FAILURES
245     // (BUG) This assert fails because 'A'(and 'B', and 'C') < 'X'
246     CPPUNIT_ASSERT_THROW(ASCII_FIELD_DRIVER<double> aDriver5
247                          ("anyfile5", aField1, MED_EN::ASCENDING, "ABC"), MEDEXCEPTION);
248 //#endif
249   }
250   else if (spaceDimension == 2) {
251     // good
252     CPPUNIT_ASSERT_NO_THROW(ASCII_FIELD_DRIVER<double> aDriver2
253                             ("anyfile2", aField1, MED_EN::ASCENDING, "XY"));
254     // too long
255     CPPUNIT_ASSERT_THROW(ASCII_FIELD_DRIVER<double> aDriver3
256                          ("anyfile3", aField1, MED_EN::ASCENDING, "XYZ"), MEDEXCEPTION);
257     // too short
258     CPPUNIT_ASSERT_THROW(ASCII_FIELD_DRIVER<double> aDriver4
259                          ("anyfile4", aField1, MED_EN::ASCENDING, "X"), MEDEXCEPTION);
260     // invalid
261 //#ifdef ENABLE_FORCED_FAILURES
262     // (BUG) Invalid string is accepted for priority
263     CPPUNIT_ASSERT_THROW(ASCII_FIELD_DRIVER<double> aDriver5
264                          ("anyfile5", aField1, MED_EN::ASCENDING, "AB"), MEDEXCEPTION);
265 //#endif
266   }
267   else {
268     CPPUNIT_FAIL("Cannot test ASCII_FIELD_DRIVER because file pointe.med"
269                  " contains mesh of wrong dimension: must be 2 or 3");
270   }
271
272   //Copy constructor
273   ASCII_FIELD_DRIVER<double> aDriver1_Cpy1 = ASCII_FIELD_DRIVER<double> (*aDriver1);
274
275   //Test copy() function
276   ASCII_FIELD_DRIVER<double> *aDriver1_Cpy2 = (ASCII_FIELD_DRIVER<double>*)aDriver1->copy();
277
278   // free memory
279   delete aDriver1;
280   delete aField1;
281   delete aMesh;
282 }