00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <PetscSolver.h>
00036 #include <PetscSOE.h>
00037 #include <f2c.h>
00038 #include <math.h>
00039 #include <Channel.h>
00040 #include <FEM_ObjectBroker.h>
00041 #include <Timer.h>
00042 #include <ID.h>
00043 #include <Vector.h>
00044
00045 int PetscSolver::numSolver=0;
00046
00047 PetscSolver::PetscSolver()
00048 :LinearSOESolver(SOLVER_TAGS_PetscSolver),
00049 rTol(PETSC_DEFAULT), aTol(PETSC_DEFAULT), dTol(PETSC_DEFAULT), maxIts(PETSC_DEFAULT)
00050 {
00051 numSolver++;
00052 }
00053
00054 PetscSolver::PetscSolver(KSPType meth, PCType pre)
00055 :LinearSOESolver(SOLVER_TAGS_PetscSolver), method(meth), preconditioner(pre),
00056 rTol(PETSC_DEFAULT), aTol(PETSC_DEFAULT), dTol(PETSC_DEFAULT), maxIts(PETSC_DEFAULT)
00057 {
00058 numSolver++;
00059 }
00060
00061 PetscSolver::PetscSolver(KSPType meth, PCType pre, double relTol, double absTol, double divTol, int maxIterations)
00062 :LinearSOESolver(SOLVER_TAGS_PetscSolver), method(meth), preconditioner(pre),
00063 rTol(relTol), aTol(absTol), dTol(divTol), maxIts(maxIterations)
00064 {
00065 numSolver++;
00066 }
00067
00068 PetscSolver::~PetscSolver()
00069 {
00070
00071 KSPDestroy(ksp);
00072 numSolver--;
00073
00074
00075
00076
00077 }
00078
00079
00080
00081 int
00082 PetscSolver::solve(void)
00083 {
00084 int size = theSOE->size;
00085 int factored = theSOE->isFactored;
00086
00087 int numProcesses = theSOE->numProcesses;
00088 int processID = theSOE->processID;
00089
00090 int ierr;
00091 ierr = MatAssemblyBegin(theSOE->A, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
00092 ierr = MatAssemblyEnd(theSOE->A, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
00093
00094
00095
00096
00097
00098 static Vector recvVector(1);
00099
00100 if (numProcesses > 1) {
00101 Vector *vectX = theSOE->vectX;
00102 Vector *vectB = theSOE->vectB;
00103
00104
00105 vectX->Zero();
00106
00107
00108
00109
00110
00111 int numChannels = theSOE->numChannels;
00112 Channel **theChannels = theSOE->theChannels;
00113
00114 if (processID != 0) {
00115 Channel *theChannel = theChannels[0];
00116
00117 theChannel->sendVector(0, 0, *vectB);
00118 theChannel->recvVector(0, 0, *vectB);
00119
00120 } else {
00121
00122 if (recvVector.Size() != size)
00123 recvVector.resize(size);
00124 for (int j=0; j<numChannels; j++) {
00125 Channel *theChannel = theChannels[j];
00126 theChannel->recvVector(0, 0, recvVector);
00127 *vectB += recvVector;
00128 }
00129 for (int j=0; j<numChannels; j++) {
00130 Channel *theChannel = theChannels[j];
00131 theChannel->sendVector(0, 0, *vectB);
00132 }
00133 }
00134 }
00135
00136
00137
00138
00139
00140 ierr = KSPSolve(ksp, theSOE->b, theSOE->x); CHKERRQ(ierr);
00141 theSOE->isFactored = 1;
00142
00143
00144
00145
00146
00147 if (numProcesses > 1) {
00148 Vector *vectX = theSOE->vectX;
00149
00150 int numChannels = theSOE->numChannels;
00151 Channel **theChannels = theSOE->theChannels;
00152
00153 if (processID != 0) {
00154 Channel *theChannel = theChannels[0];
00155
00156 theChannel->sendVector(0, 0, *vectX);
00157 theChannel->recvVector(0, 0, *vectX);
00158
00159 } else {
00160
00161 if (recvVector.Size() != size)
00162 recvVector.resize(size);
00163
00164 for (int j=0; j<numChannels; j++) {
00165 Channel *theChannel = theChannels[j];
00166 theChannel->recvVector(0, 0, recvVector);
00167 *vectX += recvVector;
00168 }
00169 for (int j=0; j<numChannels; j++) {
00170 Channel *theChannel = theChannels[j];
00171 theChannel->sendVector(0, 0, *vectX);
00172 }
00173 }
00174 }
00175
00176 return ierr;
00177 }
00178
00179
00180 int
00181 PetscSolver::setSize()
00182 {
00183
00184
00185
00186
00187 KSPCreate(PETSC_COMM_WORLD, &ksp);
00188
00189
00190
00191
00192
00193
00194 KSPSetOperators(ksp, theSOE->A, theSOE->A, DIFFERENT_NONZERO_PATTERN);
00195
00196
00197
00198
00199
00200 int ierr;
00201 ierr = KSPSetType(ksp, method); CHKERRQ(ierr);
00202 ierr = KSPSetTolerances(ksp, rTol, aTol, dTol, maxIts);
00203
00204
00205
00206
00207
00208 KSPGetPC(ksp, &pc);
00209 ierr = PCSetType(pc, preconditioner); CHKERRQ(ierr);
00210
00211
00212
00213
00214
00215
00216
00217 return ierr;
00218 }
00219
00220
00221 int
00222 PetscSolver::setLinearSOE(PetscSOE &theSys)
00223 {
00224 theSOE = &theSys;
00225 return 0;
00226 }
00227
00228
00229 int
00230 PetscSolver::sendSelf(int cTag, Channel &theChannel)
00231 {
00232 static ID idData(3);
00233 idData(0) = maxIts;
00234 if (strcmp(method, KSPCG) == 0)
00235 idData(1) = 0;
00236 else if (strcmp(method, KSPBICG) == 0)
00237 idData(1) = 1;
00238 else if (strcmp(method, KSPRICHARDSON) == 0)
00239 idData(1) = 2;
00240 else if (strcmp(method, KSPCHEBYCHEV) == 0)
00241 idData(1) = 3;
00242 else if (strcmp(method, KSPGMRES) ==0)
00243 idData(1) = 4;
00244 else {
00245 opserr << "PetscSolver::sendSelf() - unknown method set\n";
00246 return -1;
00247 }
00248
00249 if (strcmp(preconditioner, PCJACOBI) == 0)
00250 idData(2) = 0;
00251 else if (strcmp(preconditioner, PCILU) == 0)
00252 idData(2) = 1;
00253 else if (strcmp(preconditioner, PCICC) == 0)
00254 idData(2) = 2;
00255 else if (strcmp(preconditioner, PCBJACOBI) == 0)
00256 idData(2) = 3;
00257 else if (strcmp(preconditioner, PCNONE) == 0)
00258 idData(2) = 4;
00259 else {
00260 opserr << "PetscSolver::sendSelf() - unknown preconditioner set\n";
00261 return -1;
00262 }
00263
00264 theChannel.sendID(0, cTag, idData);
00265
00266 static Vector data(3);
00267 data(0) = rTol;
00268 data(1) = aTol;
00269 data(2) = dTol;
00270
00271 theChannel.sendVector(0, cTag, data);
00272 return 0;
00273 }
00274
00275 int
00276 PetscSolver::recvSelf(int cTag, Channel &theChannel,
00277 FEM_ObjectBroker &theBroker)
00278 {
00279 static ID idData(3);
00280 theChannel.recvID(0, cTag, idData);
00281 maxIts = idData(0);
00282 if (idData(1) == 0)
00283 method = KSPCG;
00284 else if (idData(1) == 1)
00285 method = KSPBICG;
00286 else if (idData(1) == 2)
00287 method = KSPRICHARDSON;
00288 else if (idData(1) == 3)
00289 method = KSPCHEBYCHEV;
00290 else if (idData(1) == 4)
00291 method = KSPGMRES;
00292 else {
00293 opserr << "PetscSolver::recvSelf() - unknown method recvd\n";
00294 return -1;
00295 }
00296
00297 if (idData(2) == 0)
00298 preconditioner = PCJACOBI;
00299 else if (idData(2) == 1)
00300 preconditioner = PCILU;
00301 else if (idData(2) == 2)
00302 preconditioner = PCICC;
00303 else if (idData(2) == 3)
00304 preconditioner = PCBJACOBI;
00305 else if (idData(2) == 4)
00306 preconditioner = PCNONE;
00307 else {
00308 opserr << "PetscSolver::sendSelf() - unknown preconditioner set\n";
00309 return -1;
00310 }
00311
00312
00313 static Vector data(3);
00314 theChannel.recvVector(0, cTag, data);
00315 rTol = data(0);
00316 aTol = data(1);
00317 dTol = data(2);
00318
00319 return 0;
00320 }
00321
00322
00323