1 // Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 #include "MEDMEMTest.hxx"
22 #include <cppunit/TestAssert.h>
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>
36 // use this define to enable lines, execution of which leads to Segmentation Fault
37 //#define ENABLE_FAULTS
39 // use this define to enable CPPUNIT asserts and fails, showing bugs
40 #define ENABLE_FORCED_FAILURES
43 using namespace MEDMEM;
45 // #14,15: MEDMEMTest_Field.cxx
46 // Check methods from MEDMEM_Field.hxx, MEDMEM_FieldConvert.hxx
49 * Check methods (48), defined in MEDMEM_Field.hxx:
52 * (+) FIELD_(const SUPPORT * Support, const int NumberOfComponents);
53 * (+) FIELD_(const FIELD_ &m);
54 * (+) virtual ~FIELD_();
55 * (+) FIELD_& operator=(const FIELD_ &m);
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);
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="");
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;
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;
105 * (+) inline MED_EN::med_type_champ getValueType () const;
106 * (+) inline MED_EN::medModeSwitch getInterlacingType() const;
107 * (-) virtual inline bool getGaussPresence() const throw (MEDEXCEPTION);
110 * template <class T, class INTERLACING_TAG> class FIELD : public 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);
121 * (+) FIELD & operator=(const FIELD &m);
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);
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);
142 * (+) double normMax() const throw (MEDEXCEPTION);
143 * (+) double norm2() const throw (MEDEXCEPTION);
145 * (+) void applyLin(T a, T b);
146 * (+) template <T T_function(T)> void applyFunc();
147 * (+) void applyPow(T scalar);
149 * (+) static FIELD* scalarProduct(const FIELD& m, const FIELD& n, bool deepCheck=false);
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;
156 * (+) FIELD* extract(const SUPPORT *subSupport) const throw (MEDEXCEPTION);
158 * (EMPTY COMMENT, EMPTY IMPLEMENTATION!!!) void init ();
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);
167 * (+) void allocValue(const int NumberOfComponents);
168 * (+) void allocValue(const int NumberOfComponents, const int LengthValue);
169 * (+) void deallocValue();
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 &);
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);
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);
191 * (+) const int getNumberOfGeometricTypes() const throw (MEDEXCEPTION);
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);
204 * (+) const int * getNumberOfElements() const throw (MEDEXCEPTION);
205 * (+) const MED_EN::medGeometryElement * getGeometricTypes() const throw (MEDEXCEPTION);
206 * (+) bool isOnAllElements() const throw (MEDEXCEPTION);
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);
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);
220 * (+) void fillFromAnalytic(myFuncType f) throw (MEDEXCEPTION);
223 * Use code of test_operation_fieldint.cxx
224 * test_operation_fielddouble.cxx
225 * test_copie_field_.cxx
226 * test_copie_fieldT.cxx
228 void compareField_(const FIELD_ * theField_1, const FIELD_ * theField_2, bool isFIELD, bool isValue)
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());
235 // components information
236 int aNbComps = theField_1->getNumberOfComponents();
237 CPPUNIT_ASSERT_EQUAL(aNbComps, theField_2->getNumberOfComponents());
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));
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);
251 int nbOfValues = theField_1->getNumberOfValues();
252 CPPUNIT_ASSERT_EQUAL(nbOfValues, theField_2->getNumberOfValues());
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());
261 CPPUNIT_ASSERT_EQUAL(theField_1->getGaussPresence(), theField_2->getGaussPresence());
264 CPPUNIT_ASSERT_THROW(theField_1->getGaussPresence(), MEDEXCEPTION);
265 CPPUNIT_ASSERT_THROW(theField_2->getGaussPresence(), MEDEXCEPTION);
269 CPPUNIT_ASSERT_THROW(theField_1->getGaussPresence(), MEDEXCEPTION);
270 CPPUNIT_ASSERT_THROW(theField_2->getGaussPresence(), MEDEXCEPTION);
274 void checkField_(FIELD_ * theField_, const SUPPORT * theSupport,
275 MED_EN::med_type_champ theValueType,
276 MED_EN::medModeSwitch theInterlace)
279 const string aFieldName = "a_name_of_a_field";
280 theField_->setName(aFieldName);
281 CPPUNIT_ASSERT_EQUAL(aFieldName, theField_->getName());
284 const string aFieldDescr = "a_description_of_a_field";
285 theField_->setDescription(aFieldDescr);
286 CPPUNIT_ASSERT_EQUAL(aFieldDescr, theField_->getDescription());
289 theField_->setSupport(theSupport);
290 CPPUNIT_ASSERT(theField_->getSupport() == theSupport);
292 // components information
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"};
299 theField_->setNumberOfComponents(aNbComps);
300 CPPUNIT_ASSERT_EQUAL(aNbComps, theField_->getNumberOfComponents());
302 theField_->setComponentsNames(aCompsNames);
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");
312 catch (MEDEXCEPTION& ex) {
313 // Ok, it is good to have MEDEXCEPTION here
316 CPPUNIT_FAIL("Unknown exception cought");
318 // restore components names
319 theField_->setNumberOfComponents(aNbComps);
320 theField_->setComponentsNames(aCompsNames);
322 #ifdef ENABLE_FORCED_FAILURES
323 CPPUNIT_FAIL("FIELD_::_componentsNames bad management");
326 theField_->setComponentsDescriptions(aCompsDescs);
327 theField_->setMEDComponentsUnits(aCompsUnits);
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]);
336 CPPUNIT_ASSERT_EQUAL(aCompsDescsBack[i-1], theField_->getComponentDescription(i));
337 CPPUNIT_ASSERT_EQUAL(aCompsDescsBack[i-1], aCompsDescs[i-1]);
339 CPPUNIT_ASSERT_EQUAL(aCompsUnitsBack[i-1], theField_->getMEDComponentUnit(i));
340 CPPUNIT_ASSERT_EQUAL(aCompsUnitsBack[i-1], aCompsUnits[i-1]);
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");
347 theField_->setComponentName(2, aCompName2);
348 theField_->setComponentDescription(2, aCompDesc2);
349 theField_->setMEDComponentUnit(2, aCompUnit2);
351 const string * aCompsNamesBack2 = theField_->getComponentsNames();
352 const string * aCompsDescsBack2 = theField_->getComponentsDescriptions();
353 const string * aCompsUnitsBack2 = theField_->getMEDComponentsUnits();
355 CPPUNIT_ASSERT_EQUAL(aCompsNamesBack2[1], theField_->getComponentName(2));
356 CPPUNIT_ASSERT_EQUAL(aCompsNamesBack2[1], aCompName2);
358 CPPUNIT_ASSERT_EQUAL(aCompsDescsBack2[1], theField_->getComponentDescription(2));
359 CPPUNIT_ASSERT_EQUAL(aCompsDescsBack2[1], aCompDesc2);
361 CPPUNIT_ASSERT_EQUAL(aCompsUnitsBack2[1], theField_->getMEDComponentUnit(2));
362 CPPUNIT_ASSERT_EQUAL(aCompsUnitsBack2[1], aCompUnit2);
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);
373 #ifdef ENABLE_FORCED_FAILURES
374 CPPUNIT_FAIL("FIELD::setComponentXXX() does not check component index");
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());
382 int anOrderNumber = 1; // set value to MED_NONOR if undefined (default)
383 theField_->setOrderNumber(anOrderNumber);
384 CPPUNIT_ASSERT_EQUAL(anOrderNumber, theField_->getOrderNumber());
386 double aTime = 3.435678; // in second
387 theField_->setTime(aTime);
388 CPPUNIT_ASSERT_DOUBLES_EQUAL(aTime, theField_->getTime(), 0.0000001);
392 // dangerous method, because it does not reallocate values array
393 theField_->setNumberOfValues(nbOfValues);
394 CPPUNIT_ASSERT_EQUAL(nbOfValues, theField_->getNumberOfValues());
396 // Value type and Interlacing type
397 CPPUNIT_ASSERT_EQUAL(theValueType, theField_->getValueType());
398 CPPUNIT_ASSERT_EQUAL(theInterlace, theField_->getInterlacingType());
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)
405 // compare FIELD_ part
406 compareField_(theField_1, theField_2, /*isFIELD = */true, isValue);
408 // compare FIELD part
412 template<class T, class INTERLACING_TAG>
413 void checkField (FIELD<T, INTERLACING_TAG> * theField, const SUPPORT * theSupport)
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);
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, )
427 MESH* aMesh = theSupport->getMesh();
429 if (aMesh) spaceDim = aMesh->getSpaceDimension();
430 theField->deallocValue();
431 theField->allocValue(/*NumberOfComponents = */spaceDim + 1);
433 CPPUNIT_ASSERT_THROW(theField->getVolume(), MEDEXCEPTION);
434 CPPUNIT_ASSERT_THROW(theField->getArea(), MEDEXCEPTION);
435 CPPUNIT_ASSERT_THROW(theField->getLength(), MEDEXCEPTION);
437 CPPUNIT_ASSERT_THROW(theField->getNormal(), MEDEXCEPTION);
438 CPPUNIT_ASSERT_THROW(theField->getBarycenter(), MEDEXCEPTION);
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());
449 CPPUNIT_ASSERT_THROW(theField->getVolume(), MEDEXCEPTION);
450 CPPUNIT_ASSERT_THROW(theField->getArea(), MEDEXCEPTION);
451 CPPUNIT_ASSERT_THROW(theField->getLength(), MEDEXCEPTION);
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());
462 CPPUNIT_ASSERT_THROW(theField->getNormal(), MEDEXCEPTION);
463 CPPUNIT_ASSERT_THROW(theField->getBarycenter(), MEDEXCEPTION);
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());
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();
481 #ifdef ENABLE_FORCED_FAILURES
482 CPPUNIT_FAIL("FIELD::deallocValue() does not nullify _value pointer");
486 FIELD<T, INTERLACING_TAG> aField_copy1 (*theField);
487 //compareField(theField, &aField_copy1, /*isValue = */false);
488 compareField(theField, &aField_copy1, /*isValue = */true);
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);
499 #ifdef ENABLE_FORCED_FAILURES
500 CPPUNIT_FAIL("FIELD_::operator=() fails if _componentsUnits is not set");
505 FIELD<T> * createFieldOnGroup(MESH* theMesh, const GROUP* theGroup,
506 const string theName, const string theDescr)
508 FIELD<T> * aFieldOnGroup = new FIELD<T> (theGroup, /*NumberOfComponents = */2);
510 aFieldOnGroup->setName(theName);
511 aFieldOnGroup->setDescription(theDescr);
513 string aCompsNames[2] = {"Pos", "Neg"};
514 string aCompsDescs[2] = {"+", "-"};
515 string aCompsUnits[2] = {"unit1", "unit2"};
517 aFieldOnGroup->setComponentsNames(aCompsNames);
518 aFieldOnGroup->setComponentsDescriptions(aCompsDescs);
519 aFieldOnGroup->setMEDComponentsUnits(aCompsUnits);
521 return aFieldOnGroup;
524 double plus13 (double val)
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)
535 // dimetric projection with coefficients:
536 // 1.0 along Oy and Oz, 0.5 along Ox
545 // x_ = y - x * sqrt(2.) / 4.
546 // y_ = z - x * sqrt(2.) / 4.
548 double dx = temp[0] * std::sqrt(2.) / 4.;
549 output[0] = temp[1] - dx;
550 output[1] = temp[2] - dx;
555 string data_dir = getenv("DATA_DIR");
556 string tmp_dir = getenv("TMP");
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;
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";
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);
581 system(cp_file.c_str());
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),
587 CPPUNIT_ASSERT_THROW(aInvalidField = FIELD<int>(GIBI_DRIVER, filename_rd, fieldname_nodeint_rd),
589 CPPUNIT_ASSERT_THROW(aInvalidField = FIELD<int>(PORFLOW_DRIVER, filename_rd, fieldname_nodeint_rd),
591 CPPUNIT_ASSERT_THROW(aInvalidField = FIELD<int>(ASCII_DRIVER, filename_rd, fieldname_nodeint_rd),
597 FIELD<double> *aField_1 = NULL;
598 CPPUNIT_ASSERT_NO_THROW(aField_1 = new FIELD<double>(MED_DRIVER, filename_rd, fieldname_celldouble_rd));
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));
607 //Test read(GENDRIVER & genDriver) method
609 MED_FIELD_RDONLY_DRIVER21<int> *aMedRdFieldDriver21_1 =
610 new MED_FIELD_RDONLY_DRIVER21<int>();
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);
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;
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();
646 //Test write(int index) method
647 //Add drivers to FIELDs
651 IdDriver1 = aField_3->addDriver(MED_DRIVER,filename_wr,fieldname_celldouble_wr);
653 catch(MEDEXCEPTION &e)
659 CPPUNIT_FAIL("Unknown exception");
661 //Trying call write(int index) method with incorrect index
663 CPPUNIT_ASSERT_THROW(aField_3->write(IdDriver1+1, fieldname_celldouble_wr),MEDEXCEPTION);
664 // => Segmentation fault
667 //Write field to file
671 aField_3->write(IdDriver1, fieldname_celldouble_wr);
672 // => Segmentation fault
674 catch(MEDEXCEPTION &e)
680 CPPUNIT_FAIL("Unknown exception");
684 CPPUNIT_ASSERT_NO_THROW(aField_3->rmDriver(IdDriver1));
686 //Test write(const GENDRIVER &);
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);
697 aField_2->write(*aMedWrFieldDriver21);
699 catch(MEDEXCEPTION &e)
705 CPPUNIT_FAIL("Unknown exception");
708 //Test writeAppend(int index) method
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);
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();
730 //Add Driver to a field
734 IdDriver2 = aField_4->addDriver(VTK_DRIVER, filenamevtk_wr ,fieldname_nodeint_wr);
736 catch(MEDEXCEPTION &e)
742 CPPUNIT_FAIL("Unknown exception");
745 //Trying call writeAppend() method with incorrect index
746 CPPUNIT_ASSERT_THROW(aField_4->writeAppend(IdDriver2+1,fieldname_nodeint_wr),MEDEXCEPTION);
747 // => Segmentation fault
751 // (BUG) => Segmentation fault
752 CPPUNIT_ASSERT_NO_THROW(aField_4->writeAppend(IdDriver2, fieldname_nodeint_wr));
755 //Test writeAppend(const GENDRIVER &) method
756 aField_4->setName(fieldname_nodeint_wr1);
758 //Add driver to a field
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));
770 delete aMedRdFieldDriver21_1;
773 delete aMedRdFieldDriver21_2;
775 delete aMedMeshRdDriver22;
776 delete aMedWrFieldDriver21;
780 delete aMedRdFieldDriver22;
784 void MEDMEMTest::testField()
786 SUPPORT anEmptySupport;
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);
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);
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
809 aField_copy2 = aField_;
810 compareField_(&aField_, &aField_copy2, /*isFIELD = */false, /*isValue = */false);
812 #ifdef ENABLE_FORCED_FAILURES
813 CPPUNIT_FAIL("FIELD_::operator=() fails if _componentsUnits is not set");
816 // construction on a given support
818 anEmptySupport.setTotalNumberOfElements(11);
820 FIELD_ aField_case1 (&anEmptySupport, 10);
823 aField_case2.setSupport(&anEmptySupport);
824 aField_case2.setNumberOfComponents(10);
826 #ifdef ENABLE_FORCED_FAILURES
827 CPPUNIT_ASSERT_EQUAL_MESSAGE("No correspondance between CASE1 and CASE2",
828 aField_case1.getNumberOfValues(),
829 aField_case2.getNumberOfValues());
833 ////////////////////////
834 // TEST 2: FIELD<int> //
835 ////////////////////////
836 FIELD<int> aFieldInt;
837 checkField(&aFieldInt, &anEmptySupport);
839 ////////////////////////////////////////
840 // TEST 3: FIELD<double, NoInterlace> //
841 ////////////////////////////////////////
842 MESH * aMesh = MEDMEMTest_createTestMesh();
843 const GROUP* aGroup = aMesh->getGroup(MED_EN::MED_FACE, 1);
845 FIELD<double, NoInterlace> aFieldDouble;
846 checkField(&aFieldDouble, aGroup);
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");
854 int nbVals = aFieldOnGroup1->getNumberOfValues();
855 CPPUNIT_ASSERT(nbVals);
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.;
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));
866 aFieldOnGroup2->setValueIJ(anElems[i-1], 1, (double)i*i);
867 aFieldOnGroup2->setValueIJ(anElems[i-1], 2, (double)(-i*i));
870 eucl2 += 2. * i * i * i * i;
873 // out of bound (inexisting 33-th component of last element)
874 CPPUNIT_ASSERT_THROW(aFieldOnGroup1->setValueIJ(anElems[nbVals-1], 33, 10.), MEDEXCEPTION);
877 CPPUNIT_ASSERT_DOUBLES_EQUAL(nbVals, aFieldOnGroup1->normMax(), 0.000001);
878 CPPUNIT_ASSERT_DOUBLES_EQUAL(nbVals*nbVals, aFieldOnGroup2->normMax(), 0.000001);
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
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();
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_);
894 const double * aValues = aFieldOnGroup1->getValue();
897 CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getColumn(3), MEDEXCEPTION);
898 // cannot get column in FullInterlace
899 CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getColumn(1), MEDEXCEPTION);
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);
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);
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);
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);
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);
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);
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);
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);
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);
949 aFieldOnGroup2->fillFromAnalytic(proj2d);
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);
962 //cout << "barycenter (" << bary[0] << ", " << bary[1] << ", " << bary[2] << ")" << endl;
963 //cout << "proj2d (" << outp[0] << ", " << outp[1] << ")" << endl;
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 )
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);
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 )
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();
994 CPPUNIT_ASSERT_EQUAL(MED_EN::MED_TRIA3, aGeomTypes[0]);
995 CPPUNIT_ASSERT_EQUAL(MED_EN::MED_QUAD4, aGeomTypes[1]);
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);
1005 CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getGaussLocalization(MED_EN::MED_TRIA3), MEDEXCEPTION);
1006 CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getGaussLocalizationPtr(MED_EN::MED_TRIA3), MEDEXCEPTION);
1008 CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNbGaussI(anElems[0]));
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);
1016 aFieldOnGroup1->setGaussLocalization(MED_EN::MED_TRIA3, gl1);
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);
1024 CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getGaussLocalization(MED_EN::MED_QUAD4), MEDEXCEPTION);
1025 CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getGaussLocalizationPtr(MED_EN::MED_QUAD4), MEDEXCEPTION);
1027 GAUSS_LOCALIZATION<> gl1Back = aFieldOnGroup1->getGaussLocalization(MED_EN::MED_TRIA3);
1028 const GAUSS_LOCALIZATION<> * gl1BackPtr = aFieldOnGroup1->getGaussLocalizationPtr(MED_EN::MED_TRIA3);
1030 CPPUNIT_ASSERT(gl1 == gl1Back);
1031 CPPUNIT_ASSERT(gl1 == *gl1BackPtr);
1033 CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNbGaussI(anElems[0]));
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);
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];
1050 aSubSupport1->setpartial("Support for sub-field 1 on one type of elements",
1051 nbTypes1, nbElems1, aGeomTypes1, nbElemsInEachType1, anElems1);
1053 //cout << "aSubSupport1:" << endl;
1054 //cout << *aSubSupport1 << endl;
1056 // extract sub-field on aSubSupport1
1057 FIELD<double, FullInterlace> * aSubField1 = aFieldOnGroup1->extract(aSubSupport1);
1058 CPPUNIT_ASSERT_EQUAL(nbElems1 * /*NumberOfComponents = */2, aSubField1->getValueLength());
1062 //--------------------
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);
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
1079 CPPUNIT_ASSERT_DOUBLES_EQUAL(343.0, aSubField1->normL2() , 0.00001); // 210.5 + 132.5
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
1085 double aNewArea [2] = {1., 0.}; // only first element will be taken into account
1086 anAreaField->setValue(aNewArea);
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
1094 CPPUNIT_ASSERT_DOUBLES_EQUAL(340.0, aSubField1->normL2(anAreaField) , 0.00001); // 196 + 144
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
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
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
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);
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);
1131 CPPUNIT_ASSERT_THROW(aSubField1->setRow(3, row), MEDEXCEPTION);
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);
1142 CPPUNIT_ASSERT_DOUBLES_EQUAL( 1., aSubField1->getValueIJ(anElems1[1], 2), 0.000001);
1144 CPPUNIT_ASSERT_THROW(aSubField1->setColumn(3, col), MEDEXCEPTION);
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);
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.);
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) ?");
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.);
1171 aSubField1->setArray(aNewArrayGauss);
1172 // no need to delete aNewArrayGauss, because it will be deleted
1173 // in destructor or in deallocValue() method of aSubField1
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);
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) ?");
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);
1194 // alloc/dealloc; compatibility of new size with support
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();
1202 #ifdef ENABLE_FORCED_FAILURES
1203 CPPUNIT_FAIL("Error: no compatibility between Support and allocated value");
1206 catch (MEDEXCEPTION & ex) {
1210 CPPUNIT_FAIL("Error: no compatibility between Support and allocated value");
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);
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);
1225 int len = aFieldOnGroup1->getValueLength();
1226 const double * val1 = aFieldOnGroup1->getValue();
1227 const double * val2 = aFieldOnGroup2->getValue();
1228 const double * val_res;
1230 // operators and add, sub, mul, div
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);
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);
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);
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);
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);
1282 double val22 = aFieldOnGroup2->getValueIJ(anElems[2], 2);
1283 aFieldOnGroup2->setValueIJ(anElems[2], 2, 0.);
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);
1290 CPPUNIT_ASSERT_THROW(FIELD<double>::div(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION);
1291 CPPUNIT_ASSERT_THROW(FIELD<double>::divDeep(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION);
1294 aFieldOnGroup2->setValueIJ(anElems[2], 2, val22);
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);
1303 FIELD<double> * aPtr;
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
1430 const double * val3 = aFieldOnGroup3->getValue();
1432 //CPPUNIT_ASSERT_NO_THROW();
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);
1444 aPtr = FIELD<double>::subDeep(*aFieldOnGroup1, *aFieldOnGroup3);
1446 aPtr = FIELD<double>::mulDeep(*aFieldOnGroup1, *aFieldOnGroup3);
1448 aPtr = FIELD<double>::divDeep(*aFieldOnGroup1, *aFieldOnGroup3);
1451 catch (MEDEXCEPTION & ex) {
1452 CPPUNIT_FAIL(ex.what());
1455 CPPUNIT_FAIL("Unknown exception in FIELD::xxxDeep()");
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);
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);
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);
1473 // check case of different operands: MEDComponentsUnits
1474 aFieldOnGroup1->setMEDComponentUnit(1, "unit3");
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);
1485 //CPPUNIT_ASSERT_NO_THROW();
1487 aPtr = FIELD<double>::mul(*aFieldOnGroup1, *aFieldOnGroup2);
1489 aPtr = FIELD<double>::div(*aFieldOnGroup1, *aFieldOnGroup2);
1491 aPtr = FIELD<double>::mulDeep(*aFieldOnGroup1, *aFieldOnGroup2);
1493 aPtr = FIELD<double>::divDeep(*aFieldOnGroup1, *aFieldOnGroup2);
1496 *aFieldOnGroup1 *= *aFieldOnGroup2;
1497 *aFieldOnGroup1 /= *aFieldOnGroup2;
1499 FIELD<double> aPr = *aFieldOnGroup1 * *aFieldOnGroup2;
1500 FIELD<double> aQu = *aFieldOnGroup1 / *aFieldOnGroup2;
1502 catch (MEDEXCEPTION & ex) {
1503 CPPUNIT_FAIL(ex.what());
1506 CPPUNIT_FAIL("Unknown exception");
1509 // restore MED units
1510 aFieldOnGroup1->setMEDComponentUnit(1, "unit1");
1512 // check case of different operands: valueType
1513 //FIELD<int> * aFieldOnGroup4 =
1514 // createFieldOnGroup<int>(aMeshOneMore, aGroupOneMore, "Test_Diff_Mesh", "test");
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;
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);
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.");
1532 aFieldOnGroup1->setNumberOfComponents(5);
1534 CPPUNIT_ASSERT_THROW(FIELD<double>::sub(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION);
1535 CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 * *aFieldOnGroup2, MEDEXCEPTION);
1536 CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 /= *aFieldOnGroup2, MEDEXCEPTION);
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
1543 CPPUNIT_ASSERT_THROW(FIELD<double>::mul(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION);
1544 CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 / *aFieldOnGroup2, MEDEXCEPTION);
1545 CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 += *aFieldOnGroup2, MEDEXCEPTION);
1547 // restore aFieldOnGroup1
1548 aFieldOnGroup1->deallocValue();
1549 aFieldOnGroup1->allocValue(2, nbVals);
1550 // be carefull: aFieldOnGroup1 reallocated and contains random values
1552 delete aSubSupport1;
1555 delete aScalarProduct;
1559 delete aFieldOnGroup1;
1560 delete aFieldOnGroup2;
1561 delete aFieldOnGroup3;
1564 delete aMeshOneMore;
1566 /////////////////////
1567 // TEST 5: Drivers //
1568 /////////////////////
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);
1577 void MEDMEMTest::testFieldConvert()
1579 // create an empty integer field 2x10
1580 FIELD<int, FullInterlace> * aField_FING = new FIELD<int, FullInterlace> ();
1582 aField_FING->setName("Field_FING");
1583 aField_FING->setDescription("Field full interlace no gauss");
1585 aField_FING->setNumberOfComponents(2);
1586 aField_FING->setNumberOfValues(10);
1588 string aCompsNames[2] = {"Pos", "Neg"};
1589 string aCompsDescs[2] = {"+", "-"};
1590 string aMEDCompsUnits[2] = {"unit1", "unit2"};
1591 UNIT aCompsUnits[2];
1593 aCompsUnits[0] = UNIT("u1", "descr1");
1594 aCompsUnits[1] = UNIT("u2", "descr2");
1596 aField_FING->setComponentsNames(aCompsNames);
1597 aField_FING->setComponentsDescriptions(aCompsDescs);
1598 aField_FING->setMEDComponentsUnits(aMEDCompsUnits);
1599 aField_FING->setComponentsUnits(aCompsUnits);
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());
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());
1611 // create one more field by copy
1612 FIELD<int, FullInterlace> * aField_FIGG = new FIELD<int, FullInterlace> (*aField_FING);
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};
1618 /////////////////////
1619 // TEST 1: NoGauss //
1620 /////////////////////
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
1628 // 1. FullInterlace -> NoInterlace
1629 FIELD<int, NoInterlace> * aField_NING = FieldConvert(*aField_FING);
1630 const int * values_NING = aField_NING->getValue();
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]);
1638 // 2. NoInterlace -> FullInterlace
1639 FIELD<int, FullInterlace> * aField_FING_conv = FieldConvert(*aField_NING);
1640 const int * values_FING_conv = aField_FING_conv->getValue();
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]);
1651 delete aField_FING_conv;
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
1665 // 1. FullInterlace -> NoInterlace
1666 FIELD<int, NoInterlace> * aField_NIGG = FieldConvert(*aField_FIGG);
1667 const int * values_NIGG = aField_NIGG->getValue();
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]);
1675 // 2. NoInterlace -> FullInterlace
1676 FIELD<int, FullInterlace> * aField_FIGG_conv = FieldConvert(*aField_NIGG);
1677 const int * values_FIGG_conv = aField_FIGG_conv->getValue();
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]);
1688 delete aField_FIGG_conv;
1690 #ifdef ENABLE_FAULTS
1691 // (BUG) in FieldConvert(), concerning FIELD_::operator=
1693 // create an empty integer field 2x10
1694 FIELD<int, FullInterlace> * aField = new FIELD<int, FullInterlace> ();
1696 aField->setName("aField");
1697 aField->setDescription("Field full interlace no gauss");
1699 aField->setNumberOfComponents(2);
1700 aField->setNumberOfValues(10);
1702 aField->setComponentsNames(aCompsNames);
1703 aField->setComponentsDescriptions(aCompsDescs);
1704 aField->setMEDComponentsUnits(aMEDCompsUnits);
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
1712 FIELD<int, NoInterlace> * aField_conv = FieldConvert(*aField);
1715 #ifdef ENABLE_FORCED_FAILURES
1716 CPPUNIT_FAIL("FieldConvert() fails if _componentsUnits is not set, because it calls FIELD_::operator=");