DiagonalDirectSolver.cpp

Go to the documentation of this file.
00001 /* ****************************************************************** **
00002 **    OpenSees - Open System for Earthquake Engineering Simulation    **
00003 **          Pacific Earthquake Engineering Research Center            **
00004 **                                                                    **
00005 **                                                                    **
00006 ** (C) Copyright 1999, The Regents of the University of California    **
00007 ** All Rights Reserved.                                               **
00008 **                                                                    **
00009 ** Commercial use of this program without express permission of the   **
00010 ** University of California, Berkeley, is strictly prohibited.  See   **
00011 ** file 'COPYRIGHT'  in main directory for information on usage and   **
00012 ** redistribution,  and for a DISCLAIMER OF ALL WARRANTIES.           **
00013 **                                                                    **
00014 ** Developed by:                                                      **
00015 **   Frank McKenna (fmckenna@ce.berkeley.edu)                         **
00016 **   Gregory L. Fenves (fenves@ce.berkeley.edu)                       **
00017 **   Filip C. Filippou (filippou@ce.berkeley.edu)                     **
00018 **                                                                    **
00019 ** ****************************************************************** */
00020                                                                         
00021 // $Revision: 1.2 $
00022 // $Date: 2005/02/09 19:58:47 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/system_of_eqn/linearSOE/diagonal/DiagonalDirectSolver.cpp,v $
00024 
00025 // Written: fmk 
00026 // Created: Jan 2005
00027 // Revision: A
00028 //
00029 // Description: This file contains the implementation for ProfileSPDLinSOESolver
00030 // Description: This file contains the class definition for 
00031 // DiagonalDirectSolver. DiagonalDirectSolver is a subclass 
00032 // of LinearSOESOlver. It solves a DiagonalSOE object directly!
00033 
00034 // What: "@(#) DiagonalDirectSolver.C, revA"
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   // check for quick returns
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   // set some pointers
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     // FACTOR & SOLVE
00090     double invD;
00091     for (int i=0; i<size; i++) {
00092       
00093       double aii = *Aptr;
00094 
00095       // check that the diag > the tolerance specified
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       // store the inverse 1/Aii in A; and solve for Xi
00109       invD = 1.0/aii; 
00110       *Xptr++ = invD * *Bptr++;
00111       *Aptr++ = invD;
00112     }
00113 
00114     theSOE->isAfactored = true;
00115 
00116   } else {
00117 
00118     // JUST SOLVE
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 

Generated on Mon Oct 23 15:05:28 2006 for OpenSees by doxygen 1.5.0