1 // Copyright (C) 2007-2008 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
19 #include "ParaMEDMEMTest.hxx"
20 #include <cppunit/TestAssert.h>
22 #include "CommInterface.hxx"
23 #include "ProcessorGroup.hxx"
24 #include "MPIProcessorGroup.hxx"
25 #include "Topology.hxx"
27 #include "MxN_Mapping.hxx"
28 #include "IntersectionDEC.hxx"
29 #include "ParaMESH.hxx"
30 #include "ParaFIELD.hxx"
31 #include "ICoCoMEDField.hxx"
32 #include "MEDLoader.hxx"
36 // use this define to enable lines, execution of which leads to Segmentation Fault
39 // use this define to enable CPPUNIT asserts and fails, showing bugs
40 #define ENABLE_FORCED_FAILURES
44 using namespace ParaMEDMEM;
46 void ParaMEDMEMTest::testIntersectionDEC_2D()
48 testIntersectionDEC_2D_("P0","P0");
51 void ParaMEDMEMTest::testIntersectionDEC_2DP0P1()
53 //testIntersectionDEC_2D_("P0","P1");
57 * Check methods defined in IntersectionDEC.hxx
60 IntersectionDEC(ProcessorGroup& local_group, ProcessorGroup& distant_group);
61 virtual ~IntersectionDEC();
67 void ParaMEDMEMTest::testIntersectionDEC_2D_(const char *srcMeth, const char *targetMeth)
69 std::string srcM(srcMeth);
70 std::string targetM(targetMeth);
73 MPI_Comm_size(MPI_COMM_WORLD,&size);
74 MPI_Comm_rank(MPI_COMM_WORLD,&rank);
76 //the test is meant to run on five processors
77 if (size !=5) return ;
81 set<int> procs_source;
82 set<int> procs_target;
84 for (int i=0; i<nproc_source; i++)
85 procs_source.insert(i);
86 for (int i=nproc_source; i<size; i++)
87 procs_target.insert(i);
88 self_procs.insert(rank);
90 ParaMEDMEM::CommInterface interface;
92 ParaMEDMEM::ProcessorGroup* self_group = new ParaMEDMEM::MPIProcessorGroup(interface,self_procs);
93 ParaMEDMEM::ProcessorGroup* target_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_target);
94 ParaMEDMEM::ProcessorGroup* source_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_source);
96 //loading the geometry for the source group
98 ParaMEDMEM::IntersectionDEC dec (*source_group,*target_group);
100 ParaMEDMEM::MEDCouplingUMesh* mesh;
101 ParaMEDMEM::ParaMESH* paramesh;
102 ParaMEDMEM::ParaFIELD* parafield;
103 ICoCo::Field* icocofield ;
105 string data_dir = getenv("MED_ROOT_DIR");
106 string tmp_dir = getenv("TMP");
109 string filename_xml1 = data_dir + "/share/salome/resources/med/square1_split";
110 string filename_xml2 = data_dir + "/share/salome/resources/med/square2_split";
111 string filename_seq_wr = tmp_dir + "/";
112 string filename_seq_med = tmp_dir + "/myWrField_seq_pointe221.med";
114 // To remove tmp files from disk
115 ParaMEDMEMTest_TmpFilesRemover aRemover;
117 MPI_Barrier(MPI_COMM_WORLD);
118 if (source_group->containsMyRank())
120 string master = filename_xml1;
122 ostringstream strstream;
123 strstream <<master<<rank+1<<".med";
124 ostringstream meshname ;
125 meshname<< "Mesh_2_"<< rank+1;
127 mesh=MEDLoader::ReadUMeshFromFile(strstream.str().c_str(),meshname.str().c_str(),0);
130 paramesh=new ParaMESH (mesh,*source_group,"source mesh");
132 // ParaMEDMEM::ParaSUPPORT* parasupport=new UnstructuredParaSUPPORT( support,*source_group);
133 ParaMEDMEM::ComponentTopology comptopo;
135 parafield = new ParaFIELD(ON_CELLS,paramesh, comptopo);
137 parafield = new ParaFIELD(ON_NODES,paramesh, comptopo);
140 nb_local=mesh->getNumberOfCells();
142 nb_local=mesh->getNumberOfNodes();
143 // double * value= new double[nb_local];
144 double *value=parafield->getField()->getArray()->getPointer();
145 for(int ielem=0; ielem<nb_local;ielem++)
148 // ICoCo::Field* icocofield=new ICoCo::MEDField(paramesh,parafield);
149 icocofield=new ICoCo::MEDField(paramesh,parafield);
150 dec.setMethod(srcMeth);
151 dec.attachLocalField(icocofield);
154 //loading the geometry for the target group
155 if (target_group->containsMyRank())
157 string master= filename_xml2;
158 ostringstream strstream;
159 strstream << master<<(rank-nproc_source+1)<<".med";
160 ostringstream meshname ;
161 meshname<< "Mesh_3_"<<rank-nproc_source+1;
162 mesh = MEDLoader::ReadUMeshFromFile(strstream.str().c_str(),meshname.str().c_str(),0);
164 paramesh=new ParaMESH (mesh,*target_group,"target mesh");
165 // ParaMEDMEM::ParaSUPPORT* parasupport=new UnstructuredParaSUPPORT(support,*target_group);
166 ParaMEDMEM::ComponentTopology comptopo;
168 parafield = new ParaFIELD(ON_CELLS,paramesh, comptopo);
170 parafield = new ParaFIELD(ON_NODES,paramesh, comptopo);
173 nb_local=mesh->getNumberOfCells();
175 nb_local=mesh->getNumberOfNodes();
176 // double * value= new double[nb_local];
177 double *value=parafield->getField()->getArray()->getPointer();
178 for(int ielem=0; ielem<nb_local;ielem++)
180 // ICoCo::Field* icocofield=new ICoCo::MEDField(paramesh,parafield);
181 icocofield=new ICoCo::MEDField(paramesh,parafield);
182 dec.setMethod(targetMeth);
183 dec.attachLocalField(icocofield);
187 //attaching a DEC to the source group
188 double field_before_int;
189 double field_after_int;
191 if (source_group->containsMyRank())
193 field_before_int = parafield->getVolumeIntegral(0);
195 cout<<"DEC usage"<<endl;
196 dec.setForcedRenormalization(false);
199 MEDLoader::writeParaMesh("./sourcesquareb",paramesh);
200 if (source_group->myRank()==0)
201 aRemover.Register("./sourcesquareb");
202 ostringstream filename;
203 filename<<"./sourcesquareb_"<<source_group->myRank()+1;
204 aRemover.Register(filename.str().c_str());
205 MEDLoader::writeParaField("./sourcesquareb","boundary",parafield);
208 cout <<"writing"<<endl;
209 MEDLoader::writeParaMesh("./sourcesquare",paramesh);
210 if (source_group->myRank()==0)
211 aRemover.Register("./sourcesquare");
212 MEDLoader::writeParaField("./sourcesquare","boundary",parafield);
215 filename<<"./sourcesquare_"<<source_group->myRank()+1;
216 aRemover.Register(filename.str().c_str());
217 field_after_int = parafield->getVolumeIntegral(0);
220 // MPI_Bcast(&field_before_int,1,MPI_DOUBLE,0,MPI_COMM_WORLD);
221 // MPI_Bcast(&field_after_int,1,MPI_DOUBLE,0,MPI_COMM_WORLD);
223 CPPUNIT_ASSERT_DOUBLES_EQUAL(field_before_int, field_after_int, 1e-6);
227 //attaching a DEC to the target group
228 if (target_group->containsMyRank())
231 dec.setForcedRenormalization(false);
234 MEDLoader::writeParaMesh("./targetsquareb",paramesh);
235 MEDLoader::writeParaField("./targetsquareb", "boundary",parafield);
236 if (target_group->myRank()==0)
237 aRemover.Register("./targetsquareb");
238 ostringstream filename;
239 filename<<"./targetsquareb_"<<target_group->myRank()+1;
240 aRemover.Register(filename.str().c_str());
242 MEDLoader::writeParaMesh("./targetsquare",paramesh);
243 MEDLoader::writeParaField("./targetsquare", "boundary",parafield);
245 if (target_group->myRank()==0)
246 aRemover.Register("./targetsquareb");
248 filename<<"./targetsquareb_"<<target_group->myRank()+1;
249 aRemover.Register(filename.str().c_str());
250 // double field_before_int, field_after_int;
251 // MPI_Bcast(&field_before_int,1,MPI_DOUBLE,0,MPI_COMM_WORLD);
252 // MPI_Bcast(&field_after_int,1,MPI_DOUBLE,0,MPI_COMM_WORLD);
254 // CPPUNIT_ASSERT_DOUBLES_EQUAL(field_before_int, field_after_int, 1e-6);
267 MPI_Barrier(MPI_COMM_WORLD);
268 cout << "end of IntersectionDEC_2D test"<<endl;
271 //Synchronous tests without interpolation with native mode (AllToAll(v) from lam/MPI:
272 void ParaMEDMEMTest::testSynchronousEqualIntersectionWithoutInterpNativeDEC_2D()
274 testAsynchronousIntersectionDEC_2D(0.1,1,0.1,1,false,false,false,"P0","P0");
277 //Synchronous tests without interpolation :
278 void ParaMEDMEMTest::testSynchronousEqualIntersectionWithoutInterpDEC_2D()
280 testAsynchronousIntersectionDEC_2D(0.1,1,0.1,1,true,false,false,"P0","P0");
283 //Synchronous tests with interpolation :
284 void ParaMEDMEMTest::testSynchronousEqualIntersectionDEC_2D()
286 testAsynchronousIntersectionDEC_2D(0.1,1,0.1,1,true,false,true,"P0","P0");
288 void ParaMEDMEMTest::testSynchronousFasterSourceIntersectionDEC_2D()
290 testAsynchronousIntersectionDEC_2D(0.09,1,0.1,1,true,false,true,"P0","P0");
292 void ParaMEDMEMTest::testSynchronousSlowerSourceIntersectionDEC_2D()
294 testAsynchronousIntersectionDEC_2D(0.11,1,0.1,1,true,false,true,"P0","P0");
296 void ParaMEDMEMTest::testSynchronousSlowSourceIntersectionDEC_2D()
298 testAsynchronousIntersectionDEC_2D(0.11,1,0.01,1,true,false,true,"P0","P0");
300 void ParaMEDMEMTest::testSynchronousFastSourceIntersectionDEC_2D()
302 testAsynchronousIntersectionDEC_2D(0.01,1,0.11,1,true,false,true,"P0","P0");
305 //Asynchronous tests with interpolation :
306 void ParaMEDMEMTest::testAsynchronousEqualIntersectionDEC_2D()
308 testAsynchronousIntersectionDEC_2D(0.1,1,0.1,1,true,true,true,"P0","P0");
310 void ParaMEDMEMTest::testAsynchronousFasterSourceIntersectionDEC_2D()
312 testAsynchronousIntersectionDEC_2D(0.09,1,0.1,1,true,true,true,"P0","P0");
314 void ParaMEDMEMTest::testAsynchronousSlowerSourceIntersectionDEC_2D()
316 testAsynchronousIntersectionDEC_2D(0.11,1,0.1,1,true,true,true,"P0","P0");
318 void ParaMEDMEMTest::testAsynchronousSlowSourceIntersectionDEC_2D()
320 testAsynchronousIntersectionDEC_2D(0.11,1,0.01,1,true,true,true,"P0","P0");
322 void ParaMEDMEMTest::testAsynchronousFastSourceIntersectionDEC_2D()
324 testAsynchronousIntersectionDEC_2D(0.01,1,0.11,1,true,true,true,"P0","P0");
328 * Tests an asynchronous exchange between two codes
329 * one sends data with dtA as an interval, the max time being tmaxA
330 * the other one receives with dtB as an interval, the max time being tmaxB
332 void ParaMEDMEMTest::testAsynchronousIntersectionDEC_2D(double dtA, double tmaxA,
333 double dtB, double tmaxB, bool WithPointToPoint, bool Asynchronous,
334 bool WithInterp, const char *srcMeth, const char *targetMeth)
336 std::string srcM(srcMeth);
337 std::string targetM(targetMeth);
340 MPI_Comm_size(MPI_COMM_WORLD,&size);
341 MPI_Comm_rank(MPI_COMM_WORLD,&rank);
343 //the test is meant to run on five processors
344 if (size !=5) return ;
346 int nproc_source = 3;
348 set<int> procs_source;
349 set<int> procs_target;
351 for (int i=0; i<nproc_source; i++)
352 procs_source.insert(i);
353 for (int i=nproc_source; i<size; i++)
354 procs_target.insert(i);
355 self_procs.insert(rank);
357 ParaMEDMEM::CommInterface interface;
359 ParaMEDMEM::ProcessorGroup* self_group = new ParaMEDMEM::MPIProcessorGroup(interface,self_procs);
360 ParaMEDMEM::ProcessorGroup* target_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_target);
361 ParaMEDMEM::ProcessorGroup* source_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_source);
363 //loading the geometry for the source group
365 ParaMEDMEM::IntersectionDEC dec (*source_group,*target_group);
367 ParaMEDMEM::MEDCouplingUMesh* mesh;
368 ParaMEDMEM::ParaMESH* paramesh;
369 ParaMEDMEM::ParaFIELD* parafield;
372 ICoCo::Field* icocofield ;
374 string data_dir = getenv("MED_ROOT_DIR");
375 string tmp_dir = getenv("TMP");
378 string filename_xml1 = data_dir + "/share/salome/resources/med/square1_split";
379 string filename_xml2 = data_dir + "/share/salome/resources/med/square2_split";
380 string filename_seq_wr = tmp_dir + "/";
381 string filename_seq_med = tmp_dir + "/myWrField_seq_pointe221.med";
383 // To remove tmp files from disk
384 ParaMEDMEMTest_TmpFilesRemover aRemover;
386 MPI_Barrier(MPI_COMM_WORLD);
388 if (source_group->containsMyRank())
390 string master = filename_xml1;
392 ostringstream strstream;
393 strstream <<master<<rank+1<<".med";
394 ostringstream meshname ;
395 meshname<< "Mesh_2_"<< rank+1;
397 mesh=MEDLoader::ReadUMeshFromFile(strstream.str().c_str(),meshname.str().c_str(),0);
399 paramesh=new ParaMESH (mesh,*source_group,"source mesh");
401 // ParaMEDMEM::ParaSUPPORT* parasupport=new UnstructuredParaSUPPORT( support,*source_group);
402 ParaMEDMEM::ComponentTopology comptopo;
404 parafield = new ParaFIELD(ON_CELLS,paramesh, comptopo);
406 parafield = new ParaFIELD(ON_NODES,paramesh, comptopo);
410 nb_local=mesh->getNumberOfCells();
412 nb_local=mesh->getNumberOfNodes();
413 // double * value= new double[nb_local];
414 double *value=parafield->getField()->getArray()->getPointer();
415 for(int ielem=0; ielem<nb_local;ielem++)
418 // ICoCo::Field* icocofield=new ICoCo::MEDField(paramesh,parafield);
419 icocofield=new ICoCo::MEDField(paramesh,parafield);
421 dec.attachLocalField(icocofield);
426 //loading the geometry for the target group
427 if (target_group->containsMyRank())
429 string master= filename_xml2;
430 ostringstream strstream;
431 strstream << master<<(rank-nproc_source+1)<<".med";
432 ostringstream meshname ;
433 meshname<< "Mesh_3_"<<rank-nproc_source+1;
435 mesh = MEDLoader::ReadUMeshFromFile(strstream.str().c_str(),meshname.str().c_str(),0);
437 paramesh=new ParaMESH (mesh,*target_group,"target mesh");
438 // ParaMEDMEM::ParaSUPPORT* parasupport=new UnstructuredParaSUPPORT(support,*target_group);
439 ParaMEDMEM::ComponentTopology comptopo;
441 parafield = new ParaFIELD(ON_CELLS,paramesh, comptopo);
443 parafield = new ParaFIELD(ON_NODES,paramesh, comptopo);
447 nb_local=mesh->getNumberOfCells();
449 nb_local=mesh->getNumberOfNodes();
451 double *value=parafield->getField()->getArray()->getPointer();
452 for(int ielem=0; ielem<nb_local;ielem++)
454 // ICoCo::Field* icocofield=new ICoCo::MEDField(paramesh,parafield);
455 icocofield=new ICoCo::MEDField(paramesh,parafield);
457 dec.attachLocalField(icocofield);
461 //attaching a DEC to the source group
463 if (source_group->containsMyRank())
465 cout<<"DEC usage"<<endl;
466 dec.setAsynchronous(Asynchronous);
468 dec.setTimeInterpolationMethod(LinearTimeInterp);
470 if ( WithPointToPoint ) {
471 dec.setAllToAllMethod(PointToPoint);
474 dec.setAllToAllMethod(Native);
477 dec.setForcedRenormalization(false);
478 for (double time=0; time<tmaxA+1e-10; time+=dtA)
480 cout << "testAsynchronousIntersectionDEC_2D" << rank << " time " << time
481 << " dtA " << dtA << " tmaxA " << tmaxA << endl ;
482 if ( time+dtA < tmaxA+1e-7 ) {
483 dec.sendData( time , dtA );
486 dec.sendData( time , 0 );
488 double* value = parafield->getField()->getArray()->getPointer();
489 int nb_local=parafield->getField()->getMesh()->getNumberOfCells();
490 for (int i=0; i<nb_local;i++)
497 //attaching a DEC to the target group
498 if (target_group->containsMyRank())
500 cout<<"DEC usage"<<endl;
501 dec.setAsynchronous(Asynchronous);
503 dec.setTimeInterpolationMethod(LinearTimeInterp);
505 if ( WithPointToPoint ) {
506 dec.setAllToAllMethod(PointToPoint);
509 dec.setAllToAllMethod(Native);
512 dec.setForcedRenormalization(false);
513 vector<double> times;
514 for (double time=0; time<tmaxB+1e-10; time+=dtB)
516 cout << "testAsynchronousIntersectionDEC_2D" << rank << " time " << time
517 << " dtB " << dtB << " tmaxB " << tmaxB << endl ;
518 dec.recvData( time );
519 double vi = parafield->getVolumeIntegral(0);
520 cout << "testAsynchronousIntersectionDEC_2D" << rank << " time " << time
521 << " VolumeIntegral " << vi
522 << " time*10000 " << time*10000 << endl ;
524 CPPUNIT_ASSERT_DOUBLES_EQUAL(vi,time*10000,0.001);
537 cout << "testAsynchronousIntersectionDEC_2D" << rank << " MPI_Barrier " << endl ;
539 if (Asynchronous) MPI_Barrier(MPI_COMM_WORLD);
540 cout << "end of IntersectionDEC_2D test"<<endl;