Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[modules/med.git] / src / MEDMEM / Test / MEDMEMTest_Field.cxx
1 // Copyright (C) 2006  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 //
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
8 //
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 // Lesser General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 //
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 //
20
21 #include "MEDMEMTest.hxx"
22 #include <cppunit/TestAssert.h>
23
24 #include "MEDMEM_FieldConvert.hxx"
25 #include "MEDMEM_Field.hxx"
26 #include "MEDMEM_Mesh.hxx"
27 #include "MEDMEM_Group.hxx"
28 #include "MEDMEM_Support.hxx"
29 #include <MEDMEM_VtkMeshDriver.hxx>
30 #include <MEDMEM_MedMeshDriver22.hxx>
31
32
33 #include <sstream>
34 #include <cmath>
35
36 // use this define to enable lines, execution of which leads to Segmentation Fault
37 //#define ENABLE_FAULTS
38
39 // use this define to enable CPPUNIT asserts and fails, showing bugs
40 #define ENABLE_FORCED_FAILURES
41
42 using namespace std;
43 using namespace MEDMEM;
44
45 // #14,15: MEDMEMTest_Field.cxx
46 // Check methods from MEDMEM_Field.hxx, MEDMEM_FieldConvert.hxx
47
48 /*!
49  *  Check methods (48), defined in MEDMEM_Field.hxx:
50  *  class FIELD_ {
51  *   (+)     FIELD_();
52  *   (+)     FIELD_(const SUPPORT * Support, const int NumberOfComponents);
53  *   (+)     FIELD_(const FIELD_ &m);
54  *   (+)     virtual ~FIELD_();
55  *   (+)     FIELD_& operator=(const FIELD_ &m);
56  *
57  *   (-)     virtual  void     rmDriver(int index=0);
58  *   (-)     virtual   int     addDriver(driverTypes driverType,
59  *                             const string & fileName="Default File Name.med",
60  *                              const string & driverFieldName="Default Field Nam",
61  *                              MED_EN::med_mode_acces access=MED_EN::MED_REMP);
62  *   (-)     virtual  int      addDriver(GENDRIVER & driver);
63  *
64  *   (-)     virtual  void     read (const GENDRIVER &);
65  *   (-)     virtual  void     read(int index=0);
66  *   (-)     virtual  void     openAppend(void);
67  *   (-)     virtual  void     write(const GENDRIVER &);
68  *   (-)     virtual  void     write(int index=0, const string & driverName="");
69  *   (-)     virtual  void     writeAppend(const GENDRIVER &);
70  *   (-)     virtual  void     writeAppend(int index=0, const string & driverName="");
71  *
72  *   (+)     inline void     setName(const string Name);
73  *   (+)     inline string   getName() const;
74  *   (+)     inline void     setDescription(const string Description);
75  *   (+)     inline string   getDescription() const;
76  *   (+)     inline const SUPPORT * getSupport() const;
77  *   (+)     inline void     setSupport(const SUPPORT * support);
78  *   (+)     inline void     setNumberOfComponents(const int NumberOfComponents);
79  *   (+)     inline int      getNumberOfComponents() const;
80  *   (+)     inline void     setNumberOfValues(const int NumberOfValues);
81  *   (+)     inline int      getNumberOfValues() const;
82  *   (+)     inline void     setComponentsNames(const string * ComponentsNames);
83  *   (+)     inline void     setComponentName(int i, const string ComponentName);
84  *   (+)     inline const string * getComponentsNames() const;
85  *   (+)     inline string   getComponentName(int i) const;
86  *   (+)     inline void     setComponentsDescriptions(const string * ComponentsDescriptions);
87  *   (+)     inline void     setComponentDescription(int i, const string ComponentDescription);
88  *   (+)     inline const string * getComponentsDescriptions() const;
89  *   (+)     inline string   getComponentDescription(int i) const;
90  *   (+)     inline void     setComponentsUnits(const UNIT * ComponentsUnits);
91  *   (+)     inline const UNIT *   getComponentsUnits() const;
92  *   (+)     inline const UNIT *   getComponentUnit(int i) const;
93  *   (+)     inline void     setMEDComponentsUnits(const string * MEDComponentsUnits);
94  *   (+)     inline void     setMEDComponentUnit(int i, const string MEDComponentUnit);
95  *   (+)     inline const string * getMEDComponentsUnits() const;
96  *   (+)     inline string   getMEDComponentUnit(int i) const;
97  *
98  *   (+)     inline void     setIterationNumber(int IterationNumber);
99  *   (+)     inline int      getIterationNumber() const;
100  *   (+)     inline void     setTime(double Time);
101  *   (+)     inline double   getTime() const;
102  *   (+)     inline void     setOrderNumber(int OrderNumber);
103  *   (+)     inline int      getOrderNumber() const;
104  *
105  *   (+)     inline MED_EN::med_type_champ getValueType () const;
106  *   (+)     inline MED_EN::medModeSwitch  getInterlacingType() const;
107  *   (-)     virtual inline bool getGaussPresence() const throw (MEDEXCEPTION);
108  *  }
109  *
110  *  template <class T, class INTERLACING_TAG> class FIELD : public FIELD_ {
111  *   (+)     FIELD();
112  *   (+)     FIELD(const FIELD &m);
113  *   (+)     FIELD(const SUPPORT * Support, const int NumberOfComponents) throw (MEDEXCEPTION);
114  *   (+)     FIELD(driverTypes driverType,
115  *                 const string & fileName, const string & fieldDriverName,
116  *                 const int iterationNumber=-1, const int orderNumber=-1) throw (MEDEXCEPTION);
117  *   (+) FIELD(const SUPPORT * Support, driverTypes driverType,
118  *                 const string & fileName="", const string & fieldName="",
119  *                 const int iterationNumber = -1, const int orderNumber = -1) throw (MEDEXCEPTION);
120  *   (+)     ~FIELD();
121  *   (+)     FIELD & operator=(const FIELD &m);
122  *
123  *   (+) const FIELD operator+(const FIELD& m) const;
124  *   (+) const FIELD operator-(const FIELD& m) const;
125  *   (+) const FIELD operator*(const FIELD& m) const;
126  *   (+) const FIELD operator/(const FIELD& m) const;
127  *   (+) const FIELD operator-() const;
128  *   (+) FIELD& operator+=(const FIELD& m);
129  *   (+) FIELD& operator-=(const FIELD& m);
130  *   (+) FIELD& operator*=(const FIELD& m);
131  *   (+) FIELD& operator/=(const FIELD& m);
132  *
133  *   (+) static FIELD* add(const FIELD& m, const FIELD& n);
134  *   (+) static FIELD* addDeep(const FIELD& m, const FIELD& n);
135  *   (+) static FIELD* sub(const FIELD& m, const FIELD& n);
136  *   (+) static FIELD* subDeep(const FIELD& m, const FIELD& n);
137  *   (+) static FIELD* mul(const FIELD& m, const FIELD& n);
138  *   (+) static FIELD* mulDeep(const FIELD& m, const FIELD& n);
139  *   (+) static FIELD* div(const FIELD& m, const FIELD& n);
140  *   (+) static FIELD* divDeep(const FIELD& m, const FIELD& n);
141  *
142  *   (+)     double normMax() const throw (MEDEXCEPTION);
143  *   (+)     double norm2() const throw (MEDEXCEPTION);
144  *
145  *   (+)     void   applyLin(T a, T b);
146  *   (+)     template <T T_function(T)> void applyFunc();
147  *   (+)     void applyPow(T scalar);
148  *
149  *   (+)     static FIELD* scalarProduct(const FIELD& m, const FIELD& n, bool deepCheck=false);
150  *
151  *   (+)     double normL2(int component, const FIELD<double,FullInterlace> * p_field_volume=NULL) const;
152  *   (+)     double normL2(const FIELD<double,FullInterlace> * p_field_volume=NULL) const;
153  *   (+)     double normL1(int component, const FIELD<double,FullInterlace> * p_field_volume=NULL) const;
154  *   (+)     double normL1(const FIELD<double,FullInterlace> * p_field_volume=NULL) const;
155  *
156  *   (+)     FIELD* extract(const SUPPORT *subSupport) const throw (MEDEXCEPTION);
157  *
158  *   (EMPTY COMMENT, EMPTY IMPLEMENTATION!!!) void init ();
159  *
160  *   (+)     void rmDriver(int index=0);
161  *   (+)     int  addDriver(driverTypes driverType,
162  *                          const string & fileName="Default File Name.med",
163  *                          const string & driverFieldName="Default Field Name",
164  *                          MED_EN::med_mode_acces access=MED_EN::MED_REMP);
165  *   (+)     int  addDriver(GENDRIVER & driver);
166  *
167  *   (+)     void allocValue(const int NumberOfComponents);
168  *   (+)     void allocValue(const int NumberOfComponents, const int LengthValue);
169  *   (+)     void deallocValue();
170  *
171  *   (+)     inline void read(int index=0);
172  *   (+)     inline void read(const GENDRIVER & genDriver);
173  *   (+)     inline void write(int index=0, const string & driverName = "");
174  *   (+)     inline void write(const GENDRIVER &);
175  *   (+)     inline void writeAppend(int index=0, const string & driverName = "");
176  *   (+) inline void writeAppend(const GENDRIVER &);
177  *
178  *   (+)     inline MEDMEM_Array_  * getArray()        const throw (MEDEXCEPTION);
179  *   (+)     inline ArrayGauss     * getArrayGauss()   const throw (MEDEXCEPTION);
180  *   (+)     inline ArrayNoGauss   * getArrayNoGauss() const throw (MEDEXCEPTION);
181  *   (+)     inline bool             getGaussPresence() const throw (MEDEXCEPTION);
182  *
183  *   (+)     inline int      getValueLength() const throw (MEDEXCEPTION);
184  *   (+)     inline const T* getValue()       const throw (MEDEXCEPTION);
185  *   (+)     inline const T* getRow(int i)    const throw (MEDEXCEPTION);
186  *   (+)     inline const T* getColumn(int j) const throw (MEDEXCEPTION);
187  *   (+)     inline T        getValueIJ(int i,int j) const throw (MEDEXCEPTION);
188  *   (+)     inline T        getValueIJK(int i,int j,int k) const throw (MEDEXCEPTION);
189  *   (+)     bool            getValueOnElement(int eltIdInSup,T* retValues) const throw (MEDEXCEPTION);
190  *
191  *   (+)     const int getNumberOfGeometricTypes() const throw (MEDEXCEPTION);
192  *
193  *   (+)     const GAUSS_LOCALIZATION<INTERLACING_TAG> & getGaussLocalization
194  *                          (MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION);
195  *   (+)     const GAUSS_LOCALIZATION<INTERLACING_TAG> * getGaussLocalizationPtr
196  *                          (MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION);
197  *   (+)     void setGaussLocalization(MED_EN::medGeometryElement geomElement,
198  *                                     const GAUSS_LOCALIZATION<INTERLACING_TAG> & gaussloc);
199  *   (+)     const int * getNumberOfGaussPoints() const throw (MEDEXCEPTION);
200  *   (+)     const int   getNumberOfGaussPoints
201  *                          (MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION);
202  *   (+)     const int   getNbGaussI(int i) const throw (MEDEXCEPTION);
203  *
204  *   (+)     const int * getNumberOfElements() const throw (MEDEXCEPTION);
205  *   (+)     const MED_EN::medGeometryElement * getGeometricTypes() const throw (MEDEXCEPTION);
206  *   (+)     bool        isOnAllElements() const throw (MEDEXCEPTION);
207  *
208  *   (+)     inline void setArray(MEDMEM_Array_ *value) throw (MEDEXCEPTION);
209  *   (+)     inline void setValue(T* value) throw (MEDEXCEPTION);
210  *   (+)     inline void setRow(int i, T* value) throw (MEDEXCEPTION);
211  *   (+)     inline void setColumn(int i, T* value) throw (MEDEXCEPTION);
212  *   (+)     inline void setValueIJ(int i, int j, T value) throw (MEDEXCEPTION);
213  *
214  *   (NOT IMPLEMENTED!!!) void getVolume() const throw (MEDEXCEPTION);
215  *   (NOT IMPLEMENTED!!!) void getArea() const throw (MEDEXCEPTION);
216  *   (NOT IMPLEMENTED!!!) void getLength() const throw (MEDEXCEPTION);
217  *   (NOT IMPLEMENTED!!!) void getNormal() const throw (MEDEXCEPTION);
218  *   (NOT IMPLEMENTED!!!) void getBarycenter() const throw (MEDEXCEPTION);
219  *
220  *   (+)     void fillFromAnalytic(myFuncType f) throw (MEDEXCEPTION);
221  *  }
222  *
223  *  Use code of test_operation_fieldint.cxx
224  *              test_operation_fielddouble.cxx
225  *              test_copie_field_.cxx
226  *              test_copie_fieldT.cxx
227  */
228 void compareField_(const FIELD_ * theField_1, const FIELD_ * theField_2, bool isFIELD, bool isValue)
229 {
230   // name, description, support
231   CPPUNIT_ASSERT_EQUAL(theField_1->getName(), theField_2->getName());
232   CPPUNIT_ASSERT_EQUAL(theField_1->getDescription(), theField_2->getDescription());
233   CPPUNIT_ASSERT_EQUAL(theField_1->getSupport(), theField_2->getSupport());
234
235   // components information
236   int aNbComps = theField_1->getNumberOfComponents();
237   CPPUNIT_ASSERT_EQUAL(aNbComps, theField_2->getNumberOfComponents());
238
239   for (int i = 1; i <= aNbComps; i++) {
240     CPPUNIT_ASSERT_EQUAL(theField_1->getComponentName(i), theField_2->getComponentName(i));
241     CPPUNIT_ASSERT_EQUAL(theField_1->getComponentDescription(i), theField_2->getComponentDescription(i));
242     CPPUNIT_ASSERT_EQUAL(theField_1->getMEDComponentUnit(i), theField_2->getMEDComponentUnit(i));
243   }
244
245   // iteration information
246   CPPUNIT_ASSERT_EQUAL(theField_1->getIterationNumber(), theField_2->getIterationNumber());
247   CPPUNIT_ASSERT_EQUAL(theField_1->getOrderNumber(), theField_2->getOrderNumber());
248   CPPUNIT_ASSERT_DOUBLES_EQUAL(theField_1->getTime(), theField_2->getTime(), 0.0000001);
249
250   // Value
251   int nbOfValues = theField_1->getNumberOfValues();
252   CPPUNIT_ASSERT_EQUAL(nbOfValues, theField_2->getNumberOfValues());
253
254   if (isFIELD) {
255     // Value type and Interlacing type
256     CPPUNIT_ASSERT_EQUAL(theField_1->getValueType(), theField_2->getValueType());
257     CPPUNIT_ASSERT_EQUAL(theField_1->getInterlacingType(), theField_2->getInterlacingType());
258
259     // Gauss Presence
260     if (isValue) {
261       CPPUNIT_ASSERT_EQUAL(theField_1->getGaussPresence(), theField_2->getGaussPresence());
262     }
263     else {
264       CPPUNIT_ASSERT_THROW(theField_1->getGaussPresence(), MEDEXCEPTION);
265       CPPUNIT_ASSERT_THROW(theField_2->getGaussPresence(), MEDEXCEPTION);
266     }
267   }
268   else {
269     CPPUNIT_ASSERT_THROW(theField_1->getGaussPresence(), MEDEXCEPTION);
270     CPPUNIT_ASSERT_THROW(theField_2->getGaussPresence(), MEDEXCEPTION);
271   }
272 }
273
274 void checkField_(FIELD_ * theField_, const SUPPORT * theSupport,
275                  MED_EN::med_type_champ theValueType,
276                  MED_EN::medModeSwitch theInterlace)
277 {
278   // name
279   const string aFieldName = "a_name_of_a_field";
280   theField_->setName(aFieldName);
281   CPPUNIT_ASSERT_EQUAL(aFieldName, theField_->getName());
282
283   // description
284   const string aFieldDescr = "a_description_of_a_field";
285   theField_->setDescription(aFieldDescr);
286   CPPUNIT_ASSERT_EQUAL(aFieldDescr, theField_->getDescription());
287
288   // support
289   theField_->setSupport(theSupport);
290   CPPUNIT_ASSERT(theField_->getSupport() == theSupport);
291
292   // components information
293   int aNbComps = 3;
294
295   string aCompsNames[3] = {"Vx", "Vy", "Vz"};
296   string aCompsDescs[3] = {"vitesse selon x", "vitesse selon y", "vitesse selon z"};
297   string aCompsUnits[3] = {"m.s-1", "m.s-1", "m.s-1"};
298
299   theField_->setNumberOfComponents(aNbComps);
300   CPPUNIT_ASSERT_EQUAL(aNbComps, theField_->getNumberOfComponents());
301
302   theField_->setComponentsNames(aCompsNames);
303
304 #ifdef ENABLE_FAULTS
305   try {
306     theField_->setNumberOfComponents(7);
307     // Segmentation fault here because array of components names is not resized
308     for (int i = 1; i <= 7; i++) {
309       theField_->setComponentName(i, "AnyComponent");
310     }
311   }
312   catch (MEDEXCEPTION& ex) {
313     // Ok, it is good to have MEDEXCEPTION here
314   }
315   catch (...) {
316     CPPUNIT_FAIL("Unknown exception cought");
317   }
318   // restore components names
319   theField_->setNumberOfComponents(aNbComps);
320   theField_->setComponentsNames(aCompsNames);
321 #endif
322 #ifdef ENABLE_FORCED_FAILURES
323   CPPUNIT_FAIL("FIELD_::_componentsNames bad management");
324 #endif
325
326   theField_->setComponentsDescriptions(aCompsDescs);
327   theField_->setMEDComponentsUnits(aCompsUnits);
328
329   const string * aCompsNamesBack = theField_->getComponentsNames();
330   const string * aCompsDescsBack = theField_->getComponentsDescriptions();
331   const string * aCompsUnitsBack = theField_->getMEDComponentsUnits();
332   for (int i = 1; i <= aNbComps; i++) {
333     CPPUNIT_ASSERT_EQUAL(aCompsNamesBack[i-1], theField_->getComponentName(i));
334     CPPUNIT_ASSERT_EQUAL(aCompsNamesBack[i-1], aCompsNames[i-1]);
335
336     CPPUNIT_ASSERT_EQUAL(aCompsDescsBack[i-1], theField_->getComponentDescription(i));
337     CPPUNIT_ASSERT_EQUAL(aCompsDescsBack[i-1], aCompsDescs[i-1]);
338
339     CPPUNIT_ASSERT_EQUAL(aCompsUnitsBack[i-1], theField_->getMEDComponentUnit(i));
340     CPPUNIT_ASSERT_EQUAL(aCompsUnitsBack[i-1], aCompsUnits[i-1]);
341   }
342
343   const string aCompName2 ("Name of second component");
344   const string aCompDesc2 ("Description of second component");
345   const string aCompUnit2 ("Unit of second MED component");
346
347   theField_->setComponentName(2, aCompName2);
348   theField_->setComponentDescription(2, aCompDesc2);
349   theField_->setMEDComponentUnit(2, aCompUnit2);
350
351   const string * aCompsNamesBack2 = theField_->getComponentsNames();
352   const string * aCompsDescsBack2 = theField_->getComponentsDescriptions();
353   const string * aCompsUnitsBack2 = theField_->getMEDComponentsUnits();
354
355   CPPUNIT_ASSERT_EQUAL(aCompsNamesBack2[1], theField_->getComponentName(2));
356   CPPUNIT_ASSERT_EQUAL(aCompsNamesBack2[1], aCompName2);
357
358   CPPUNIT_ASSERT_EQUAL(aCompsDescsBack2[1], theField_->getComponentDescription(2));
359   CPPUNIT_ASSERT_EQUAL(aCompsDescsBack2[1], aCompDesc2);
360
361   CPPUNIT_ASSERT_EQUAL(aCompsUnitsBack2[1], theField_->getMEDComponentUnit(2));
362   CPPUNIT_ASSERT_EQUAL(aCompsUnitsBack2[1], aCompUnit2);
363
364 #ifdef ENABLE_FAULTS
365   // (BUG) No index checking
366   CPPUNIT_ASSERT_THROW(theField_->setComponentName(0, "str"), MEDEXCEPTION);
367   CPPUNIT_ASSERT_THROW(theField_->setComponentName(aNbComps + 1, "str"), MEDEXCEPTION);
368   CPPUNIT_ASSERT_THROW(theField_->setComponentDescription(0, "str"), MEDEXCEPTION);
369   CPPUNIT_ASSERT_THROW(theField_->setComponentDescription(aNbComps + 1, "str"), MEDEXCEPTION);
370   CPPUNIT_ASSERT_THROW(theField_->setMEDComponentUnit(0, "str"), MEDEXCEPTION);
371   CPPUNIT_ASSERT_THROW(theField_->setMEDComponentUnit(aNbComps + 1, "str"), MEDEXCEPTION);
372 #endif
373 #ifdef ENABLE_FORCED_FAILURES
374   CPPUNIT_FAIL("FIELD::setComponentXXX() does not check component index");
375 #endif
376
377   // iteration information
378   int anIterNumber = 10; // set value to MED_NOPDT if undefined (default)
379   theField_->setIterationNumber(anIterNumber);
380   CPPUNIT_ASSERT_EQUAL(anIterNumber, theField_->getIterationNumber());
381
382   int anOrderNumber = 1; // set value to MED_NONOR if undefined (default)
383   theField_->setOrderNumber(anOrderNumber);
384   CPPUNIT_ASSERT_EQUAL(anOrderNumber, theField_->getOrderNumber());
385
386   double aTime = 3.435678; // in second
387   theField_->setTime(aTime);
388   CPPUNIT_ASSERT_DOUBLES_EQUAL(aTime, theField_->getTime(), 0.0000001);
389
390   // Value
391   int nbOfValues = 10;
392   // dangerous method, because it does not reallocate values array
393   theField_->setNumberOfValues(nbOfValues);
394   CPPUNIT_ASSERT_EQUAL(nbOfValues, theField_->getNumberOfValues());
395
396   // Value type and Interlacing type
397   CPPUNIT_ASSERT_EQUAL(theValueType, theField_->getValueType());
398   CPPUNIT_ASSERT_EQUAL(theInterlace, theField_->getInterlacingType());
399 }
400
401 template<class T, class INTERLACING_TAG>
402 void compareField(const FIELD<T, INTERLACING_TAG> * theField_1,
403                   const FIELD<T, INTERLACING_TAG> * theField_2, bool isValue)
404 {
405   // compare FIELD_ part
406   compareField_(theField_1, theField_2, /*isFIELD = */true, isValue);
407
408   // compare FIELD part
409   // TO DO
410 }
411
412 template<class T, class INTERLACING_TAG>
413 void checkField (FIELD<T, INTERLACING_TAG> * theField, const SUPPORT * theSupport)
414 {
415   // check FIELD_ part
416   MED_EN::med_type_champ aValueType = SET_VALUE_TYPE<T>::_valueType;
417   MED_EN::medModeSwitch  anInterlace = SET_INTERLACING_TYPE<INTERLACING_TAG>::_interlacingType;
418   checkField_(theField, theSupport, aValueType, anInterlace);
419
420   // check FIELD part
421
422   // filling by support charackteristics (NOT IMPLEMENTED METHODS!!!):
423   // value type must be MED_REEL64 (i.e. a FIELD<double>) for these methods,
424   // nb. of components must be equal 1 (for Volume, Area, Length) or
425   // space dimension (for Normal, Barycenter, )
426   {
427     MESH* aMesh = theSupport->getMesh();
428     int spaceDim = 3;
429     if (aMesh) spaceDim = aMesh->getSpaceDimension();
430     theField->deallocValue();
431     theField->allocValue(/*NumberOfComponents = */spaceDim + 1);
432
433     CPPUNIT_ASSERT_THROW(theField->getVolume(), MEDEXCEPTION);
434     CPPUNIT_ASSERT_THROW(theField->getArea(), MEDEXCEPTION);
435     CPPUNIT_ASSERT_THROW(theField->getLength(), MEDEXCEPTION);
436     if (aMesh) {
437       CPPUNIT_ASSERT_THROW(theField->getNormal(), MEDEXCEPTION);
438       CPPUNIT_ASSERT_THROW(theField->getBarycenter(), MEDEXCEPTION);
439     }
440
441     theField->deallocValue();
442     theField->allocValue(/*NumberOfComponents = */1);
443     if (aValueType == MED_EN::MED_REEL64) {
444       CPPUNIT_ASSERT_NO_THROW(theField->getVolume());
445       CPPUNIT_ASSERT_NO_THROW(theField->getArea());
446       CPPUNIT_ASSERT_NO_THROW(theField->getLength());
447     }
448     else {
449       CPPUNIT_ASSERT_THROW(theField->getVolume(), MEDEXCEPTION);
450       CPPUNIT_ASSERT_THROW(theField->getArea(), MEDEXCEPTION);
451       CPPUNIT_ASSERT_THROW(theField->getLength(), MEDEXCEPTION);
452     }
453
454     if (aMesh) {
455       theField->deallocValue();
456       theField->allocValue(/*NumberOfComponents = */spaceDim);
457       if (aValueType == MED_EN::MED_REEL64) {
458         CPPUNIT_ASSERT_NO_THROW(theField->getNormal());
459         CPPUNIT_ASSERT_NO_THROW(theField->getBarycenter());
460       }
461       else {
462         CPPUNIT_ASSERT_THROW(theField->getNormal(), MEDEXCEPTION);
463         CPPUNIT_ASSERT_THROW(theField->getBarycenter(), MEDEXCEPTION);
464       }
465     }
466   }
467
468   // values
469   theField->deallocValue();
470   theField->allocValue(/*NumberOfComponents = */2);
471   int nbElemSupport = theSupport->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS);
472   CPPUNIT_ASSERT_EQUAL(nbElemSupport, theField->getNumberOfValues());
473
474 #ifdef ENABLE_FAULTS
475   // (BUG) FIELD::deallocValue() does not nullify _value pointer,
476   // that is why there can be failures in other methods
477   // (even if simply call deallocValue() two times)
478   theField->deallocValue();
479   theField->getGaussPresence();
480 #endif
481 #ifdef ENABLE_FORCED_FAILURES
482   CPPUNIT_FAIL("FIELD::deallocValue() does not nullify _value pointer");
483 #endif
484
485   // copy constructor
486   FIELD<T, INTERLACING_TAG> aField_copy1 (*theField);
487   //compareField(theField, &aField_copy1, /*isValue = */false);
488   compareField(theField, &aField_copy1, /*isValue = */true);
489
490   // operator=
491 #ifdef ENABLE_FAULTS
492   // (BUG) This fails (Segmentation fault) if not set:
493   // _componentsNames or _componentsDescriptions, or _componentsUnits, or _MEDComponentsUnits
494   FIELD<T, INTERLACING_TAG> aField_copy2;
495   aField_copy2 = *theField;
496   //compareField(theField, &aField_copy2, /*isValue = */false);
497   compareField(theField, &aField_copy2, /*isValue = */true);
498 #endif
499 #ifdef ENABLE_FORCED_FAILURES
500   CPPUNIT_FAIL("FIELD_::operator=() fails if _componentsUnits is not set");
501 #endif
502 }
503
504 template<class T>
505 FIELD<T> * createFieldOnGroup(MESH* theMesh, const GROUP* theGroup,
506                               const string theName, const string theDescr)
507 {
508   FIELD<T> * aFieldOnGroup = new FIELD<T> (theGroup, /*NumberOfComponents = */2);
509
510   aFieldOnGroup->setName(theName);
511   aFieldOnGroup->setDescription(theDescr);
512
513   string aCompsNames[2] = {"Pos", "Neg"};
514   string aCompsDescs[2] = {"+", "-"};
515   string aCompsUnits[2] = {"unit1", "unit2"};
516
517   aFieldOnGroup->setComponentsNames(aCompsNames);
518   aFieldOnGroup->setComponentsDescriptions(aCompsDescs);
519   aFieldOnGroup->setMEDComponentsUnits(aCompsUnits);
520
521   return aFieldOnGroup;
522 }
523
524 double plus13 (double val)
525 {
526   return val + 13;
527 }
528
529 // function to calculate field values from coordinates of an element
530 // typedef void (*myFuncType)(const double * temp, T* output);
531 // size of temp array = space dim = 3
532 // size of output array = nb. comps = 2
533 void proj2d (const double * temp, double* output)
534 {
535   // dimetric projection with coefficients:
536   // 1.0 along Oy and Oz, 0.5 along Ox
537   //
538   //    ^ z (y_)
539   //    |
540   //    |
541   //    .----> y (x_)
542   //   /
543   //  L x
544   //
545   // x_ = y - x * sqrt(2.) / 4.
546   // y_ = z - x * sqrt(2.) / 4.
547
548   double dx = temp[0] * std::sqrt(2.) / 4.;
549   output[0] = temp[1] - dx;
550   output[1] = temp[2] - dx;
551 }
552
553 void testDrivers()
554 {
555   string data_dir                     = getenv("DATA_DIR");
556   string tmp_dir                      = getenv("TMP");
557   if (tmp_dir == "")
558     tmp_dir = "/tmp";
559
560   string filename_rd                  = data_dir + "/MedFiles/pointe.med";
561   string filename_wr                  = tmp_dir  + "/myMedFieldfile.med";
562   string filename_support_wr          = tmp_dir  + "/myMedSupportFiledfile.med";
563   string filename22_rd                = data_dir + "/MedFiles/pointe_import22.med";
564   string filenamevtk_wr                = tmp_dir  + "/myMedFieldfile22.vtk";
565   string cp_file                      = "cp " + filename_rd + " " + filename_wr;
566
567   string fieldname_celldouble_rd      = "fieldcelldouble";
568   string fieldname_celldouble_wr      = fieldname_celldouble_rd + "_cpy";
569   string fieldname_nodeint_rd         = "fieldnodeint";
570   string fieldname_nodeint_wr         = fieldname_nodeint_rd + "_cpy";
571   string fieldname_nodeint_wr1        = fieldname_nodeint_rd + "_cpy1";
572   string meshname                     = "maa1";
573
574   // To remove tmp files from disk
575   MEDMEMTest_TmpFilesRemover aRemover;
576   aRemover.Register(filename_wr);
577   aRemover.Register(filenamevtk_wr);
578   aRemover.Register(filename_support_wr);
579
580   //Copy file
581   system(cp_file.c_str());
582
583   FIELD<int> aInvalidField;
584   //must throw becase only VTK_DRIVER or MED_DRIVER may be specified as driverType for FIELD
585   CPPUNIT_ASSERT_THROW(aInvalidField = FIELD<int>(NO_DRIVER, filename_rd, fieldname_nodeint_rd),
586                        MEDEXCEPTION);
587   CPPUNIT_ASSERT_THROW(aInvalidField = FIELD<int>(GIBI_DRIVER, filename_rd, fieldname_nodeint_rd),
588                        MEDEXCEPTION);
589   CPPUNIT_ASSERT_THROW(aInvalidField = FIELD<int>(PORFLOW_DRIVER, filename_rd, fieldname_nodeint_rd),
590                        MEDEXCEPTION);
591   CPPUNIT_ASSERT_THROW(aInvalidField = FIELD<int>(ASCII_DRIVER, filename_rd, fieldname_nodeint_rd),
592                        MEDEXCEPTION);
593
594   //////////////////
595   //TestRead Part//
596   //////////////////
597   FIELD<double> *aField_1 = NULL;
598   CPPUNIT_ASSERT_NO_THROW(aField_1 = new FIELD<double>(MED_DRIVER, filename_rd, fieldname_celldouble_rd));
599
600   //Test read(int index) method
601   int IdDriver_rd = aField_1->addDriver(MED_DRIVER,filename_rd,fieldname_celldouble_rd);
602 #ifdef ENABLE_FORCED_FAILURES
603   // (BUG) Cannot open file, but file exist
604   CPPUNIT_ASSERT_NO_THROW(aField_1->read(IdDriver_rd));
605 #endif
606
607   //Test read(GENDRIVER & genDriver) method
608   //Creation a Driver
609   MED_FIELD_RDONLY_DRIVER21<int> *aMedRdFieldDriver21_1 =
610     new MED_FIELD_RDONLY_DRIVER21<int>();
611   //Creation a Field
612   FIELD<int> *aField_2 = new FIELD<int>();
613   aField_2->setName(fieldname_nodeint_rd);
614   aField_2->addDriver(*aMedRdFieldDriver21_1);
615   aField_2->read(*aMedRdFieldDriver21_1);
616
617   ///////////////////
618   //Test Write Part//
619   ///////////////////
620   int IdDriver;
621   MESH *aMesh = new MESH(MED_DRIVER,filename_rd,meshname);
622   SUPPORT *aSupport = new SUPPORT(aMesh, "aSupport",MED_CELL);
623   FIELD<int> *aFieldSupport;
624 #ifdef ENABLE_FORCED_FAILURES  
625   CPPUNIT_ASSERT_NO_THROW(aFieldSupport = 
626                           new FIELD<int>(aSupport, MED_DRIVER,filename_support_wr,fieldname_nodeint_rd));
627   //(BUG) Can not open file
628   MED_FIELD_WRONLY_DRIVER21<int> * aFieldWrDriver21 = 
629     new MED_FIELD_WRONLY_DRIVER21<int>(filename_support_wr,aFieldSupport);
630   aFieldWrDriver21->setFieldName(aFieldSupport->getName() + "_copy");
631   CPPUNIT_ASSERT_NO_THROW(IdDriver= aFieldSupport->addDriver(*aFieldWrDriver21));
632   CPPUNIT_ASSERT_NO_THROW(aFieldSupport->write(IdDriver));
633   delete aFieldSupport;
634   delete aFieldWrDriver21;
635 #endif    
636
637   //Create fileds
638   FIELD<double> * aField_3 = new FIELD<double>();
639   MED_FIELD_RDONLY_DRIVER21<double> *aMedRdFieldDriver21_2 =
640     new MED_FIELD_RDONLY_DRIVER21<double>(filename_rd, aField_3);
641   aMedRdFieldDriver21_2->open();
642   aMedRdFieldDriver21_2->setFieldName(fieldname_celldouble_rd);
643   aMedRdFieldDriver21_2->read();
644   aMedRdFieldDriver21_2->close();
645
646   //Test write(int index) method
647   //Add drivers to FIELDs
648   int IdDriver1 = -1;
649   try
650   {
651     IdDriver1 = aField_3->addDriver(MED_DRIVER,filename_wr,fieldname_celldouble_wr);
652   }
653   catch(MEDEXCEPTION &e)
654   {
655     e.what();
656   }
657   catch( ... )
658   {
659     CPPUNIT_FAIL("Unknown exception");
660   }
661   //Trying call write(int index) method with incorrect index
662 #ifdef ENABLE_FAULTS
663   CPPUNIT_ASSERT_THROW(aField_3->write(IdDriver1+1, fieldname_celldouble_wr),MEDEXCEPTION);
664   // => Segmentation fault
665 #endif
666
667   //Write field to file
668 #ifdef ENABLE_FAULTS
669   try
670   {
671     aField_3->write(IdDriver1, fieldname_celldouble_wr);
672     // => Segmentation fault
673   }
674   catch(MEDEXCEPTION &e)
675   {
676     e.what();
677   }
678   catch( ... )
679   {
680     CPPUNIT_FAIL("Unknown exception");
681   }
682 #endif
683
684   CPPUNIT_ASSERT_NO_THROW(aField_3->rmDriver(IdDriver1));
685
686   //Test write(const GENDRIVER &);
687   //Create a driver
688   MED_FIELD_WRONLY_DRIVER21<int> *aMedWrFieldDriver21 =
689     new MED_FIELD_WRONLY_DRIVER21<int>();
690   aMedWrFieldDriver21->setFileName(filename_wr);
691   aField_2->setName(fieldname_nodeint_wr1);
692   //Add driver to a field
693   aField_2->addDriver(*aMedWrFieldDriver21);
694
695   try
696   {
697   aField_2->write(*aMedWrFieldDriver21);
698   }
699   catch(MEDEXCEPTION &e)
700   {
701     e.what();
702   }
703   catch( ... )
704   {
705     CPPUNIT_FAIL("Unknown exception");
706   }
707
708   //Test writeAppend(int index) method
709   //Create a vtk file
710   MESH * aMesh_1 = new MESH();
711   MED_MESH_RDONLY_DRIVER22 *aMedMeshRdDriver22 = new MED_MESH_RDONLY_DRIVER22(filename22_rd, aMesh_1);
712   aMedMeshRdDriver22->open();
713   aMedMeshRdDriver22->setMeshName(meshname);
714   aMedMeshRdDriver22->read();
715   aMedMeshRdDriver22->close();
716   VTK_MESH_DRIVER *aVtkDriver = new VTK_MESH_DRIVER(filenamevtk_wr, aMesh_1);
717   aVtkDriver->open();
718   aVtkDriver->write();
719   aVtkDriver->close();
720
721   //Create a field
722   FIELD<int> * aField_4 = new FIELD<int>();
723   MED_FIELD_RDONLY_DRIVER22<int> *aMedRdFieldDriver22 =
724     new MED_FIELD_RDONLY_DRIVER22<int>(filename22_rd, aField_2);
725   aMedRdFieldDriver22->open();
726   aMedRdFieldDriver22->setFieldName(fieldname_nodeint_rd);
727   aMedRdFieldDriver22->read();
728   aMedRdFieldDriver22->close();
729
730   //Add Driver to a field
731   int IdDriver2;
732   try
733   {
734     IdDriver2 = aField_4->addDriver(VTK_DRIVER, filenamevtk_wr ,fieldname_nodeint_wr);
735   }
736   catch(MEDEXCEPTION &e)
737   {
738     e.what();
739   }
740   catch( ... )
741   {
742     CPPUNIT_FAIL("Unknown exception");
743   }
744 #ifdef ENABLE_FAULTS
745   //Trying call writeAppend() method with incorrect index
746   CPPUNIT_ASSERT_THROW(aField_4->writeAppend(IdDriver2+1,fieldname_nodeint_wr),MEDEXCEPTION);
747   // => Segmentation fault
748 #endif
749
750 #ifdef ENABLE_FAULTS
751   // (BUG) => Segmentation fault
752   CPPUNIT_ASSERT_NO_THROW(aField_4->writeAppend(IdDriver2, fieldname_nodeint_wr));
753 #endif
754   
755   //Test writeAppend(const GENDRIVER &) method
756   aField_4->setName(fieldname_nodeint_wr1);
757  
758   //Add driver to a field
759 #ifdef ENABLE_FAULTS
760   //Create a driver
761   VTK_FIELD_DRIVER<int> *aVtkFieldDriver = new VTK_FIELD_DRIVER<int>(filenamevtk_wr, aField_4);
762   CPPUNIT_ASSERT_NO_THROW(aField_4->addDriver(*aVtkFieldDriver));
763   //(BUG) => Segmentation fault after addDriver(const GENDRIVER &)
764   CPPUNIT_ASSERT_NO_THROW(aField_4->writeAppend(*aVtkFieldDriver));
765 #endif
766
767
768   //Delete objects
769   delete aField_1;
770   delete aMedRdFieldDriver21_1;
771   delete aField_2;
772   delete aField_3;
773   delete aMedRdFieldDriver21_2;
774   delete aField_4;
775   delete aMedMeshRdDriver22;
776   delete aMedWrFieldDriver21;
777   delete aVtkDriver;
778   delete aMesh;
779   delete aMesh_1;
780   delete aMedRdFieldDriver22;
781   delete aSupport;
782 }
783
784 void MEDMEMTest::testField()
785 {
786   SUPPORT anEmptySupport;
787   ////////////////////
788   // TEST 1: FIELD_ //
789   ////////////////////
790   FIELD_ aField_;
791
792   // check set/get methods
793   MED_EN::med_type_champ aValueType = MED_EN::MED_UNDEFINED_TYPE;
794   MED_EN::medModeSwitch  anInterlace = MED_EN::MED_UNDEFINED_INTERLACE;
795   checkField_(&aField_, &anEmptySupport, aValueType, anInterlace);
796
797   // copy constructor
798   // This fails (Segmentation fault) if not set:
799   // _componentsNames or _componentsDescriptions, or _MEDComponentsUnits
800   FIELD_ aField_copy1 (aField_);
801   compareField_(&aField_, &aField_copy1, /*isFIELD = */false, /*isValue = */false);
802
803   // operator=
804 #ifdef ENABLE_FAULTS
805   // (BUG) This fails (Segmentation fault) if not set:
806   // _componentsNames or _componentsDescriptions, or _componentsUnits, or _MEDComponentsUnits
807   // (BUG) Code duplication with copyGlobalInfo(), called from copy constructor
808   FIELD_ aField_copy2;
809   aField_copy2 = aField_;
810   compareField_(&aField_, &aField_copy2, /*isFIELD = */false, /*isValue = */false);
811 #endif
812 #ifdef ENABLE_FORCED_FAILURES
813   CPPUNIT_FAIL("FIELD_::operator=() fails if _componentsUnits is not set");
814 #endif
815
816   // construction on a given support
817   {
818     anEmptySupport.setTotalNumberOfElements(11);
819     // CASE1:
820     FIELD_ aField_case1 (&anEmptySupport, 10);
821     // CASE2:
822     FIELD_ aField_case2;
823     aField_case2.setSupport(&anEmptySupport);
824     aField_case2.setNumberOfComponents(10);
825
826 #ifdef ENABLE_FORCED_FAILURES
827     CPPUNIT_ASSERT_EQUAL_MESSAGE("No correspondance between CASE1 and CASE2",
828                                  aField_case1.getNumberOfValues(),
829                                  aField_case2.getNumberOfValues());
830 #endif
831   }
832
833   ////////////////////////
834   // TEST 2: FIELD<int> //
835   ////////////////////////
836   FIELD<int> aFieldInt;
837   checkField(&aFieldInt, &anEmptySupport);
838
839   ////////////////////////////////////////
840   // TEST 3: FIELD<double, NoInterlace> //
841   ////////////////////////////////////////
842   MESH * aMesh = MEDMEMTest_createTestMesh();
843   const GROUP* aGroup = aMesh->getGroup(MED_EN::MED_FACE, 1);
844
845   FIELD<double, NoInterlace> aFieldDouble;
846   checkField(&aFieldDouble, aGroup);
847
848   //////////////////////////////////////////
849   // TEST 4: FIELD<double, FullInterlace> //
850   //////////////////////////////////////////
851   FIELD<double> * aFieldOnGroup1 = createFieldOnGroup<double>(aMesh, aGroup, "Linear", "N");
852   FIELD<double> * aFieldOnGroup2 = createFieldOnGroup<double>(aMesh, aGroup, "Quadratic", "N**2");
853
854   int nbVals = aFieldOnGroup1->getNumberOfValues();
855   CPPUNIT_ASSERT(nbVals);
856
857   // numbers of elements in group,
858   // they are needed in method FIELD::setValueIJ()
859   const int *anElems = aGroup->getnumber()->getValue();
860   double eucl1 = 0., eucl2 = 0.;
861
862   for (int i = 1; i <= nbVals; i++) {
863     aFieldOnGroup1->setValueIJ(anElems[i-1], 1, (double)i);
864     aFieldOnGroup1->setValueIJ(anElems[i-1], 2, (double)(-i));
865
866     aFieldOnGroup2->setValueIJ(anElems[i-1], 1, (double)i*i);
867     aFieldOnGroup2->setValueIJ(anElems[i-1], 2, (double)(-i*i));
868
869     eucl1 += 2. * i * i;
870     eucl2 += 2. * i * i * i * i;
871   }
872
873   // out of bound (inexisting 33-th component of last element)
874   CPPUNIT_ASSERT_THROW(aFieldOnGroup1->setValueIJ(anElems[nbVals-1], 33, 10.), MEDEXCEPTION);
875
876   // normMax
877   CPPUNIT_ASSERT_DOUBLES_EQUAL(nbVals, aFieldOnGroup1->normMax(), 0.000001);
878   CPPUNIT_ASSERT_DOUBLES_EQUAL(nbVals*nbVals, aFieldOnGroup2->normMax(), 0.000001);
879
880   // norm2
881   CPPUNIT_ASSERT_DOUBLES_EQUAL(std::sqrt(eucl1), aFieldOnGroup1->norm2(), 0.000001); // 10.4881
882   CPPUNIT_ASSERT_DOUBLES_EQUAL(std::sqrt(eucl2), aFieldOnGroup2->norm2(), 0.000001); // 44.2493
883
884   // check getXXX methods
885   CPPUNIT_ASSERT(!aFieldOnGroup1->getGaussPresence());
886   CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getArrayGauss(), MEDEXCEPTION);
887   MEDMEM_ArrayInterface<double, FullInterlace,NoGauss>::Array * anArrayNoGauss =
888     aFieldOnGroup1->getArrayNoGauss();
889
890   MEDMEM_Array_ * aMEDMEM_Array_ = aFieldOnGroup1->getArray();
891   MEDMEM_ArrayInterface<double, FullInterlace,NoGauss>::Array * aMEDMEM_Array_conv =
892     static_cast<MEDMEM_ArrayInterface<double, FullInterlace,NoGauss>::Array *>(aMEDMEM_Array_);
893
894   const double * aValues = aFieldOnGroup1->getValue();
895
896   // out of range
897   CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getColumn(3), MEDEXCEPTION);
898   // cannot get column in FullInterlace
899   CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getColumn(1), MEDEXCEPTION);
900
901   for (int i = 1; i <= nbVals; i++) {
902     CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i   , aFieldOnGroup1->getValueIJK(anElems[i-1], 1, 1), 0.000001);
903     CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), aFieldOnGroup1->getValueIJK(anElems[i-1], 2, 1), 0.000001);
904
905     CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i   , aValues[(i-1)*2 + 0], 0.000001);
906     CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), aValues[(i-1)*2 + 1], 0.000001);
907
908     CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i   , anArrayNoGauss->getIJ(i, 1), 0.000001);
909     CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), anArrayNoGauss->getIJ(i, 2), 0.000001);
910
911     CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i   , aMEDMEM_Array_conv->getIJ(i, 1), 0.000001);
912     CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), aMEDMEM_Array_conv->getIJ(i, 2), 0.000001);
913
914     const double* row_i = aFieldOnGroup1->getRow(anElems[i-1]);
915     CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i   , row_i[0], 0.000001);
916     CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), row_i[1], 0.000001);
917
918     double vals_i [2];
919     aFieldOnGroup1->getValueOnElement(anElems[i-1], vals_i);
920     CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i   , vals_i[0], 0.000001);
921     CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), vals_i[1], 0.000001);
922   }
923
924   // modify all values of aFieldOnGroup2 by formula a*x + b (a = 2, b = 3)
925   aFieldOnGroup2->applyLin(2., 3.);
926   for (int i = 1; i <= nbVals; i++) {
927     CPPUNIT_ASSERT_DOUBLES_EQUAL(3. + 2.*i*i, aFieldOnGroup2->getValueIJ(anElems[i-1], 1), 0.000001);
928     CPPUNIT_ASSERT_DOUBLES_EQUAL(3. - 2.*i*i, aFieldOnGroup2->getValueIJ(anElems[i-1], 2), 0.000001);
929   }
930
931   // apply function plus13() to aFieldOnGroup1
932   aFieldOnGroup1->applyFunc<plus13>();
933   for (int i = 1; i <= nbVals; i++) {
934     CPPUNIT_ASSERT_DOUBLES_EQUAL(13 + i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001);
935     CPPUNIT_ASSERT_DOUBLES_EQUAL(13 - i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001);
936   }
937
938   // scalarProduct
939   FIELD<double, FullInterlace> * aScalarProduct =
940     FIELD<double, FullInterlace>::scalarProduct(*aFieldOnGroup1, *aFieldOnGroup2, /*deepCheck = */true);
941   CPPUNIT_ASSERT_EQUAL(nbVals, aScalarProduct->getNumberOfValues());
942   CPPUNIT_ASSERT_EQUAL(1, aScalarProduct->getNumberOfComponents());
943   for (int i = 1; i <= nbVals; i++) {
944     CPPUNIT_ASSERT_DOUBLES_EQUAL(78. + 4.*i*i*i, //(3. + 2.*i*i)*(13 + i) + (3. - 2.*i*i)*(13 - i)
945                                  aScalarProduct->getValueIJ(anElems[i-1], 1), 0.000001);
946   }
947
948   // fillFromAnalytic
949   aFieldOnGroup2->fillFromAnalytic(proj2d);
950
951   double bary [3];
952   double outp [2];
953   const SUPPORT * aSupp = aFieldOnGroup2->getSupport();
954   FIELD<double,FullInterlace> * barycenter = aMesh->getBarycenter(aSupp);
955   for (int i = 1; i <= nbVals; i++) {
956     bary[0] = barycenter->getValueIJ(anElems[i-1], 1);
957     bary[1] = barycenter->getValueIJ(anElems[i-1], 2);
958     bary[2] = barycenter->getValueIJ(anElems[i-1], 3);
959
960     proj2d(bary, outp);
961
962     //cout << "barycenter (" << bary[0] << ", " << bary[1] << ", " << bary[2] << ")" << endl;
963     //cout << "proj2d     (" << outp[0] << ", " << outp[1] << ")" << endl;
964
965     //bary (-0.666667,  0.666667, 0.666667) -> outp ( 0.902369, 0.902369)
966     //bary ( 0.666667, -0.666667, 0.666667) -> outp (-0.902369, 0.430964)
967     //bary ( 0.      ,  0.      , 2.      ) -> outp ( 0.      , 2.      )
968     //bary ( 0.      ,  0.      , 3.      ) -> outp ( 0.      , 3.      )
969     //bary (-1.      ,  0.      , 2.5     ) -> outp ( 0.353553, 2.85355 )
970
971 #ifdef ENABLE_FORCED_FAILURES
972     // (BUG) in FIELD::fillFromAnalytic() in case of support, different from nodes:
973     //       barycenterField in FullInterlace, but values extracted like from NoInterlace
974     CPPUNIT_ASSERT_DOUBLES_EQUAL(outp[0], aFieldOnGroup2->getValueIJ(anElems[i-1], 1), 0.000001);
975     CPPUNIT_ASSERT_DOUBLES_EQUAL(outp[1], aFieldOnGroup2->getValueIJ(anElems[i-1], 2), 0.000001);
976 #endif
977
978     // currently it gives values, that are wrong:
979     //aFieldOnGroup2 row1 ( 0.902369,  0.235702)
980     //aFieldOnGroup2 row2 (-0.235702,  2.7643  )
981     //aFieldOnGroup2 row3 (-0.235702, -1.2357  )
982     //aFieldOnGroup2 row4 ( 1.7643  , -0.235702)
983     //aFieldOnGroup2 row5 ( 0.235702,  2.7357  )
984   }
985
986   // info about support (Group1)
987   CPPUNIT_ASSERT(!aFieldOnGroup1->isOnAllElements()); // because we build Group1 so
988   int nbTypes = aFieldOnGroup1->getNumberOfGeometricTypes();
989   //CPPUNIT_ASSERT(nbTypes);
990   CPPUNIT_ASSERT_EQUAL(2, nbTypes);
991   const int * nbElemsInEachType = aFieldOnGroup1->getNumberOfElements();
992   const MED_EN::medGeometryElement * aGeomTypes = aFieldOnGroup1->getGeometricTypes();
993
994   CPPUNIT_ASSERT_EQUAL(MED_EN::MED_TRIA3, aGeomTypes[0]);
995   CPPUNIT_ASSERT_EQUAL(MED_EN::MED_QUAD4, aGeomTypes[1]);
996
997   // GAUSS
998
999   // now we have no gauss localization in aFieldOnGroup1
1000   CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_TRIA3));
1001   CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_QUAD4));
1002   CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_TRIA6), MEDEXCEPTION);
1003   CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getNumberOfGaussPoints(), MEDEXCEPTION);
1004
1005   CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getGaussLocalization(MED_EN::MED_TRIA3), MEDEXCEPTION);
1006   CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getGaussLocalizationPtr(MED_EN::MED_TRIA3), MEDEXCEPTION);
1007
1008   CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNbGaussI(anElems[0]));
1009
1010   // set a gauss localization into aFieldOnGroup1
1011   double cooRef[6] = {1.,1., 2.,4., 3.,9.}; // xy xy xy
1012   double cooGauss[10] = {7.,7., 6.,6., 5.,5., 4.,3., 2.,1.}; // x1,y1  x2,y2  x3,y3  x4,y4  x5,y5
1013   double wg[5] = {1., 2., 3., 4., 5.};
1014   GAUSS_LOCALIZATION<> gl1 ("GL1", MED_EN::MED_TRIA3, /*nGauss*/5, cooRef, cooGauss, wg);
1015
1016   aFieldOnGroup1->setGaussLocalization(MED_EN::MED_TRIA3, gl1);
1017
1018   // now we have a gauss localization for MED_TRIA3 type
1019   CPPUNIT_ASSERT_EQUAL(5, aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_TRIA3));
1020   CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_QUAD4));
1021   CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_TRIA6), MEDEXCEPTION);
1022   CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getNumberOfGaussPoints(), MEDEXCEPTION);
1023
1024   CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getGaussLocalization(MED_EN::MED_QUAD4), MEDEXCEPTION);
1025   CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getGaussLocalizationPtr(MED_EN::MED_QUAD4), MEDEXCEPTION);
1026
1027   GAUSS_LOCALIZATION<> gl1Back = aFieldOnGroup1->getGaussLocalization(MED_EN::MED_TRIA3);
1028   const GAUSS_LOCALIZATION<> * gl1BackPtr = aFieldOnGroup1->getGaussLocalizationPtr(MED_EN::MED_TRIA3);
1029
1030   CPPUNIT_ASSERT(gl1 == gl1Back);
1031   CPPUNIT_ASSERT(gl1 == *gl1BackPtr);
1032
1033   CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNbGaussI(anElems[0]));
1034
1035   // sub-support of Group1 on one (first) geometric type
1036   SUPPORT * aSubSupport1 = new SUPPORT(aMesh, "Sub-Support 1 of Group1", MED_EN::MED_FACE);
1037   aSubSupport1->setAll(false);
1038
1039   int nbTypes1 = 1;
1040   int nbElemsInEachType1[1];
1041   nbElemsInEachType1[0] = nbElemsInEachType[0];
1042   int nbElems1 = nbElemsInEachType1[0];
1043   MED_EN::medGeometryElement aGeomTypes1[1];
1044   aGeomTypes1[0] = aGeomTypes[0];
1045   int * anElems1 = new int[nbElems1];
1046   for (int i = 0; i < nbElems1; i++) {
1047     anElems1[i] = anElems[i];
1048   }
1049
1050   aSubSupport1->setpartial("Support for sub-field 1 on one type of elements",
1051                            nbTypes1, nbElems1, aGeomTypes1, nbElemsInEachType1, anElems1);
1052
1053   //cout << "aSubSupport1:" << endl;
1054   //cout << *aSubSupport1 << endl;
1055
1056   // extract sub-field on aSubSupport1
1057   FIELD<double, FullInterlace> * aSubField1 = aFieldOnGroup1->extract(aSubSupport1);
1058   CPPUNIT_ASSERT_EQUAL(nbElems1 * /*NumberOfComponents = */2, aSubField1->getValueLength());
1059
1060   // aSubField1:
1061   // elt\comp |  1 |  2
1062   //--------------------
1063   //  1       | 14 | 12
1064   //  2       | 15 | 11
1065
1066   // check normL2() and normL1()
1067   FIELD<double>* anAreaField = aMesh->getArea(aSubSupport1);
1068   double area1 = anAreaField->getValueIJ(anElems1[0], 1);
1069   double area2 = anAreaField->getValueIJ(anElems1[1], 1);
1070   CPPUNIT_ASSERT_DOUBLES_EQUAL(2.44949, area1, 0.00001);
1071   CPPUNIT_ASSERT_DOUBLES_EQUAL(2.44949, area2, 0.00001);
1072
1073   CPPUNIT_ASSERT_DOUBLES_EQUAL(210.5, aSubField1->normL2(1), 0.00001); // (14*14 + 15*15)/2
1074 #ifdef ENABLE_FORCED_FAILURES
1075   // (BUG) FIELD::normL2(int component, const FIELD * p_field_volume):
1076   //       component is not taken into account
1077   CPPUNIT_ASSERT_DOUBLES_EQUAL(132.5, aSubField1->normL2(2), 0.00001); // (12*12 + 11*11)/2
1078 #endif
1079   CPPUNIT_ASSERT_DOUBLES_EQUAL(343.0, aSubField1->normL2() , 0.00001); // 210.5 + 132.5
1080
1081   CPPUNIT_ASSERT_DOUBLES_EQUAL(14.5, aSubField1->normL1(1), 0.00001); // (14 + 15)/2
1082   CPPUNIT_ASSERT_DOUBLES_EQUAL(11.5, aSubField1->normL1(2), 0.00001); // (12 + 11)/2
1083   CPPUNIT_ASSERT_DOUBLES_EQUAL(26.0, aSubField1->normL1() , 0.00001); // 14.5 + 11.5
1084
1085   double aNewArea [2] = {1., 0.}; // only first element will be taken into account
1086   anAreaField->setValue(aNewArea);
1087
1088   CPPUNIT_ASSERT_DOUBLES_EQUAL(196.0, aSubField1->normL2(1, anAreaField), 0.00001); // 14*14/1
1089 #ifdef ENABLE_FORCED_FAILURES
1090   // (BUG) FIELD::normL2(int component, const FIELD * p_field_volume):
1091   //       component is not taken into account
1092   CPPUNIT_ASSERT_DOUBLES_EQUAL(144.0, aSubField1->normL2(2, anAreaField), 0.00001); // 12*12/1
1093 #endif
1094   CPPUNIT_ASSERT_DOUBLES_EQUAL(340.0, aSubField1->normL2(anAreaField) , 0.00001); // 196 + 144
1095
1096   CPPUNIT_ASSERT_DOUBLES_EQUAL(14.0, aSubField1->normL1(1, anAreaField), 0.00001); // 14/1
1097   CPPUNIT_ASSERT_DOUBLES_EQUAL(12.0, aSubField1->normL1(2, anAreaField), 0.00001); // 12/1
1098   CPPUNIT_ASSERT_DOUBLES_EQUAL(26.0, aSubField1->normL1(anAreaField) , 0.00001); // 14 + 12
1099
1100   // applyPow
1101   aSubField1->applyPow(2.);
1102   CPPUNIT_ASSERT_DOUBLES_EQUAL(196., aSubField1->getValueIJ(anElems1[0], 1), 0.000001); // 14*14
1103   CPPUNIT_ASSERT_DOUBLES_EQUAL(144., aSubField1->getValueIJ(anElems1[0], 2), 0.000001); // 12*12
1104   CPPUNIT_ASSERT_DOUBLES_EQUAL(225., aSubField1->getValueIJ(anElems1[1], 1), 0.000001); // 15*15
1105   CPPUNIT_ASSERT_DOUBLES_EQUAL(121., aSubField1->getValueIJ(anElems1[1], 2), 0.000001); // 11*11
1106
1107   // setArray (NoGauss)
1108   MEDMEM_ArrayInterface<double,FullInterlace,NoGauss>::Array * aNewArrayNoGauss =
1109     new MEDMEM_ArrayInterface<double,FullInterlace,NoGauss>::Array(/*dim*/2, /*nbelem*/2);
1110   aNewArrayNoGauss->setIJ(1, 1, 4.);
1111   aNewArrayNoGauss->setIJ(1, 2, 2.);
1112   aNewArrayNoGauss->setIJ(2, 1, 5.);
1113   aNewArrayNoGauss->setIJ(2, 2, 1.);
1114   aSubField1->setArray(aNewArrayNoGauss);
1115   // no need to delete aNewArrayNoGauss, because it will be deleted
1116   // in destructor or in deallocValue() method of aSubField1
1117
1118   CPPUNIT_ASSERT_DOUBLES_EQUAL(4., aSubField1->getValueIJ(anElems1[0], 1), 0.000001);
1119   CPPUNIT_ASSERT_DOUBLES_EQUAL(2., aSubField1->getValueIJ(anElems1[0], 2), 0.000001);
1120   CPPUNIT_ASSERT_DOUBLES_EQUAL(5., aSubField1->getValueIJ(anElems1[1], 1), 0.000001);
1121   CPPUNIT_ASSERT_DOUBLES_EQUAL(1., aSubField1->getValueIJ(anElems1[1], 2), 0.000001);
1122
1123   // setRow
1124   double row[2] = {-1., -3.};
1125   aSubField1->setRow(anElems1[0], row);
1126   CPPUNIT_ASSERT_DOUBLES_EQUAL(-1., aSubField1->getValueIJ(anElems1[0], 1), 0.000001);
1127   CPPUNIT_ASSERT_DOUBLES_EQUAL(-3., aSubField1->getValueIJ(anElems1[0], 2), 0.000001);
1128   CPPUNIT_ASSERT_DOUBLES_EQUAL( 5., aSubField1->getValueIJ(anElems1[1], 1), 0.000001);
1129   CPPUNIT_ASSERT_DOUBLES_EQUAL( 1., aSubField1->getValueIJ(anElems1[1], 2), 0.000001);
1130   // out of range
1131   CPPUNIT_ASSERT_THROW(aSubField1->setRow(3, row), MEDEXCEPTION);
1132
1133   // setColumn
1134   double col[2] = {-7., -9.};
1135   aSubField1->setColumn(1, col);
1136   CPPUNIT_ASSERT_DOUBLES_EQUAL(-7., aSubField1->getValueIJ(anElems1[0], 1), 0.000001);
1137   CPPUNIT_ASSERT_DOUBLES_EQUAL(-3., aSubField1->getValueIJ(anElems1[0], 2), 0.000001);
1138 #ifdef ENABLE_FORCED_FAILURES
1139   // (BUG) in MEDMEM_Array::setColumn()
1140   CPPUNIT_ASSERT_DOUBLES_EQUAL(-9., aSubField1->getValueIJ(anElems1[1], 1), 0.000001);
1141 #endif
1142   CPPUNIT_ASSERT_DOUBLES_EQUAL( 1., aSubField1->getValueIJ(anElems1[1], 2), 0.000001);
1143   // out of range
1144   CPPUNIT_ASSERT_THROW(aSubField1->setColumn(3, col), MEDEXCEPTION);
1145
1146   // setArray (Gauss)
1147   {
1148     int nbelgeoc[2] = {1, 3}; // 3 - 1 = two elements for the first (and the only) type
1149     int nbgaussgeo[2] = {-1, 1}; // one gauss point per each element
1150     MEDMEM_ArrayInterface<double,FullInterlace,Gauss>::Array * aNewArrayGauss =
1151       new MEDMEM_ArrayInterface<double,FullInterlace,Gauss>::Array
1152       (/*dim*/2, /*nbelem*/2, /*nbtypegeo*/1, /*nbelgeoc*/nbelgeoc, /*nbgaussgeo*/nbgaussgeo);
1153
1154 #ifdef ENABLE_FAULTS
1155     aNewArrayGauss->setIJ(1, 1, -4.);
1156     aNewArrayGauss->setIJ(1, 2, -2.);
1157     aNewArrayGauss->setIJ(2, 1, -5.);
1158     aNewArrayGauss->setIJ(2, 2, -1.);
1159 #endif
1160 #ifdef ENABLE_FORCED_FAILURES
1161     // ? (BUG) in FullInterlaceGaussPolicy::getIndex(int i,int j)
1162     // FullInterlaceGaussPolicy::getIndex(2,2) returns 4!!!
1163     CPPUNIT_FAIL("? Bug in FullInterlaceGaussPolicy::getIndex(int i,int j) ?");
1164 #endif
1165
1166     aNewArrayGauss->setIJK(1, 1, 1, -4.);
1167     aNewArrayGauss->setIJK(1, 2, 1, -2.);
1168     aNewArrayGauss->setIJK(2, 1, 1, -5.);
1169     aNewArrayGauss->setIJK(2, 2, 1, -1.);
1170
1171     aSubField1->setArray(aNewArrayGauss);
1172     // no need to delete aNewArrayGauss, because it will be deleted
1173     // in destructor or in deallocValue() method of aSubField1
1174
1175 #ifdef ENABLE_FAULTS
1176     CPPUNIT_ASSERT_DOUBLES_EQUAL(-4., aSubField1->getValueIJ(anElems1[0], 1), 0.000001);
1177     CPPUNIT_ASSERT_DOUBLES_EQUAL(-2., aSubField1->getValueIJ(anElems1[0], 2), 0.000001);
1178     CPPUNIT_ASSERT_DOUBLES_EQUAL(-5., aSubField1->getValueIJ(anElems1[1], 1), 0.000001);
1179     CPPUNIT_ASSERT_DOUBLES_EQUAL(-1., aSubField1->getValueIJ(anElems1[1], 2), 0.000001);
1180 #endif
1181 #ifdef ENABLE_FORCED_FAILURES
1182     // ? (BUG) in FullInterlaceGaussPolicy::getIndex(int i,int j)
1183     // Must be   : return _G[i-1]-1 + (j-1);
1184     // Instead of: return _G[i-1]-1 + (j-1)*_dim;
1185     CPPUNIT_FAIL("? Bug in FullInterlaceGaussPolicy::getIndex(int i,int j) ?");
1186 #endif
1187
1188     CPPUNIT_ASSERT_DOUBLES_EQUAL(-4., aSubField1->getValueIJK(anElems1[0], 1, 1), 0.000001);
1189     CPPUNIT_ASSERT_DOUBLES_EQUAL(-2., aSubField1->getValueIJK(anElems1[0], 2, 1), 0.000001);
1190     CPPUNIT_ASSERT_DOUBLES_EQUAL(-5., aSubField1->getValueIJK(anElems1[1], 1, 1), 0.000001);
1191     CPPUNIT_ASSERT_DOUBLES_EQUAL(-1., aSubField1->getValueIJK(anElems1[1], 2, 1), 0.000001);
1192   }
1193
1194   // alloc/dealloc; compatibility of new size with support
1195   try {
1196     aSubField1->deallocValue();
1197     aSubField1->allocValue(/*NumberOfComponents*/2, /*LengthValue*/5);
1198 #ifdef ENABLE_FAULTS
1199     // (BUG) No compatibility between Support and allocated value
1200     aSubField1->normL1();
1201 #endif
1202 #ifdef ENABLE_FORCED_FAILURES
1203     CPPUNIT_FAIL("Error: no compatibility between Support and allocated value");
1204 #endif
1205   }
1206   catch (MEDEXCEPTION & ex) {
1207     // normal behaviour
1208   }
1209   catch (...) {
1210     CPPUNIT_FAIL("Error: no compatibility between Support and allocated value");
1211   }
1212
1213   // check that aFieldOnGroup1 is not changed after aSubField1 modifications
1214   for (int i = 1; i <= nbVals; i++) {
1215     CPPUNIT_ASSERT_DOUBLES_EQUAL(13 + i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001);
1216     CPPUNIT_ASSERT_DOUBLES_EQUAL(13 - i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001);
1217   }
1218
1219   // reset aFieldOnGroup2 values for simple control of operators results
1220   for (int i = 1; i <= nbVals; i++) {
1221     aFieldOnGroup2->setValueIJ(anElems[i-1], 1, i*i);
1222     aFieldOnGroup2->setValueIJ(anElems[i-1], 2, -i*i);
1223   }
1224
1225   int len = aFieldOnGroup1->getValueLength();
1226   const double * val1 = aFieldOnGroup1->getValue();
1227   const double * val2 = aFieldOnGroup2->getValue();
1228   const double * val_res;
1229
1230   // operators and add, sub, mul, div
1231
1232   // +
1233   FIELD<double> aSum = *aFieldOnGroup1 + *aFieldOnGroup2;
1234   aSum.setName(aFieldOnGroup1->getName());
1235   aSum.setDescription(aFieldOnGroup1->getDescription());
1236   compareField_(aFieldOnGroup1, &aSum, true, true);
1237   val_res = aSum.getValue();
1238   for (int i = 0; i < len; i++) {
1239     CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] + val2[i], val_res[i], 0.000001);
1240   }
1241
1242   // -
1243   FIELD<double> aDifference = *aFieldOnGroup1 - *aFieldOnGroup2;
1244   aDifference.setName(aFieldOnGroup1->getName());
1245   aDifference.setDescription(aFieldOnGroup1->getDescription());
1246   compareField_(aFieldOnGroup1, &aDifference, true, true);
1247   val_res = aDifference.getValue();
1248   for (int i = 0; i < len; i++) {
1249     CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] - val2[i], val_res[i], 0.000001);
1250   }
1251
1252   // - (unary)
1253   FIELD<double> aNegative = - *aFieldOnGroup1;
1254   aNegative.setName(aFieldOnGroup1->getName());
1255   aNegative.setDescription(aFieldOnGroup1->getDescription());
1256   compareField_(aFieldOnGroup1, &aNegative, true, true);
1257   val_res = aNegative.getValue();
1258   for (int i = 0; i < len; i++) {
1259     CPPUNIT_ASSERT_DOUBLES_EQUAL(- val1[i], val_res[i], 0.000001);
1260   }
1261
1262   // *
1263   FIELD<double> aProduct = (*aFieldOnGroup1) * (*aFieldOnGroup2);
1264   aProduct.setName(aFieldOnGroup1->getName());
1265   aProduct.setDescription(aFieldOnGroup1->getDescription());
1266   compareField_(aFieldOnGroup1, &aProduct, true, true);
1267   val_res = aProduct.getValue();
1268   for (int i = 0; i < len; i++) {
1269     CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] * val2[i], val_res[i], 0.000001);
1270   }
1271
1272   // /
1273   FIELD<double> aQuotient = *aFieldOnGroup1 / *aFieldOnGroup2;
1274   aQuotient.setName(aFieldOnGroup1->getName());
1275   aQuotient.setDescription(aFieldOnGroup1->getDescription());
1276   compareField_(aFieldOnGroup1, &aQuotient, true, true);
1277   val_res = aQuotient.getValue();
1278   for (int i = 0; i < len; i++) {
1279     CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] / val2[i], val_res[i], 0.000001);
1280   }
1281
1282   double val22 = aFieldOnGroup2->getValueIJ(anElems[2], 2);
1283   aFieldOnGroup2->setValueIJ(anElems[2], 2, 0.);
1284
1285   CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 / *aFieldOnGroup2, MEDEXCEPTION);
1286 #ifdef ENABLE_FORCED_FAILURES
1287   // (BUG) is it up to user to control validity of data to avoid division on zero?
1288   CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 /= *aFieldOnGroup2, MEDEXCEPTION);
1289 #endif
1290   CPPUNIT_ASSERT_THROW(FIELD<double>::div(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION);
1291   CPPUNIT_ASSERT_THROW(FIELD<double>::divDeep(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION);
1292
1293   // restore value
1294   aFieldOnGroup2->setValueIJ(anElems[2], 2, val22);
1295
1296   // restore values
1297   for (int i = 1; i <= nbVals; i++) {
1298     aFieldOnGroup1->setValueIJ(anElems[i-1], 1, 13 + i);
1299     aFieldOnGroup1->setValueIJ(anElems[i-1], 2, 13 - i);
1300   }
1301
1302   // static methods
1303   FIELD<double> * aPtr;
1304
1305   // add
1306   aPtr = FIELD<double>::add(*aFieldOnGroup1, *aFieldOnGroup2);
1307   aPtr->setName(aFieldOnGroup1->getName());
1308   aPtr->setDescription(aFieldOnGroup1->getDescription());
1309   compareField_(aFieldOnGroup1, aPtr, true, true);
1310   val_res = aPtr->getValue();
1311   for (int i = 0; i < len; i++) {
1312     CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] + val2[i], val_res[i], 0.000001);
1313   }
1314   delete aPtr;
1315
1316   // sub
1317   aPtr = FIELD<double>::sub(*aFieldOnGroup1, *aFieldOnGroup2);
1318   aPtr->setName(aFieldOnGroup1->getName());
1319   aPtr->setDescription(aFieldOnGroup1->getDescription());
1320   compareField_(aFieldOnGroup1, aPtr, true, true);
1321   val_res = aPtr->getValue();
1322   for (int i = 0; i < len; i++) {
1323     CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] - val2[i], val_res[i], 0.000001);
1324   }
1325   delete aPtr;
1326
1327   // mul
1328   aPtr = FIELD<double>::mul(*aFieldOnGroup1, *aFieldOnGroup2);
1329   aPtr->setName(aFieldOnGroup1->getName());
1330   aPtr->setDescription(aFieldOnGroup1->getDescription());
1331   compareField_(aFieldOnGroup1, aPtr, true, true);
1332   val_res = aPtr->getValue();
1333   for (int i = 0; i < len; i++) {
1334     CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] * val2[i], val_res[i], 0.000001);
1335   }
1336   delete aPtr;
1337
1338   // div
1339   aPtr = FIELD<double>::div(*aFieldOnGroup1, *aFieldOnGroup2);
1340   aPtr->setName(aFieldOnGroup1->getName());
1341   aPtr->setDescription(aFieldOnGroup1->getDescription());
1342   compareField_(aFieldOnGroup1, aPtr, true, true);
1343   val_res = aPtr->getValue();
1344   for (int i = 0; i < len; i++) {
1345     CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] / val2[i], val_res[i], 0.000001);
1346   }
1347   delete aPtr;
1348
1349   // addDeep
1350   aPtr = FIELD<double>::addDeep(*aFieldOnGroup1, *aFieldOnGroup2);
1351   aPtr->setName(aFieldOnGroup1->getName());
1352   aPtr->setDescription(aFieldOnGroup1->getDescription());
1353   compareField_(aFieldOnGroup1, aPtr, true, true);
1354   val_res = aPtr->getValue();
1355   for (int i = 0; i < len; i++) {
1356     CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] + val2[i], val_res[i], 0.000001);
1357   }
1358   delete aPtr;
1359
1360   // subDeep
1361   aPtr = FIELD<double>::subDeep(*aFieldOnGroup1, *aFieldOnGroup2);
1362   aPtr->setName(aFieldOnGroup1->getName());
1363   aPtr->setDescription(aFieldOnGroup1->getDescription());
1364   compareField_(aFieldOnGroup1, aPtr, true, true);
1365   val_res = aPtr->getValue();
1366   for (int i = 0; i < len; i++) {
1367     CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] - val2[i], val_res[i], 0.000001);
1368   }
1369   delete aPtr;
1370
1371   // mulDeep
1372   aPtr = FIELD<double>::mulDeep(*aFieldOnGroup1, *aFieldOnGroup2);
1373   aPtr->setName(aFieldOnGroup1->getName());
1374   aPtr->setDescription(aFieldOnGroup1->getDescription());
1375   compareField_(aFieldOnGroup1, aPtr, true, true);
1376   val_res = aPtr->getValue();
1377   for (int i = 0; i < len; i++) {
1378     CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] * val2[i], val_res[i], 0.000001);
1379   }
1380   delete aPtr;
1381
1382   // divDeep
1383   aPtr = FIELD<double>::divDeep(*aFieldOnGroup1, *aFieldOnGroup2);
1384   aPtr->setName(aFieldOnGroup1->getName());
1385   aPtr->setDescription(aFieldOnGroup1->getDescription());
1386   compareField_(aFieldOnGroup1, aPtr, true, true);
1387   val_res = aPtr->getValue();
1388   for (int i = 0; i < len; i++) {
1389     CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] / val2[i], val_res[i], 0.000001);
1390   }
1391   delete aPtr;
1392
1393   // +=
1394   *aFieldOnGroup1 += *aFieldOnGroup2;
1395   for (int i = 1; i <= nbVals; i++) {
1396     CPPUNIT_ASSERT_DOUBLES_EQUAL(13 + i + i*i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001);
1397     CPPUNIT_ASSERT_DOUBLES_EQUAL(13 - i - i*i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001);
1398   }
1399
1400   // -=
1401   *aFieldOnGroup1 -= *aFieldOnGroup2;
1402   for (int i = 1; i <= nbVals; i++) {
1403     CPPUNIT_ASSERT_DOUBLES_EQUAL(13 + i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001);
1404     CPPUNIT_ASSERT_DOUBLES_EQUAL(13 - i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001);
1405   }
1406
1407   // *=
1408   *aFieldOnGroup1 *= *aFieldOnGroup2;
1409   for (int i = 1; i <= nbVals; i++) {
1410     CPPUNIT_ASSERT_DOUBLES_EQUAL( (13 + i)*i*i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001);
1411     CPPUNIT_ASSERT_DOUBLES_EQUAL(-(13 - i)*i*i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001);
1412   }
1413
1414   // /=
1415   *aFieldOnGroup1 /= *aFieldOnGroup2;
1416   for (int i = 1; i <= nbVals; i++) {
1417     CPPUNIT_ASSERT_DOUBLES_EQUAL(13 + i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001);
1418     CPPUNIT_ASSERT_DOUBLES_EQUAL(13 - i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001);
1419   }
1420
1421   // check case of different operands: support
1422   MESH * aMeshOneMore = MEDMEMTest_createTestMesh();
1423   const GROUP* aGroupOneMore = aMeshOneMore->getGroup(MED_EN::MED_FACE, 1);
1424   FIELD<double> * aFieldOnGroup3 =
1425     createFieldOnGroup<double>(aMeshOneMore, aGroupOneMore, "Test_Diff_Mesh", "test");
1426   for (int i = 1; i <= nbVals; i++) {
1427     aFieldOnGroup3->setValueIJ(anElems[i-1], 1, 2*i);
1428     aFieldOnGroup3->setValueIJ(anElems[i-1], 2, 3*i);
1429   }
1430   const double * val3 = aFieldOnGroup3->getValue();
1431
1432   //CPPUNIT_ASSERT_NO_THROW();
1433   try {
1434     aPtr = FIELD<double>::addDeep(*aFieldOnGroup1, *aFieldOnGroup3);
1435     aPtr->setName(aFieldOnGroup1->getName());
1436     aPtr->setDescription(aFieldOnGroup1->getDescription());
1437     compareField_(aFieldOnGroup1, aPtr, true, true);
1438     val_res = aPtr->getValue();
1439     for (int i = 0; i < len; i++) {
1440       CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] + val3[i], val_res[i], 0.000001);
1441     }
1442     delete aPtr;
1443
1444     aPtr = FIELD<double>::subDeep(*aFieldOnGroup1, *aFieldOnGroup3);
1445     delete aPtr;
1446     aPtr = FIELD<double>::mulDeep(*aFieldOnGroup1, *aFieldOnGroup3);
1447     delete aPtr;
1448     aPtr = FIELD<double>::divDeep(*aFieldOnGroup1, *aFieldOnGroup3);
1449     delete aPtr;
1450   }
1451   catch (MEDEXCEPTION & ex) {
1452     CPPUNIT_FAIL(ex.what());
1453   }
1454   catch (...) {
1455     CPPUNIT_FAIL("Unknown exception in FIELD::xxxDeep()");
1456   }
1457
1458   CPPUNIT_ASSERT_THROW(FIELD<double>::add(*aFieldOnGroup1, *aFieldOnGroup3), MEDEXCEPTION);
1459   CPPUNIT_ASSERT_THROW(FIELD<double>::sub(*aFieldOnGroup1, *aFieldOnGroup3), MEDEXCEPTION);
1460   CPPUNIT_ASSERT_THROW(FIELD<double>::mul(*aFieldOnGroup1, *aFieldOnGroup3), MEDEXCEPTION);
1461   CPPUNIT_ASSERT_THROW(FIELD<double>::div(*aFieldOnGroup1, *aFieldOnGroup3), MEDEXCEPTION);
1462
1463   CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 + *aFieldOnGroup3, MEDEXCEPTION);
1464   CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 - *aFieldOnGroup3, MEDEXCEPTION);
1465   CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 * *aFieldOnGroup3, MEDEXCEPTION);
1466   CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 / *aFieldOnGroup3, MEDEXCEPTION);
1467
1468   CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 += *aFieldOnGroup3, MEDEXCEPTION);
1469   CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 -= *aFieldOnGroup3, MEDEXCEPTION);
1470   CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 *= *aFieldOnGroup3, MEDEXCEPTION);
1471   CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 /= *aFieldOnGroup3, MEDEXCEPTION);
1472
1473   // check case of different operands: MEDComponentsUnits
1474   aFieldOnGroup1->setMEDComponentUnit(1, "unit3");
1475
1476   CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 + *aFieldOnGroup2, MEDEXCEPTION);
1477   CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 - *aFieldOnGroup2, MEDEXCEPTION);
1478   CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 += *aFieldOnGroup2, MEDEXCEPTION);
1479   CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 -= *aFieldOnGroup2, MEDEXCEPTION);
1480   CPPUNIT_ASSERT_THROW(FIELD<double>::add(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION);
1481   CPPUNIT_ASSERT_THROW(FIELD<double>::sub(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION);
1482   CPPUNIT_ASSERT_THROW(FIELD<double>::addDeep(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION);
1483   CPPUNIT_ASSERT_THROW(FIELD<double>::subDeep(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION);
1484
1485   //CPPUNIT_ASSERT_NO_THROW();
1486   try {
1487     aPtr = FIELD<double>::mul(*aFieldOnGroup1, *aFieldOnGroup2);
1488     delete aPtr;
1489     aPtr = FIELD<double>::div(*aFieldOnGroup1, *aFieldOnGroup2);
1490     delete aPtr;
1491     aPtr = FIELD<double>::mulDeep(*aFieldOnGroup1, *aFieldOnGroup2);
1492     delete aPtr;
1493     aPtr = FIELD<double>::divDeep(*aFieldOnGroup1, *aFieldOnGroup2);
1494     delete aPtr;
1495
1496     *aFieldOnGroup1 *= *aFieldOnGroup2;
1497     *aFieldOnGroup1 /= *aFieldOnGroup2;
1498
1499     FIELD<double> aPr = *aFieldOnGroup1 * *aFieldOnGroup2;
1500     FIELD<double> aQu = *aFieldOnGroup1 / *aFieldOnGroup2;
1501   }
1502   catch (MEDEXCEPTION & ex) {
1503     CPPUNIT_FAIL(ex.what());
1504   }
1505   catch (...) {
1506     CPPUNIT_FAIL("Unknown exception");
1507   }
1508
1509   // restore MED units
1510   aFieldOnGroup1->setMEDComponentUnit(1, "unit1");
1511
1512   // check case of different operands: valueType
1513   //FIELD<int> * aFieldOnGroup4 =
1514   //  createFieldOnGroup<int>(aMeshOneMore, aGroupOneMore, "Test_Diff_Mesh", "test");
1515   //
1516   //CPPUNIT_ASSERT_THROW(FIELD<double>::add(*aFieldOnGroup4, *aFieldOnGroup3), MEDEXCEPTION);
1517   //CPPUNIT_ASSERT_THROW(*aFieldOnGroup4 - *aFieldOnGroup3, MEDEXCEPTION);
1518   //CPPUNIT_ASSERT_THROW(*aFieldOnGroup4 *= *aFieldOnGroup3, MEDEXCEPTION);
1519   //delete aFieldOnGroup4;
1520
1521   // check case of different operands: numberOfComponents
1522 #ifdef ENABLE_FAULTS
1523   // (BUG) Cannot allocate value of higher dimension because of _componentsTypes reinitialization
1524   aFieldOnGroup1->deallocValue();
1525   CPPUNIT_ASSERT_THROW(aFieldOnGroup1->allocValue(/*dim*/5), MEDEXCEPTION);
1526 #endif
1527 #ifdef ENABLE_FORCED_FAILURES
1528   CPPUNIT_FAIL("Segmentation fault on attempt to allocate value of higher dimension."
1529                " Must be MEDEXCEPTION instead. And on attempt to change nb.components"
1530                " must be the same behaviour.");
1531 #endif
1532   aFieldOnGroup1->setNumberOfComponents(5);
1533
1534   CPPUNIT_ASSERT_THROW(FIELD<double>::sub(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION);
1535   CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 * *aFieldOnGroup2, MEDEXCEPTION);
1536   CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 /= *aFieldOnGroup2, MEDEXCEPTION);
1537
1538   // check case of different operands: numberOfValues
1539   aFieldOnGroup1->deallocValue();
1540   aFieldOnGroup1->allocValue(2, nbVals + 1);
1541   // be carefull: aFieldOnGroup1 reallocated and contains random values
1542
1543   CPPUNIT_ASSERT_THROW(FIELD<double>::mul(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION);
1544   CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 / *aFieldOnGroup2, MEDEXCEPTION);
1545   CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 += *aFieldOnGroup2, MEDEXCEPTION);
1546
1547   // restore aFieldOnGroup1
1548   aFieldOnGroup1->deallocValue();
1549   aFieldOnGroup1->allocValue(2, nbVals);
1550   // be carefull: aFieldOnGroup1 reallocated and contains random values
1551
1552   delete aSubSupport1;
1553   delete [] anElems1;
1554
1555   delete aScalarProduct;
1556   delete aSubField1;
1557   delete anAreaField;
1558   delete barycenter;
1559   delete aFieldOnGroup1;
1560   delete aFieldOnGroup2;
1561   delete aFieldOnGroup3;
1562
1563   delete aMesh;
1564   delete aMeshOneMore;
1565
1566   /////////////////////
1567   // TEST 5: Drivers //
1568   /////////////////////
1569   testDrivers();
1570 }
1571
1572 /*!
1573  *  Check methods (2), defined in MEDMEM_FieldConvert.hxx:
1574  *  (+) template <class T> FIELD<T,FullInterlace> * FieldConvert(const FIELD<T,NoInterlace> & field);
1575  *  (+) template <class T> FIELD<T,NoInterlace> * FieldConvert(const FIELD<T,FullInterlace> & field);
1576  */
1577 void MEDMEMTest::testFieldConvert()
1578 {
1579   // create an empty integer field 2x10
1580   FIELD<int, FullInterlace> * aField_FING = new FIELD<int, FullInterlace> ();
1581
1582   aField_FING->setName("Field_FING");
1583   aField_FING->setDescription("Field full interlace no gauss");
1584
1585   aField_FING->setNumberOfComponents(2);
1586   aField_FING->setNumberOfValues(10);
1587
1588   string aCompsNames[2] = {"Pos", "Neg"};
1589   string aCompsDescs[2] = {"+", "-"};
1590   string aMEDCompsUnits[2] = {"unit1", "unit2"};
1591   UNIT   aCompsUnits[2];
1592
1593   aCompsUnits[0] = UNIT("u1", "descr1");
1594   aCompsUnits[1] = UNIT("u2", "descr2");
1595
1596   aField_FING->setComponentsNames(aCompsNames);
1597   aField_FING->setComponentsDescriptions(aCompsDescs);
1598   aField_FING->setMEDComponentsUnits(aMEDCompsUnits);
1599   aField_FING->setComponentsUnits(aCompsUnits);
1600
1601   // check UNITs (for testField())
1602   const UNIT * aCompsUnitsBack = aField_FING->getComponentsUnits();
1603   CPPUNIT_ASSERT(aCompsUnits[0].getName() == aCompsUnitsBack[0].getName());
1604   CPPUNIT_ASSERT(aCompsUnits[1].getName() == aCompsUnitsBack[1].getName());
1605
1606   const UNIT * aCompUnitBack1 = aField_FING->getComponentUnit(1);
1607   const UNIT * aCompUnitBack2 = aField_FING->getComponentUnit(2);
1608   CPPUNIT_ASSERT(aCompsUnits[0].getName() == aCompUnitBack1->getName());
1609   CPPUNIT_ASSERT(aCompsUnits[1].getName() == aCompUnitBack2->getName());
1610
1611   // create one more field by copy
1612   FIELD<int, FullInterlace> * aField_FIGG = new FIELD<int, FullInterlace> (*aField_FING);
1613
1614   // values
1615   int values_FING[20] = { 7,- 7, 14,-14, 21,-21, 28,-28, 35,-35,
1616                           42,-42, 49,-49, 56,-56, 63,-63, 70,-70};
1617
1618   /////////////////////
1619   // TEST 1: NoGauss //
1620   /////////////////////
1621
1622   MEDMEM_ArrayInterface<int,FullInterlace,NoGauss>::Array * anArray_FING =
1623     new MEDMEM_ArrayInterface<int,FullInterlace,NoGauss>::Array
1624     (values_FING, /*dim*/2, /*nbelem*/10, /*shallowCopy*/false, /*ownershipOfValues*/false);
1625   aField_FING->setArray(anArray_FING);
1626   // no need to delete anArray_FING, because it will be deleted in destructor of aField_FING
1627
1628   // 1. FullInterlace -> NoInterlace
1629   FIELD<int, NoInterlace> * aField_NING = FieldConvert(*aField_FING);
1630   const int * values_NING = aField_NING->getValue();
1631
1632   for (int i = 0; i < 10; i++) {
1633     for (int j = 0; j < 2; j++) {
1634       CPPUNIT_ASSERT_EQUAL(values_FING[2*i + j], values_NING[10*j + i]);
1635     }
1636   }
1637
1638   // 2. NoInterlace -> FullInterlace
1639   FIELD<int, FullInterlace> * aField_FING_conv = FieldConvert(*aField_NING);
1640   const int * values_FING_conv = aField_FING_conv->getValue();
1641
1642   for (int i = 0; i < 10; i++) {
1643     for (int j = 0; j < 2; j++) {
1644       CPPUNIT_ASSERT_EQUAL(values_FING_conv[2*i + j], values_FING[2*i + j]);
1645       CPPUNIT_ASSERT_EQUAL(values_FING_conv[2*i + j], values_NING[10*j + i]);
1646     }
1647   }
1648
1649   delete aField_FING;
1650   delete aField_NING;
1651   delete aField_FING_conv;
1652
1653   ///////////////////
1654   // TEST 2: Gauss //
1655   ///////////////////
1656   int nbelgeoc[2] = {1, 11};
1657   int nbgaussgeo[2] = {-1, 1};
1658   MEDMEM_ArrayInterface<int,FullInterlace,Gauss>::Array * anArray_FIGG =
1659     new MEDMEM_ArrayInterface<int,FullInterlace,Gauss>::Array
1660     (values_FING, /*dim*/2, /*nbelem*/10, /*nbtypegeo*/1, /*nbelgeoc*/nbelgeoc,
1661      /*nbgaussgeo*/nbgaussgeo, /*shallowCopy*/false, /*ownershipOfValues*/false);
1662   aField_FIGG->setArray(anArray_FIGG);
1663   // no need to delete anArray_FIGG, because it will be deleted in destructor of aField_FIGG
1664
1665   // 1. FullInterlace -> NoInterlace
1666   FIELD<int, NoInterlace> * aField_NIGG = FieldConvert(*aField_FIGG);
1667   const int * values_NIGG = aField_NIGG->getValue();
1668
1669   for (int i = 0; i < 10; i++) {
1670     for (int j = 0; j < 2; j++) {
1671       CPPUNIT_ASSERT_EQUAL(values_FING[2*i + j], values_NIGG[10*j + i]);
1672     }
1673   }
1674
1675   // 2. NoInterlace -> FullInterlace
1676   FIELD<int, FullInterlace> * aField_FIGG_conv = FieldConvert(*aField_NIGG);
1677   const int * values_FIGG_conv = aField_FIGG_conv->getValue();
1678
1679   for (int i = 0; i < 10; i++) {
1680     for (int j = 0; j < 2; j++) {
1681       CPPUNIT_ASSERT_EQUAL(values_FIGG_conv[2*i + j], values_FING[2*i + j]);
1682       CPPUNIT_ASSERT_EQUAL(values_FIGG_conv[2*i + j], values_NIGG[10*j + i]);
1683     }
1684   }
1685
1686   delete aField_FIGG;
1687   delete aField_NIGG;
1688   delete aField_FIGG_conv;
1689
1690 #ifdef ENABLE_FAULTS
1691   // (BUG) in FieldConvert(), concerning FIELD_::operator=
1692   {
1693     // create an empty integer field 2x10
1694     FIELD<int, FullInterlace> * aField = new FIELD<int, FullInterlace> ();
1695
1696     aField->setName("aField");
1697     aField->setDescription("Field full interlace no gauss");
1698
1699     aField->setNumberOfComponents(2);
1700     aField->setNumberOfValues(10);
1701
1702     aField->setComponentsNames(aCompsNames);
1703     aField->setComponentsDescriptions(aCompsDescs);
1704     aField->setMEDComponentsUnits(aMEDCompsUnits);
1705
1706     MEDMEM_ArrayInterface<int,FullInterlace,NoGauss>::Array * anArray =
1707       new MEDMEM_ArrayInterface<int,FullInterlace,NoGauss>::Array
1708       (values_FING, /*dim*/2, /*nbelem*/10, /*shallowCopy*/false, /*ownershipOfValues*/false);
1709     aField->setArray(anArray);
1710     // no need to delete anArray, because it will be deleted in destructor of aField
1711
1712     FIELD<int, NoInterlace> * aField_conv = FieldConvert(*aField);
1713   }
1714 #endif
1715 #ifdef ENABLE_FORCED_FAILURES
1716   CPPUNIT_FAIL("FieldConvert() fails if _componentsUnits is not set, because it calls FIELD_::operator=");
1717 #endif
1718 }