00001
00007 #include "mpi.h"
00008 #include "petsc.h"
00009 #include "sys.h"
00010 #include "petscmat.h"
00011 #include "petscvec.h"
00012 #include "petscksp.h"
00013 #include "oda.h"
00014 #include <cstdlib>
00015 #include "massMatrix.h"
00016 #include "stiffnessMatrix.h"
00017 #include "externVars.h"
00018
00019 static char help[] = "Driver for a variable coefficient Laplacian problem on octrees";
00020
00021 #ifdef MPI_WTIME_IS_GLOBAL
00022 #undef MPI_WTIME_IS_GLOBAL
00023 #endif
00024
00025 PetscErrorCode LaplacianMatMult(Mat J , Vec in, Vec out);
00026 PetscErrorCode InitializeData(ot::DA* da, Vec nu, Vec inc);
00027
00028 typedef struct {
00029 massMatrix* Mass;
00030 stiffnessMatrix* Stiffness;
00031 } AppCtx;
00032
00033 int main(int argc, char **argv)
00034 {
00035 unsigned int dof = 1;
00036 double nuval = 1.0;
00037
00038 Vec nu;
00039 Vec rhs, inc, sol;
00040
00041 int size, rank;
00042
00043
00044
00045 bool incCorner = 1;
00046 unsigned int maxNumPts= 1;
00047 unsigned int dim=3;
00048 unsigned int maxDepth=30;
00049
00050 char filePrefix[PETSC_MAX_PATH_LEN];
00051 char filename[PETSC_MAX_PATH_LEN];
00052
00053
00054 double gSize[3];
00055 gSize[0] = 1.; gSize[1] = 1.; gSize[2] = 1.;
00056
00057 std::vector<ot::TreeNode> linOct, balOct;
00058 std::vector<double> pts;
00059
00060 PetscInitialize(&argc, &argv, "options", NULL);
00061 ot::RegisterEvents();
00062 ot::DA_Initialize(MPI_COMM_WORLD);
00063
00064 MPI_Comm_size(MPI_COMM_WORLD, &size);
00065 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
00066
00067 if(argc < 3) {
00068 std::cerr << "Usage: " << argv[0] << "-pfx file_prefix" << std::endl;
00069 return -1;
00070 }
00071
00072 CHKERRQ ( PetscOptionsGetString(PETSC_NULL, "-pfx", filePrefix, PETSC_MAX_PATH_LEN-1, PETSC_NULL));
00073
00074
00075
00076
00077 sprintf(filename, "%s.%d.pts", filePrefix, rank);
00078 ot::readPtsFromFile(filename, pts);
00079
00080 MPI_Barrier(MPI_COMM_WORLD);
00081
00082
00083
00084
00085 ot::points2Octree(pts, gSize, linOct, dim, maxDepth, maxNumPts, MPI_COMM_WORLD);
00086
00087
00088 pts.clear();
00089
00090
00091
00092
00093 ot::balanceOctree (linOct, balOct, dim, maxDepth, incCorner, MPI_COMM_WORLD, NULL, NULL);
00094
00095
00096 linOct.clear();
00097
00098
00099
00100
00101
00102
00103
00104 assert(!(balOct.empty()));
00105 ot::DA da(balOct,MPI_COMM_WORLD, MPI_COMM_WORLD);
00106 balOct.clear();
00107
00108 MPI_Barrier(MPI_COMM_WORLD);
00109
00110 if (!rank)
00111 std::cout <<"Finshed Meshing" << std::endl;
00112
00113
00114
00115
00116
00117 PetscOptionsGetScalar(0,"-nu",&nuval,0);
00118
00119
00120 da.createVector(inc, false, false, dof);
00121 da.createVector(nu, false, false, dof);
00122 da.createVector(rhs, false, false, dof);
00123 da.createVector(sol, false, false, dof);
00124
00125
00126 CHKERRQ( VecSet(nu, nuval ) );
00127 CHKERRQ( VecSet(inc, 1.0) );
00128
00129
00130
00131 InitializeData(&da, nu, inc);
00132
00133
00134
00135 massMatrix *Mass = new massMatrix(ot::fem::feMat::OCT);
00136 stiffnessMatrix *Stiffness = new stiffnessMatrix(ot::fem::feMat::OCT);
00137
00138
00139 Mass->setProblemDimensions(1.0,1.0,1.0);
00140 Mass->setDA(&da);
00141 Mass->setDof(dof);
00142
00143 Stiffness->setProblemDimensions(1.0,1.0,1.0);
00144 Stiffness->setDA(&da);
00145 Stiffness->setNuVec(nu);
00146 Stiffness->setDof(dof);
00147
00148
00149 Mass->MatVec(inc, rhs);
00150
00151
00152 AppCtx user;
00153 user.Stiffness = Stiffness;
00154 user.Mass = Mass;
00155
00156 unsigned int Nx = da.getNodeSize();
00157
00158 Mat J;
00159 MatCreateShell(PETSC_COMM_WORLD,dof*Nx, dof*Nx, PETSC_DETERMINE,PETSC_DETERMINE,&user,&J);
00160 MatShellSetOperation(J,MATOP_MULT,(void(*)(void))LaplacianMatMult);
00161
00162 KSP ksp;
00163 KSPCreate(PETSC_COMM_WORLD,&ksp);
00164 KSPSetOperators(ksp,J,J,SAME_NONZERO_PATTERN);
00165 KSPSetType(ksp,KSPCG);
00166 KSPSetFromOptions(ksp);
00167
00168
00169 KSPSolve(ksp, rhs, sol);
00170
00171 ot::DA_Finalize();
00172 PetscFinalize();
00173
00174 return 0;
00175 }
00176
00177 #undef __FUNCT__
00178 #define __FUNCT__ "LaplacianMatMult"
00179 PetscErrorCode LaplacianMatMult(Mat J , Vec in, Vec out)
00180 {
00181 PetscFunctionBegin;
00182 AppCtx *data;
00183
00184 MatShellGetContext( J, (void **)&data);
00185
00186 VecZeroEntries(out);
00187 data->Mass->MatVec(in,out);
00188 data->Stiffness->MatVec(in,out,-1.0);
00189 PetscFunctionReturn(0);
00190 }
00191
00192
00193 #undef __FUNCT__
00194 #define __FUNCT__ "InitializeData"
00195 PetscErrorCode InitializeData(ot::DA* da, Vec nu, Vec inc) {
00196 PetscScalar *inarray;
00197 PetscScalar *nuarray;
00198
00199 unsigned int dof = 1;
00200
00201
00202 da->vecGetBuffer(inc, inarray,false,false,false,dof);
00203 da->vecGetBuffer(nu, nuarray,false,false,false,dof);
00204
00205 unsigned int maxD = da->getMaxDepth();
00206 unsigned int balOctmaxD = maxD - 1;
00207 unsigned int Nx = da->getNodeSize();
00208
00209 double facsol = 1.0;
00210
00211 for( da->init<ot::DA_FLAGS::ALL>(), da->init<ot::DA_FLAGS::WRITABLE>(); da->curr() < da->end<ot::DA_FLAGS::ALL>(); da->next<ot::DA_FLAGS::ALL>()) {
00212
00213 Point pt;
00214 pt = da->getCurrentOffset();
00215 unsigned levelhere = da->getLevel(da->curr()) - 1;
00216 double hxOct = (double)((double)(1u << (balOctmaxD - levelhere))/(double)(1u << balOctmaxD));
00217
00218 double x = (double)(pt.xint())/((double)(1u << (maxD-1)));
00219 double y = (double)(pt.yint())/((double)(1u << (maxD-1)));
00220 double z = (double)(pt.zint())/((double)(1u << (maxD-1)));
00221
00222 int xindx = (static_cast<int>(x+y+z))%2;
00223 unsigned int indices[8];
00224 da->getNodeIndices(indices);
00225 double coord[8][3] = {
00226 {0.0,0.0,0.0},
00227 {1.0,0.0,0.0},
00228 {0.0,1.0,0.0},
00229 {1.0,1.0,0.0},
00230 {0.0,0.0,1.0},
00231 {1.0,0.0,1.0},
00232 {0.0,1.0,1.0},
00233 {1.0,1.0,1.0}
00234 };
00235
00236 unsigned char hn = da->getHangingNodeIndex(da->curr());
00237
00238 for(int i = 0; i < 8; i++) {
00239 if (!(hn & (1 << i))) {
00240 double xhere, yhere, zhere;
00241 xhere = x + coord[i][0]*hxOct ;
00242 yhere = y + coord[i][1]*hxOct;
00243 zhere = z + coord[i][2]*hxOct;
00244
00245 nuarray[dof*indices[i]] = cos(facsol*M_PI*xhere)*cos(facsol*M_PI*yhere)*cos(facsol*M_PI*zhere);
00246 inarray[dof*indices[i]] = (1.0 + 3.0*facsol*facsol*M_PI*M_PI)*cos(facsol*M_PI*xhere)*cos(facsol*M_PI*yhere)*cos(facsol*M_PI*zhere);
00247 }
00248 }
00249 }
00250
00251 da->vecRestoreBuffer(inc,inarray,false,false,false,dof);
00252 da->vecRestoreBuffer(nu,nuarray,false,false,false,dof);
00253
00254 PetscFunctionReturn(0);
00255 }
00256