NewmarkSensitivityIntegrator.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 2001, 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 ** Reliability module developed by:                                   **
00020 **   Terje Haukaas (haukaas@ce.berkeley.edu)                          **
00021 **   Armen Der Kiureghian (adk@ce.berkeley.edu)                       **
00022 **                                                                    **
00023 ** ****************************************************************** */
00024                                                                         
00025 // $Revision: 1.2 $
00026 // $Date: 2003/10/27 23:05:30 $
00027 // $Source: /usr/local/cvs/OpenSees/SRC/reliability/FEsensitivity/NewmarkSensitivityIntegrator.cpp,v $
00028 
00029 
00030 //
00031 // Written by Terje Haukaas (haukaas@ce.berkeley.edu)
00032 //
00033 
00034 #include <SensitivityIntegrator.h>
00035 #include <Newmark.h>
00036 #include <NewmarkSensitivityIntegrator.h>
00037 #include <FE_Element.h>
00038 #include <DOF_Group.h>
00039 #include <Information.h>
00040 #include <DOF_GrpIter.h>
00041 #include <FE_EleIter.h>
00042 #include <LoadPattern.h>
00043 #include <Domain.h>
00044 #include <LoadPatternIter.h>
00045 #include <Node.h>
00046 #include <NodeIter.h>
00047 
00048 
00049 NewmarkSensitivityIntegrator::NewmarkSensitivityIntegrator()
00050 :Newmark(),SensitivityIntegrator(),parameterID(0),sensitivityFlag(0),gradNumber(0)
00051 {
00052         massMatrixMultiplicator = 0;
00053         dampingMatrixMultiplicator = 0;
00054         assemblyFlag = 0;
00055 }
00056 
00057 NewmarkSensitivityIntegrator::NewmarkSensitivityIntegrator(int passedAssemblyFlag, double theGamma, double theBeta, bool dispFlag)
00058 :Newmark(theGamma, theBeta, dispFlag),SensitivityIntegrator(),
00059 parameterID(0),sensitivityFlag(0),gradNumber(0)
00060 {
00061         massMatrixMultiplicator = 0;
00062         dampingMatrixMultiplicator = 0;
00063         assemblyFlag = passedAssemblyFlag;
00064 }
00065 
00066 NewmarkSensitivityIntegrator::NewmarkSensitivityIntegrator(int passedAssemblyFlag, double theGamma, double theBeta, 
00067                  double alpham, double betak, 
00068                  double betaki, double betakc,
00069                  bool dispFlag)
00070 :Newmark(theGamma, theBeta, alpham, betak, betaki, betakc, dispFlag),
00071 SensitivityIntegrator(),
00072 parameterID(0),sensitivityFlag(0),gradNumber(0)
00073 {
00074         massMatrixMultiplicator = 0;
00075         dampingMatrixMultiplicator = 0;
00076         assemblyFlag = passedAssemblyFlag;
00077 }
00078 
00079 NewmarkSensitivityIntegrator::~NewmarkSensitivityIntegrator()
00080 {
00081         if (massMatrixMultiplicator!=0)
00082                 delete massMatrixMultiplicator;
00083 
00084         if (dampingMatrixMultiplicator!=0)
00085                 delete dampingMatrixMultiplicator;
00086 }
00087 
00088 int
00089 NewmarkSensitivityIntegrator::formEleResidual(FE_Element *theEle)
00090 {
00091 
00092         if (sensitivityFlag == 0) {  // NO SENSITIVITY ANALYSIS
00093 
00094                 this->Newmark::formEleResidual(theEle);
00095 
00096         }
00097         else {  // (ASSEMBLE ALL TERMS)
00098 
00099                 theEle->zeroResidual();
00100 
00101                 // Compute the time-stepping parameters on the form
00102                 // udotdot = a1*ui+1 + a2*ui + a3*udoti + a4*udotdoti
00103                 // udot    = a5*ui+1 + a6*ui + a7*udoti + a8*udotdoti
00104                 // (see p. 166 of Chopra)
00105 
00106                 // The constants are:
00107                 // a1 = 1.0/(beta*dt*dt)
00108                 // a2 = -1.0/(beta*dt*dt)
00109                 // a3 = -1.0/beta*dt
00110                 // a4 = 1.0 - 1.0/(2.0*beta)
00111                 // a5 = gamma/(beta*dt)
00112                 // a6 = -gamma/(beta*dt)
00113                 // a7 = 1.0 - gamma/beta
00114                 // a8 = 1.0 - gamma/(2.0*beta)
00115 
00116                 // We can make use of the data members c2 and c3 of this class. 
00117                 // As long as disp==true, they are defined as:
00118                 // c2 = gamma/(beta*dt)
00119                 // c3 = 1.0/(beta*dt*dt)
00120 
00121                 // So, the constants can be computed as follows:
00122                 if (displ==false) {
00123                         opserr << "ERROR: Newmark::formEleResidual() -- the implemented"
00124                                 << " scheme only works if the displ variable is set to true." << endln;
00125                 }
00126                 double a2 = -c3;
00127                 double a3 = -c2/gamma;
00128                 double a4 = 1.0 - 1.0/(2.0*beta);
00129                 double a6 = -c2;
00130                 double a7 = 1.0 - gamma/beta;
00131                 double dt = gamma/(beta*c2);
00132                 double a8 = dt*(1.0 - gamma/(2.0*beta));
00133 
00134 
00135                 // Obtain sensitivity vectors from previous step
00136                 int vectorSize = U->Size();
00137                 Vector V(vectorSize);
00138                 Vector Vdot(vectorSize);
00139                 Vector Vdotdot(vectorSize);
00140                 int i, loc;
00141 
00142                 AnalysisModel *myModel = this->getAnalysisModelPtr();
00143                 DOF_GrpIter &theDOFs = myModel->getDOFs();
00144                 DOF_Group *dofPtr;
00145                 while ((dofPtr = theDOFs()) != 0) {
00146 
00147                         const ID &id = dofPtr->getID();
00148                         int idSize = id.Size();
00149                         const Vector &dispSens = dofPtr->getDispSensitivity(gradNumber);        
00150                         for (i=0; i < idSize; i++) {
00151                                 loc = id(i);
00152                                 if (loc >= 0) {
00153                                         V(loc) = dispSens(i);           
00154                                 }
00155                         }
00156 
00157                         const Vector &velSens = dofPtr->getVelSensitivity(gradNumber);
00158                         for (i=0; i < idSize; i++) {
00159                                 loc = id(i);
00160                                 if (loc >= 0) {
00161                                         Vdot(loc) = velSens(i);
00162                                 }
00163                         }
00164 
00165                         const Vector &accelSens = dofPtr->getAccSensitivity(gradNumber);        
00166                         for (i=0; i < idSize; i++) {
00167                                 loc = id(i);
00168                                 if (loc >= 0) {
00169                                         Vdotdot(loc) = accelSens(i);
00170                                 }
00171                         }
00172                 }
00173 
00174 
00175                 // Pre-compute the vectors involving a2, a3, etc.
00176                 Vector tmp1 = V*a2 + Vdot*a3 + Vdotdot*a4;
00177                 Vector tmp2 = V*a6 + Vdot*a7 + Vdotdot*a8;
00178 
00179                 if (massMatrixMultiplicator == 0)
00180                         massMatrixMultiplicator = new Vector(tmp1.Size());
00181                 if (dampingMatrixMultiplicator == 0)
00182                         dampingMatrixMultiplicator = new Vector(tmp2.Size());
00183 
00184                 (*massMatrixMultiplicator) = tmp1;
00185                 (*dampingMatrixMultiplicator) = tmp2;
00186 
00187 
00188                 // Now we're ready to make calls to the FE Element:
00189 
00190                 // The term -dPint/dh|u fixed
00191                 theEle->addResistingForceSensitivity(gradNumber); 
00192 
00193                 // The term -dM/dh*acc
00194                 theEle->addM_ForceSensitivity(gradNumber, *Udotdot, -1.0);
00195 
00196                 // The term -M*(a2*v + a3*vdot + a4*vdotdot)
00197                 theEle->addM_Force(*massMatrixMultiplicator,-1.0);
00198 
00199                 // The term -C*(a6*v + a7*vdot + a8*vdotdot)
00200                 theEle->addD_Force(*dampingMatrixMultiplicator,-1.0);
00201 
00202                 // The term -dC/dh*vel
00203                 theEle->addD_ForceSensitivity(gradNumber, *Udot,-1.0);
00204                 
00205         }
00206 
00207         return 0;
00208 }
00209 
00210 
00211 
00212 int
00213 NewmarkSensitivityIntegrator::formNodUnbalance(DOF_Group *theDof)
00214 {
00215 
00216         if (sensitivityFlag == 0) {  // NO SENSITIVITY ANALYSIS
00217 
00218                 this->Newmark::formNodUnbalance(theDof);
00219 
00220         }
00221         else {  // ASSEMBLE ALL TERMS
00222 
00223                 theDof->zeroUnbalance();
00224 
00225 
00226                 // The term -M*(a2*v + a3*vdot + a4*vdotdot)
00227                 theDof->addM_Force(*massMatrixMultiplicator,-1.0);
00228 
00229 
00230                 // The term -dM/dh*acc
00231                 theDof->addM_ForceSensitivity(*Udotdot, -1.0);
00232 
00233 
00234                 // The term -C*(a6*v + a7*vdot + a8*vdotdot)
00235                 theDof->addD_Force(*dampingMatrixMultiplicator,-1.0);
00236 
00237 
00238                 // The term -dC/dh*vel
00239                 theDof->addD_ForceSensitivity(*Udot,-1.0);
00240 
00241 
00242                 // In case of random loads (have already been formed by 'applyLoadSensitivity')
00243                 theDof->addPtoUnbalance();
00244 
00245         }
00246 
00247 
00248         return 0;
00249 }
00250 
00251 
00252 int 
00253 NewmarkSensitivityIntegrator::formSensitivityRHS(int passedGradNumber)
00254 {
00255         sensitivityFlag = 1;
00256 
00257 
00258         // Set a couple of data members
00259         gradNumber = passedGradNumber;
00260 
00261         // Get pointer to the SOE
00262         LinearSOE *theSOE = this->getLinearSOEPtr();
00263 
00264 
00265         // Possibly set the independent part of the RHS
00266         if (assemblyFlag != 0) {
00267                 theSOE->setB(independentRHS);
00268         }
00269 
00270         // Get the analysis model
00271         AnalysisModel *theModel = this->getAnalysisModelPtr();
00272 
00273 
00274 
00275         // Randomness in external load (including randomness in time series)
00276         // Get domain
00277         Domain *theDomain = theModel->getDomainPtr();
00278 
00279         // Loop through nodes to zero the unbalaced load
00280         Node *nodePtr;
00281         NodeIter &theNodeIter = theDomain->getNodes();
00282         while ((nodePtr = theNodeIter()) != 0)
00283         nodePtr->zeroUnbalancedLoad();
00284 
00285 
00286         // Loop through load patterns to add external load sensitivity
00287         LoadPattern *loadPatternPtr;
00288         LoadPatternIter &thePatterns = theDomain->getLoadPatterns();
00289         double time;
00290         while((loadPatternPtr = thePatterns()) != 0) {
00291                 time = theDomain->getCurrentTime();
00292                 loadPatternPtr->applyLoadSensitivity(time);
00293         }
00294 
00295 
00296         // Randomness in element/material contributions
00297         // Loop through FE elements
00298         FE_Element *elePtr;
00299         FE_EleIter &theEles = theModel->getFEs();    
00300         while((elePtr = theEles()) != 0) {
00301                 theSOE->addB(  elePtr->getResidual(this),  elePtr->getID()  );
00302         }
00303 
00304 
00305         // Loop through DOF groups (IT IS IMPORTANT THAT THIS IS DONE LAST!)
00306         DOF_Group *dofPtr;
00307         DOF_GrpIter &theDOFs = theModel->getDOFs();
00308         while((dofPtr = theDOFs()) != 0) {
00309                 theSOE->addB(  dofPtr->getUnbalance(this),  dofPtr->getID()  );
00310         }
00311 
00312 
00313         // Reset the sensitivity flag
00314         sensitivityFlag = 0;
00315 
00316         return 0;
00317 }
00318                 
00319 
00320 
00321 
00322 
00323 
00324 int 
00325 NewmarkSensitivityIntegrator::formIndependentSensitivityRHS()
00326 {
00327         // For now; don't use this
00328 /*
00329         sensitivityFlag = 2; // Tell subsequent methods what to be assembled
00330 
00331         // Get pointer to the SOE
00332         LinearSOE *theSOE = this->getLinearSOEPtr();
00333 
00334 
00335         // Get the analysis model
00336         AnalysisModel *theModel = this->getAnalysisModelPtr();
00337 
00338         
00339         // Loop through FE elements
00340         FE_Element *elePtr;
00341         FE_EleIter &theEles = theModel->getFEs();    
00342         while((elePtr = theEles()) != 0) {
00343                 theSOE->addB(  elePtr->getResidual(this),  elePtr->getID()  );
00344         }
00345 
00346 
00347         // Loop through DOF groups (IT IS IMPORTANT THAT THIS IS DONE LAST!)
00348         DOF_Group *dofPtr;
00349         DOF_GrpIter &theDOFs = theModel->getDOFs();
00350         while((dofPtr = theDOFs()) != 0) {
00351                 theSOE->addB(  dofPtr->getUnbalance(this),  dofPtr->getID()  );
00352         }
00353 
00354 
00355         // Set the data member of this class
00356         independentRHS = theSOE->getB();
00357 
00358 
00359         // Reset the sensitivity flag
00360         sensitivityFlag = 0;
00361 */
00362 
00363         return 0;
00364 }
00365                 
00366 
00367 
00368 
00369 
00370 int 
00371 NewmarkSensitivityIntegrator::saveSensitivity(const Vector & vNew,int gradNum,int numGrads)
00372 {
00373 
00374         // Compute Newmark parameters in general notation
00375         double a1 = c3;
00376         double a2 = -c3;
00377         double a3 = -c2/gamma;
00378         double a4 = 1.0 - 1.0/(2.0*beta);
00379         double a5 = c2;
00380         double a6 = -c2;
00381         double a7 = 1.0 - gamma/beta;
00382         double dt = gamma/(beta*c2);
00383         double a8 = dt*(1.0 - gamma/(2.0*beta));
00384 
00385 
00386         // Recover sensitivity results from previous step
00387         int vectorSize = U->Size();
00388         Vector V(vectorSize);
00389         Vector Vdot(vectorSize);
00390         Vector Vdotdot(vectorSize);
00391         int i, loc;
00392 
00393         AnalysisModel *myModel = this->getAnalysisModelPtr();
00394         DOF_GrpIter &theDOFs = myModel->getDOFs();
00395         DOF_Group *dofPtr;
00396         while ((dofPtr = theDOFs()) != 0) {
00397 
00398                 const ID &id = dofPtr->getID();
00399                 int idSize = id.Size();
00400                 const Vector &dispSens = dofPtr->getDispSensitivity(gradNumber);        
00401                 for (i=0; i < idSize; i++) {
00402                         loc = id(i);
00403                         if (loc >= 0) {
00404                                 V(loc) = dispSens(i);           
00405                         }
00406                 }
00407 
00408                 const Vector &velSens = dofPtr->getVelSensitivity(gradNumber);
00409                 for (i=0; i < idSize; i++) {
00410                         loc = id(i);
00411                         if (loc >= 0) {
00412                                 Vdot(loc) = velSens(i);
00413                         }
00414                 }
00415 
00416                 const Vector &accelSens = dofPtr->getAccSensitivity(gradNumber);        
00417                 for (i=0; i < idSize; i++) {
00418                         loc = id(i);
00419                         if (loc >= 0) {
00420                                 Vdotdot(loc) = accelSens(i);
00421                         }
00422                 }
00423         }
00424 
00425 
00426         // Compute new acceleration and velocity vectors:
00427         Vector *vNewPtr = new Vector(vectorSize);
00428         Vector *vdotNewPtr = new Vector(vectorSize);
00429         Vector *vdotdotNewPtr = new Vector(vectorSize);
00430         (*vdotdotNewPtr) = vNew*a1 + V*a2 + Vdot*a3 + Vdotdot*a4;
00431         (*vdotNewPtr) = vNew*a5 + V*a6 + Vdot*a7 + Vdotdot*a8;
00432         (*vNewPtr) = vNew;
00433 
00434 
00435         // Now we can save vNew, vdotNew and vdotdotNew
00436     DOF_GrpIter &theDOFGrps = myModel->getDOFs();
00437     DOF_Group   *dofPtr1;
00438     while ( (dofPtr1 = theDOFGrps() ) != 0)  {
00439                 dofPtr1->saveSensitivity(vNewPtr,vdotNewPtr,vdotdotNewPtr,gradNum,numGrads);
00440         }
00441 
00442         delete vNewPtr;
00443         delete vdotNewPtr;
00444         delete vdotdotNewPtr;
00445 
00446         return 0;
00447 }
00448 
00449 
00450 
00451 int 
00452 NewmarkSensitivityIntegrator::commitSensitivity(int gradNum, int numGrads)
00453 {
00454 
00455         // Loop through the FE_Elements and set unconditional sensitivities
00456         AnalysisModel *theAnalysisModel = this->getAnalysisModelPtr();
00457     FE_Element *elePtr;
00458     FE_EleIter &theEles = theAnalysisModel->getFEs();    
00459     while((elePtr = theEles()) != 0) {
00460                 elePtr->commitSensitivity(gradNum, numGrads);
00461         }
00462 
00463         return 0;
00464 }
00465 
00466 
00467 
00468 
00469 int
00470 NewmarkSensitivityIntegrator::setParameter(char **argv, int argc, Information &info)
00471 {
00472     if (strcmp(argv[0],"alphaM") == 0) {
00473         info.theType = DoubleType;
00474         return 1;
00475     }
00476     if (strcmp(argv[0],"betaK") == 0) {
00477         info.theType = DoubleType;
00478         return 2;
00479     }
00480     // otherwise parameter is unknown
00481     else {
00482                 opserr << "ERROR: Unknown random parameter in Newmark::setParameter()" << endln;
00483       return -1;
00484         }
00485 }
00486 
00487 int
00488 NewmarkSensitivityIntegrator::updateParameter   (int parameterID, Information &info)
00489 {
00490   switch (parameterID) {
00491       
00492     case 1:
00493         this->alphaM = info.theDouble;
00494         return 0;
00495 
00496     case 2:
00497         this->betaK = info.theDouble;
00498         return 0;
00499 
00500     default:
00501                 return 0;
00502   }
00503 }
00504 
00505 int
00506 NewmarkSensitivityIntegrator::activateParameter (int passedParameterID)
00507 {
00508         parameterID = passedParameterID;
00509 
00510         return 0;
00511 }
00512 
00513 
00514 
00515 
00516 
00517 
00518 
00519 
00520 

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