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
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
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
00131
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
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;
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
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 }
00215 linOct.clear();
00216 gSize[0] = 1.0;
00217 gSize[1] = 1.0;
00218 gSize[2] = 1.0;
00219
00220
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
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
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
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
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;
00275 PetscInt numRefinements = 0;
00276 unsigned int dof = 3;
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
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
00341
00342
00343 ot::getPrivateMatricesForKSP_Shell = getPrivateMatricesForKSP_Shell_Elas;
00344
00345
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 }
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
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
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
00447 r = sqrt(-2.0 * log(r) / r);
00448
00449
00450 t1 = (r * x2);
00451 t2 = (r * x3);
00452
00453 return mean + (std_deviation * r * x1);
00454 }
00455
00456