1 // Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "MEDMEMTest.hxx"
22 #include "MEDMEM_FieldConvert.hxx"
23 #include "MEDMEM_Field.hxx"
24 #include "MEDMEM_MedMeshDriver.hxx"
25 #include "MEDMEM_Grid.hxx"
26 #include "MEDMEM_Group.hxx"
27 #include "MEDMEM_Mesh.hxx"
28 #include "MEDMEM_Meshing.hxx"
29 #include "MEDMEM_Support.hxx"
30 #include "MEDMEM_VtkMeshDriver.hxx"
33 #include <cppunit/TestAssert.h>
37 // use this define to enable lines, execution of which leads to Segmentation Fault
38 //#define ENABLE_FAULTS
40 // use this define to enable CPPUNIT asserts and fails, showing bugs
41 //#define ENABLE_FORCED_FAILURES
44 using namespace MEDMEM;
46 // #14,15: MEDMEMTest_Field.cxx
47 // Check methods from MEDMEM_Field.hxx, MEDMEM_FieldConvert.hxx
50 * Check methods (48), defined in MEDMEM_Field.hxx:
54 * (+) FIELD_(const SUPPORT * Support, const int NumberOfComponents);
55 * (+) FIELD_(const FIELD_ &m);
56 * (+) virtual ~FIELD_();
57 * (+) FIELD_& operator=(const FIELD_ &m);
59 * (-) virtual void rmDriver(int index=0);
60 * (-) virtual int addDriver(driverTypes driverType,
61 * const string & fileName="Default File Name.med",
62 * const string & driverFieldName="Default Field Nam",
63 * MED_EN::med_mode_acces access=MED_EN::MED_REMP);
64 * (-) virtual int addDriver(GENDRIVER & driver);
66 * (-) virtual void read (const GENDRIVER &);
67 * (-) virtual void read(int index=0);
68 * (-) virtual void openAppend(void);
69 * (-) virtual void write(const GENDRIVER &);
70 * (-) virtual void write(int index=0, const string & driverName="");
71 * (-) virtual void writeAppend(const GENDRIVER &);
72 * (-) virtual void writeAppend(int index=0, const string & driverName="");
74 * (+) inline void setName(const string Name);
75 * (+) inline string getName() const;
76 * (+) inline void setDescription(const string Description);
77 * (+) inline string getDescription() const;
78 * (+) inline const SUPPORT * getSupport() const;
79 * (+) inline void setSupport(const SUPPORT * support);
80 * (+) inline void setNumberOfComponents(const int NumberOfComponents);
81 * (+) inline int getNumberOfComponents() const;
82 * (+) inline void setNumberOfValues(const int NumberOfValues);
83 * (+) inline int getNumberOfValues() const;
84 * (+) inline void setComponentsNames(const string * ComponentsNames);
85 * (+) inline void setComponentName(int i, const string ComponentName);
86 * (+) inline const string * getComponentsNames() const;
87 * (+) inline string getComponentName(int i) const;
88 * (+) inline void setComponentsDescriptions(const string * ComponentsDescriptions);
89 * (+) inline void setComponentDescription(int i, const string ComponentDescription);
90 * (+) inline const string * getComponentsDescriptions() const;
91 * (+) inline string getComponentDescription(int i) const;
92 * (+) inline void setComponentsUnits(const UNIT * ComponentsUnits);
93 * (+) inline const UNIT * getComponentsUnits() const;
94 * (+) inline const UNIT * getComponentUnit(int i) const;
95 * (+) inline void setMEDComponentsUnits(const string * MEDComponentsUnits);
96 * (+) inline void setMEDComponentUnit(int i, const string MEDComponentUnit);
97 * (+) inline const string * getMEDComponentsUnits() const;
98 * (+) inline string getMEDComponentUnit(int i) const;
100 * (+) inline void setIterationNumber(int IterationNumber);
101 * (+) inline int getIterationNumber() const;
102 * (+) inline void setTime(double Time);
103 * (+) inline double getTime() const;
104 * (+) inline void setOrderNumber(int OrderNumber);
105 * (+) inline int getOrderNumber() const;
107 * (+) inline MED_EN::med_type_champ getValueType () const;
108 * (+) inline MED_EN::medModeSwitch getInterlacingType() const;
109 * (-) virtual inline bool getGaussPresence() const throw (MEDEXCEPTION);
113 * template <class T, class INTERLACING_TAG> class FIELD : public FIELD_
116 * (+) FIELD(const FIELD &m);
117 * (+) FIELD(const SUPPORT * Support, const int NumberOfComponents) throw (MEDEXCEPTION);
118 * (+) FIELD(driverTypes driverType,
119 * const string & fileName, const string & fieldDriverName,
120 * const int iterationNumber=-1, const int orderNumber=-1) throw (MEDEXCEPTION);
121 * (+) FIELD(const SUPPORT * Support, driverTypes driverType,
122 * const string & fileName="", const string & fieldName="",
123 * const int iterationNumber = -1, const int orderNumber = -1) throw (MEDEXCEPTION);
125 * (+) FIELD & operator=(const FIELD &m);
127 * (+) const FIELD operator+(const FIELD& m) const;
128 * (+) const FIELD operator-(const FIELD& m) const;
129 * (+) const FIELD operator*(const FIELD& m) const;
130 * (+) const FIELD operator/(const FIELD& m) const;
131 * (+) const FIELD operator-() const;
132 * (+) FIELD& operator+=(const FIELD& m);
133 * (+) FIELD& operator-=(const FIELD& m);
134 * (+) FIELD& operator*=(const FIELD& m);
135 * (+) FIELD& operator/=(const FIELD& m);
137 * (+) static FIELD* add(const FIELD& m, const FIELD& n);
138 * (+) static FIELD* addDeep(const FIELD& m, const FIELD& n);
139 * (+) static FIELD* sub(const FIELD& m, const FIELD& n);
140 * (+) static FIELD* subDeep(const FIELD& m, const FIELD& n);
141 * (+) static FIELD* mul(const FIELD& m, const FIELD& n);
142 * (+) static FIELD* mulDeep(const FIELD& m, const FIELD& n);
143 * (+) static FIELD* div(const FIELD& m, const FIELD& n);
144 * (+) static FIELD* divDeep(const FIELD& m, const FIELD& n);
146 * (+) double normMax() const throw (MEDEXCEPTION);
147 * (+) double norm2() const throw (MEDEXCEPTION);
149 * (+) void applyLin(T a, T b);
150 * (+) template <T T_function(T)> void applyFunc();
151 * (+) void applyPow(T scalar);
153 * (+) static FIELD* scalarProduct(const FIELD& m, const FIELD& n, bool deepCheck=false);
155 * (+) double normL2(int component, const FIELD<double,FullInterlace> * p_field_volume=NULL) const;
156 * (+) double normL2(const FIELD<double,FullInterlace> * p_field_volume=NULL) const;
157 * (+) double normL1(int component, const FIELD<double,FullInterlace> * p_field_volume=NULL) const;
158 * (+) double normL1(const FIELD<double,FullInterlace> * p_field_volume=NULL) const;
160 * (+) FIELD* extract(const SUPPORT *subSupport) const throw (MEDEXCEPTION);
162 * (EMPTY COMMENT, EMPTY IMPLEMENTATION!!!) void init ();
164 * (+) void rmDriver(int index=0);
165 * (+) int addDriver(driverTypes driverType,
166 * const string & fileName="Default File Name.med",
167 * const string & driverFieldName="Default Field Name",
168 * MED_EN::med_mode_acces access=MED_EN::MED_REMP);
169 * (+) int addDriver(GENDRIVER & driver);
171 * (+) void allocValue(const int NumberOfComponents);
172 * (+) void allocValue(const int NumberOfComponents, const int LengthValue);
173 * (+) void deallocValue();
175 * (+) inline void read(int index=0);
176 * (+) inline void read(const GENDRIVER & genDriver);
177 * (+) inline void read(driverTypes driverType, const std::string& filename);
178 * (+) inline void write(int index=0);
179 * (+) inline void write(const GENDRIVER &,
180 * MED_EN::med_mode_acces medMode=MED_EN::RDWR);
181 * (+) inline void write(driverTypes driverType, const std::string& filename,
182 * MED_EN::med_mode_acces medMode=MED_EN::RDWR);
183 * (+) inline void writeAppend(int index=0, const string & driverName = "");
184 * (+) inline void writeAppend(const GENDRIVER &);
186 * (+) inline MEDMEM_Array_ * getArray() const throw (MEDEXCEPTION);
187 * (+) inline ArrayGauss * getArrayGauss() const throw (MEDEXCEPTION);
188 * (+) inline ArrayNoGauss * getArrayNoGauss() const throw (MEDEXCEPTION);
189 * (+) inline bool getGaussPresence() const throw (MEDEXCEPTION);
191 * (+) inline int getValueLength() const throw (MEDEXCEPTION);
192 * (+) inline const T* getValue() const throw (MEDEXCEPTION);
193 * (+) inline const T* getRow(int i) const throw (MEDEXCEPTION);
194 * (+) inline const T* getColumn(int j) const throw (MEDEXCEPTION);
195 * (+) inline T getValueIJ(int i,int j) const throw (MEDEXCEPTION);
196 * (+) inline T getValueIJK(int i,int j,int k) const throw (MEDEXCEPTION);
197 * (+) bool getValueOnElement(int eltIdInSup,T* retValues) const throw (MEDEXCEPTION);
199 * (+) const int getNumberOfGeometricTypes() const throw (MEDEXCEPTION);
201 * (+) const GAUSS_LOCALIZATION<INTERLACING_TAG> & getGaussLocalization
202 * (MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION);
203 * (+) const GAUSS_LOCALIZATION<INTERLACING_TAG> * getGaussLocalizationPtr
204 * (MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION);
205 * (+) void setGaussLocalization(MED_EN::medGeometryElement geomElement,
206 * const GAUSS_LOCALIZATION<INTERLACING_TAG> & gaussloc);
207 * (+) const int * getNumberOfGaussPoints() const throw (MEDEXCEPTION);
208 * (+) const int getNumberOfGaussPoints
209 * (MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION);
210 * (+) const int getNbGaussI(int i) const throw (MEDEXCEPTION);
212 * (+) const int * getNumberOfElements() const throw (MEDEXCEPTION);
213 * (+) const MED_EN::medGeometryElement * getGeometricTypes() const throw (MEDEXCEPTION);
214 * (+) bool isOnAllElements() const throw (MEDEXCEPTION);
216 * (+) inline void setArray(MEDMEM_Array_ *value) throw (MEDEXCEPTION);
217 * (+) FIELD<double, FullInterlace>* getGaussPointsCoordinates() const throw (MEDEXCEPTION);
218 * (+) inline void setValue(T* value) throw (MEDEXCEPTION);
219 * (+) inline void setRow(int i, T* value) throw (MEDEXCEPTION);
220 * (+) inline void setColumn(int i, T* value) throw (MEDEXCEPTION);
221 * (+) inline void setValueIJ(int i, int j, T value) throw (MEDEXCEPTION);
223 * (NOT IMPLEMENTED!!!) void getVolume() const throw (MEDEXCEPTION);
224 * (NOT IMPLEMENTED!!!) void getArea() const throw (MEDEXCEPTION);
225 * (NOT IMPLEMENTED!!!) void getLength() const throw (MEDEXCEPTION);
226 * (NOT IMPLEMENTED!!!) void getNormal() const throw (MEDEXCEPTION);
227 * (NOT IMPLEMENTED!!!) void getBarycenter() const throw (MEDEXCEPTION);
229 * (+) void fillFromAnalytic(myFuncType f) throw (MEDEXCEPTION);
233 * Use code of test_operation_fieldint.cxx
234 * test_operation_fielddouble.cxx
235 * test_copie_field_.cxx
236 * test_copie_fieldT.cxx
238 static void compareField_(const FIELD_ * theField_1, const FIELD_ * theField_2, bool isFIELD, bool isValue)
240 // name, description, support
241 CPPUNIT_ASSERT_EQUAL(theField_1->getName(), theField_2->getName());
242 CPPUNIT_ASSERT_EQUAL(theField_1->getDescription(), theField_2->getDescription());
243 CPPUNIT_ASSERT_EQUAL(theField_1->getSupport(), theField_2->getSupport());
245 // components information
246 int aNbComps = theField_1->getNumberOfComponents();
247 CPPUNIT_ASSERT_EQUAL(aNbComps, theField_2->getNumberOfComponents());
249 for (int i = 1; i <= aNbComps; i++)
251 CPPUNIT_ASSERT_EQUAL(theField_1->getComponentName(i), theField_2->getComponentName(i));
252 CPPUNIT_ASSERT_EQUAL(theField_1->getComponentDescription(i), theField_2->getComponentDescription(i));
253 CPPUNIT_ASSERT_EQUAL(theField_1->getMEDComponentUnit(i), theField_2->getMEDComponentUnit(i));
256 // iteration information
257 CPPUNIT_ASSERT_EQUAL(theField_1->getIterationNumber(), theField_2->getIterationNumber());
258 CPPUNIT_ASSERT_EQUAL(theField_1->getOrderNumber(), theField_2->getOrderNumber());
259 CPPUNIT_ASSERT_DOUBLES_EQUAL(theField_1->getTime(), theField_2->getTime(), 0.0000001);
262 int nbOfValues = theField_1->getNumberOfValues();
263 CPPUNIT_ASSERT_EQUAL(nbOfValues, theField_2->getNumberOfValues());
267 // Value type and Interlacing type
268 CPPUNIT_ASSERT_EQUAL(theField_1->getValueType(), theField_2->getValueType());
269 CPPUNIT_ASSERT_EQUAL(theField_1->getInterlacingType(), theField_2->getInterlacingType());
274 CPPUNIT_ASSERT_EQUAL(theField_1->getGaussPresence(), theField_2->getGaussPresence());
278 CPPUNIT_ASSERT_THROW(theField_1->getGaussPresence(), MEDEXCEPTION);
279 CPPUNIT_ASSERT_THROW(theField_2->getGaussPresence(), MEDEXCEPTION);
284 CPPUNIT_ASSERT_THROW(theField_1->getGaussPresence(), MEDEXCEPTION);
285 CPPUNIT_ASSERT_THROW(theField_2->getGaussPresence(), MEDEXCEPTION);
289 static void checkField_(FIELD_ * theField_, const SUPPORT * theSupport,
290 MED_EN::med_type_champ theValueType,
291 MED_EN::medModeSwitch theInterlace)
294 const string aFieldName = "a_name_of_a_field";
295 theField_->setName(aFieldName);
296 CPPUNIT_ASSERT_EQUAL(aFieldName, theField_->getName());
299 const string aFieldDescr = "a_description_of_a_field";
300 theField_->setDescription(aFieldDescr);
301 CPPUNIT_ASSERT_EQUAL(aFieldDescr, theField_->getDescription());
304 theField_->setSupport(theSupport);
305 CPPUNIT_ASSERT(theField_->getSupport() == theSupport);
307 // components information
310 string aCompsNames[3] =
314 string aCompsDescs[3] =
316 "vitesse selon x", "vitesse selon y", "vitesse selon z"
318 string aCompsUnits[3] =
320 "m.s-1", "m.s-1", "m.s-1"
323 theField_->setNumberOfComponents(aNbComps);
324 CPPUNIT_ASSERT_EQUAL(aNbComps, theField_->getNumberOfComponents());
326 theField_->setComponentsNames(aCompsNames);
328 //#ifdef ENABLE_FAULTS
331 theField_->setNumberOfComponents(7);
332 // Segmentation fault here because array of components names is not resized
333 for (int i = 1; i <= 7; i++)
335 theField_->setComponentName(i, "AnyComponent");
338 catch (MEDEXCEPTION& ex)
340 // Ok, it is good to have MEDEXCEPTION here
344 CPPUNIT_FAIL("Unknown exception cought");
346 // restore components names
347 theField_->setNumberOfComponents(aNbComps);
348 theField_->setComponentsNames(aCompsNames);
350 theField_->setComponentsDescriptions(aCompsDescs);
351 theField_->setMEDComponentsUnits(aCompsUnits);
353 const string * aCompsNamesBack = theField_->getComponentsNames();
354 const string * aCompsDescsBack = theField_->getComponentsDescriptions();
355 const string * aCompsUnitsBack = theField_->getMEDComponentsUnits();
356 for (int i = 1; i <= aNbComps; i++)
358 CPPUNIT_ASSERT_EQUAL(aCompsNamesBack[i-1], theField_->getComponentName(i));
359 CPPUNIT_ASSERT_EQUAL(aCompsNamesBack[i-1], aCompsNames[i-1]);
361 CPPUNIT_ASSERT_EQUAL(aCompsDescsBack[i-1], theField_->getComponentDescription(i));
362 CPPUNIT_ASSERT_EQUAL(aCompsDescsBack[i-1], aCompsDescs[i-1]);
364 CPPUNIT_ASSERT_EQUAL(aCompsUnitsBack[i-1], theField_->getMEDComponentUnit(i));
365 CPPUNIT_ASSERT_EQUAL(aCompsUnitsBack[i-1], aCompsUnits[i-1]);
368 const string aCompName2 ("Name of second component");
369 const string aCompDesc2 ("Description of second component");
370 const string aCompUnit2 ("Unit of second MED component");
372 theField_->setComponentName(2, aCompName2);
373 theField_->setComponentDescription(2, aCompDesc2);
374 theField_->setMEDComponentUnit(2, aCompUnit2);
376 const string * aCompsNamesBack2 = theField_->getComponentsNames();
377 const string * aCompsDescsBack2 = theField_->getComponentsDescriptions();
378 const string * aCompsUnitsBack2 = theField_->getMEDComponentsUnits();
380 CPPUNIT_ASSERT_EQUAL(aCompsNamesBack2[1], theField_->getComponentName(2));
381 CPPUNIT_ASSERT_EQUAL(aCompsNamesBack2[1], aCompName2);
383 CPPUNIT_ASSERT_EQUAL(aCompsDescsBack2[1], theField_->getComponentDescription(2));
384 CPPUNIT_ASSERT_EQUAL(aCompsDescsBack2[1], aCompDesc2);
386 CPPUNIT_ASSERT_EQUAL(aCompsUnitsBack2[1], theField_->getMEDComponentUnit(2));
387 CPPUNIT_ASSERT_EQUAL(aCompsUnitsBack2[1], aCompUnit2);
389 CPPUNIT_ASSERT_THROW(theField_->setComponentName(0, "str"), MEDEXCEPTION);
390 CPPUNIT_ASSERT_THROW(theField_->setComponentName(aNbComps + 1, "str"), MEDEXCEPTION);
391 CPPUNIT_ASSERT_THROW(theField_->setComponentDescription(0, "str"), MEDEXCEPTION);
392 CPPUNIT_ASSERT_THROW(theField_->setComponentDescription(aNbComps + 1, "str"), MEDEXCEPTION);
393 CPPUNIT_ASSERT_THROW(theField_->setMEDComponentUnit(0, "str"), MEDEXCEPTION);
394 CPPUNIT_ASSERT_THROW(theField_->setMEDComponentUnit(aNbComps + 1, "str"), MEDEXCEPTION);
396 // iteration information
397 int anIterNumber = 10; // set value to MED_NOPDT if undefined (default)
398 theField_->setIterationNumber(anIterNumber);
399 CPPUNIT_ASSERT_EQUAL(anIterNumber, theField_->getIterationNumber());
401 int anOrderNumber = 1; // set value to MED_NONOR if undefined (default)
402 theField_->setOrderNumber(anOrderNumber);
403 CPPUNIT_ASSERT_EQUAL(anOrderNumber, theField_->getOrderNumber());
405 double aTime = 3.435678; // in second
406 theField_->setTime(aTime);
407 CPPUNIT_ASSERT_DOUBLES_EQUAL(aTime, theField_->getTime(), 0.0000001);
411 // dangerous method, because it does not reallocate values array
412 theField_->setNumberOfValues(nbOfValues);
413 CPPUNIT_ASSERT_EQUAL(nbOfValues, theField_->getNumberOfValues());
415 // Value type and Interlacing type
416 CPPUNIT_ASSERT_EQUAL(theValueType, theField_->getValueType());
417 CPPUNIT_ASSERT_EQUAL(theInterlace, theField_->getInterlacingType());
420 template<class T, class INTERLACING_TAG>
421 void compareField(const FIELD<T, INTERLACING_TAG> * theField_1,
422 const FIELD<T, INTERLACING_TAG> * theField_2, bool isValue)
424 // compare FIELD_ part
425 compareField_(theField_1, theField_2, /*isFIELD = */true, isValue);
427 // compare FIELD part
431 template<class T, class INTERLACING_TAG>
432 void checkField (FIELD<T, INTERLACING_TAG> * theField, const SUPPORT * theSupport)
435 MED_EN::med_type_champ aValueType = SET_VALUE_TYPE<T>::_valueType;
436 MED_EN::medModeSwitch anInterlace = SET_INTERLACING_TYPE<INTERLACING_TAG>::_interlacingType;
437 checkField_(theField, theSupport, aValueType, anInterlace);
441 // filling by support charackteristics (NOT IMPLEMENTED METHODS!!!):
442 // value type must be MED_REEL64 (i.e. a FIELD<double>) for these methods,
443 // nb. of components must be equal 1 (for Volume, Area, Length) or
444 // space dimension (for Normal, Barycenter, )
446 const GMESH* aMesh = theSupport->getMesh();
448 if (aMesh) spaceDim = aMesh->getSpaceDimension();
449 theField->deallocValue();
450 theField->allocValue(/*NumberOfComponents = */spaceDim + 1);
452 theField->deallocValue();
453 theField->allocValue(/*NumberOfComponents = */1);
457 theField->deallocValue();
458 theField->allocValue(/*NumberOfComponents = */spaceDim);
463 theField->deallocValue();
464 theField->allocValue(/*NumberOfComponents = */spaceDim);
465 // 0020142: [CEA 315] Unused function in MEDMEM::FIELD
466 // getVolume() etc. does nothing
467 // if (aValueType == MED_EN::MED_REEL64)
469 // CPPUNIT_ASSERT_NO_THROW(theField->getNormal());
470 // CPPUNIT_ASSERT_NO_THROW(theField->getBarycenter());
475 // CPPUNIT_ASSERT_THROW(theField->getNormal(), MEDEXCEPTION);
476 // CPPUNIT_ASSERT_THROW(theField->getBarycenter(), MEDEXCEPTION);
483 theField->deallocValue();
484 theField->allocValue(/*NumberOfComponents = */2);
485 int nbElemSupport = theSupport->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS);
486 CPPUNIT_ASSERT_EQUAL(nbElemSupport, theField->getNumberOfValues());
488 theField->deallocValue();
489 CPPUNIT_ASSERT_THROW(theField->getGaussPresence(), MEDEXCEPTION);
492 FIELD<T, INTERLACING_TAG> *aField_copy1= new FIELD<T, INTERLACING_TAG>(*theField);
493 compareField(theField, aField_copy1, /*isValue = */false);
494 aField_copy1->removeReference();
497 FIELD<T, INTERLACING_TAG> *aField_copy2=new FIELD<T, INTERLACING_TAG>();
498 *aField_copy2 = *theField;
499 compareField(theField, aField_copy2, /*isValue = */false);
500 aField_copy2->removeReference();
504 FIELD<T> * createFieldOnGroup(MESH* theMesh, const GROUP* theGroup,
505 const string theName, const string theDescr)
507 FIELD<T> * aFieldOnGroup = new FIELD<T>(theGroup, /*NumberOfComponents = */2);
509 aFieldOnGroup->setName(theName);
510 aFieldOnGroup->setDescription(theDescr);
512 string aCompsNames[2] =
516 string aCompsDescs[2] =
520 string aCompsUnits[2] =
525 aFieldOnGroup->setComponentsNames(aCompsNames);
526 aFieldOnGroup->setComponentsDescriptions(aCompsDescs);
527 aFieldOnGroup->setMEDComponentsUnits(aCompsUnits);
529 return aFieldOnGroup;
532 double plus13 (double val);
533 double plus13 (double val)
538 // function to calculate field values from coordinates of an element
539 // typedef void (*myFuncType)(const double * temp, T* output);
540 // size of temp array = space dim = 3
541 // size of output array = nb. comps = 2
542 static void proj2d (const double * temp, double* output)
544 // dimetric projection with coefficients:
545 // 1.0 along Oy and Oz, 0.5 along Ox
554 // x_ = y - x * sqrt(2.) / 4.
555 // y_ = z - x * sqrt(2.) / 4.
557 double dx = temp[0] * std::sqrt(2.) / 4.;
558 output[0] = temp[1] - dx;
559 output[1] = temp[2] - dx;
562 static void testDrivers()
564 string filename_rd = getResourceFile("pointe.med");
565 string filename_wr = makeTmpFile("myMedFieldfile.med", filename_rd);
566 string filename_support_wr = makeTmpFile("myMedSupportFiledfile.med");
567 string filename22_rd = getResourceFile("pointe.med");
568 string filenamevtk_wr = makeTmpFile("myMedFieldfile22.vtk");
570 string fieldname_celldouble_rd = "fieldcelldoublescalar";
571 string fieldname_celldouble_wr = fieldname_celldouble_rd + "_cpy";
572 string fieldname_nodeint_rd = "fieldnodeint";
573 string fieldname_nodeint_wr = fieldname_nodeint_rd + "_cpy";
574 string fieldname_nodeint_wr1 = fieldname_nodeint_rd + "_cpy1";
575 string meshname = "maa1";
577 // To remove tmp files from disk
578 MEDMEMTest_TmpFilesRemover aRemover;
579 aRemover.Register(filename_wr);
580 aRemover.Register(filenamevtk_wr);
581 aRemover.Register(filename_support_wr);
583 FIELD<int> *aInvalidField=new FIELD<int>();
584 //must throw becase only VTK_DRIVER or MED_DRIVER may be specified as driverType for FIELD
585 CPPUNIT_ASSERT_THROW(*aInvalidField = *(new FIELD<int>(NO_DRIVER, filename_rd, fieldname_nodeint_rd)),
587 CPPUNIT_ASSERT_THROW(*aInvalidField = *(new FIELD<int>(GIBI_DRIVER, filename_rd, fieldname_nodeint_rd)),
589 CPPUNIT_ASSERT_THROW(*aInvalidField = *(new FIELD<int>(PORFLOW_DRIVER, filename_rd, fieldname_nodeint_rd)),
591 CPPUNIT_ASSERT_THROW(*aInvalidField = *(new FIELD<int>(ASCII_DRIVER, filename_rd, fieldname_nodeint_rd)),
593 aInvalidField->removeReference();
597 FIELD<double> *aField_1 = NULL;
598 CPPUNIT_ASSERT_NO_THROW(aField_1 = new FIELD<double>(MED_DRIVER, filename_rd,
599 fieldname_celldouble_rd));
601 //Test read(int index) method
602 int IdDriver_rd = aField_1->addDriver(MED_DRIVER,filename_rd,fieldname_celldouble_rd,MED_EN::RDONLY);
603 // TODO: throw if read for the second time
604 // (BUG) Cannot open file, but file exist
605 // EAP: no more pb with opening the file for the second time with "weaker" mode,
606 // but why to re-read the field?
607 //CPPUNIT_ASSERT_THROW(aField_1->read(IdDriver_rd),MEDEXCEPTION);
608 CPPUNIT_ASSERT_NO_THROW(aField_1->read(IdDriver_rd));
610 //Test read(GENDRIVER & genDriver) method
611 FIELD<int> *aField_2 = new FIELD<int>();
612 aField_2->setName(fieldname_nodeint_rd);
614 MED_FIELD_RDONLY_DRIVER<int> aMedRdFieldDriver;
615 aMedRdFieldDriver.setFileName(filename_rd);
616 aField_2->read( aMedRdFieldDriver );
618 //Test read(driverTypes driverType, const std::string & fileName);
619 FIELD<double> * aField_3 = new FIELD<double>();
620 aField_3->setName(fieldname_celldouble_rd);
621 aField_3->read( MED_DRIVER, filename_rd);
627 MESH *aMesh = new MESH(MED_DRIVER,filename_rd,meshname);
628 const SUPPORT *aSupport = aMesh->getSupportOnAll(MED_CELL);
629 FIELD<int> *aFieldSupport;
630 CPPUNIT_ASSERT_THROW(aFieldSupport =
631 new FIELD<int>(aSupport, MED_DRIVER,filename_rd,
632 fieldname_nodeint_rd), MEDMEM::MEDEXCEPTION);
633 aSupport = aMesh->getSupportOnAll(MED_NODE);
634 CPPUNIT_ASSERT_NO_THROW(aFieldSupport =
635 new FIELD<int>(aSupport, MED_DRIVER, filename_rd,
636 fieldname_nodeint_rd));
637 aFieldSupport->removeReference();
639 //Test write(int index) method
640 // Add drivers to FIELDs
641 int IdDriver1 = aField_3->addDriver(MED_DRIVER,filename_wr,fieldname_celldouble_wr);
643 //Trying call write(int index) method with incorrect index
644 CPPUNIT_ASSERT_THROW(aField_3->write(IdDriver1+1),MEDEXCEPTION);
646 //Write field to file
647 aField_3->write(IdDriver1);
649 CPPUNIT_ASSERT_NO_THROW(aField_3->rmDriver(IdDriver1));
651 //Test write(const GENDRIVER &, MED_EN::med_mode_acces medMode=MED_EN::RDWR);
653 MED_FIELD_WRONLY_DRIVER<int> aMedWrFieldDriver;
654 aMedWrFieldDriver.setFileName(filename_wr);
656 aField_3->setName(fieldname_nodeint_wr);
657 aField_3->write(aMedWrFieldDriver);
658 FIELD<double> aField_3_RD;
659 aField_3_RD.setName(fieldname_nodeint_wr);
660 aField_3_RD.read(MED_DRIVER,filename_wr);
663 // Test write(driverTypes driverType, const std::string& filename
664 // MED_EN::med_mode_acces medMode=MED_EN::RDWR)
665 aField_3->setName(fieldname_nodeint_wr1);
667 CPPUNIT_ASSERT_THROW(aField_3->write(MED_DRIVER,filename_wr,MED_EN::RDONLY), MEDEXCEPTION);
668 aField_3->write(MED_DRIVER,filename_wr);
670 FIELD<double> aField_3_RD;
671 aField_3_RD.setName(fieldname_nodeint_wr1);
672 aField_3_RD.read(MED_DRIVER,filename_wr);
674 aField_3->setName("fieldname_nodeint_wr1");
675 aField_3->write(MED_DRIVER,filename_wr, MED_EN::WRONLY);// overwrite filename_wr
677 FIELD<double> aField_3_RD;
678 aField_3_RD.setName(fieldname_nodeint_wr1);
679 CPPUNIT_ASSERT_THROW(aField_3_RD.read(MED_DRIVER,filename_wr),MEDEXCEPTION);
681 //Test writeAppend(int index) method
683 MESH * aMesh_1 = new MESH(MED_DRIVER,filename22_rd, meshname);
684 aMesh_1->write(VTK_DRIVER, filenamevtk_wr);
686 FIELD<int> * aField_4 =
687 new FIELD<int>(MED_DRIVER,filename22_rd,fieldname_nodeint_rd,-1,-1,aMesh_1);
688 //Add Driver to a field
689 int IdDriver2 = aField_4->addDriver(VTK_DRIVER, filenamevtk_wr ,fieldname_nodeint_wr);
690 //Trying call writeAppend() method with incorrect index
691 CPPUNIT_ASSERT_THROW(aField_4->writeAppend(IdDriver2+1,fieldname_nodeint_wr),MEDEXCEPTION);
693 CPPUNIT_ASSERT_NO_THROW(aField_4->writeAppend(IdDriver2, fieldname_nodeint_wr));
695 //Test writeAppend(const GENDRIVER &) method
696 aField_4->setName(fieldname_nodeint_wr1);
698 VTK_FIELD_DRIVER<int> aVtkFieldDriver(filenamevtk_wr, aField_4);
699 CPPUNIT_ASSERT_NO_THROW(aField_4->writeAppend(aVtkFieldDriver));
703 aField_1->removeReference();
704 aField_2->removeReference();
705 aField_3->removeReference();
706 aField_4->removeReference();
707 aMesh->removeReference();
708 aMesh_1->removeReference();
711 void MEDMEMTest::testField()
713 SUPPORT *anEmptySupport=new SUPPORT;
717 FIELD_ *aField_=new FIELD_;
719 // check set/get methods
720 MED_EN::med_type_champ aValueType = MED_EN::MED_UNDEFINED_TYPE;
721 MED_EN::medModeSwitch anInterlace = MED_EN::MED_UNDEFINED_INTERLACE;
722 checkField_(aField_, anEmptySupport, aValueType, anInterlace);
725 // This fails (Segmentation fault) if not set:
726 // _componentsNames or _componentsDescriptions, or _MEDComponentsUnits
727 FIELD_ *aField_copy1=new FIELD_(*aField_);
728 compareField_(aField_, aField_copy1, /*isFIELD = */false, /*isValue = */false);
729 aField_copy1->removeReference();
731 FIELD_ *aField_copy2=new FIELD_;
732 *aField_copy2 = *aField_;
733 compareField_(aField_, aField_copy2,/*isFIELD = */false, /*isValue = */false);
734 aField_copy2->removeReference();
735 aField_->removeReference();
737 ////////////////////////
738 // TEST 2: FIELD<int> //
739 ////////////////////////
740 FIELD<int> *aFieldInt=new FIELD<int>();
741 checkField(aFieldInt, anEmptySupport);
742 aFieldInt->removeReference();
743 anEmptySupport->removeReference();
744 ////////////////////////////////////////
745 // TEST 3: FIELD<double, NoInterlace> //
746 ////////////////////////////////////////
747 MESH * aMesh = MEDMEMTest_createTestMesh();
748 const GROUP* aGroup = aMesh->getGroup(MED_EN::MED_FACE, 1);
750 FIELD<double, NoInterlace> *aFieldDouble=new FIELD<double, NoInterlace>();
751 checkField(aFieldDouble, aGroup);
752 aFieldDouble->removeReference();
753 //////////////////////////////////////////
754 // TEST 4: FIELD<double, FullInterlace> //
755 //////////////////////////////////////////
756 FIELD<double> * aFieldOnGroup1 = createFieldOnGroup<double>(aMesh, aGroup, "Linear", "N");
757 FIELD<double> * aFieldOnGroup2 = createFieldOnGroup<double>(aMesh, aGroup, "Quadratic", "N**2");
759 int nbVals = aFieldOnGroup1->getNumberOfValues();
760 CPPUNIT_ASSERT(nbVals);
762 // numbers of elements in group,
763 // they are needed in method FIELD::setValueIJ()
764 const int *anElems = aGroup->getnumber()->getValue();
765 double eucl1 = 0., eucl2 = 0.;
767 for (int i = 1; i <= nbVals; i++)
769 aFieldOnGroup1->setValueIJ(anElems[i-1], 1, (double)i);
770 aFieldOnGroup1->setValueIJ(anElems[i-1], 2, (double)(-i));
772 aFieldOnGroup2->setValueIJ(anElems[i-1], 1, (double)i*i);
773 aFieldOnGroup2->setValueIJ(anElems[i-1], 2, (double)(-i*i));
776 eucl2 += 2. * i * i * i * i;
779 // out of bound (inexisting 33-th component of last element)
780 CPPUNIT_ASSERT_THROW(aFieldOnGroup1->setValueIJ(anElems[nbVals-1], 33, 10.), MEDEXCEPTION);
783 CPPUNIT_ASSERT_DOUBLES_EQUAL(nbVals, aFieldOnGroup1->normMax(), 0.000001);
784 CPPUNIT_ASSERT_DOUBLES_EQUAL(nbVals*nbVals, aFieldOnGroup2->normMax(), 0.000001);
787 CPPUNIT_ASSERT_DOUBLES_EQUAL(std::sqrt(eucl1), aFieldOnGroup1->norm2(), 0.000001); // 10.4881
788 CPPUNIT_ASSERT_DOUBLES_EQUAL(std::sqrt(eucl2), aFieldOnGroup2->norm2(), 0.000001); // 44.2493
790 // check getXXX methods
791 CPPUNIT_ASSERT(!aFieldOnGroup1->getGaussPresence());
792 CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getArrayGauss(), MEDEXCEPTION);
793 MEDMEM_ArrayInterface<double, FullInterlace,NoGauss>::Array * anArrayNoGauss =
794 aFieldOnGroup1->getArrayNoGauss();
796 MEDMEM_Array_ * aMEDMEM_Array_ = aFieldOnGroup1->getArray();
797 MEDMEM_ArrayInterface<double, FullInterlace,NoGauss>::Array * aMEDMEM_Array_conv =
798 static_cast<MEDMEM_ArrayInterface<double, FullInterlace,NoGauss>::Array *>(aMEDMEM_Array_);
800 const double * aValues = aFieldOnGroup1->getValue();
803 CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getColumn(3), MEDEXCEPTION);
804 // cannot get column in FullInterlace
805 CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getColumn(1), MEDEXCEPTION);
807 for (int i = 1; i <= nbVals; i++)
809 CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i , aFieldOnGroup1->getValueIJK(anElems[i-1], 1, 1), 0.000001);
810 CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), aFieldOnGroup1->getValueIJK(anElems[i-1], 2, 1), 0.000001);
812 CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i , aValues[(i-1)*2 + 0], 0.000001);
813 CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), aValues[(i-1)*2 + 1], 0.000001);
815 CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i , anArrayNoGauss->getIJ(i, 1), 0.000001);
816 CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), anArrayNoGauss->getIJ(i, 2), 0.000001);
818 CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i , aMEDMEM_Array_conv->getIJ(i, 1), 0.000001);
819 CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), aMEDMEM_Array_conv->getIJ(i, 2), 0.000001);
821 const double* row_i = aFieldOnGroup1->getRow(anElems[i-1]);
822 CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i , row_i[0], 0.000001);
823 CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), row_i[1], 0.000001);
826 aFieldOnGroup1->getValueOnElement(anElems[i-1], vals_i);
827 CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i , vals_i[0], 0.000001);
828 CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), vals_i[1], 0.000001);
831 // Test getValueOnPoints()
832 // -----------------------
833 const string file = getResourceFile("cube_hexa8.med");
834 MESH mesh(MED_DRIVER, file, "CUBE_EN_HEXA8");
837 FIELD<double> fieldcelldouble(MED_DRIVER, file, "fieldcelldouble", -1,-1, &mesh);
838 fieldcelldouble.getSupport()->setMesh( &mesh );
841 0.25, 0.75, 0.25, // the 3-d cell
844 fieldcelldouble.getValueOnPoint(point, value);
845 const double tol = 1e-20;
846 CPPUNIT_ASSERT_DOUBLES_EQUAL( 2.0, value[0], tol );
847 CPPUNIT_ASSERT_DOUBLES_EQUAL( 3.0, value[1], tol );
848 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, value[2], tol );
849 fieldcelldouble.getValueOnPoints(2, point, value);
850 CPPUNIT_ASSERT_DOUBLES_EQUAL( 2.0, value[0], tol );
851 CPPUNIT_ASSERT_DOUBLES_EQUAL( 3.0, value[1], tol );
852 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, value[2], tol );
853 CPPUNIT_ASSERT_DOUBLES_EQUAL( 2.0, value[3], tol );
854 CPPUNIT_ASSERT_DOUBLES_EQUAL( 2.0, value[4], tol );
855 CPPUNIT_ASSERT_DOUBLES_EQUAL( 3.0, value[5], tol );
858 FIELD<double> fieldnodedouble(MED_DRIVER, file, "fieldnodedouble", -1,-1, &mesh); // t=0.0
859 fieldnodedouble.getSupport()->setMesh( &mesh );
862 1.0, 1.0, 0.0, // the 9-th node
865 fieldnodedouble.getValueOnPoint(point, value);
866 const double tol = 1e-20;
867 CPPUNIT_ASSERT_DOUBLES_EQUAL( 5.0, value[0], tol );
868 fieldnodedouble.getValueOnPoints(2, point, value);
869 CPPUNIT_ASSERT_DOUBLES_EQUAL( 5.0, value[0], tol );
870 CPPUNIT_ASSERT_DOUBLES_EQUAL( 4.0, value[1], tol );
872 point[0] = 1.1; // point out of mesh
873 CPPUNIT_ASSERT_THROW(fieldnodedouble.getValueOnPoint(point, value), MEDEXCEPTION);
877 // modify all values of aFieldOnGroup2 by formula a*x + b (a = 2, b = 3)
878 aFieldOnGroup2->applyLin(2., 3.);
879 for (int i = 1; i <= nbVals; i++)
881 CPPUNIT_ASSERT_DOUBLES_EQUAL(3. + 2.*i*i, aFieldOnGroup2->getValueIJ(anElems[i-1], 1), 0.000001);
882 CPPUNIT_ASSERT_DOUBLES_EQUAL(3. - 2.*i*i, aFieldOnGroup2->getValueIJ(anElems[i-1], 2), 0.000001);
885 // apply function plus13() to aFieldOnGroup1
886 aFieldOnGroup1->applyFunc<plus13>();
887 for (int i = 1; i <= nbVals; i++)
889 CPPUNIT_ASSERT_DOUBLES_EQUAL(13 + i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001);
890 CPPUNIT_ASSERT_DOUBLES_EQUAL(13 - i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001);
894 FIELD<double, FullInterlace> * aScalarProduct =
895 FIELD<double, FullInterlace>::scalarProduct(*aFieldOnGroup1, *aFieldOnGroup2, /*deepCheck = */true);
896 CPPUNIT_ASSERT_EQUAL(nbVals, aScalarProduct->getNumberOfValues());
897 CPPUNIT_ASSERT_EQUAL(1, aScalarProduct->getNumberOfComponents());
898 for (int i = 1; i <= nbVals; i++)
900 CPPUNIT_ASSERT_DOUBLES_EQUAL(78. + 4.*i*i*i, //(3. + 2.*i*i)*(13 + i) + (3. - 2.*i*i)*(13 - i)
901 aScalarProduct->getValueIJ(anElems[i-1], 1), 0.000001);
905 aFieldOnGroup2->fillFromAnalytic(proj2d);
909 const SUPPORT * aSupp = aFieldOnGroup2->getSupport();
910 FIELD<double,FullInterlace> * barycenter = aMesh->getBarycenter(aSupp);
911 for (int i = 1; i <= nbVals; i++)
913 bary[0] = barycenter->getValueIJ(anElems[i-1], 1);
914 bary[1] = barycenter->getValueIJ(anElems[i-1], 2);
915 bary[2] = barycenter->getValueIJ(anElems[i-1], 3);
919 //cout << "barycenter (" << bary[0] << ", " << bary[1] << ", " << bary[2] << ")" << endl;
920 //cout << "proj2d (" << outp[0] << ", " << outp[1] << ")" << endl;
922 //bary (-0.666667, 0.666667, 0.666667) -> outp ( 0.902369, 0.902369)
923 //bary ( 0.666667, -0.666667, 0.666667) -> outp (-0.902369, 0.430964)
924 //bary ( 0. , 0. , 2. ) -> outp ( 0. , 2. )
925 //bary ( 0. , 0. , 3. ) -> outp ( 0. , 3. )
926 //bary (-1. , 0. , 2.5 ) -> outp ( 0.353553, 2.85355 )
928 //#ifdef ENABLE_FORCED_FAILURES
929 // (BUG) in FIELD::fillFromAnalytic() in case of support, different from nodes:
930 // barycenterField in FullInterlace, but values extracted like from NoInterlace
931 // TODO: fix MEDMEM_Field:3483 - code should depend on interlace
932 CPPUNIT_ASSERT_DOUBLES_EQUAL(outp[0], aFieldOnGroup2->getValueIJ(anElems[i-1], 1), 0.000001);
933 CPPUNIT_ASSERT_DOUBLES_EQUAL(outp[1], aFieldOnGroup2->getValueIJ(anElems[i-1], 2), 0.000001);
936 // currently it gives values, that are wrong:
937 //aFieldOnGroup2 row1 ( 0.902369, 0.235702)
938 //aFieldOnGroup2 row2 (-0.235702, 2.7643 )
939 //aFieldOnGroup2 row3 (-0.235702, -1.2357 )
940 //aFieldOnGroup2 row4 ( 1.7643 , -0.235702)
941 //aFieldOnGroup2 row5 ( 0.235702, 2.7357 )
944 // info about support (Group1)
945 CPPUNIT_ASSERT(!aFieldOnGroup1->isOnAllElements()); // because we build Group1 so
946 int nbTypes = aFieldOnGroup1->getNumberOfGeometricTypes();
947 //CPPUNIT_ASSERT(nbTypes);
948 CPPUNIT_ASSERT_EQUAL(2, nbTypes);
949 const int * nbElemsInEachType = aFieldOnGroup1->getNumberOfElements();
950 const MED_EN::medGeometryElement * aGeomTypes = aFieldOnGroup1->getGeometricTypes();
952 CPPUNIT_ASSERT_EQUAL(MED_EN::MED_TRIA3, aGeomTypes[0]);
953 CPPUNIT_ASSERT_EQUAL(MED_EN::MED_QUAD4, aGeomTypes[1]);
957 // now we have no gauss localization in aFieldOnGroup1
958 CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_TRIA3));
959 CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_QUAD4));
960 CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_TRIA6), MEDEXCEPTION);
961 CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getNumberOfGaussPoints(), MEDEXCEPTION);
963 CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getGaussLocalization(MED_EN::MED_TRIA3), MEDEXCEPTION);
964 CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getGaussLocalizationPtr(MED_EN::MED_TRIA3), MEDEXCEPTION);
966 CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNbGaussI(anElems[0]));
968 // set a gauss localization into aFieldOnGroup1
973 double cooGauss[10] =
975 7.,7., 6.,6., 5.,5., 4.,3., 2.,1.
976 }; // x1,y1 x2,y2 x3,y3 x4,y4 x5,y5
981 GAUSS_LOCALIZATION<> gl1 ("GL1", MED_EN::MED_TRIA3, /*nGauss*/5, cooRef, cooGauss, wg);
983 aFieldOnGroup1->setGaussLocalization(MED_EN::MED_TRIA3, gl1);
985 // now we have a gauss localization for MED_TRIA3 type
986 CPPUNIT_ASSERT_EQUAL(5, aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_TRIA3));
987 CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_QUAD4));
988 CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_TRIA6), MEDEXCEPTION);
989 CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getNumberOfGaussPoints(), MEDEXCEPTION);
991 CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getGaussLocalization(MED_EN::MED_QUAD4), MEDEXCEPTION);
992 CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getGaussLocalizationPtr(MED_EN::MED_QUAD4), MEDEXCEPTION);
994 GAUSS_LOCALIZATION<> gl1Back = aFieldOnGroup1->getGaussLocalization(MED_EN::MED_TRIA3);
995 const GAUSS_LOCALIZATION<> * gl1BackPtr = aFieldOnGroup1->getGaussLocalizationPtr(MED_EN::MED_TRIA3);
997 CPPUNIT_ASSERT(gl1 == gl1Back);
998 CPPUNIT_ASSERT(gl1 == *gl1BackPtr);
1000 CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNbGaussI(anElems[0]));
1002 // sub-support of Group1 on one (first) geometric type
1003 SUPPORT * aSubSupport1 = new SUPPORT();
1004 aSubSupport1->setMesh( aMesh );
1005 aSubSupport1->setName( "Sub-Support 1 of Group1" );
1006 aSubSupport1->setEntity( MED_EN::MED_FACE );
1009 int nbElemsInEachType1[1];
1010 nbElemsInEachType1[0] = nbElemsInEachType[0];
1011 int nbElems1 = nbElemsInEachType1[0];
1012 MED_EN::medGeometryElement aGeomTypes1[1];
1013 aGeomTypes1[0] = aGeomTypes[0];
1014 int * anElems1 = new int[nbElems1];
1015 for (int i = 0; i < nbElems1; i++)
1017 anElems1[i] = anElems[i];
1020 aSubSupport1->setpartial("Support for sub-field 1 on one type of elements",
1021 nbTypes1, nbElems1, aGeomTypes1, nbElemsInEachType1, anElems1);
1023 // extract sub-field on aSubSupport1
1024 FIELD<double, FullInterlace> * aSubField1 = aFieldOnGroup1->extract(aSubSupport1);
1025 CPPUNIT_ASSERT_EQUAL(nbElems1 * /*NumberOfComponents = */2, aSubField1->getValueLength());
1029 //--------------------
1033 // check normL2() and normL1()
1034 FIELD<double>* anAreaField = aMesh->getArea(aSubSupport1);
1035 double area1 = anAreaField->getValueIJ(anElems1[0], 1);
1036 double area2 = anAreaField->getValueIJ(anElems1[1], 1);
1037 CPPUNIT_ASSERT_DOUBLES_EQUAL(2.44949, area1, 0.00001);
1038 CPPUNIT_ASSERT_DOUBLES_EQUAL(2.44949, area2, 0.00001);
1040 CPPUNIT_ASSERT_DOUBLES_EQUAL(210.5, aSubField1->normL2(1), 0.00001); // (14*14 + 15*15)/2
1041 CPPUNIT_ASSERT_DOUBLES_EQUAL(132.5, aSubField1->normL2(2), 0.00001); // (12*12 + 11*11)/2
1042 CPPUNIT_ASSERT_DOUBLES_EQUAL(343.0, aSubField1->normL2() , 0.00001); // 210.5 + 132.5
1044 CPPUNIT_ASSERT_DOUBLES_EQUAL(14.5, aSubField1->normL1(1), 0.00001); // (14 + 15)/2
1045 CPPUNIT_ASSERT_DOUBLES_EQUAL(11.5, aSubField1->normL1(2), 0.00001); // (12 + 11)/2
1046 CPPUNIT_ASSERT_DOUBLES_EQUAL(26.0, aSubField1->normL1() , 0.00001); // 14.5 + 11.5
1048 double aNewArea [2] =
1051 }; // only first element will be taken into account
1052 anAreaField->setValue(aNewArea);
1054 CPPUNIT_ASSERT_DOUBLES_EQUAL(196.0, aSubField1->normL2(1, anAreaField), 0.00001); // 14*14/1
1055 CPPUNIT_ASSERT_DOUBLES_EQUAL(144.0, aSubField1->normL2(2, anAreaField), 0.00001); // 12*12/1
1056 CPPUNIT_ASSERT_DOUBLES_EQUAL(340.0, aSubField1->normL2(anAreaField) , 0.00001); // 196 + 144
1058 CPPUNIT_ASSERT_DOUBLES_EQUAL(14.0, aSubField1->normL1(1, anAreaField), 0.00001); // 14/1
1059 CPPUNIT_ASSERT_DOUBLES_EQUAL(12.0, aSubField1->normL1(2, anAreaField), 0.00001); // 12/1
1060 CPPUNIT_ASSERT_DOUBLES_EQUAL(26.0, aSubField1->normL1(anAreaField) , 0.00001); // 14 + 12
1062 // check normL2() on nodal field (issue 0020120)
1064 // read nodal field from pointe.med
1065 string filename = getResourceFile("pointe.med");
1066 string fieldname = "fieldnodedouble";
1067 string meshname = "maa1";
1068 FIELD<double> *nodalField=new FIELD<double>( MED_DRIVER, filename, fieldname);
1069 MESH *mesh=new MESH( MED_DRIVER, filename, meshname);
1070 nodalField->getSupport()->setMesh( mesh );
1072 // make a field on the nodes of first cell only
1073 SUPPORT *oneCellNodesSup=new SUPPORT;
1074 oneCellNodesSup->setMesh(mesh);
1075 oneCellNodesSup->setName("Sub-Support of nodes of 1 cell");
1076 oneCellNodesSup->setEntity(MED_NODE);
1077 int NumberOfElements[] =
1079 mesh->getTypes(MED_CELL)[0]%100
1081 medGeometryElement GeometricType[] =
1085 oneCellNodesSup->setpartial("Support for sub-field of one cell nodes",
1086 /*NumberOfGeometricType=*/1,
1087 /*TotalNumberOfElements=*/ *NumberOfElements,
1090 /*NumberValue=*/ mesh->getConnectivity(MED_NODAL,MED_CELL,MED_ALL_ELEMENTS ));
1091 FIELD<double, FullInterlace> * oneCellNodesField = nodalField->extract( oneCellNodesSup );
1092 oneCellNodesSup->removeReference();
1093 // compute normL2 by avarage nodal value on the cell
1095 const SUPPORT *allCellsSupport=mesh->getSupportOnAll( MED_CELL );
1096 FIELD<double>* volumeField = mesh->getVolume(allCellsSupport);
1098 // - Mailles de type MED_TETRA4 :
1101 // | 1.000000 | 1.000000 | 1.000000 | 2.000000 | 2.000000 | 2.000000 | ...
1102 const double cellVal = ( 1.000000 + 1.000000 + 1.000000 + 2.000000 ) / 4;
1103 const double vol = abs( volumeField->getValueIJ( 1, 1 ));
1104 const double norm = cellVal*cellVal*vol/vol; // v*v*vol/totVol;
1105 CPPUNIT_ASSERT_DOUBLES_EQUAL(norm, oneCellNodesField->normL2(), 0.000001);
1106 CPPUNIT_ASSERT_DOUBLES_EQUAL(norm, oneCellNodesField->normL2(1), 0.000001);
1107 CPPUNIT_ASSERT_DOUBLES_EQUAL(norm, oneCellNodesField->normL2(volumeField), 0.000001);
1108 CPPUNIT_ASSERT_DOUBLES_EQUAL(norm, oneCellNodesField->normL2(1, volumeField), 0.000001);
1110 CPPUNIT_ASSERT_THROW(oneCellNodesField->normL1(), MEDEXCEPTION);
1111 CPPUNIT_ASSERT_THROW(oneCellNodesField->normL1(1), MEDEXCEPTION);
1112 CPPUNIT_ASSERT_THROW(oneCellNodesField->normL2(nodalField), MEDEXCEPTION);
1113 CPPUNIT_ASSERT_THROW(oneCellNodesField->normL2(anAreaField), MEDEXCEPTION);
1114 CPPUNIT_ASSERT_THROW(oneCellNodesField->normL2(aSubField1), MEDEXCEPTION);
1115 CPPUNIT_ASSERT_THROW(oneCellNodesField->normL2(aFieldOnGroup1), MEDEXCEPTION);
1116 nodalField->removeReference();
1117 volumeField->removeReference();
1118 oneCellNodesField->removeReference();
1119 mesh->removeReference();
1122 // double integral(SUPPORT*) - mantis issue 0020460:
1123 // [CEA 352] Integral calculus on all field or on a field subarea (groupe or family)
1125 // make 2D grid 2x2 with steps along axis 1.0, 2.0
1131 vector< vector<double> > xyz_array( dim, vector<double>( coord, coord + 3 ));
1132 vector<string> coord_name( dim, "coord_name");
1133 vector<string> coord_unit( dim, "m");
1134 MESH *mesh= const_cast<MESH*>( GRID( xyz_array, coord_name, coord_unit ).convertInMESH());
1136 // make supports on the grid
1137 const SUPPORT *supOnAll=mesh->getSupportOnAll(MED_CELL);
1138 SUPPORT *sup123=new SUPPORT;
1139 sup123->setMesh(mesh);
1140 sup123->setName("sup123");
1149 SUPPORT *sup12=new SUPPORT;
1150 sup12->setMesh(mesh);
1151 sup12->setName("sup12");
1160 SUPPORT *sup34=new SUPPORT;
1161 sup34->setMesh(mesh);
1162 sup34->setName("sup34");
1171 const int nbGeomTypes = 1;
1172 const medGeometryElement * geomType = mesh->getTypes(MED_EN::MED_CELL);
1173 mesh->removeReference();
1174 sup123->setpartial("test", nbGeomTypes, *nbEl123, geomType, nbEl123, elems123 );
1175 sup12->setpartial("test", nbGeomTypes, *nbEl12 , geomType, nbEl12 , elems12 );
1176 sup34->setpartial("test", nbGeomTypes, *nbEl34 , geomType, nbEl34 , elems34 );
1178 // make vectorial fields with values of i-th elem { i, i*10, i*100 }
1179 const int nbComp = 3, nbElems = 4;
1180 const int mult[nbComp] =
1184 FIELD<int,NoInterlaceByType> *fAllNoTy=new FIELD<int,NoInterlaceByType>(supOnAll, nbComp), *f12NoTy=new FIELD<int,NoInterlaceByType>(sup12, nbComp);
1185 FIELD<int,NoInterlace> *fAllNo=new FIELD<int,NoInterlace>(supOnAll, nbComp), *f12No=new FIELD<int,NoInterlace>(sup12, nbComp);
1186 FIELD<int,FullInterlace> *fAllFull=new FIELD<int,FullInterlace>(supOnAll, nbComp), *f12Full=new FIELD<int,FullInterlace>(sup12, nbComp);
1188 for ( i = 1; i <= nbElems; ++i )
1189 for ( j = 1; j <= nbComp; ++j )
1191 fAllFull->setValueIJ( i, j, i * mult[j-1]);
1192 fAllNoTy->setValueIJ( i, j, i * mult[j-1]);
1193 fAllNo ->setValueIJ( i, j, i * mult[j-1]);
1196 f12Full->setValueIJ( i, j, i * mult[j-1]);
1197 f12NoTy->setValueIJ( i, j, i * mult[j-1]);
1198 f12No ->setValueIJ( i, j, i * mult[j-1]);
1202 double preci = 1e-18, integral;
1203 // Integral = SUM( area * (i*1 + i*10 + i*100)) == 111 * SUM( area * i )
1204 // elem area: { 1, 2, 2, 4 }
1205 integral = 111*( 1*1 + 2*2 + 2*3 + 4*4 );
1206 CPPUNIT_ASSERT_DOUBLES_EQUAL( integral, fAllNoTy->integral(), preci );
1207 CPPUNIT_ASSERT_DOUBLES_EQUAL( integral, fAllNo ->integral(), preci );
1208 CPPUNIT_ASSERT_DOUBLES_EQUAL( integral, fAllFull->integral(), preci );
1209 integral = 111*( 1*1 + 2*2 );
1210 CPPUNIT_ASSERT_DOUBLES_EQUAL( integral, f12NoTy->integral(), preci );
1211 CPPUNIT_ASSERT_DOUBLES_EQUAL( integral, f12No ->integral(), preci );
1212 CPPUNIT_ASSERT_DOUBLES_EQUAL( integral, f12Full->integral(), preci );
1214 CPPUNIT_ASSERT_DOUBLES_EQUAL( integral, fAllNoTy->integral(sup12), preci );
1215 CPPUNIT_ASSERT_DOUBLES_EQUAL( integral, fAllNo ->integral(sup12), preci );
1216 CPPUNIT_ASSERT_DOUBLES_EQUAL( integral, fAllFull->integral(sup12), preci );
1218 CPPUNIT_ASSERT_DOUBLES_EQUAL( integral, f12NoTy->integral(sup12), preci );
1219 CPPUNIT_ASSERT_DOUBLES_EQUAL( integral, f12No ->integral(sup12), preci );
1220 CPPUNIT_ASSERT_DOUBLES_EQUAL( integral, f12Full->integral(sup12), preci );
1221 sup12->removeReference();
1222 CPPUNIT_ASSERT_DOUBLES_EQUAL( integral, f12NoTy->integral(sup123), preci );
1223 CPPUNIT_ASSERT_DOUBLES_EQUAL( integral, f12No ->integral(sup123), preci );
1224 CPPUNIT_ASSERT_DOUBLES_EQUAL( integral, f12Full->integral(sup123), preci );
1225 integral = 111*( 1*1 + 2*2 + 2*3 );
1226 CPPUNIT_ASSERT_DOUBLES_EQUAL( integral, fAllNoTy->integral(sup123), preci );
1227 CPPUNIT_ASSERT_DOUBLES_EQUAL( integral, fAllNo ->integral(sup123), preci );
1228 CPPUNIT_ASSERT_DOUBLES_EQUAL( integral, fAllFull->integral(sup123), preci );
1229 fAllNoTy->removeReference();
1230 fAllNo->removeReference();
1231 sup123->removeReference();
1232 fAllFull->removeReference();
1234 CPPUNIT_ASSERT_DOUBLES_EQUAL( integral, f12NoTy->integral(sup34), preci );
1235 CPPUNIT_ASSERT_DOUBLES_EQUAL( integral, f12No ->integral(sup34), preci );
1236 CPPUNIT_ASSERT_DOUBLES_EQUAL( integral, f12Full->integral(sup34), preci );
1237 sup34->removeReference();
1238 f12NoTy->removeReference();
1239 f12No->removeReference();
1240 f12Full->removeReference();
1244 aSubField1->applyPow(2.);
1245 CPPUNIT_ASSERT_DOUBLES_EQUAL(196., aSubField1->getValueIJ(anElems1[0], 1), 0.000001); // 14*14
1246 CPPUNIT_ASSERT_DOUBLES_EQUAL(144., aSubField1->getValueIJ(anElems1[0], 2), 0.000001); // 12*12
1247 CPPUNIT_ASSERT_DOUBLES_EQUAL(225., aSubField1->getValueIJ(anElems1[1], 1), 0.000001); // 15*15
1248 CPPUNIT_ASSERT_DOUBLES_EQUAL(121., aSubField1->getValueIJ(anElems1[1], 2), 0.000001); // 11*11
1250 // setArray (NoGauss)
1251 MEDMEM_ArrayInterface<double,FullInterlace,NoGauss>::Array * aNewArrayNoGauss =
1252 new MEDMEM_ArrayInterface<double,FullInterlace,NoGauss>::Array(/*dim*/2, /*nbelem*/2);
1253 aNewArrayNoGauss->setIJ(1, 1, 4.);
1254 aNewArrayNoGauss->setIJ(1, 2, 2.);
1255 aNewArrayNoGauss->setIJ(2, 1, 5.);
1256 aNewArrayNoGauss->setIJ(2, 2, 1.);
1257 aSubField1->setArray(aNewArrayNoGauss);
1258 // no need to delete aNewArrayNoGauss, because it will be deleted
1259 // in destructor or in deallocValue() method of aSubField1
1261 CPPUNIT_ASSERT_DOUBLES_EQUAL(4., aSubField1->getValueIJ(anElems1[0], 1), 0.000001);
1262 CPPUNIT_ASSERT_DOUBLES_EQUAL(2., aSubField1->getValueIJ(anElems1[0], 2), 0.000001);
1263 CPPUNIT_ASSERT_DOUBLES_EQUAL(5., aSubField1->getValueIJ(anElems1[1], 1), 0.000001);
1264 CPPUNIT_ASSERT_DOUBLES_EQUAL(1., aSubField1->getValueIJ(anElems1[1], 2), 0.000001);
1271 aSubField1->setRow(anElems1[0], row);
1272 CPPUNIT_ASSERT_DOUBLES_EQUAL(-1., aSubField1->getValueIJ(anElems1[0], 1), 0.000001);
1273 CPPUNIT_ASSERT_DOUBLES_EQUAL(-3., aSubField1->getValueIJ(anElems1[0], 2), 0.000001);
1274 CPPUNIT_ASSERT_DOUBLES_EQUAL( 5., aSubField1->getValueIJ(anElems1[1], 1), 0.000001);
1275 CPPUNIT_ASSERT_DOUBLES_EQUAL( 1., aSubField1->getValueIJ(anElems1[1], 2), 0.000001);
1277 CPPUNIT_ASSERT_THROW(aSubField1->setRow(3, row), MEDEXCEPTION);
1284 aSubField1->setColumn(1, col);
1285 CPPUNIT_ASSERT_DOUBLES_EQUAL(-7., aSubField1->getValueIJ(anElems1[0], 1), 0.000001);
1286 CPPUNIT_ASSERT_DOUBLES_EQUAL(-3., aSubField1->getValueIJ(anElems1[0], 2), 0.000001);
1287 CPPUNIT_ASSERT_DOUBLES_EQUAL(-9., aSubField1->getValueIJ(anElems1[1], 1), 0.000001);
1288 CPPUNIT_ASSERT_DOUBLES_EQUAL( 1., aSubField1->getValueIJ(anElems1[1], 2), 0.000001);
1290 CPPUNIT_ASSERT_THROW(aSubField1->setColumn(3, col), MEDEXCEPTION);
1297 }; // 3 - 1 = two elements for the first (and the only) type
1301 }; // one gauss point per each element
1302 MEDMEM_ArrayInterface<double,FullInterlace,Gauss>::Array * aNewArrayGauss =
1303 new MEDMEM_ArrayInterface<double,FullInterlace,Gauss>::Array
1304 (/*dim*/2, /*nbelem*/2, /*nbtypegeo*/1, /*nbelgeoc*/nbelgeoc, /*nbgaussgeo*/nbgaussgeo);
1306 aNewArrayGauss->setIJ(1, 1, -4.);
1307 aNewArrayGauss->setIJ(1, 2, -2.);
1308 aNewArrayGauss->setIJ(2, 1, -5.);
1309 aNewArrayGauss->setIJ(2, 2, -1.);
1311 aNewArrayGauss->setIJK(1, 1, 1, -4.);
1312 aNewArrayGauss->setIJK(1, 2, 1, -2.);
1313 aNewArrayGauss->setIJK(2, 1, 1, -5.);
1314 aNewArrayGauss->setIJK(2, 2, 1, -1.);
1316 aSubField1->setArray(aNewArrayGauss);
1317 // no need to delete aNewArrayGauss, because it will be deleted
1318 // in destructor or in deallocValue() method of aSubField1
1320 CPPUNIT_ASSERT_DOUBLES_EQUAL(-4., aSubField1->getValueIJ(anElems1[0], 1), 0.000001);
1321 CPPUNIT_ASSERT_DOUBLES_EQUAL(-2., aSubField1->getValueIJ(anElems1[0], 2), 0.000001);
1322 CPPUNIT_ASSERT_DOUBLES_EQUAL(-5., aSubField1->getValueIJ(anElems1[1], 1), 0.000001);
1323 CPPUNIT_ASSERT_DOUBLES_EQUAL(-1., aSubField1->getValueIJ(anElems1[1], 2), 0.000001);
1325 CPPUNIT_ASSERT_DOUBLES_EQUAL(-4., aSubField1->getValueIJK(anElems1[0], 1, 1), 0.000001);
1326 CPPUNIT_ASSERT_DOUBLES_EQUAL(-2., aSubField1->getValueIJK(anElems1[0], 2, 1), 0.000001);
1327 CPPUNIT_ASSERT_DOUBLES_EQUAL(-5., aSubField1->getValueIJK(anElems1[1], 1, 1), 0.000001);
1328 CPPUNIT_ASSERT_DOUBLES_EQUAL(-1., aSubField1->getValueIJK(anElems1[1], 2, 1), 0.000001);
1331 // alloc/dealloc; compatibility of new size with support
1334 aSubField1->deallocValue();
1335 aSubField1->allocValue(/*NumberOfComponents*/2, /*LengthValue*/5);
1336 //#ifdef ENABLE_FAULTS
1337 // (BUG) No compatibility between Support and allocated value
1338 //aSubField1->normL1();
1339 CPPUNIT_ASSERT_THROW(aSubField1->normL1(),MEDEXCEPTION);
1341 //#ifdef ENABLE_FORCED_FAILURES
1342 // TODO: FIX to throw an EXCEPTION
1343 // CPPUNIT_FAIL("Error: no compatibility between Support and allocated value");
1346 catch (MEDEXCEPTION & ex)
1352 CPPUNIT_FAIL("Error: no compatibility between Support and allocated value");
1355 // check that aFieldOnGroup1 is not changed after aSubField1 modifications
1356 for (int i = 1; i <= nbVals; i++)
1358 CPPUNIT_ASSERT_DOUBLES_EQUAL(13 + i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001);
1359 CPPUNIT_ASSERT_DOUBLES_EQUAL(13 - i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001);
1362 // reset aFieldOnGroup2 values for simple control of operators results
1363 for (int i = 1; i <= nbVals; i++)
1365 aFieldOnGroup2->setValueIJ(anElems[i-1], 1, i*i);
1366 aFieldOnGroup2->setValueIJ(anElems[i-1], 2, -i*i);
1369 int len = aFieldOnGroup1->getValueLength();
1370 const double * val1 = aFieldOnGroup1->getValue();
1371 const double * val2 = aFieldOnGroup2->getValue();
1372 const double * val_res;
1374 // operators and add, sub, mul, div
1377 FIELD<double> *aSum = *aFieldOnGroup1 + *aFieldOnGroup2;
1378 aSum->setName(aFieldOnGroup1->getName());
1379 aSum->setDescription(aFieldOnGroup1->getDescription());
1380 compareField_(aFieldOnGroup1, aSum, true, true);
1381 val_res = aSum->getValue();
1382 for (int i = 0; i < len; i++)
1384 CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] + val2[i], val_res[i], 0.000001);
1386 aSum->removeReference();
1388 FIELD<double> *aDifference = *aFieldOnGroup1 - *aFieldOnGroup2;
1389 aDifference->setName(aFieldOnGroup1->getName());
1390 aDifference->setDescription(aFieldOnGroup1->getDescription());
1391 compareField_(aFieldOnGroup1, aDifference, true, true);
1392 val_res = aDifference->getValue();
1393 for (int i = 0; i < len; i++)
1395 CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] - val2[i], val_res[i], 0.000001);
1397 aDifference->removeReference();
1399 FIELD<double> *aNegative = - *aFieldOnGroup1;
1400 aNegative->setName(aFieldOnGroup1->getName());
1401 aNegative->setDescription(aFieldOnGroup1->getDescription());
1402 compareField_(aFieldOnGroup1, aNegative, true, true);
1403 val_res = aNegative->getValue();
1404 for (int i = 0; i < len; i++)
1406 CPPUNIT_ASSERT_DOUBLES_EQUAL(- val1[i], val_res[i], 0.000001);
1408 aNegative->removeReference();
1410 FIELD<double> *aProduct = (*aFieldOnGroup1) * (*aFieldOnGroup2);
1411 aProduct->setName(aFieldOnGroup1->getName());
1412 aProduct->setDescription(aFieldOnGroup1->getDescription());
1413 compareField_(aFieldOnGroup1, aProduct, true, true);
1414 val_res = aProduct->getValue();
1415 for (int i = 0; i < len; i++)
1417 CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] * val2[i], val_res[i], 0.000001);
1419 aProduct->removeReference();
1421 FIELD<double> *aQuotient = *aFieldOnGroup1 / *aFieldOnGroup2;
1422 aQuotient->setName(aFieldOnGroup1->getName());
1423 aQuotient->setDescription(aFieldOnGroup1->getDescription());
1424 compareField_(aFieldOnGroup1, aQuotient, true, true);
1425 val_res = aQuotient->getValue();
1426 for (int i = 0; i < len; i++)
1428 CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] / val2[i], val_res[i], 0.000001);
1430 aQuotient->removeReference();
1431 double val22 = aFieldOnGroup2->getValueIJ(anElems[2], 2);
1432 aFieldOnGroup2->setValueIJ(anElems[2], 2, 0.);
1434 CPPUNIT_ASSERT_THROW((*aFieldOnGroup1 / *aFieldOnGroup2), MEDEXCEPTION);
1435 //#ifdef ENABLE_FORCED_FAILURES
1436 // (BUG) is it up to user to control validity of data to avoid division on zero?
1437 // YES: USER SHOULD CARE OF IT
1438 //CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 /= *aFieldOnGroup2, MEDEXCEPTION);
1440 CPPUNIT_ASSERT_THROW(FIELD<double>::div(*aFieldOnGroup1, *aFieldOnGroup2)->removeReference(), MEDEXCEPTION);
1441 CPPUNIT_ASSERT_THROW(FIELD<double>::divDeep(*aFieldOnGroup1, *aFieldOnGroup2)->removeReference(), MEDEXCEPTION);
1444 aFieldOnGroup2->setValueIJ(anElems[2], 2, val22);
1447 for (int i = 1; i <= nbVals; i++)
1449 aFieldOnGroup1->setValueIJ(anElems[i-1], 1, 13 + i);
1450 aFieldOnGroup1->setValueIJ(anElems[i-1], 2, 13 - i);
1454 FIELD<double> * aPtr;
1457 aPtr = FIELD<double>::add(*aFieldOnGroup1, *aFieldOnGroup2);
1458 aPtr->setName(aFieldOnGroup1->getName());
1459 aPtr->setDescription(aFieldOnGroup1->getDescription());
1460 compareField_(aFieldOnGroup1, aPtr, true, true);
1461 val_res = aPtr->getValue();
1462 for (int i = 0; i < len; i++)
1464 CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] + val2[i], val_res[i], 0.000001);
1466 aPtr->removeReference();
1469 aPtr = FIELD<double>::sub(*aFieldOnGroup1, *aFieldOnGroup2);
1470 aPtr->setName(aFieldOnGroup1->getName());
1471 aPtr->setDescription(aFieldOnGroup1->getDescription());
1472 compareField_(aFieldOnGroup1, aPtr, true, true);
1473 val_res = aPtr->getValue();
1474 for (int i = 0; i < len; i++)
1476 CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] - val2[i], val_res[i], 0.000001);
1478 aPtr->removeReference();
1481 aPtr = FIELD<double>::mul(*aFieldOnGroup1, *aFieldOnGroup2);
1482 aPtr->setName(aFieldOnGroup1->getName());
1483 aPtr->setDescription(aFieldOnGroup1->getDescription());
1484 compareField_(aFieldOnGroup1, aPtr, true, true);
1485 val_res = aPtr->getValue();
1486 for (int i = 0; i < len; i++)
1488 CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] * val2[i], val_res[i], 0.000001);
1490 aPtr->removeReference();
1493 aPtr = FIELD<double>::div(*aFieldOnGroup1, *aFieldOnGroup2);
1494 aPtr->setName(aFieldOnGroup1->getName());
1495 aPtr->setDescription(aFieldOnGroup1->getDescription());
1496 compareField_(aFieldOnGroup1, aPtr, true, true);
1497 val_res = aPtr->getValue();
1498 for (int i = 0; i < len; i++)
1500 CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] / val2[i], val_res[i], 0.000001);
1502 aPtr->removeReference();
1505 aPtr = FIELD<double>::addDeep(*aFieldOnGroup1, *aFieldOnGroup2);
1506 aPtr->setName(aFieldOnGroup1->getName());
1507 aPtr->setDescription(aFieldOnGroup1->getDescription());
1508 compareField_(aFieldOnGroup1, aPtr, true, true);
1509 val_res = aPtr->getValue();
1510 for (int i = 0; i < len; i++)
1512 CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] + val2[i], val_res[i], 0.000001);
1514 aPtr->removeReference();
1517 aPtr = FIELD<double>::subDeep(*aFieldOnGroup1, *aFieldOnGroup2);
1518 aPtr->setName(aFieldOnGroup1->getName());
1519 aPtr->setDescription(aFieldOnGroup1->getDescription());
1520 compareField_(aFieldOnGroup1, aPtr, true, true);
1521 val_res = aPtr->getValue();
1522 for (int i = 0; i < len; i++)
1524 CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] - val2[i], val_res[i], 0.000001);
1526 aPtr->removeReference();
1529 aPtr = FIELD<double>::mulDeep(*aFieldOnGroup1, *aFieldOnGroup2);
1530 aPtr->setName(aFieldOnGroup1->getName());
1531 aPtr->setDescription(aFieldOnGroup1->getDescription());
1532 compareField_(aFieldOnGroup1, aPtr, true, true);
1533 val_res = aPtr->getValue();
1534 for (int i = 0; i < len; i++)
1536 CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] * val2[i], val_res[i], 0.000001);
1538 aPtr->removeReference();
1541 aPtr = FIELD<double>::divDeep(*aFieldOnGroup1, *aFieldOnGroup2);
1542 aPtr->setName(aFieldOnGroup1->getName());
1543 aPtr->setDescription(aFieldOnGroup1->getDescription());
1544 compareField_(aFieldOnGroup1, aPtr, true, true);
1545 val_res = aPtr->getValue();
1546 for (int i = 0; i < len; i++)
1548 CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] / val2[i], val_res[i], 0.000001);
1550 aPtr->removeReference();
1553 *aFieldOnGroup1 += *aFieldOnGroup2;
1554 for (int i = 1; i <= nbVals; i++)
1556 CPPUNIT_ASSERT_DOUBLES_EQUAL(13 + i + i*i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001);
1557 CPPUNIT_ASSERT_DOUBLES_EQUAL(13 - i - i*i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001);
1561 *aFieldOnGroup1 -= *aFieldOnGroup2;
1562 for (int i = 1; i <= nbVals; i++)
1564 CPPUNIT_ASSERT_DOUBLES_EQUAL(13 + i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001);
1565 CPPUNIT_ASSERT_DOUBLES_EQUAL(13 - i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001);
1569 *aFieldOnGroup1 *= *aFieldOnGroup2;
1570 for (int i = 1; i <= nbVals; i++)
1572 CPPUNIT_ASSERT_DOUBLES_EQUAL( (13 + i)*i*i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001);
1573 CPPUNIT_ASSERT_DOUBLES_EQUAL(-(13 - i)*i*i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001);
1577 *aFieldOnGroup1 /= *aFieldOnGroup2;
1578 for (int i = 1; i <= nbVals; i++)
1580 CPPUNIT_ASSERT_DOUBLES_EQUAL(13 + i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001);
1581 CPPUNIT_ASSERT_DOUBLES_EQUAL(13 - i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001);
1584 // check case of different operands: support
1585 MESH * aMeshOneMore = MEDMEMTest_createTestMesh();
1586 const GROUP* aGroupOneMore = aMeshOneMore->getGroup(MED_EN::MED_FACE, 1);
1587 FIELD<double> * aFieldOnGroup3 =
1588 createFieldOnGroup<double>(aMeshOneMore, aGroupOneMore, "Test_Diff_Mesh", "test");
1589 for (int i = 1; i <= nbVals; i++)
1591 aFieldOnGroup3->setValueIJ(anElems[i-1], 1, 2*i);
1592 aFieldOnGroup3->setValueIJ(anElems[i-1], 2, 3*i);
1594 const double * val3 = aFieldOnGroup3->getValue();
1596 //CPPUNIT_ASSERT_NO_THROW();
1599 aPtr = FIELD<double>::addDeep(*aFieldOnGroup1, *aFieldOnGroup3);
1600 aPtr->setName(aFieldOnGroup1->getName());
1601 aPtr->setDescription(aFieldOnGroup1->getDescription());
1602 compareField_(aFieldOnGroup1, aPtr, true, true);
1603 val_res = aPtr->getValue();
1604 for (int i = 0; i < len; i++)
1606 CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] + val3[i], val_res[i], 0.000001);
1608 aPtr->removeReference();
1610 aPtr = FIELD<double>::subDeep(*aFieldOnGroup1, *aFieldOnGroup3);
1611 aPtr->removeReference();
1612 aPtr = FIELD<double>::mulDeep(*aFieldOnGroup1, *aFieldOnGroup3);
1613 aPtr->removeReference();
1614 aPtr = FIELD<double>::divDeep(*aFieldOnGroup1, *aFieldOnGroup3);
1615 aPtr->removeReference();
1617 catch (MEDEXCEPTION & ex)
1619 CPPUNIT_FAIL(ex.what());
1623 CPPUNIT_FAIL("Unknown exception in FIELD::xxxDeep()");
1626 CPPUNIT_ASSERT_THROW(FIELD<double>::add(*aFieldOnGroup1, *aFieldOnGroup3), MEDEXCEPTION);
1627 CPPUNIT_ASSERT_THROW(FIELD<double>::sub(*aFieldOnGroup1, *aFieldOnGroup3), MEDEXCEPTION);
1628 CPPUNIT_ASSERT_THROW(FIELD<double>::mul(*aFieldOnGroup1, *aFieldOnGroup3), MEDEXCEPTION);
1629 CPPUNIT_ASSERT_THROW(FIELD<double>::div(*aFieldOnGroup1, *aFieldOnGroup3), MEDEXCEPTION);
1631 CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 + *aFieldOnGroup3, MEDEXCEPTION);
1632 CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 - *aFieldOnGroup3, MEDEXCEPTION);
1633 CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 * *aFieldOnGroup3, MEDEXCEPTION);
1634 CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 / *aFieldOnGroup3, MEDEXCEPTION);
1636 CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 += *aFieldOnGroup3, MEDEXCEPTION);
1637 CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 -= *aFieldOnGroup3, MEDEXCEPTION);
1638 CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 *= *aFieldOnGroup3, MEDEXCEPTION);
1639 CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 /= *aFieldOnGroup3, MEDEXCEPTION);
1641 // check case of different operands: MEDComponentsUnits
1642 aFieldOnGroup1->setMEDComponentUnit(1, "unit3");
1644 CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 + *aFieldOnGroup2, MEDEXCEPTION);
1645 CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 - *aFieldOnGroup2, MEDEXCEPTION);
1646 CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 += *aFieldOnGroup2, MEDEXCEPTION);
1647 CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 -= *aFieldOnGroup2, MEDEXCEPTION);
1648 CPPUNIT_ASSERT_THROW(FIELD<double>::add(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION);
1649 CPPUNIT_ASSERT_THROW(FIELD<double>::sub(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION);
1650 CPPUNIT_ASSERT_THROW(FIELD<double>::addDeep(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION);
1651 CPPUNIT_ASSERT_THROW(FIELD<double>::subDeep(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION);
1653 //CPPUNIT_ASSERT_NO_THROW();
1656 aPtr = FIELD<double>::mul(*aFieldOnGroup1, *aFieldOnGroup2);
1657 aPtr->removeReference();
1658 aPtr = FIELD<double>::div(*aFieldOnGroup1, *aFieldOnGroup2);
1659 aPtr->removeReference();
1660 aPtr = FIELD<double>::mulDeep(*aFieldOnGroup1, *aFieldOnGroup2);
1661 aPtr->removeReference();
1662 aPtr = FIELD<double>::divDeep(*aFieldOnGroup1, *aFieldOnGroup2);
1663 aPtr->removeReference();
1665 *aFieldOnGroup1 *= *aFieldOnGroup2;
1666 *aFieldOnGroup1 /= *aFieldOnGroup2;
1668 FIELD<double> *aPr = *aFieldOnGroup1 * *aFieldOnGroup2;
1669 FIELD<double> *aQu = *aFieldOnGroup1 / *aFieldOnGroup2;
1670 aPr->removeReference();
1671 aQu->removeReference();
1673 catch (MEDEXCEPTION & ex)
1675 CPPUNIT_FAIL(ex.what());
1679 CPPUNIT_FAIL("Unknown exception");
1682 // restore MED units
1683 aFieldOnGroup1->setMEDComponentUnit(1, "unit1");
1685 // check case of different operands: valueType
1686 //FIELD<int> * aFieldOnGroup4 =
1687 // createFieldOnGroup<int>(aMeshOneMore, aGroupOneMore, "Test_Diff_Mesh", "test");
1689 //CPPUNIT_ASSERT_THROW(FIELD<double>::add(*aFieldOnGroup4, *aFieldOnGroup3), MEDEXCEPTION);
1690 //CPPUNIT_ASSERT_THROW(*aFieldOnGroup4 - *aFieldOnGroup3, MEDEXCEPTION);
1691 //CPPUNIT_ASSERT_THROW(*aFieldOnGroup4 *= *aFieldOnGroup3, MEDEXCEPTION);
1692 //delete aFieldOnGroup4;
1694 // check case of different operands: numberOfComponents
1695 //#ifdef ENABLE_FAULTS
1696 // (BUG) Cannot allocate value of higher dimension because of _componentsTypes reinitialization
1697 aFieldOnGroup1->deallocValue();
1698 //CPPUNIT_ASSERT_THROW(aFieldOnGroup1->allocValue(/*dim*/5), MEDEXCEPTION);
1699 CPPUNIT_ASSERT_NO_THROW(aFieldOnGroup1->allocValue(/*dim*/5));
1701 //#ifdef ENABLE_FORCED_FAILURES
1702 // YES THERE MUST BE AN EXCEPTION
1703 // CPPUNIT_FAIL("Segmentation fault on attempt to allocate value of higher dimension."
1704 // " Must be MEDEXCEPTION instead. And on attempt to change nb.components"
1705 // " must be the same behaviour.");
1707 aFieldOnGroup1->setNumberOfComponents(5);
1709 CPPUNIT_ASSERT_THROW(FIELD<double>::sub(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION);
1710 CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 * *aFieldOnGroup2, MEDEXCEPTION);
1711 CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 /= *aFieldOnGroup2, MEDEXCEPTION);
1713 // check case of different operands: numberOfValues
1714 aFieldOnGroup1->deallocValue();
1715 aFieldOnGroup1->allocValue(2, nbVals + 1);
1716 // be carefull: aFieldOnGroup1 reallocated and contains random values
1718 CPPUNIT_ASSERT_THROW(FIELD<double>::mul(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION);
1719 CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 / *aFieldOnGroup2, MEDEXCEPTION);
1720 CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 += *aFieldOnGroup2, MEDEXCEPTION);
1722 // restore aFieldOnGroup1
1723 aFieldOnGroup1->deallocValue();
1724 aFieldOnGroup1->allocValue(2, nbVals);
1725 // be carefull: aFieldOnGroup1 reallocated and contains random values
1727 aSubSupport1->removeReference();
1730 aScalarProduct->removeReference();
1731 aSubField1->removeReference();
1732 anAreaField->removeReference();
1733 barycenter->removeReference();
1734 aFieldOnGroup1->removeReference();
1735 aFieldOnGroup2->removeReference();
1736 aFieldOnGroup3->removeReference();
1738 aMesh->removeReference();
1739 aMeshOneMore->removeReference();
1741 /////////////////////
1742 // TEST 5: Drivers //
1743 /////////////////////
1748 * Check methods (2), defined in MEDMEM_FieldConvert.hxx:
1749 * (+) template <class T> FIELD<T,FullInterlace> * FieldConvert(const FIELD<T,NoInterlace> & field);
1750 * (+) template <class T> FIELD<T,NoInterlace> * FieldConvert(const FIELD<T,FullInterlace> & field);
1752 void MEDMEMTest::testFieldConvert()
1754 // create an empty integer field 2x10
1755 FIELD<int, FullInterlace> * aField_FING = new FIELD<int, FullInterlace>();
1757 aField_FING->setName("Field_FING");
1758 aField_FING->setDescription("Field full interlace no gauss");
1760 aField_FING->setNumberOfComponents(2);
1761 aField_FING->setNumberOfValues(10);
1763 string aCompsNames[2] =
1767 string aCompsDescs[2] =
1771 string aMEDCompsUnits[2] =
1775 UNIT aCompsUnits[2];
1777 aCompsUnits[0] = UNIT("u1", "descr1");
1778 aCompsUnits[1] = UNIT("u2", "descr2");
1780 aField_FING->setComponentsNames(aCompsNames);
1781 aField_FING->setComponentsDescriptions(aCompsDescs);
1782 aField_FING->setMEDComponentsUnits(aMEDCompsUnits);
1783 aField_FING->setComponentsUnits(aCompsUnits);
1785 // check UNITs (for testField())
1786 const UNIT * aCompsUnitsBack = aField_FING->getComponentsUnits();
1787 CPPUNIT_ASSERT(aCompsUnits[0].getName() == aCompsUnitsBack[0].getName());
1788 CPPUNIT_ASSERT(aCompsUnits[1].getName() == aCompsUnitsBack[1].getName());
1790 const UNIT * aCompUnitBack1 = aField_FING->getComponentUnit(1);
1791 const UNIT * aCompUnitBack2 = aField_FING->getComponentUnit(2);
1792 CPPUNIT_ASSERT(aCompsUnits[0].getName() == aCompUnitBack1->getName());
1793 CPPUNIT_ASSERT(aCompsUnits[1].getName() == aCompUnitBack2->getName());
1795 // create one more field by copy
1796 FIELD<int, FullInterlace> * aField_FIGG = new FIELD<int, FullInterlace>(*aField_FING);
1799 int values_FING[20] =
1801 7,- 7, 14,-14, 21,-21, 28,-28, 35,-35,
1802 42,-42, 49,-49, 56,-56, 63,-63, 70,-70
1805 /////////////////////
1806 // TEST 1: NoGauss //
1807 /////////////////////
1809 MEDMEM_ArrayInterface<int,FullInterlace,NoGauss>::Array * anArray_FING =
1810 new MEDMEM_ArrayInterface<int,FullInterlace,NoGauss>::Array
1811 (values_FING, /*dim*/2, /*nbelem*/10, /*shallowCopy*/false, /*ownershipOfValues*/false);
1812 aField_FING->setArray(anArray_FING);
1813 // no need to delete anArray_FING, because it will be deleted in destructor of aField_FING
1815 // 1. FullInterlace -> NoInterlace
1816 FIELD<int, NoInterlace> * aField_NING = FieldConvert(*aField_FING);
1817 const int * values_NING = aField_NING->getValue();
1819 for (int i = 0; i < 10; i++)
1821 for (int j = 0; j < 2; j++)
1823 CPPUNIT_ASSERT_EQUAL(values_FING[2*i + j], values_NING[10*j + i]);
1827 // 2. NoInterlace -> FullInterlace
1828 FIELD<int, FullInterlace> * aField_FING_conv = FieldConvert(*aField_NING);
1829 const int * values_FING_conv = aField_FING_conv->getValue();
1831 for (int i = 0; i < 10; i++)
1833 for (int j = 0; j < 2; j++)
1835 CPPUNIT_ASSERT_EQUAL(values_FING_conv[2*i + j], values_FING[2*i + j]);
1836 CPPUNIT_ASSERT_EQUAL(values_FING_conv[2*i + j], values_NING[10*j + i]);
1840 aField_FING->removeReference();
1841 aField_NING->removeReference();
1842 aField_FING_conv->removeReference();
1855 MEDMEM_ArrayInterface<int,FullInterlace,Gauss>::Array * anArray_FIGG =
1856 new MEDMEM_ArrayInterface<int,FullInterlace,Gauss>::Array
1857 (values_FING, /*dim*/2, /*nbelem*/10, /*nbtypegeo*/1, /*nbelgeoc*/nbelgeoc,
1858 /*nbgaussgeo*/nbgaussgeo, /*shallowCopy*/false, /*ownershipOfValues*/false);
1859 aField_FIGG->setArray(anArray_FIGG);
1860 // no need to delete anArray_FIGG, because it will be deleted in destructor of aField_FIGG
1862 // 1. FullInterlace -> NoInterlace
1863 FIELD<int, NoInterlace> * aField_NIGG = FieldConvert(*aField_FIGG);
1864 const int * values_NIGG = aField_NIGG->getValue();
1866 for (int i = 0; i < 10; i++)
1868 for (int j = 0; j < 2; j++)
1870 CPPUNIT_ASSERT_EQUAL(values_FING[2*i + j], values_NIGG[10*j + i]);
1874 // 2. NoInterlace -> FullInterlace
1875 FIELD<int, FullInterlace> * aField_FIGG_conv = FieldConvert(*aField_NIGG);
1876 const int * values_FIGG_conv = aField_FIGG_conv->getValue();
1878 for (int i = 0; i < 10; i++)
1880 for (int j = 0; j < 2; j++)
1882 CPPUNIT_ASSERT_EQUAL(values_FIGG_conv[2*i + j], values_FING[2*i + j]);
1883 CPPUNIT_ASSERT_EQUAL(values_FIGG_conv[2*i + j], values_NIGG[10*j + i]);
1887 aField_FIGG->removeReference();
1888 aField_NIGG->removeReference();
1889 aField_FIGG_conv->removeReference();
1891 // create an empty integer field 2x10
1892 FIELD<int, FullInterlace> * aField = new FIELD<int, FullInterlace>();
1894 aField->setName("aField");
1895 aField->setDescription("Field full interlace no gauss");
1897 aField->setNumberOfComponents(2);
1898 aField->setNumberOfValues(10);
1900 aField->setComponentsNames(aCompsNames);
1901 aField->setComponentsDescriptions(aCompsDescs);
1902 aField->setMEDComponentsUnits(aMEDCompsUnits);
1904 MEDMEM_ArrayInterface<int,FullInterlace,NoGauss>::Array * anArray =
1905 new MEDMEM_ArrayInterface<int,FullInterlace,NoGauss>::Array
1906 (values_FING, /*dim*/2, /*nbelem*/10, /*shallowCopy*/false, /*ownershipOfValues*/false);
1907 aField->setArray(anArray);
1908 // no need to delete anArray, because it will be deleted in destructor of aField
1910 FIELD<int, NoInterlace> * aField_conv = FieldConvert(*aField);
1911 aField->removeReference();
1912 CPPUNIT_ASSERT(aField_conv);
1913 aField_conv->removeReference();
1917 //================================================================================
1919 * \brief 0020582: [CEA 368] MEDMEM don't work with a same field on NODES and CELLS
1920 * Before fixing the issue there was the error:
1921 * RuntimeError: MED Exception in .../MED_SRC/src/MEDMEM/MEDMEM_MedFieldDriver22.hxx [503] : MED_FIELD_DRIVER<T>::createFieldSupportPart1(...) Field |field on NODEs and CELLs| with (ndt,or) = (-1,-1) must not be defined on different entity types
1923 //================================================================================
1925 void MEDMEMTest::testReadFieldOnNodesAndCells()
1927 const string outfile = makeTmpFile("field_on_nodes_and_cells.med");
1928 const string fieldName = "field on NODEs and CELLs";
1930 MEDMEMTest_TmpFilesRemover aTmpFilesRemover;
1931 aTmpFilesRemover.Register( outfile );
1933 // write file with a field on NODEs and CELLs
1935 using namespace MED_EN;
1937 MEDMEM::MESH *mesh=MEDMEMTest_createTestMesh();
1938 int drv = mesh->addDriver( MED_DRIVER, outfile, mesh->getName());
1941 const SUPPORT *supportOnCells=mesh->getSupportOnAll( MED_CELL );
1942 const SUPPORT *supportOnNodes=mesh->getSupportOnAll( MED_NODE );
1943 supportOnCells->addReference();
1944 supportOnNodes->addReference();
1945 mesh->removeReference();
1946 int numberOfCells = supportOnCells->getNumberOfElements(MED_ALL_ELEMENTS);
1947 int numberOfNodes = supportOnNodes->getNumberOfElements(MED_ALL_ELEMENTS);
1949 PointerOf<double> cellValues( numberOfCells ), nodeValues( numberOfNodes );
1950 for ( int i = 0; i < numberOfCells; ++i ) cellValues[i] = i;
1951 for ( int i = 0; i < numberOfNodes; ++i ) nodeValues[i] = -i;
1953 FIELD<double> *wrFieldOnCells=new FIELD<double>(supportOnCells,1);
1954 wrFieldOnCells->setName(fieldName);
1955 wrFieldOnCells->setComponentName(1,"Vx");
1956 wrFieldOnCells->setComponentDescription(1,"comp1");
1957 wrFieldOnCells->setMEDComponentUnit(1,"unit1");
1958 wrFieldOnCells->setValue( cellValues );
1959 drv = wrFieldOnCells->addDriver(MED_DRIVER, outfile, fieldName);
1960 wrFieldOnCells->write( drv );
1961 wrFieldOnCells->removeReference();
1963 FIELD<double> *wrFieldOnNodes=new FIELD<double>(supportOnNodes,1);
1964 wrFieldOnNodes->setName(fieldName);
1965 wrFieldOnNodes->setComponentName(1,"Vx");
1966 wrFieldOnNodes->setComponentDescription(1,"comp1");
1967 wrFieldOnNodes->setMEDComponentUnit(1,"unit1");
1968 wrFieldOnNodes->setValue( nodeValues );
1969 drv = wrFieldOnNodes->addDriver(MED_DRIVER, outfile, fieldName);
1970 wrFieldOnNodes->write( drv );
1971 wrFieldOnNodes->removeReference();
1976 FIELD<double> *cellField=new FIELD<double>(supportOnCells, MED_DRIVER, outfile, fieldName, -1, -1 );
1977 CPPUNIT_ASSERT_EQUAL( MED_CELL, cellField->getSupport()->getEntity());
1978 CPPUNIT_ASSERT_DOUBLES_EQUAL( numberOfCells-1, cellField->getValueIJ( numberOfCells, 1 ),1e-20);
1979 cellField->removeReference();
1982 FIELD<double> *nodeField=new FIELD<double>(supportOnNodes, MED_DRIVER, outfile, fieldName, -1, -1 );
1983 CPPUNIT_ASSERT_EQUAL( MED_NODE, nodeField->getSupport()->getEntity());
1984 CPPUNIT_ASSERT_DOUBLES_EQUAL( -(numberOfNodes-1), nodeField->getValueIJ( numberOfNodes, 1 ),1e-20);
1985 nodeField->removeReference();
1987 supportOnCells->removeReference();
1988 supportOnNodes->removeReference();
1992 //================================================================================
1994 * \brief 0021052: [CEA 431] Computation of Gauss point location
1996 * Check method GetGaussPointsCoordinates() defined in MEDMEM_Field.hxx:
1998 //================================================================================
1999 void MEDMEMTest::testGetGaussPointsCoordinates()
2001 const int spaceDimension = 3;
2002 const int numberOfNodes = 56;
2013 const int numberOfCellTypes = 14;
2015 double coordinates [ spaceDimension*numberOfNodes ] =
2028 0.0, 4.0, 0.0, //N10
2029 4.0, 4.0, 0.0, //N11
2030 4.0, 0.0, 0.0, //N12
2031 0.0, 2.0, 0.0, //N13
2032 2.0, 4.0, 0.0, //N14
2033 4.0, 2.0, 0.0, //N15
2034 2.0, 0.0, 0.0, //N16
2036 0.0, 6.0, 0.0, //N17
2037 3.0, 3.0, 0.0, //N18
2038 1.3, 3.0, 3.0, //N19
2040 0.0, 3.0, 0.0, //N20
2041 1.5, 4.5, 0.0, //N21
2042 1.5, 1.5, 0.0, //N22
2043 0.65, 1.5, 1.5, //N23
2044 0.65, 4.5, 1.5, //N24
2045 2.15, 3.0, 1.5, //N25
2047 2.0, 2.0, 2.0, //N26
2048 3.0, 1.0, 1.0, //N27
2049 3.0, 3.0, 1.0, //N28
2050 1.0, 3.0, 1.0, //N29
2051 1.0, 1.0, 1.0, //N30
2053 0.0, 3.0, 0.0, //N31
2054 2.0, 0.0, 0.0, //N32
2055 0.0, 0.0, 6.0, //N33
2056 0.0, 3.0, 6.0, //N34
2057 3.0, 0.0, 6.0, //N35
2059 0.0, 1.5, 0.0, //N36
2060 1.5, 1.5, 0.0, //N37
2061 1.5, 0.0, 0.0, //N38
2062 0.0, 1.5, 6.0, //N39
2063 1.5, 1.5, 6.0, //N40
2064 1.5, 0.0, 6.0, //N41
2065 0.0, 0.0, 3.0, //N42
2066 0.0, 3.0, 3.0, //N43
2067 3.0, 0.0, 3.0, //N44
2069 0.0, 0.0, 4.0, //N45
2070 0.0, 4.0, 4.0, //N46
2071 4.0, 4.0, 4.0, //N47
2072 4.0, 0.0, 4.0, //N48
2073 0.0, 2.0, 4.0, //N49
2074 2.0, 4.0, 4.0, //N50
2075 4.0, 2.0, 4.0, //N51
2076 2.0, 0.0, 4.0, //N52
2077 0.0, 0.0, 2.0, //N53
2078 0.0, 4.0, 2.0, //N54
2079 4.0, 4.0, 2.0, //N55
2080 4.0, 0.0, 2.0, //N56
2083 MED_EN::medGeometryElement cellTypes[ numberOfCellTypes ] =
2092 MED_EN::MED_TETRA10,
2096 MED_EN::MED_PENTA15,
2101 const int numberOfCells[numberOfCellTypes] =
2105 1, 1, 1, 1, 1, 1, 1, 1 //3D
2120 //Tria3 Connectivity
2126 //Tria6 Connectivity
2132 //Quad4 Connectivity
2138 //Quad8 Connectivity
2141 1, 10, 11, 12, 13, 14, 15, 16
2144 //Tetra4 Connectivity
2150 //Tetra10 Connectivity
2153 1, 17, 18, 19, 20, 21, 22, 23, 24, 25
2156 //Pyra13 Connectivity
2162 //Pyra13 Connectivity
2165 1, 12, 11, 10, 26, 16, 15, 14, 13, 27, 28, 29, 30
2168 //Penta6 Connectivity
2171 1, 31, 32, 33, 34, 35
2174 //Penta6 Connectivity
2177 1, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44
2180 //Hexa8 Connectivity
2183 1, 10, 11, 12, 45, 46, 47, 48
2186 //Hexa20 Connectivity
2189 1, 10, 11, 12, 45, 46, 47, 48, 13, 14, 15, 16, 49, 50, 51, 52, 53, 54, 55, 56
2194 MEDMEM::MESHING* mesh = new MEDMEM::MESHING;
2195 mesh->setCoordinates(spaceDimension, numberOfNodes, coordinates,
2196 "CARTESIAN", MED_EN::MED_FULL_INTERLACE);
2197 mesh->setCoordinatesNames(names);
2198 mesh->setCoordinatesUnits(units);
2201 mesh->setNumberOfTypes(numberOfCellTypes, MED_EN::MED_CELL);
2202 mesh->setTypes(cellTypes, MED_EN::MED_CELL);
2203 mesh->setNumberOfElements(numberOfCells, MED_EN::MED_CELL);
2205 mesh->setConnectivity( MED_EN::MED_CELL, MED_EN::MED_SEG2, seg2C );
2206 mesh->setConnectivity( MED_EN::MED_CELL, MED_EN::MED_SEG3, seg3C );
2207 mesh->setConnectivity( MED_EN::MED_CELL, MED_EN::MED_TRIA3, tria3C );
2208 mesh->setConnectivity( MED_EN::MED_CELL, MED_EN::MED_TRIA6, tria6C );
2209 mesh->setConnectivity( MED_EN::MED_CELL, MED_EN::MED_QUAD4, quad4C );
2210 mesh->setConnectivity( MED_EN::MED_CELL, MED_EN::MED_QUAD8, quad8C );
2211 mesh->setConnectivity( MED_EN::MED_CELL, MED_EN::MED_TETRA4, tetra4C );
2212 mesh->setConnectivity( MED_EN::MED_CELL, MED_EN::MED_TETRA10, tetra10C );
2213 mesh->setConnectivity( MED_EN::MED_CELL, MED_EN::MED_PYRA5, pyra5C );
2214 mesh->setConnectivity( MED_EN::MED_CELL, MED_EN::MED_PYRA13, pyra13C );
2215 mesh->setConnectivity( MED_EN::MED_CELL, MED_EN::MED_PENTA6, penta6C );
2216 mesh->setConnectivity( MED_EN::MED_CELL, MED_EN::MED_PENTA15, penta15C );
2217 mesh->setConnectivity( MED_EN::MED_CELL, MED_EN::MED_HEXA8, hexa8C );
2218 mesh->setConnectivity( MED_EN::MED_CELL, MED_EN::MED_HEXA20, hexa20C );
2221 //Support definition
2222 const SUPPORT* sup = mesh->getSupportOnAll( MED_EN::MED_CELL );
2225 FIELD<int>* aField = new FIELD<int>(sup,1);
2227 //Gauss Localization definition:
2245 // --------- Seg2 localization ---------
2246 // Nb of the gauss points = 1
2247 double seg2CooRef[2] =
2251 double seg2CooGauss[1] =
2256 GAUSS_LOCALIZATION<>* aseg2L = new GAUSS_LOCALIZATION<>("Seg2 Gauss localization",
2263 // --------- Seg3 localization ---------
2264 // Nb of the gauss points = 1
2265 double seg3CooRef[3] =
2269 double seg3CooGauss[1] =
2274 GAUSS_LOCALIZATION<>* aseg3L = new GAUSS_LOCALIZATION<>("Seg3 Gauss localization",
2280 // --------- Tria3 localization ---------
2281 // Nb of the gauss points = 2
2282 double tria3CooRef[6] =
2284 0.0, 0.0, 1.0 , 0.0, 0.0, 1.0
2287 double tria3CooGauss[4] =
2292 GAUSS_LOCALIZATION<>* atria3L = new GAUSS_LOCALIZATION<>("Tria3 Gauss localization",
2299 // --------- Tria6 localization ---------
2300 // Nb of the gauss points = 3
2301 double tria6CooRef[12] =
2303 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.5, 0.0, 0.5, 0.5, 0.0, 0.5
2306 double tria6CooGauss[6] =
2308 0.3, 0.2, 0.2, 0.1, 0.2, 0.4
2311 GAUSS_LOCALIZATION<>* atria6L = new GAUSS_LOCALIZATION<>("Tria6 Gauss localization",
2317 // --------- Quad4 localization ---------
2318 // Nb of the gauss points = 4
2319 double quad4CooRef[8] =
2321 -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0
2324 double quad4CooGauss[8] =
2325 { //Size is type/10*NbGauss = (204/100)*4 = 8
2326 0.3, 0.2, 0.2, 0.1, 0.2, 0.4, 0.15, 0.27
2329 GAUSS_LOCALIZATION<>* aquad4L = new GAUSS_LOCALIZATION<>("Quad8 Gauss localization",
2335 // --------- Quad8 localization ---------
2336 // Nb of the gauss points = 4
2337 double quad8CooRef[16] =
2349 double quad8CooGauss[8] =
2351 0.34, 0.16, 0.21, 0.3, 0.23, 0.4, 0.14, 0.37
2354 GAUSS_LOCALIZATION<>* aquad8L = new GAUSS_LOCALIZATION<>("Quad8 Gauss localization",
2361 // --------- Tetra4 localization
2362 // Nb of the gauss points = 1
2363 double tetra4CooRef[12] =
2371 double tetra4CooGauss[3] =
2376 GAUSS_LOCALIZATION<>* atetra4L = new GAUSS_LOCALIZATION<>("Tetra4 Gauss localization",
2383 // --------- Tetra10 localization
2384 // Nb of the gauss points = 1
2385 double tetra10CooRef[30] =
2399 double tetra10CooGauss[3] =
2404 GAUSS_LOCALIZATION<>* atetra10L = new GAUSS_LOCALIZATION<>("Tetra10 Gauss localization",
2405 MED_EN::MED_TETRA10,
2410 // --------- Pyra5 localization
2411 // Nb of the gauss points = 1
2412 double pyra5CooRef[15] =
2421 double pyra5CooGauss[3] =
2426 GAUSS_LOCALIZATION<>* apyra5L = new GAUSS_LOCALIZATION<>("Pyra5 Gauss localization",
2433 // --------- Pyra13 localization
2434 // Nb of the gauss points = 1
2435 double pyra13CooRef[39] =
2452 double pyra13CooGauss[3] =
2457 GAUSS_LOCALIZATION<>* apyra13L = new GAUSS_LOCALIZATION<>("Pyra13 Gauss localization",
2463 // --------- Penta6 localization
2464 // Nb of the gauss points = 1
2465 double penta6CooRef[18] =
2475 double penta6CooGauss[3] =
2480 GAUSS_LOCALIZATION<>* apenta6L = new GAUSS_LOCALIZATION<>("Penta6 Gauss localization",
2487 // --------- Penta15 localization
2488 // Nb of the gauss points = 1
2489 double penta15CooRef[45] =
2508 double penta15CooGauss[3] =
2513 GAUSS_LOCALIZATION<>* apenta15L = new GAUSS_LOCALIZATION<>("Penta15 Gauss localization",
2514 MED_EN::MED_PENTA15,
2520 // --------- Hexa8 localization
2521 // Nb of the gauss points = 1
2522 double hexa8CooRef [24] =
2534 double hexa8CooGauss[3] =
2539 GAUSS_LOCALIZATION<>* ahexa8L = new GAUSS_LOCALIZATION<>("Hexa8 Gauss localization",
2546 // --------- Hexa20 localization
2547 // Nb of the gauss points = 1
2548 double hexa20CooRef[60] =
2572 double hexa20CooGauss[3] =
2577 GAUSS_LOCALIZATION<>* ahexa20L = new GAUSS_LOCALIZATION<>("Hexa20 Gauss localization",
2586 aField->setGaussLocalization(MED_EN::MED_SEG2, aseg2L);
2587 aField->setGaussLocalization(MED_EN::MED_SEG3, aseg3L);
2588 aField->setGaussLocalization(MED_EN::MED_TRIA3, atria3L);
2589 aField->setGaussLocalization(MED_EN::MED_TRIA6, atria6L);
2590 aField->setGaussLocalization(MED_EN::MED_QUAD4, aquad4L);
2591 aField->setGaussLocalization(MED_EN::MED_QUAD8, aquad8L);
2592 aField->setGaussLocalization(MED_EN::MED_TETRA4, atetra4L);
2593 aField->setGaussLocalization(MED_EN::MED_TETRA10, atetra10L);
2594 aField->setGaussLocalization(MED_EN::MED_PYRA5, apyra5L);
2595 aField->setGaussLocalization(MED_EN::MED_PYRA13, apyra13L);
2596 aField->setGaussLocalization(MED_EN::MED_PENTA6, apenta6L);
2597 aField->setGaussLocalization(MED_EN::MED_PENTA15, apenta15L);
2598 aField->setGaussLocalization(MED_EN::MED_HEXA8, ahexa8L);
2599 aField->setGaussLocalization(MED_EN::MED_HEXA20, ahexa20L);
2601 FIELD<double>* aGaussCoords = aField->getGaussPointsCoordinates();
2604 //Coordinates to check result
2605 double seg2Coord[3] =
2609 double seg3Coord[3] =
2614 double tria3Coord[3*2] =
2616 5.1, 1.55, 0.0, //First GP Coordinates
2617 4.7, 1.65, 0.0 //Second GP Coordinates
2620 double tria6Coord[3*3] =
2622 2.32, 1.52, 0.0, //First GP Coordinates
2623 1.6 , 1.32, 0.0, //Second GP Coordinates
2624 3.52, 1.26, 0.0 //Third GP Coordinates
2627 double quad4Coord[4*3] =
2635 double quad8Coord[4*3] =
2643 double tetra4Coord[3] =
2648 double tetra10Coord[3] =
2653 double pyra5Coord [3]=
2658 double pyra13Coord [3] =
2663 double penta6Coord [3] =
2668 double penta15Coord [3] =
2673 double hexa8Coord [3] =
2678 double hexa20Coord [3] =
2680 2.31232, 2.3934, 1.55326
2683 //Check result of the calculation
2685 double EPS = 0.000001;
2689 for(int j = 1; j<=3;j++)
2691 CPPUNIT_ASSERT_DOUBLES_EQUAL(aGaussCoords->getValueIJK(ElemId,j,1),
2692 seg2Coord[j-1], EPS);
2697 for(int j = 1; j<=3;j++)
2699 CPPUNIT_ASSERT_DOUBLES_EQUAL(aGaussCoords->getValueIJK(ElemId,j,1),
2700 seg3Coord[j-1], EPS);
2705 for(int k = 1; k <=2 ; k++)
2707 for(int j = 1; j<=3;j++)
2709 CPPUNIT_ASSERT_DOUBLES_EQUAL(aGaussCoords->getValueIJK(ElemId,j,k),
2710 tria3Coord[idx++], EPS);
2717 for(int k = 1; k <=3 ; k++)
2719 for(int j = 1; j<=3;j++)
2721 CPPUNIT_ASSERT_DOUBLES_EQUAL(aGaussCoords->getValueIJK(ElemId,j,k),
2722 tria6Coord[idx++], EPS);
2729 for(int k = 1; k <=4 ; k++)
2731 for(int j = 1; j<=3;j++)
2733 CPPUNIT_ASSERT_DOUBLES_EQUAL(aGaussCoords->getValueIJK(ElemId,j,k),
2734 quad4Coord[idx++], EPS);
2741 for(int k = 1; k <=4 ; k++)
2743 for(int j = 1; j<=3;j++)
2745 CPPUNIT_ASSERT_DOUBLES_EQUAL(aGaussCoords->getValueIJK(ElemId,j,k),
2746 quad8Coord[idx++], EPS);
2752 for(int j = 1; j<=3;j++)
2754 CPPUNIT_ASSERT_DOUBLES_EQUAL(aGaussCoords->getValueIJK(ElemId,j,1),
2755 tetra4Coord[j-1], EPS);
2760 for(int j = 1; j<=3;j++)
2762 CPPUNIT_ASSERT_DOUBLES_EQUAL(aGaussCoords->getValueIJK(ElemId,j,1),
2763 tetra10Coord[j-1], EPS);
2768 for(int j = 1; j<=3;j++)
2770 CPPUNIT_ASSERT_DOUBLES_EQUAL(aGaussCoords->getValueIJK(ElemId,j,1),
2771 pyra5Coord[j-1], EPS);
2776 for(int j = 1; j<=3;j++)
2778 CPPUNIT_ASSERT_DOUBLES_EQUAL(aGaussCoords->getValueIJK(ElemId,j,1),
2779 pyra13Coord[j-1], EPS);
2784 for(int j = 1; j<=3;j++)
2786 CPPUNIT_ASSERT_DOUBLES_EQUAL(aGaussCoords->getValueIJK(ElemId,j,1),
2787 penta6Coord[j-1], EPS);
2792 for(int j = 1; j<=3;j++)
2794 CPPUNIT_ASSERT_DOUBLES_EQUAL(aGaussCoords->getValueIJK(ElemId,j,1),
2795 penta15Coord[j-1], EPS);
2800 for(int j = 1; j<=3;j++)
2802 CPPUNIT_ASSERT_DOUBLES_EQUAL(aGaussCoords->getValueIJK(ElemId,j,1),
2803 hexa8Coord[j-1], EPS);
2808 for(int j = 1; j<=3;j++)
2810 CPPUNIT_ASSERT_DOUBLES_EQUAL(aGaussCoords->getValueIJK(ElemId,j,1),
2811 hexa20Coord[j-1], 0.0001);
2814 aGaussCoords->removeReference();
2815 aField->removeReference();
2816 mesh->removeReference();