1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D
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 "SauvLoaderTest.hxx"
22 #include "SauvReader.hxx"
23 #include "SauvWriter.hxx"
24 #include "MEDFileData.hxx"
25 #include "MEDCouplingFieldDouble.hxx"
26 #include "MEDCouplingMemArray.hxx"
37 using namespace ParaMEDMEM;
39 void SauvLoaderTest::testSauv2Med()
41 // read a file containing all types of readable piles
42 std::string file = getResourceFile("allPillesTest.sauv");
43 MEDCouplingAutoRefCountObjectPtr<SauvReader> sr=SauvReader::New(file.c_str());
44 MEDCouplingAutoRefCountObjectPtr<MEDFileData> d2=sr->loadInMEDFileDS();
46 d2->write("allPillesTest.med",0);
48 CPPUNIT_ASSERT_EQUAL(1,d2->getNumberOfMeshes());
49 CPPUNIT_ASSERT_EQUAL(8+97,d2->getNumberOfFields());
50 MEDFileMesh * m = d2->getMeshes()->getMeshAtPos(0);
51 CPPUNIT_ASSERT_EQUAL(17,int(m->getGroupsNames().size()));
54 void SauvLoaderTest::testMed2SauvOnAMeshWithVoidFamily()
56 // Create a mesh with 2 quads.
57 const int spaceDim = 2;
58 const int nbOfNodes = 6;
59 double coords[nbOfNodes*spaceDim] = {0,0, 1,0, 1,1, 0,1, 2,0, 2,1};
60 int conn[8]={0,1,2,3, 1,4,5,2};
61 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh2d=MEDCouplingUMesh::New("Mesh",spaceDim);
62 mesh2d->allocateCells(2);
63 mesh2d->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn);
64 mesh2d->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+4);
65 mesh2d->finishInsertingCells();
66 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> myCoords=DataArrayDouble::New();
67 myCoords->alloc(nbOfNodes,spaceDim);
68 std::copy(coords,coords+nbOfNodes*spaceDim,myCoords->getPointer());
69 mesh2d->setCoords(myCoords);
71 // create a MedFileUMesh
72 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> m= MEDFileUMesh::New();
73 m->setMeshAtLevel(0,mesh2d);
75 // Create families and groups
77 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam = DataArrayInt::New();
79 int elemsFams[2] = {-2,-3};
80 std::copy(elemsFams,elemsFams+2,fam->getPointer());
82 m->setFamilyFieldArr(0,fam);
84 std::map<std::string,int> theFamilies;
85 theFamilies["FAM_-1"]=-1;
86 theFamilies["FAM_-2"]=-2;
87 theFamilies["FAM_-3"]=-3;
89 std::map<std::string, std::vector<std::string> > theGroups;
90 theGroups["Group1"].push_back("FAM_-2");
91 theGroups["Group2"].push_back("FAM_-3");
92 theGroups["Grouptot"].push_back("FAM_-1");
93 theGroups["Grouptot"].push_back("FAM_-2");
94 theGroups["Grouptot"].push_back("FAM_-3");
95 m->setFamilyInfo(theFamilies);
96 m->setGroupInfo(theGroups);
98 // write to MED for visual check
99 //const char* medFile = "mesh_with_void_family.med";
100 //m->write(medFile, 2);
103 const char* sauvFile = "mesh_with_void_family.sauv";
104 MEDCouplingAutoRefCountObjectPtr<MEDFileData> medData = MEDFileData::New();
105 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> medMeshes = MEDFileMeshes::New();
106 MEDCouplingAutoRefCountObjectPtr<SauvWriter> sw=SauvWriter::New();
107 medMeshes->setMeshAtPos(0, m);
108 medData->setMeshes(medMeshes);
109 sw->setMEDFileDS(medData);
112 // read SAUV and check groups
113 MEDCouplingAutoRefCountObjectPtr<SauvReader> sr=SauvReader::New(sauvFile);
114 MEDCouplingAutoRefCountObjectPtr<MEDFileData> d2=sr->loadInMEDFileDS();
115 MEDFileUMesh* m2 = static_cast<MEDFileUMesh*>( d2->getMeshes()->getMeshAtPos(0) );
116 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> grp1 = m2->getGroup(0, "Group1");
117 CPPUNIT_ASSERT_EQUAL(1,(int)grp1->getNumberOfCells());
118 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> grp2 = m2->getGroup(0, "Group2");
119 CPPUNIT_ASSERT_EQUAL(1,(int)grp2->getNumberOfCells());
120 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> grptot = m2->getGroup(0, "Grouptot");
121 CPPUNIT_ASSERT_EQUAL(2,(int)grptot->getNumberOfCells());
124 void SauvLoaderTest::testSauv2MedOnA3SubsField()
127 std::string sauvFile = getResourceFile("portico_3subs.sauv");
128 MEDCouplingAutoRefCountObjectPtr<SauvReader> sr=SauvReader::New(sauvFile.c_str());
129 MEDCouplingAutoRefCountObjectPtr<MEDFileData> d2=sr->loadInMEDFileDS();
131 MEDFileUMesh* m2 = static_cast<MEDFileUMesh*>(d2->getMeshes()->getMeshAtPos(0));
132 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh1d = m2->getMeshAtLevel(0);
133 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> length1dField = mesh1d->getMeasureField(0);
134 std::cout << "Length of 1d elements: " << length1dField->accumulate(0) << std::endl;
135 CPPUNIT_ASSERT_DOUBLES_EQUAL(3, length1dField->accumulate(0), 1e-12);
137 MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> field =
138 dynamic_cast<MEDFileFieldMultiTS *>(d2->getFields()->getFieldWithName("CHAM1D"));
139 std::cout << "Number of components in field: " << field->getInfo().size() << std::endl;
140 CPPUNIT_ASSERT_EQUAL(6,(int)field->getInfo().size());
141 std::vector< std::pair<int,int> > timesteps = field->getIterations();
143 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field1d =
144 field->getFieldOnMeshAtLevel(ON_GAUSS_NE, timesteps[0].first, timesteps[0].second, 0, m2);
146 // Check first component of the field
147 // 2 gauss points per element => 12 values
148 double values[12] = {
160 -6.111413346910e-07};
162 for (int i=0; i < field1d->getNumberOfTuples(); i++)
164 CPPUNIT_ASSERT_DOUBLES_EQUAL( values[i], field1d->getIJ(i, 0), 1e-12 );
168 void SauvLoaderTest::testMed2Sauv()
171 std::string file = getResourceFile("pointe.med");
172 MEDCouplingAutoRefCountObjectPtr<MEDFileData> pointeMed=MEDFileData::New(file.c_str());
174 // add 3 faces to pointeMed
175 MEDFileUMesh* pointeMedMesh = static_cast<MEDFileUMesh*>(pointeMed->getMeshes()->getMeshAtPos(0));
176 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> pointeM1D = MEDCouplingUMesh::New();
177 DataArrayDouble *coords = pointeMedMesh->getCoords();
178 pointeM1D->setCoords( coords );
179 pointeM1D->setMeshDimension( 2 );
180 pointeM1D->allocateCells( 3 );
183 0,1,2, 0,1,3, 10,11,12,13
185 pointeM1D->insertNextCell( INTERP_KERNEL::NORM_TRI3, 3, conn);
186 pointeM1D->insertNextCell( INTERP_KERNEL::NORM_TRI3, 3, conn+3);
187 pointeM1D->insertNextCell( INTERP_KERNEL::NORM_QUAD4, 4, conn+6);
188 pointeM1D->finishInsertingCells();
189 pointeMedMesh->setMeshAtLevel( -1, pointeM1D );
190 pointeMed->getMeshes()->setMeshAtPos( 0, pointeMedMesh );
192 // add a field on 2 faces to pointeMed
193 MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> ff1=MEDFileFieldMultiTS::New();
194 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=MEDCouplingFieldDouble::New(ON_GAUSS_NE,ONE_TIME);
195 f1->setName("Field on 2 faces");
196 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> d=DataArrayDouble::New();
198 d->setInfoOnComponent(0,"sigX [MPa]");
199 d->setInfoOnComponent(1,"sigY [GPa]");
200 double vals[2*(3+4)] =
202 311,312,321,322,331,332,411,412,421,422,431,432,441,442
204 std::copy(vals,vals+d->getNbOfElems(),d->getPointer());
206 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=DataArrayInt::New();
211 MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> pointeM1D_part=pointeM1D->buildPartOfMySelf(ids,ids+2,true);
212 f1->setMesh( pointeM1D_part );
214 std::copy(ids,ids+da->getNbOfElems(),da->getPointer());
216 ff1->appendFieldProfile(f1,pointeMedMesh,-1,da);
217 pointeMed->getFields()->pushField( ff1 );
219 // remove "fieldnodeint"
220 MEDFileFields* pointeFields = pointeMed->getFields();
221 for ( int i = 0; i < pointeFields->getNumberOfFields(); ++i )
223 MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTS> ts = pointeFields->getFieldAtPos(i);
224 if ( std::string("fieldnodeint") == ts->getName())
226 pointeFields->destroyFieldAtPos( i );
230 // write pointeMed to SAUV
231 const char* sauvFile = "pointe.sauv";
232 MEDCouplingAutoRefCountObjectPtr<SauvWriter> sw=SauvWriter::New();
233 sw->setMEDFileDS(pointeMed);
236 // read SAUV and check
237 MEDCouplingAutoRefCountObjectPtr<SauvReader> sr=SauvReader::New(sauvFile);
238 MEDCouplingAutoRefCountObjectPtr<MEDFileData> d2=sr->loadInMEDFileDS();
239 CPPUNIT_ASSERT_EQUAL(1,d2->getNumberOfMeshes());
240 CPPUNIT_ASSERT_EQUAL(4,d2->getNumberOfFields());
241 MEDFileUMesh * m = static_cast<MEDFileUMesh*>( d2->getMeshes()->getMeshAtPos(0) );
242 CPPUNIT_ASSERT_EQUAL(std::string("maa1"),std::string(m->getName() ));
243 CPPUNIT_ASSERT_EQUAL(3,m->getMeshDimension());
244 std::vector<std::string > groups = m->getGroupsNames();
245 CPPUNIT_ASSERT_EQUAL(6,(int)groups.size());
246 CPPUNIT_ASSERT( std::find(groups.begin(),groups.end(),"groupe1") != groups.end() );
247 CPPUNIT_ASSERT( std::find(groups.begin(),groups.end(),"groupe2") != groups.end() );
248 CPPUNIT_ASSERT( std::find(groups.begin(),groups.end(),"groupe3") != groups.end() );
249 CPPUNIT_ASSERT( std::find(groups.begin(),groups.end(),"groupe4") != groups.end() );
250 CPPUNIT_ASSERT( std::find(groups.begin(),groups.end(),"groupe5") != groups.end() );
251 CPPUNIT_ASSERT( std::find(groups.begin(),groups.end(),"maa1") != groups.end() );
252 CPPUNIT_ASSERT_EQUAL(16,m->getSizeAtLevel(0));
253 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> um0 = m->getGenMeshAtLevel(0);
254 CPPUNIT_ASSERT_EQUAL(12, um0->getNumberOfCellsWithType( INTERP_KERNEL::NORM_TETRA4 ));
255 CPPUNIT_ASSERT_EQUAL(2, um0->getNumberOfCellsWithType( INTERP_KERNEL::NORM_PYRA5 ));
256 CPPUNIT_ASSERT_EQUAL(2, um0->getNumberOfCellsWithType( INTERP_KERNEL::NORM_HEXA8 ));
257 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> um1 = m->getGenMeshAtLevel(-1);
258 CPPUNIT_ASSERT_EQUAL(2, um1->getNumberOfCellsWithType( INTERP_KERNEL::NORM_TRI3 ));
259 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> pointeUM0 =
260 static_cast<MEDCouplingUMesh*>( pointeMedMesh->getGenMeshAtLevel(0));
261 DataArrayDouble *coo = m->getCoords();
262 DataArrayDouble *pointeCoo = pointeMedMesh->getCoords();
263 CPPUNIT_ASSERT(coo->isEqualWithoutConsideringStr(*pointeCoo,1e-12));
264 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> vol = um0->getMeasureField(0);
265 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> pointeVol = pointeUM0->getMeasureField(0);
266 CPPUNIT_ASSERT_DOUBLES_EQUAL( vol->accumulate(0), pointeVol->accumulate(0),1e-12);
269 MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> fieldnodedoubleTS1 =
270 dynamic_cast<MEDFileFieldMultiTS *>(pointeMed->getFields()->getFieldWithName("fieldnodedouble"));
271 MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> fieldnodedoubleTS2 =
272 dynamic_cast<MEDFileFieldMultiTS *>(d2->getFields()->getFieldWithName("fieldnodedouble"));
273 CPPUNIT_ASSERT_EQUAL( fieldnodedoubleTS1->getInfo().size(), fieldnodedoubleTS2->getInfo().size());
274 for ( size_t i = 0; i < fieldnodedoubleTS1->getInfo().size(); ++i )
275 CPPUNIT_ASSERT_EQUAL( fieldnodedoubleTS1->getInfo()[i], fieldnodedoubleTS2->getInfo()[i]);
276 CPPUNIT_ASSERT_EQUAL( fieldnodedoubleTS1->getNumberOfTS(), fieldnodedoubleTS2->getNumberOfTS());
277 std::vector< std::pair<int,int> > io1 = fieldnodedoubleTS1->getIterations();
278 std::vector< std::pair<int,int> > io2 = fieldnodedoubleTS2->getIterations();
279 for ( int i =0; i < fieldnodedoubleTS1->getNumberOfTS(); ++i )
281 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> fnd1 =
282 fieldnodedoubleTS1->getFieldOnMeshAtLevel(ON_NODES, io1[i].first,io1[i].second,pointeUM0);
283 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> fnd2 =
284 fieldnodedoubleTS2->getFieldOnMeshAtLevel(ON_NODES, io2[i].first,io2[i].second,um0);
285 CPPUNIT_ASSERT( fnd1->getArray()->isEqual( *fnd2->getArray(), 1e-12 ));
287 // fieldcelldoublevector
288 MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> fieldcelldoublevectorTS1 =
289 dynamic_cast<MEDFileFieldMultiTS *>(pointeMed->getFields()->getFieldWithName("fieldcelldoublevector"));
290 MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> fieldcelldoublevectorTS2 =
291 dynamic_cast<MEDFileFieldMultiTS *>(d2->getFields()->getFieldWithName("fieldcelldoublevector"));
292 CPPUNIT_ASSERT_EQUAL( fieldcelldoublevectorTS1->getInfo().size(), fieldcelldoublevectorTS2->getInfo().size());
293 for ( size_t i = 0; i < fieldcelldoublevectorTS1->getInfo().size(); ++i )
294 CPPUNIT_ASSERT_EQUAL( fieldcelldoublevectorTS1->getInfo()[i], fieldcelldoublevectorTS2->getInfo()[i]);
295 CPPUNIT_ASSERT_EQUAL( fieldcelldoublevectorTS1->getNumberOfTS(), fieldcelldoublevectorTS2->getNumberOfTS());
296 io1 = fieldcelldoublevectorTS1->getIterations();
297 io2 = fieldcelldoublevectorTS2->getIterations();
298 for ( int i =0; i < fieldcelldoublevectorTS1->getNumberOfTS(); ++i )
300 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> fnd1 =
301 fieldcelldoublevectorTS1->getFieldOnMeshAtLevel(ON_CELLS, io1[i].first,io1[i].second,pointeUM0);
302 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> fnd2 =
303 fieldcelldoublevectorTS2->getFieldOnMeshAtLevel(ON_CELLS, io2[i].first,io2[i].second,um0);
304 CPPUNIT_ASSERT_DOUBLES_EQUAL( fnd1->accumulate(0), fnd2->accumulate(0), 1e-12 );
305 CPPUNIT_ASSERT_DOUBLES_EQUAL( fnd1->accumulate(1), fnd2->accumulate(1), 1e-12 );
306 CPPUNIT_ASSERT_DOUBLES_EQUAL( fnd1->accumulate(2), fnd2->accumulate(2), 1e-12 );
308 // "Field on 2 faces"
309 MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> fieldOnFaces =
310 dynamic_cast<MEDFileFieldMultiTS *>(d2->getFields()->getFieldWithName(f1->getName()));
311 io1 = fieldOnFaces->getIterations();
312 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> fof =
313 fieldOnFaces->getFieldOnMeshAtLevel(f1->getTypeOfField(),io1[0].first,io1[0].second,um1);
314 CPPUNIT_ASSERT( d->isEqual( *fof->getArray(), 1e-12 ));
317 void SauvLoaderTest::tearDown()
319 const int nbFilesToRemove = 3;
320 const char* fileToRemove[nbFilesToRemove] = { "allPillesTest.med", "pointe.sauv", "mesh_with_void_family.sauv" };
321 for ( int i = 0; i < nbFilesToRemove; ++i )
324 if (GetFileAttributes(fileToRemove[i]) != INVALID_FILE_ATTRIBUTES)
326 if (access(fileToRemove[i], F_OK) == 0)
328 remove(fileToRemove[i]);
332 std::string SauvLoaderTest::getResourceFile( const std::string& filename )
334 std::string resourceFile = "";
336 if ( getenv("top_srcdir") ) {
337 // we are in 'make check' step
338 resourceFile = getenv("top_srcdir");
339 resourceFile += "/resources/";
341 else if ( getenv("MED_ROOT_DIR") ) {
342 // use MED_ROOT_DIR env.var
343 resourceFile = getenv("MED_ROOT_DIR");
344 resourceFile += "/share/salome/resources/med/";
346 resourceFile += filename;
348 std::string fixedpath = resourceFile;
349 for ( int i=0; i < fixedpath.length(); ++i )
350 if (fixedpath[i] == '/')