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
00036 #include <DiagonalDirectSolver.h>
00037 #include <DiagonalSOE.h>
00038 #include <math.h>
00039 #include <Channel.h>
00040 #include <FEM_ObjectBroker.h>
00041
00042 DiagonalDirectSolver::DiagonalDirectSolver(double tol)
00043 :DiagonalSolver(SOLVER_TAGS_DiagonalDirectSolver),
00044 minDiagTol(tol)
00045 {
00046
00047 }
00048
00049
00050 DiagonalDirectSolver::~DiagonalDirectSolver()
00051 {
00052
00053 }
00054
00055 int
00056 DiagonalDirectSolver::setSize(void)
00057 {
00058 if (theSOE == 0) {
00059 opserr << "DiagonalDirectSolver::setSize()";
00060 opserr << " No system has been set!\n";
00061 return -1;
00062 }
00063 return 0;
00064 }
00065
00066
00067 int
00068 DiagonalDirectSolver::solve(void)
00069 {
00070
00071
00072 if (theSOE == 0) {
00073 opserr << "DiagonalDirectSolver::solve(void): ";
00074 opserr << " - No ProfileSPDSOE has been assigned\n";
00075 return -1;
00076 }
00077
00078 if (theSOE->size == 0)
00079 return 0;
00080
00081
00082 double *Aptr = theSOE->A;
00083 double *Bptr = theSOE->B;
00084 double *Xptr = theSOE->X;
00085 int size = theSOE->size;
00086
00087 if (theSOE->isAfactored == false) {
00088
00089
00090 double invD;
00091 for (int i=0; i<size; i++) {
00092
00093 double aii = *Aptr;
00094
00095
00096 if (aii == 0.0) {
00097 opserr << "DiagonalDirectSolver::solve() - ";
00098 opserr << " aii = 0 (i, aii): (" << i << ", " << aii << ")\n";
00099 return(-2);
00100 }
00101 if (fabs(aii) <= minDiagTol) {
00102 opserr << "DiagonalDirectSolver::solve() - ";
00103 opserr << " aii < minDiagTol (i, aii): (" << i;
00104 opserr << ", " << aii << ")\n";
00105 return(-2);
00106 }
00107
00108
00109 invD = 1.0/aii;
00110 *Xptr++ = invD * *Bptr++;
00111 *Aptr++ = invD;
00112 }
00113
00114 theSOE->isAfactored = true;
00115
00116 } else {
00117
00118
00119 for (int i=0; i<size; i++) {
00120 *Xptr++ = *Aptr++ * *Bptr++;
00121 }
00122 }
00123
00124 return 0;
00125 }
00126
00127 double
00128 DiagonalDirectSolver::getDeterminant(void)
00129 {
00130 double determinant = 0.0;
00131 return determinant;
00132 }
00133
00134 int
00135 DiagonalDirectSolver::setDiagonalSOE(DiagonalSOE &theNewSOE)
00136 {
00137 if (theSOE != 0) {
00138 opserr << "DiagonalDirectSolver::setProfileSOE() - ";
00139 opserr << " has already been called \n";
00140 return -1;
00141 }
00142
00143 theSOE = &theNewSOE;
00144 return 0;
00145 }
00146
00147
00148 int
00149 DiagonalDirectSolver::sendSelf(int cTag,
00150 Channel &theChannel)
00151 {
00152 static Vector data(1);
00153 data(0) = minDiagTol;
00154 return theChannel.sendVector(0, cTag, data);
00155 }
00156
00157
00158 int
00159 DiagonalDirectSolver::recvSelf(int cTag,
00160 Channel &theChannel,
00161 FEM_ObjectBroker &theBroker)
00162 {
00163 static Vector data(1);
00164 theChannel.recvVector(0, cTag, data);
00165
00166 minDiagTol = data(0);
00167 return 0;
00168 }
00169
00170