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 <ProfileSPDLinSubstrSolver.h>
00036 #include <ProfileSPDLinSOE.h>
00037 #include <Matrix.h>
00038 #include <Vector.h>
00039 #include <math.h>
00040 #include <Channel.h>
00041 #include <FEM_ObjectBroker.h>
00042
00043 ProfileSPDLinSubstrSolver::ProfileSPDLinSubstrSolver(double tol)
00044 :ProfileSPDLinDirectSolver(tol),
00045 DomainSolver(SOLVER_TAGS_ProfileSPDLinSubstrSolver),
00046 dSize(0),DU(0),Aext(0),Yext(0)
00047 {
00048
00049 }
00050
00051
00052 ProfileSPDLinSubstrSolver::~ProfileSPDLinSubstrSolver()
00053 {
00054 }
00055
00056 int
00057 ProfileSPDLinSubstrSolver::solve()
00058 {
00059 return this->ProfileSPDLinDirectSolver::solve();
00060 }
00061
00062 int
00063 ProfileSPDLinSubstrSolver::setSize(void)
00064 {
00065 return this->ProfileSPDLinDirectSolver::setSize();
00066 }
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 int
00094 ProfileSPDLinSubstrSolver::condenseA(int numInt)
00095 {
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 if (theSOE == 0)
00110 return -1;
00111
00112 if (numInt == 0) {
00113 theSOE->numInt = numInt;
00114 return 0;
00115 }
00116
00117 if (dSize != size) {
00118 if (DU != 0) delete [] DU;
00119 DU = new double[numInt];
00120 if (DU == 0) {
00121 opserr << "ProfileSPDLinSubstrSolver::condenseA()";
00122 opserr << " - ran out of memory for work space\n";
00123 return -1;
00124 }
00125 dSize = numInt;
00126 }
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139 this->factor(numInt);
00140
00141
00142
00143
00144
00145 int i;
00146
00147 for (i=numInt; i<size; i++) {
00148
00149 int rowitop = RowTop[i];
00150 double *ajiPtr = topRowPtr[i];
00151
00152 int jstrt = rowitop;
00153 if (rowitop == 0) {
00154 jstrt = 1;
00155 ajiPtr++;
00156 } else {
00157 jstrt = rowitop;
00158 }
00159
00160
00161 for (int j=jstrt; j<numInt; j++) {
00162 double tmp = *ajiPtr;
00163
00164 int rowjtop = RowTop[j];
00165
00166 double *akiPtr, *akjPtr;
00167
00168 if (rowitop > rowjtop) {
00169 akiPtr = topRowPtr[i];
00170 akjPtr = topRowPtr[j] + (rowitop-rowjtop);
00171
00172 for (int k=rowitop; k<j; k++)
00173 tmp -= *akjPtr++ * *akiPtr++ ;
00174
00175 } else {
00176 akiPtr = topRowPtr[i] + (rowjtop-rowitop);
00177 akjPtr = topRowPtr[j];
00178
00179 for (int k=rowjtop; k<j; k++)
00180 tmp -= *akjPtr++ * *akiPtr++ ;
00181 }
00182
00183 *ajiPtr++ = tmp;
00184 }
00185 }
00186
00187
00188
00189
00190
00191
00192
00193 for (i=numInt; i<size; i++) {
00194
00195 int rowitop = RowTop[i];
00196 double *ajiPtr = topRowPtr[i];;
00197
00198 int jstrt;
00199
00200 if (rowitop < numInt) {
00201 ajiPtr += (numInt-rowitop);
00202 jstrt = numInt;
00203 }
00204 else
00205 jstrt = rowitop;
00206
00207 double *DUPtr = DU;
00208 double *akiPtr = topRowPtr[i];
00209
00210 for (int k=rowitop; k<numInt; k++)
00211 *DUPtr++ = *akiPtr++ * invD[k];
00212
00213
00214 for (int j=jstrt; j<=i; j++) {
00215
00216 double tmp = *ajiPtr;
00217 int rowjtop = RowTop[j];
00218 double *akiPtr, *akjPtr;
00219
00220 if (rowitop > rowjtop) {
00221 akiPtr = DU;
00222 akjPtr = topRowPtr[j] + (rowitop-rowjtop);
00223
00224 for (int k=rowitop; k<numInt; k++)
00225 tmp -= *akjPtr++ * *akiPtr++;
00226
00227 } else {
00228 akiPtr = &DU[rowjtop-rowitop];
00229 akjPtr = topRowPtr[j];
00230
00231 for (int k=rowjtop; k<numInt; k++)
00232 tmp -= *akjPtr++ * *akiPtr++;
00233 }
00234
00235 *ajiPtr++ = tmp;
00236 }
00237 }
00238
00239
00240 theSOE->isAcondensed = true;
00241 theSOE->numInt = numInt;
00242
00243 opserr << "ProfileSPDLinSubstrSolver::condenseA numDOF: " << size << " numInt: " << numInt << " numExt: " << size-numInt << endln;
00244
00245 return 0;
00246
00247 }
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 int
00278 ProfileSPDLinSubstrSolver::condenseRHS(int numInt, Vector *v)
00279 {
00280
00281
00282 if (theSOE == 0)
00283 return -1;
00284
00285 if (numInt == 0) {
00286 theSOE->numInt = numInt;
00287 return 0;
00288 }
00289
00290
00291 if (theSOE->isAcondensed != true) {
00292 int ok = this->condenseA(numInt);
00293 if (ok < 0) {
00294 opserr << "ProfileSPDLinSubstrSolver::condenseRHS()";
00295 opserr << " - failed to condenseA\n";
00296 return ok;
00297 }
00298 }
00299
00300 if (theSOE->numInt != numInt) {
00301 opserr << "ProfileSPDLinSubstrSolver::condenseRHS()";
00302 opserr << " - numInt " << numInt << "does not agree with condensedA";
00303 opserr << " numInt " << theSOE->numInt << endln;
00304 return -1;
00305 }
00306
00307
00308
00309 double *B = theSOE->B;
00310
00311
00312
00313
00314
00315
00316
00317 for (int i=1; i<numInt; i++) {
00318
00319 int rowitop = RowTop[i];
00320 double *ajiPtr = topRowPtr[i];
00321 double *bjPtr = &B[rowitop];
00322 double tmp = 0;
00323
00324 for (int j=rowitop; j<i; j++)
00325 tmp -= *ajiPtr++ * *bjPtr++;
00326
00327 B[i] += tmp;
00328 }
00329
00330
00331 double *bjPtr = B;
00332 double *aiiPtr = invD;
00333 for (int j=0; j<numInt; j++)
00334 *bjPtr++ = *aiiPtr++ * B[j];
00335
00336
00337
00338
00339
00340 for (int ii=numInt; ii<size; ii++) {
00341 int rowitop = RowTop[ii];
00342 double *ajiPtr = topRowPtr[ii];
00343 double *bjPtr = &B[rowitop];
00344 double tmp = 0;
00345
00346 for (int j=rowitop; j<numInt; j++)
00347 tmp -= *ajiPtr++ * *bjPtr++;
00348
00349 B[ii] += tmp;
00350 }
00351
00352
00353
00354
00355
00356
00357
00358 return 0;
00359 }
00360
00361
00362 int
00363 ProfileSPDLinSubstrSolver::computeCondensedMatVect(
00364 int numInt, const Vector &theVect)
00365 {
00366 opserr << "ProfileSPDLinSubstrSolver::computeCondensedMatVect() -";
00367 opserr << " not implemented yet\n";
00368 return -1;
00369 }
00370
00371
00372 const Matrix &
00373 ProfileSPDLinSubstrSolver::getCondensedA(void)
00374 {
00375 int numInt = theSOE->numInt;
00376 int matSize = size - numInt;
00377
00378
00379 if (Aext == 0) {
00380 Aext = new Matrix(matSize,matSize);
00381
00382 if (Aext == 0 || Aext->noRows() == 0) {
00383 opserr << "ProfileSPDLinSubstrSolver::getCondensedA";
00384 opserr << "- ran out of memory for matSize " << matSize << " \n";
00385 exit(-1);
00386 }
00387 }
00388
00389
00390 if (Aext->noRows() != matSize) {
00391 delete Aext;
00392 Aext = new Matrix(matSize,matSize);
00393
00394 if (Aext == 0 || Aext->noRows() == 0) {
00395 opserr << "ProfileSPDLinSubstrSolver::getCondensedA";
00396 opserr << "- ran out of memory for matSize " << matSize << " \n";
00397 exit(-1);
00398 }
00399 }
00400
00401
00402 Aext->Zero();
00403 for (int i=numInt; i<size; i++) {
00404 int col = i - numInt;
00405
00406 int rowitop = RowTop[i];
00407 double *akiPtr = topRowPtr[i];
00408
00409 int row =0;
00410 if (rowitop < numInt)
00411 akiPtr += (numInt - rowitop);
00412 else
00413 row = rowitop - numInt;
00414
00415 while (row < col){
00416 double aki = *akiPtr++;
00417 (*Aext)(row,col) = aki;
00418 (*Aext)(col,row) = aki;
00419 row++;
00420 }
00421 (*Aext)(col,row) = *akiPtr;
00422 }
00423 return *Aext;
00424 }
00425
00426
00427 const Vector &
00428 ProfileSPDLinSubstrSolver::getCondensedRHS(void)
00429 {
00430 int numInt = theSOE->numInt;
00431 int matSize = size - numInt;
00432
00433 double *Y = &(theSOE->B[numInt]);
00434
00435
00436 if (Yext == 0) {
00437 Yext = new Vector(Y,matSize);
00438
00439 if (Yext == 0 || Yext->Size() == 0) {
00440 opserr << "ProfileSPDLinSubstrSolver::getCondensedRHS";
00441 opserr << "- ran out of memory for vector Size " << matSize << " \n";
00442 exit(-1);
00443 }
00444 }
00445
00446
00447 if (Yext->Size() != matSize) {
00448 delete Yext;
00449 Yext = new Vector(Y,matSize);
00450
00451 if (Yext == 0 || Yext->Size() == 0) {
00452 opserr << "ProfileSPDLinSubstrSolver::getCondensedRHS";
00453 opserr << "- ran out of memory for vect Size " << matSize << " \n";
00454 exit(-1);
00455 }
00456 }
00457
00458 return *Yext;
00459 }
00460
00461 const Vector &
00462 ProfileSPDLinSubstrSolver::getCondensedMatVect(void)
00463 {
00464 opserr << "ProfileSPDLinSubstrSolver::computeCondensedMatVect() -";
00465 opserr << " not implemented yet\n";
00466 exit(-1);
00467
00468
00469 Vector *errVect = new Vector(0);
00470 return *errVect;
00471
00472 }
00473
00474
00475 int
00476 ProfileSPDLinSubstrSolver::setComputedXext(const Vector &xExt)
00477 {
00478 if (xExt.Size() != (size - theSOE->numInt)) {
00479 opserr << "ProfileSPDLinSubstrSolver::setComputedxExt() :";
00480 opserr << " - size mismatch " << xExt.Size() << " and ";
00481 opserr << size-theSOE->numInt << endln;
00482 return -1;
00483 }
00484
00485 double *xPtr = &(theSOE->X)[theSOE->numInt];
00486 for (int i=0; i<xExt.Size(); i++)
00487 *xPtr++ = xExt(i);
00488
00489 return 0;
00490 }
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512 int
00513 ProfileSPDLinSubstrSolver::solveXint(void)
00514 {
00515
00516
00517
00518
00519
00520 int numInt = theSOE->numInt;
00521 double *X = theSOE->X;
00522 double *B = theSOE->B;
00523
00524 for (int j=0; j<numInt; j++)
00525 X[j] = B[j]/invD[j];
00526
00527 for (int i=numInt; i<size; i++) {
00528
00529 int rowitop = RowTop[i];
00530 double *ajiPtr = topRowPtr[i];
00531 double *XjPtr = &X[rowitop];
00532 double Xi = X[i];
00533
00534 for (int j=rowitop; j<numInt; j++)
00535 *XjPtr++ -= *ajiPtr++ * Xi;
00536 }
00537
00538 for (int l=0; l<numInt; l++)
00539 X[l] = X[l]*invD[l];
00540
00541
00542
00543
00544
00545 for (int k=(numInt-1); k>0; k--) {
00546
00547 int rowktop = RowTop[k];
00548 double Xk = X[k];
00549 double *ajiPtr = topRowPtr[k];
00550
00551 for (int j=rowktop; j<k; j++)
00552 X[j] -= *ajiPtr++ * Xk;
00553 }
00554 return 0;
00555 }
00556
00557 int
00558 ProfileSPDLinSubstrSolver::getClassTag(void) const
00559 {
00560 return SOLVER_TAGS_ProfileSPDLinSubstrSolver;
00561 }
00562
00563 int
00564 ProfileSPDLinSubstrSolver::sendSelf(int cTag,
00565 Channel &theChannel)
00566 {
00567 if (size != 0)
00568 opserr << "ProfileSPDLinSubstrSolver::sendSelf - does not send itself YET\n";
00569 return 0;
00570 }
00571
00572
00573 int
00574 ProfileSPDLinSubstrSolver::recvSelf(int cTag,
00575 Channel &theChannel,
00576 FEM_ObjectBroker &theBroker)
00577 {
00578 return 0;
00579 }