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 #include <DiagonalSOE.h>
00033 #include <DiagonalSolver.h>
00034 #include <Matrix.h>
00035 #include <Graph.h>
00036 #include <Vertex.h>
00037 #include <VertexIter.h>
00038 #include <f2c.h>
00039 #include <math.h>
00040
00041 #include <Channel.h>
00042 #include <FEM_ObjectBroker.h>
00043
00044 DiagonalSOE::DiagonalSOE(DiagonalSolver &the_Solver)
00045 :LinearSOE(the_Solver, LinSOE_TAGS_DiagonalSOE),
00046 size(0), A(0), B(0), X(0), vectX(0), vectB(0), isAfactored(false)
00047 {
00048 the_Solver.setLinearSOE(*this);
00049 }
00050
00051
00052 DiagonalSOE::DiagonalSOE(int N, DiagonalSolver &the_Solver)
00053 :LinearSOE(the_Solver, LinSOE_TAGS_DiagonalSOE),
00054 size(0), A(0), B(0), X(0), vectX(0), vectB(0), isAfactored(false)
00055 {
00056 if (size > 0) {
00057 size = N;
00058 A = new double[size];
00059 B = new double[size];
00060 X = new double[size];
00061
00062 if (A == 0 || B == 0 || X == 0) {
00063 opserr << "ERROR DiagonalSOE::DiagonalSOE :";
00064 opserr << " ran out of memory for size: " << size << endln;
00065 if (A != 0) delete [] A;
00066 if (B != 0) delete [] B;
00067 if (X != 0) delete [] X;
00068 size = 0;
00069 }
00070
00071 vectX = new Vector(X,size);
00072 vectB = new Vector(B,size);
00073
00074 if (vectB == 0 || vectX == 0) {
00075 opserr << "ERROR DiagonalSOE::DiagonalSOE :";
00076 opserr << " ran out of memory for size: " << size << endln;
00077 if (A != 0) delete [] A;
00078 if (B != 0) delete [] B;
00079 if (X != 0) delete [] X;
00080 size = 0;
00081 }
00082 }
00083 the_Solver.setLinearSOE(*this);
00084
00085 int solverOK = the_Solver.setSize();
00086 if (solverOK < 0) {
00087 opserr << "WARNING DiagonalSOE::DiagonalSOE :";
00088 opserr << " solver failed setSize() in constructor\n";
00089 }
00090 }
00091
00092
00093 DiagonalSOE::~DiagonalSOE()
00094 {
00095 if (A != 0) delete [] A;
00096 if (B != 0) delete [] B;
00097 if (X != 0) delete [] X;
00098 if (vectX != 0) delete vectX;
00099 if (vectB != 0) delete vectB;
00100 }
00101
00102
00103 int
00104 DiagonalSOE::getNumEqn(void) const
00105 {
00106 return size;
00107 }
00108
00109 int
00110 DiagonalSOE::setSize(Graph &theGraph)
00111 {
00112 int oldSize = size;
00113 int result = 0;
00114 size = theGraph.getNumVertex();
00115
00116
00117
00118 if (size > oldSize) {
00119
00120 if (A != 0) delete [] A; A = 0;
00121 if (B != 0) delete [] B; B = 0;
00122 if (X != 0) delete [] X; X = 0;
00123 A = new double[size];
00124 B = new double[size];
00125 X = new double[size];
00126
00127 if (A == 0 || B == 0 || X == 0) {
00128 opserr << "ERROR DiagonalSOE::setSize() - ";
00129 opserr << " ran out of memory for size: " << size << endln;
00130 if (A != 0) delete [] A;
00131 if (B != 0) delete [] B;
00132 if (X != 0) delete [] X;
00133 size = 0;
00134 return -1;
00135 }
00136 }
00137
00138 if (size != oldSize && size != 0) {
00139 if (vectX != 0) delete vectX; vectX = 0;
00140 if (vectB != 0) delete vectB; vectB = 0;
00141 vectX = new Vector(X,size);
00142 vectB = new Vector(B,size);
00143
00144 if (vectB == 0 || vectX == 0) {
00145 opserr << "ERROR DiagonalSOE::setSize() - ";
00146 opserr << " ran out of memory for size: " << size << endln;
00147 if (A != 0) delete [] A;
00148 if (B != 0) delete [] B;
00149 if (X != 0) delete [] X;
00150 size = 0;
00151 return -1;
00152 }
00153 }
00154
00155
00156 for (int l=0; l<size; l++) {
00157 A[l] = 0;
00158 B[l] = 0;
00159 X[l] = 0;
00160 }
00161
00162
00163 LinearSOESolver *the_Solver = this->getSolver();
00164 int solverOK = the_Solver->setSize();
00165 if (solverOK < 0) {
00166 opserr << "WARNING DiagonalSOE::setSize :";
00167 opserr << " solver failed setSize()\n";
00168 return solverOK;
00169 }
00170
00171 return result;
00172 }
00173
00174 int
00175 DiagonalSOE::addA(const Matrix &m, const ID &id, double fact)
00176 {
00177
00178 if (fact == 0.0) return 0;
00179
00180 #ifdef _G3DEBUG
00181
00182 int idSize = id.Size();
00183 if (idSize != m.noRows() && idSize != m.noCols()) {
00184 opserr << "FullGenLinSOE::addA() - Matrix and ID not of similar sizes\n";
00185 return -1;
00186 }
00187 #endif
00188
00189 if (fact == 1.0) {
00190 for (int i=0; i<id.Size(); i++) {
00191 int pos = id(i);
00192 if (pos <size && pos >= 0)
00193 A[pos] += m(i,i);
00194 }
00195 } else if (fact == -1.0) {
00196 for (int i=0; i<id.Size(); i++) {
00197 int pos = id(i);
00198 if (pos <size && pos >= 0)
00199 A[pos] -= m(i,i);
00200 }
00201 } else {
00202 for (int i=0; i<id.Size(); i++) {
00203 int pos = id(i);
00204 if (pos <size && pos >= 0)
00205 A[pos] += m(i,i) * fact;
00206 }
00207 }
00208
00209 return 0;
00210 }
00211
00212
00213 int
00214 DiagonalSOE::addB(const Vector &v, const ID &id, double fact)
00215 {
00216
00217
00218 if (fact == 0.0) return 0;
00219
00220 #ifdef _G3DEBUG
00221
00222 int idSize = id.Size();
00223 if (idSize != v.Size() ) {
00224 opserr << "DiagonalSOE::addB() -";
00225 opserr << " Vector and ID not of similar sizes\n";
00226 return -1;
00227 }
00228 #endif
00229
00230 if (fact == 1.0) {
00231 for (int i=0; i<id.Size(); i++) {
00232 int pos = id(i);
00233 if (pos <size && pos >= 0)
00234 B[pos] += v(i);
00235 }
00236 } else if (fact == -1.0) {
00237 for (int i=0; i<id.Size(); i++) {
00238 int pos = id(i);
00239 if (pos <size && pos >= 0)
00240 B[pos] -= v(i);
00241 }
00242 } else {
00243 for (int i=0; i<id.Size(); i++) {
00244 int pos = id(i);
00245 if (pos <size && pos >= 0)
00246 B[pos] += v(i) * fact;
00247 }
00248 }
00249 return 0;
00250 }
00251
00252
00253 int
00254 DiagonalSOE::setB(const Vector &v, double fact)
00255 {
00256
00257 if (fact == 0.0) return 0;
00258
00259 if (v.Size() != size) {
00260 opserr << "WARNING DiagonalSOE::setB() -";
00261 opserr << " incomptable sizes " << size << " and " << v.Size() << endln;
00262 return -1;
00263 }
00264
00265 if (fact == 1.0) {
00266 for (int i=0; i<size; i++) {
00267 B[i] = v(i);
00268 }
00269 } else if (fact == -1.0) {
00270 for (int i=0; i<size; i++) {
00271 B[i] = -v(i);
00272 }
00273 } else {
00274 for (int i=0; i<size; i++) {
00275 B[i] = v(i) * fact;
00276 }
00277 }
00278 return 0;
00279 }
00280
00281 void
00282 DiagonalSOE::zeroA(void)
00283 {
00284 double *Aptr = A;
00285 for (int i=0; i<size; i++)
00286 *Aptr++ = 0;
00287
00288 isAfactored = false;
00289 }
00290
00291 void
00292 DiagonalSOE::zeroB(void)
00293 {
00294 double *Bptr = B;
00295 for (int i=0; i<size; i++)
00296 *Bptr++ = 0;
00297 }
00298
00299
00300 void
00301 DiagonalSOE::setX(int loc, double value)
00302 {
00303 if (loc < size && loc >=0)
00304 X[loc] = value;
00305 }
00306
00307 void
00308 DiagonalSOE::setX(const Vector &x)
00309 {
00310 if (x.Size() == size && vectX != 0)
00311 *vectX = x;
00312 }
00313
00314 const Vector &
00315 DiagonalSOE::getX(void)
00316 {
00317 if (vectX == 0) {
00318 opserr << "FATAL DiagonalSOE::getX - vectX == 0";
00319 exit(-1);
00320 }
00321 return *vectX;
00322 }
00323
00324 const Vector &
00325 DiagonalSOE::getB(void)
00326 {
00327 if (vectB == 0) {
00328 opserr << "FATAL DiagonalSOE::getB - vectB == 0";
00329 exit(-1);
00330 }
00331 return *vectB;
00332 }
00333
00334 double
00335 DiagonalSOE::normRHS(void)
00336 {
00337 double norm =0.0;
00338 for (int i=0; i<size; i++) {
00339 double Yi = B[i];
00340 norm += Yi*Yi;
00341 }
00342 return sqrt(norm);
00343
00344 }
00345
00346
00347 int
00348 DiagonalSOE::setDiagonalSolver(DiagonalSolver &newSolver)
00349 {
00350 newSolver.setLinearSOE(*this);
00351
00352 if (size != 0) {
00353 int solverOK = newSolver.setSize();
00354 if (solverOK < 0) {
00355 opserr << "WARNING:DiagonalSOE::setSolver :";
00356 opserr << "the new solver could not setSeize() - staying with old\n";
00357 return -1;
00358 }
00359 }
00360
00361 return this->setSolver(newSolver);
00362 }
00363
00364
00365 int
00366 DiagonalSOE::sendSelf(int cTag, Channel &theChannel)
00367 {
00368 return 0;
00369 }
00370
00371
00372 int
00373 DiagonalSOE::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
00374 {
00375 return 0;
00376 }