ExaFMM 1
Fast-multipole Method for exascale systems
|
00001 /* 00002 Copyright (C) 2011 by Rio Yokota, Simon Layton, Lorena Barba 00003 00004 Permission is hereby granted, free of charge, to any person obtaining a copy 00005 of this software and associated documentation files (the "Software"), to deal 00006 in the Software without restriction, including without limitation the rights 00007 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00008 copies of the Software, and to permit persons to whom the Software is 00009 furnished to do so, subject to the following conditions: 00010 00011 The above copyright notice and this permission notice shall be included in 00012 all copies or substantial portions of the Software. 00013 00014 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00015 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00016 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00017 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00018 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00019 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00020 THE SOFTWARE. 00021 */ 00022 #include "parallelfmm.h" 00023 #ifdef VTK 00024 #include "vtk.h" 00025 #endif 00026 00027 int main() { 00028 const int numBodies = 10000; 00029 const int numTarget = 100; 00030 IMAGES = 0; 00031 THETA = 1 / sqrtf(4); 00032 Bodies bodies(numTarget); 00033 Bodies jbodies(numBodies); 00034 Bodies jbodies2; 00035 Cells cells, jcells; 00036 ParallelFMM<Laplace> FMM; 00037 FMM.initialize(); 00038 if( MPIRANK == 0 ) FMM.printNow = true; 00039 00040 FMM.startTimer("Set bodies "); 00041 FMM.random(bodies,MPIRANK+1); 00042 FMM.random(jbodies,MPIRANK+MPISIZE+1); 00043 Bodies bodies2 = bodies; 00044 FMM.stopTimer("Set bodies ",FMM.printNow); 00045 00046 FMM.startTimer("Set domain "); 00047 FMM.setGlobDomain(bodies,0,M_PI); 00048 FMM.stopTimer("Set domain ",FMM.printNow); 00049 00050 if( IMAGES != 0 ) { 00051 FMM.startTimer("Set periodic "); 00052 jbodies2 = FMM.periodicBodies(jbodies); 00053 FMM.stopTimer("Set periodic ",FMM.printNow); 00054 FMM.eraseTimer("Set periodic "); 00055 } else { 00056 jbodies2 = jbodies; 00057 } 00058 00059 FMM.startTimer("Direct sum "); 00060 for( int i=0; i!=MPISIZE; ++i ) { 00061 FMM.shiftBodies(jbodies2); 00062 FMM.evalP2P(bodies2,jbodies2); 00063 if(FMM.printNow) std::cout << "Direct loop : " << i+1 << "/" << MPISIZE << std::endl; 00064 } 00065 FMM.stopTimer("Direct sum ",FMM.printNow); 00066 FMM.eraseTimer("Direct sum "); 00067 00068 FMM.initTarget(bodies); 00069 00070 FMM.octsection(bodies); 00071 FMM.octsection(jbodies); 00072 00073 #ifdef TOPDOWN 00074 FMM.topdown(bodies,cells); 00075 FMM.topdown(jbodies,jcells); 00076 #else 00077 FMM.bottomup(bodies,cells); 00078 FMM.bottomup(jbodies,jcells); 00079 #endif 00080 00081 FMM.commBodies(jcells); 00082 00083 FMM.commCells(jbodies,jcells); 00084 00085 FMM.startTimer("Downward "); 00086 FMM.downward(cells,jcells); 00087 FMM.stopTimer("Downward ",FMM.printNow); 00088 FMM.eraseTimer("Downward "); 00089 00090 FMM.startTimer("Unpartition "); 00091 FMM.unpartition(bodies); 00092 FMM.stopTimer("Unpartition ",FMM.printNow); 00093 FMM.eraseTimer("Unpartition "); 00094 00095 FMM.startTimer("Unsort bodies"); 00096 std::sort(bodies.begin(),bodies.end()); 00097 FMM.stopTimer("Unsort bodies",FMM.printNow); 00098 FMM.eraseTimer("Unsort bodies"); 00099 if(FMM.printNow) FMM.writeTime(); 00100 if(FMM.printNow) FMM.writeTime(); 00101 00102 real diff1 = 0, norm1 = 0, diff2 = 0, norm2 = 0, diff3 = 0, norm3 = 0, diff4 = 0, norm4 = 0; 00103 FMM.evalError(bodies,bodies2,diff1,norm1,diff2,norm2); 00104 MPI_Datatype MPI_TYPE = FMM.getType(diff1); 00105 MPI_Reduce(&diff1,&diff3,1,MPI_TYPE,MPI_SUM,0,MPI_COMM_WORLD); 00106 MPI_Reduce(&norm1,&norm3,1,MPI_TYPE,MPI_SUM,0,MPI_COMM_WORLD); 00107 MPI_Reduce(&diff2,&diff4,1,MPI_TYPE,MPI_SUM,0,MPI_COMM_WORLD); 00108 MPI_Reduce(&norm2,&norm4,1,MPI_TYPE,MPI_SUM,0,MPI_COMM_WORLD); 00109 if(FMM.printNow) FMM.printError(diff3,norm3,diff4,norm4); 00110 #ifdef DEBUG 00111 FMM.print(std::sqrt(potDiff/potNorm)); 00112 #endif 00113 00114 #ifdef VTK 00115 for( B_iter B=jbodies.begin(); B!=jbodies.end(); ++B ) B->ICELL = 0; 00116 for( C_iter C=jcells.begin(); C!=jcells.end(); ++C ) { 00117 Body body; 00118 body.ICELL = 1; 00119 body.X = C->X; 00120 body.SRC = 0; 00121 jbodies.push_back(body); 00122 } 00123 00124 int Ncell = 0; 00125 vtkPlot vtk; 00126 if( MPIRANK == 0 ) { 00127 vtk.setDomain(FMM.getR0(),FMM.getX0()); 00128 vtk.setGroupOfPoints(jbodies,Ncell); 00129 } 00130 for( int i=1; i!=MPISIZE; ++i ) { 00131 FMM.shiftBodies(jbodies); 00132 if( MPIRANK == 0 ) { 00133 vtk.setGroupOfPoints(jbodies,Ncell); 00134 } 00135 } 00136 if( MPIRANK == 0 ) { 00137 vtk.plot(Ncell); 00138 } 00139 #endif 00140 FMM.finalize(); 00141 }