Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

newElasSolver.C

Go to the documentation of this file.
00001 
00007 #include "mpi.h"
00008 #include "petsc.h"
00009 #include "sys.h"
00010 #include <vector>
00011 #include "TreeNode.h"
00012 #include "parUtils.h"
00013 #include "omg.h"
00014 #include "handleStencils.h"
00015 #include "elasticityJac.h"
00016 #include "omgJac.h"
00017 #include "colors.h"
00018 #include <cstdlib>
00019 #include "externVars.h"
00020 #include "dendro.h"
00021 
00022 static char help[] = "Solves static Navier-Lame equations\
00023                       using FEM, MG, DA and Matrix-Free methods.\n\n";
00024 
00025 //Don't want time to be synchronized. Need to check load imbalance.
00026 #ifdef MPI_WTIME_IS_GLOBAL
00027 #undef MPI_WTIME_IS_GLOBAL
00028 #endif
00029 
00030 #ifndef iC
00031 #define iC(fun) {CHKERRQ(fun);}
00032 #endif
00033 
00034 #ifdef PETSC_USE_LOG
00035 int elasticityDiagEvent;
00036 int elasticityMultEvent;
00037 int elasticityFinestDiagEvent;
00038 int elasticityFinestMultEvent;
00039 
00040 int vecMassDiagEvent;
00041 int vecMassMultEvent;
00042 int vecMassFinestDiagEvent;
00043 int vecMassFinestMultEvent;
00044 #endif
00045 
00046 #ifdef PETSC_USE_LOG
00047 //user-defined variables
00048 int Jac1DiagEvent;
00049 int Jac1MultEvent;
00050 int Jac1FinestDiagEvent;
00051 int Jac1FinestMultEvent;
00052 
00053 int Jac2DiagEvent;
00054 int Jac2MultEvent;
00055 int Jac2FinestDiagEvent;
00056 int Jac2FinestMultEvent;
00057 
00058 int Jac3DiagEvent;
00059 int Jac3MultEvent;
00060 int Jac3FinestDiagEvent;
00061 int Jac3FinestMultEvent;
00062 #endif
00063 
00064 double***** LaplacianType1Stencil; 
00065 double**** LaplacianType2Stencil; 
00066 double***** MassType1Stencil; 
00067 double**** MassType2Stencil; 
00068 double****** ShapeFnStencil;
00069 
00070 double**** GradDivType2Stencil; 
00071 
00072 double gaussian(double mean, double std_deviation);
00073 
00074 int main(int argc, char ** argv ) {     
00075   int size, rank;
00076   bool incCorner = 1;  
00077   unsigned int local_num_pts = 5000;
00078   double gSize[3];
00079   unsigned int ptsLen;
00080   unsigned int maxNumPts = 1;
00081   unsigned int dim = 3;
00082   unsigned int maxDepth = 30;
00083   bool compressLut = false;
00084   double localTime, globalTime;
00085   double startTime, endTime;
00086   DendroIntL localSz, totalSz;
00087   std::vector<ot::TreeNode> linOct, balOct;
00088   std::vector<double> pts;
00089   double mgLoadFac = 2.0;
00090 
00091   PetscInitialize(&argc,&argv,"optionsElasticity",help);
00092   ot::RegisterEvents();
00093 
00094   ot::DAMG_Initialize(MPI_COMM_WORLD);
00095 
00096 #ifdef PETSC_USE_LOG
00097   PetscLogEventRegister(&Jac1DiagEvent,"ODAmatDiag",PETSC_VIEWER_COOKIE);
00098   PetscLogEventRegister(&Jac1MultEvent,"ODAmatMult",PETSC_VIEWER_COOKIE);
00099   PetscLogEventRegister(&Jac1FinestDiagEvent,"ODAmatDiagFinest",PETSC_VIEWER_COOKIE);
00100   PetscLogEventRegister(&Jac1FinestMultEvent,"ODAmatMultFinest",PETSC_VIEWER_COOKIE);
00101 
00102   PetscLogEventRegister(&Jac2DiagEvent,"OMGmatDiag-2",PETSC_VIEWER_COOKIE);
00103   PetscLogEventRegister(&Jac2MultEvent,"OMGmatMult-2",PETSC_VIEWER_COOKIE);
00104   PetscLogEventRegister(&Jac2FinestDiagEvent,"OMGmatDiagFinest-2",PETSC_VIEWER_COOKIE);
00105   PetscLogEventRegister(&Jac2FinestMultEvent,"OMGmatMultFinest-2",PETSC_VIEWER_COOKIE);
00106 
00107   PetscLogEventRegister(&Jac3DiagEvent,"OMGmatDiag-3",PETSC_VIEWER_COOKIE);
00108   PetscLogEventRegister(&Jac3MultEvent,"OMGmatMult-3",PETSC_VIEWER_COOKIE);
00109   PetscLogEventRegister(&Jac3FinestDiagEvent,"OMGmatDiagFinest-3",PETSC_VIEWER_COOKIE);
00110   PetscLogEventRegister(&Jac3FinestMultEvent,"OMGmatMultFinest-3",PETSC_VIEWER_COOKIE);
00111   PetscLogEventRegister(&vecMassDiagEvent,"vMassDiag",PETSC_VIEWER_COOKIE);
00112   PetscLogEventRegister(&vecMassMultEvent,"vMassMult",PETSC_VIEWER_COOKIE);
00113   PetscLogEventRegister(&vecMassFinestDiagEvent,"vMassDiagFinest",PETSC_VIEWER_COOKIE);
00114   PetscLogEventRegister(&vecMassFinestMultEvent,"vMassMultFinest",PETSC_VIEWER_COOKIE);
00115 
00116   PetscLogEventRegister(&elasticityDiagEvent,"elDiag",PETSC_VIEWER_COOKIE);
00117   PetscLogEventRegister(&elasticityMultEvent,"elMult",PETSC_VIEWER_COOKIE);
00118   PetscLogEventRegister(&elasticityFinestDiagEvent,"elDiagFinest",PETSC_VIEWER_COOKIE);
00119   PetscLogEventRegister(&elasticityFinestMultEvent,"elMultFinest",PETSC_VIEWER_COOKIE);
00120 
00121   int stages[3];
00122   PetscLogStageRegister(&stages[0],"P2O.");
00123   PetscLogStageRegister(&stages[1],"Bal");  
00124   PetscLogStageRegister(&stages[2],"Solve");  
00125 #endif
00126 
00127   MPI_Comm_size(MPI_COMM_WORLD,&size);
00128   MPI_Comm_rank(MPI_COMM_WORLD,&rank);
00129   
00130 //  Usage: <exe> local_num_pts[5000] dim[3] maxDepth[30] maxNumPtsPerOctant[1] 
00131 //  incCorner[1] compressLut[0] mgLoadFac[2.0]  
00132  
00133   if(argc > 1) {
00134     local_num_pts = atoi(argv[1]);
00135   }  
00136   if(argc > 2) {
00137     dim = atoi(argv[2]);
00138   }
00139   if(argc > 3) {
00140     maxDepth = atoi(argv[3]);
00141   }
00142   if(argc > 4) {
00143     maxNumPts = atoi(argv[4]);
00144   }
00145   if(argc > 5) {
00146     incCorner = (bool)(atoi(argv[5]));
00147   }  
00148   if(argc > 6) { 
00149     compressLut = (bool)(atoi(argv[6]));
00150   }
00151   if(argc > 7) { 
00152     mgLoadFac = atof(argv[7]);
00153   }
00154 
00155   //Generate Points
00156   if(!rank){
00157     std::cout << "Creating points on the fly... "<<std::endl;
00158   }
00159 
00160   MPI_Barrier(MPI_COMM_WORLD);
00161   startTime = MPI_Wtime();
00162 
00163   srand48(0x12345678 + 76543*rank);
00164 
00165   pts.resize(3*local_num_pts);
00166   for(int i = 0; i < (3*local_num_pts); i++) {
00167     pts[i]= gaussian(0.5, 0.16);
00168   }
00169   MPI_Barrier(MPI_COMM_WORLD);
00170   endTime = MPI_Wtime();
00171   localTime = endTime - startTime;
00172 
00173   if(!rank){
00174     std::cout << " finished creating points  "<<std::endl; // Point size
00175     std::cout <<"point generation time: "<<localTime << std::endl;
00176   }
00177 
00178   ptsLen = pts.size();
00179   std::vector<ot::TreeNode> tmpNodes;
00180   for(int i = 0;i < ptsLen; i+=3) {
00181     if( (pts[i] > 0.0) &&
00182         (pts[i+1] > 0.0)  
00183         && (pts[i+2] > 0.0) &&
00184         ( ((unsigned int)(pts[i]*((double)(1u << maxDepth)))) < (1u << maxDepth))  &&
00185         ( ((unsigned int)(pts[i+1]*((double)(1u << maxDepth)))) < (1u << maxDepth))  &&
00186         ( ((unsigned int)(pts[i+2]*((double)(1u << maxDepth)))) < (1u << maxDepth)) ) {
00187       tmpNodes.push_back( ot::TreeNode((unsigned int)(pts[i]*(double)(1u << maxDepth)),
00188             (unsigned int)(pts[i+1]*(double)(1u << maxDepth)),
00189             (unsigned int)(pts[i+2]*(double)(1u << maxDepth)),
00190             maxDepth,dim,maxDepth) );
00191     }
00192   }
00193   pts.clear();
00194 
00195   par::removeDuplicates<ot::TreeNode>(tmpNodes,false,MPI_COMM_WORLD);   
00196   linOct = tmpNodes;
00197   tmpNodes.clear();
00198   par::partitionW<ot::TreeNode>(linOct, NULL,MPI_COMM_WORLD);
00199   // reduce and only print the total ...
00200   localSz = linOct.size();
00201   par::Mpi_Reduce<DendroIntL>(&localSz, &totalSz, 1, MPI_SUM, 0, MPI_COMM_WORLD);
00202   MPI_Barrier(MPI_COMM_WORLD);  
00203   if(rank==0) {
00204     std::cout<<"# pts= " << totalSz<<std::endl;
00205   }
00206   MPI_Barrier(MPI_COMM_WORLD);  
00207 
00208   pts.resize(3*(linOct.size()));
00209   ptsLen = (3*(linOct.size()));
00210   for(int i = 0; i < linOct.size(); i++) {
00211     pts[3*i] = (((double)(linOct[i].getX())) + 0.5)/((double)(1u << maxDepth));
00212     pts[(3*i)+1] = (((double)(linOct[i].getY())) +0.5)/((double)(1u << maxDepth));
00213     pts[(3*i)+2] = (((double)(linOct[i].getZ())) +0.5)/((double)(1u << maxDepth));
00214   }//end for i
00215   linOct.clear();
00216   gSize[0] = 1.0;
00217   gSize[1] = 1.0;
00218   gSize[2] = 1.0;
00219 
00220   //Points2Octree....
00221   MPI_Barrier(MPI_COMM_WORLD);  
00222 #ifdef PETSC_USE_LOG
00223   PetscLogStagePush(stages[0]);
00224 #endif
00225   startTime = MPI_Wtime();
00226   ot::points2Octree(pts, gSize, linOct, dim, maxDepth, maxNumPts, MPI_COMM_WORLD);
00227   endTime = MPI_Wtime();
00228 #ifdef PETSC_USE_LOG
00229   PetscLogStagePop();
00230 #endif
00231   localTime = endTime - startTime;
00232   par::Mpi_Reduce<double>(&localTime, &globalTime, 1, MPI_MAX, 0, MPI_COMM_WORLD);
00233   if(!rank){
00234     std::cout <<"P2n Time: "<<globalTime << std::endl;
00235   }
00236   // reduce and only print the total ...
00237   localSz = linOct.size();
00238   par::Mpi_Reduce<DendroIntL>(&localSz, &totalSz, 1, MPI_SUM, 0, MPI_COMM_WORLD);
00239   if(rank==0) {
00240     std::cout<<"# of Unbalanced Octants: " << totalSz<<std::endl;
00241   }
00242   pts.clear();
00243 
00244   //Balancing...
00245   MPI_Barrier(MPI_COMM_WORLD);  
00246 #ifdef PETSC_USE_LOG
00247   PetscLogStagePush(stages[1]);
00248 #endif
00249   startTime = MPI_Wtime();
00250   ot::balanceOctree (linOct, balOct, dim, maxDepth, incCorner, MPI_COMM_WORLD, NULL, NULL);
00251   endTime = MPI_Wtime();
00252 #ifdef PETSC_USE_LOG
00253   PetscLogStagePop();
00254 #endif
00255   linOct.clear();
00256   // compute total inp size and output size
00257   localSz = balOct.size();
00258   localTime = endTime - startTime;
00259   par::Mpi_Reduce<DendroIntL>(&localSz, &totalSz, 1, MPI_SUM, 0, MPI_COMM_WORLD);
00260   par::Mpi_Reduce<double>(&localTime, &globalTime, 1, MPI_MAX, 0, MPI_COMM_WORLD);
00261 
00262   if(!rank) {
00263     std::cout << "# of Balanced Octants: "<< totalSz << std::endl;       
00264     std::cout << "bal Time: "<<globalTime << std::endl;
00265   }
00266 
00267   //Solve ...
00268   MPI_Barrier(MPI_COMM_WORLD);  
00269 #ifdef PETSC_USE_LOG
00270   PetscLogStagePush(stages[2]);
00271 #endif
00272 
00273   ot::DAMG       *damg;    
00274   int       nlevels = 1; //number of multigrid levels
00275   PetscInt       numRefinements = 0;
00276   unsigned int   dof = 3; // degrees of freedom per node  
00277 
00278   iC(PetscOptionsGetInt(0,"-numRefinements",&numRefinements,0));
00279   for(int i = 0; i < numRefinements; i++) {
00280     std::vector<ot::TreeNode> tmpOct = balOct;
00281     balOct.clear();
00282     ot::refineOctree(tmpOct, balOct); 
00283   }
00284 
00285   PetscInt nlevelsPetscInt = nlevels;
00286   PetscOptionsGetInt(0, "-nlevels", &nlevelsPetscInt, 0);
00287   nlevels = nlevelsPetscInt;
00288 
00289   // Note: The user context for all levels will be set separately later.
00290   MPI_Barrier(MPI_COMM_WORLD);  
00291 
00292   if(!rank) {
00293     std::cout<<"nlevels initial: "<<nlevels<<std::endl;
00294   }
00295 
00296   ot::DAMGCreateAndSetDA(PETSC_COMM_WORLD, nlevels, NULL, &damg, 
00297       balOct, dof, mgLoadFac, compressLut, incCorner);
00298 
00299   balOct.clear();
00300 
00301   if(!rank) {
00302     std::cout<<"nlevels final: "<<nlevels<<std::endl;
00303   }
00304 
00305   MPI_Barrier(MPI_COMM_WORLD);  
00306 
00307   if(!rank) {
00308     std::cout << "Created DA for all levels."<< std::endl;
00309   }
00310 
00311   MPI_Barrier(MPI_COMM_WORLD);
00312   ot::PrintDAMG(damg);
00313   MPI_Barrier(MPI_COMM_WORLD);
00314 
00315   MPI_Barrier(MPI_COMM_WORLD);
00316   if(!rank) {
00317     std::cout << "Creating stencils..."<< std::endl;
00318   }
00319   MPI_Barrier(MPI_COMM_WORLD);
00320 
00321   createLmatType2(LaplacianType2Stencil);
00322   createMmatType2(MassType2Stencil);
00323   createGDmatType2(GradDivType2Stencil);
00324 
00325   MPI_Barrier(MPI_COMM_WORLD);
00326   if(!rank) {
00327     std::cout << "Created all stencils."<< std::endl;
00328   }
00329   MPI_Barrier(MPI_COMM_WORLD);
00330 
00331   ot::DAMGCreateSuppressedDOFs(damg);
00332 
00333   SetElasticityContexts(damg);
00334 
00335   MPI_Barrier(MPI_COMM_WORLD);
00336   if(!rank) {
00337     std::cout << "Set Elasticity Contexts all levels."<< std::endl;
00338   }
00339 
00340   //Functions for using KSP_Shell (will be used @ the coarsest grid if not all
00341 //processors are active on the coarsest grid)
00342 
00343   ot::getPrivateMatricesForKSP_Shell = getPrivateMatricesForKSP_Shell_Elas;
00344   
00345   //Set function pointers so that PC_BlockDiag could be used.
00346 
00347   ot::getDofAndNodeSizeForPC_BlockDiag = getDofAndNodeSizeForElasticityMat;
00348 
00349   ot::computeInvBlockDiagEntriesForPC_BlockDiag = computeInvBlockDiagEntriesForElasticityMat;
00350 
00351   PetscInt rhsType = 2;
00352   iC(PetscOptionsGetInt(0,"-rhsType",&rhsType,0));
00353 
00354   if(rhsType == 4) {
00355     ot::DAMGSetKSP(damg, CreateElasticityMat,
00356         ComputeElasticityMat, ComputeRHS4);
00357   }else {
00358     ot::DAMGSetKSP(damg, CreateElasticityMat,
00359         ComputeElasticityMat, ComputeElasticityRHS);
00360   }
00361 
00362   PetscReal norm2;
00363   PetscReal normInf;
00364 
00365   MPI_Barrier(MPI_COMM_WORLD);
00366   if(!rank) {
00367     std::cout << "Solving with 0-intial guess"<< std::endl;
00368   }
00369   MPI_Barrier(MPI_COMM_WORLD);
00370 
00371   startTime = MPI_Wtime();
00372   iC(ot::DAMGSolve(damg));
00373   endTime = MPI_Wtime();
00374   localTime = endTime - startTime;
00375   par::Mpi_Reduce<double>(&localTime, &globalTime, 1, MPI_MAX, 0, MPI_COMM_WORLD);
00376 
00377   MPI_Barrier(MPI_COMM_WORLD);
00378 
00379   if (!rank) {
00380     std::cout <<  "Done Solve" <<  std::endl;
00381     std::cout << "Solve Time: "<<globalTime << std::endl;
00382   }
00383 
00384   MPI_Barrier(MPI_COMM_WORLD);
00385 
00386   destroyLmatType2(LaplacianType2Stencil);
00387   destroyMmatType2(MassType2Stencil);
00388   destroyGDmatType2(GradDivType2Stencil);
00389 
00390   if (!rank) {
00391     std::cout <<  "Destroyed Stencils"  << std::endl;
00392   }
00393 
00394   DestroyElasticityContexts(damg);
00395 
00396   if (!rank) {
00397     std::cout <<  "Destroyed Elasticity Contexts."  << std::endl;
00398   }
00399 
00400   MPI_Barrier(MPI_COMM_WORLD);
00401 
00402   iC(DAMGDestroy(damg));
00403 
00404   if (!rank) {
00405     std::cout << GRN << "Destroyed DAMG" << NRM << std::endl;
00406   }
00407 
00408   endTime = MPI_Wtime();
00409 #ifdef PETSC_USE_LOG
00410   PetscLogStagePop();
00411 #endif
00412 
00413   if (!rank) {
00414     std::cout << GRN << "Finalizing PETSC" << NRM << std::endl;
00415   }
00416   ot::DAMG_Finalize();
00417   PetscFinalize();
00418 }//end main
00419 
00420 double gaussian(double mean, double std_deviation) {
00421   static double t1 = 0, t2=0;
00422   double x1, x2, x3, r;
00423 
00424   using namespace std;
00425 
00426   // reuse previous calculations
00427   if(t1) {
00428     const double tmp = t1;
00429     t1 = 0;
00430     return mean + std_deviation * tmp;
00431   }
00432   if(t2) {
00433     const double tmp = t2;
00434     t2 = 0;
00435     return mean + std_deviation * tmp;
00436   }
00437 
00438   // pick randomly a point inside the unit disk
00439   do {
00440     x1 = 2 * drand48() - 1;
00441     x2 = 2 * drand48() - 1;
00442     x3 = 2 * drand48() - 1;
00443     r = x1 * x1 + x2 * x2 + x3*x3;
00444   } while(r >= 1);
00445 
00446   // Box-Muller transform
00447   r = sqrt(-2.0 * log(r) / r);
00448 
00449   // save for next call
00450   t1 = (r * x2);
00451   t2 = (r * x3);
00452 
00453   return mean + (std_deviation * r * x1);
00454 }//end gaussian
00455 
00456 

Generated on Tue Mar 24 16:13:59 2009 for DENDRO by  doxygen 1.3.9.1