OpenSeesGradGEvaluator.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:45:44 $
00027 // $Source: /usr/local/cvs/OpenSees/SRC/reliability/analysis/sensitivity/OpenSeesGradGEvaluator.cpp,v $
00028 
00029 
00030 //
00031 // Written by Terje Haukaas (haukaas@ce.berkeley.edu)
00032 //
00033 
00034 #include <OpenSeesGradGEvaluator.h>
00035 #include <Vector.h>
00036 #include <Matrix.h>
00037 #include <GradGEvaluator.h>
00038 #include <ReliabilityDomain.h>
00039 #include <LimitStateFunction.h>
00040 #include <RandomVariable.h>
00041 #include <tcl.h>
00042 #include <string.h>
00043 
00044 #include <fstream>
00045 #include <iomanip>
00046 #include <iostream>
00047 using std::ifstream;
00048 using std::ios;
00049 using std::setw;
00050 using std::setprecision;
00051 using std::setiosflags;
00052 
00053 
00054 OpenSeesGradGEvaluator::OpenSeesGradGEvaluator(
00055                                         Tcl_Interp *passedTclInterp,
00056                                         ReliabilityDomain *passedReliabilityDomain,
00057                                         bool PdoGradientCheck)
00058 :GradGEvaluator(passedReliabilityDomain, passedTclInterp)
00059 {
00060         theReliabilityDomain = passedReliabilityDomain;
00061         doGradientCheck = PdoGradientCheck;
00062 
00063         int nrv = passedReliabilityDomain->getNumberOfRandomVariables();
00064         grad_g = new Vector(nrv);
00065         grad_g_matrix = 0;
00066 
00067         DgDdispl = 0;
00068 }
00069 
00070 OpenSeesGradGEvaluator::~OpenSeesGradGEvaluator()
00071 {
00072         if (grad_g != 0) 
00073                 delete grad_g;
00074 
00075         if (DgDdispl != 0)
00076                 delete DgDdispl;
00077 
00078         if (grad_g_matrix != 0)
00079                 delete grad_g_matrix;
00080 }
00081 
00082 
00083 
00084 
00085 Vector
00086 OpenSeesGradGEvaluator::getGradG()
00087 {
00088         return (*grad_g);
00089 }
00090 
00091 
00092 Matrix
00093 OpenSeesGradGEvaluator::getAllGradG()
00094 {
00095         if (grad_g_matrix==0) {
00096                 Matrix dummy(1,1);
00097                 return dummy;
00098         }
00099         else {
00100                 return (*grad_g_matrix);
00101         }
00102 }
00103 
00104 
00105 int
00106 OpenSeesGradGEvaluator::computeGradG(double g, Vector passed_x)
00107 {
00108         // Zero out the previous result matrix
00109         if (DgDdispl != 0) {
00110                 delete DgDdispl;
00111                 DgDdispl = 0;
00112         }
00113 
00114         // Call base class method
00115         computeParameterDerivatives(g);
00116 
00117         // Initial declaractions
00118         double perturbationFactor = 0.001; // (is multiplied by stdv and added to others...)
00119         char tclAssignment[500];
00120         char *dollarSign = "$";
00121         char *underscore = "_";
00122         char lsf_expression[500] = "";
00123         char separators[5] = "}{";
00124         int nrv = theReliabilityDomain->getNumberOfRandomVariables();
00125         RandomVariable *theRandomVariable;
00126         char tempchar[100]="";
00127         char newSeparators[5] = "_";
00128         double g_perturbed;
00129         int i;
00130         double onedudx;
00131         Vector dudx(nrv);
00132         
00133 
00134         // Compute gradients if this is a path-INdependent analysis
00135         // (This command only has effect if it IS path-independent.)
00136         sprintf(tclAssignment,"computeGradients");
00137         Tcl_Eval( theTclInterp, tclAssignment );
00138 
00139 
00140         // Initialize gradient vector
00141         grad_g->Zero();
00142 
00143 
00144         // "Download" limit-state function from reliability domain
00145         int lsf = theReliabilityDomain->getTagOfActiveLimitStateFunction();
00146         LimitStateFunction *theLimitStateFunction = 
00147                 theReliabilityDomain->getLimitStateFunctionPtr(lsf);
00148         char *theExpression = theLimitStateFunction->getExpression();
00149         char *lsf_copy = new char[500];
00150         strcpy(lsf_copy,theExpression);
00151 
00152 
00153         // Tokenize the limit-state function and COMPUTE GRADIENTS
00154         char *tokenPtr = strtok( lsf_copy, separators); 
00155         while ( tokenPtr != NULL ) {
00156 
00157                 strcpy(tempchar,tokenPtr);
00158 
00159                 if ( strncmp(tokenPtr, "x",1) == 0) {
00160 
00161                         // Get random variable number
00162                         int rvNum;
00163                         sscanf(tempchar,"x_%i",&rvNum);
00164 
00165                         // Perturb its value according to its standard deviation
00166                         theRandomVariable = theReliabilityDomain->getRandomVariablePtr(rvNum);
00167                         double stdv = theRandomVariable->getStdv();
00168                         sprintf(tclAssignment , "set x_%d  %35.20f", rvNum, (passed_x(rvNum-1)+perturbationFactor*stdv) );
00169                         Tcl_Eval( theTclInterp, tclAssignment);
00170 
00171                         // Evaluate limit-state function again
00172                         char *theTokenizedExpression = theLimitStateFunction->getTokenizedExpression();
00173                         Tcl_ExprDouble( theTclInterp, theTokenizedExpression, &g_perturbed );
00174 
00175                         // Make assignment back to its original value
00176                         sprintf(tclAssignment , "set x_%d  %35.20f", rvNum, passed_x(rvNum-1) );
00177                         Tcl_Eval( theTclInterp, tclAssignment);
00178 
00179                         // Add gradient contribution
00180                         (*grad_g)(rvNum-1) += (g_perturbed-g)/(perturbationFactor*stdv);
00181                 }
00182                 // If a nodal velocity is detected
00183                 else if ( strncmp(tokenPtr, "ud", 2) == 0) {
00184 
00185                         // Get node number and dof number
00186                         int nodeNumber, direction;
00187                         sscanf(tempchar,"ud_%i_%i", &nodeNumber, &direction);
00188 
00189                         // Keep the original value
00190                         double originalValue;
00191                         sprintf(tclAssignment,"$ud_%d_%d", nodeNumber, direction);
00192                         Tcl_ExprDouble( theTclInterp, tclAssignment, &originalValue);
00193 
00194                         // Set perturbed value in the Tcl workspace
00195                         double newValue = originalValue*(1.0+perturbationFactor);
00196                         sprintf(tclAssignment,"set ud_%d_%d %35.20f", nodeNumber, direction, newValue);
00197                         Tcl_Eval( theTclInterp, tclAssignment);
00198 
00199                         // Evaluate the limit-state function again
00200                         char *theTokenizedExpression = theLimitStateFunction->getTokenizedExpression();
00201                         Tcl_ExprDouble( theTclInterp, theTokenizedExpression, &g_perturbed );
00202 
00203                         // Compute gradient
00204                         double onedgdu = (g_perturbed-g)/(originalValue*perturbationFactor);
00205 
00206                         // Make assignment back to its original value
00207                         sprintf(tclAssignment,"set ud_%d_%d %35.20f", nodeNumber, direction, originalValue);
00208                         Tcl_Eval( theTclInterp, tclAssignment);
00209 
00210                         // Obtain DDM gradient vector
00211                         for (int i=1; i<=nrv; i++) {
00212                                 sprintf(tclAssignment , "set sens [sensNodeVel %d %d %d ]",nodeNumber,direction,i);
00213                                 Tcl_Eval( theTclInterp, tclAssignment);
00214                                 sprintf(tclAssignment , "$sens ");
00215                                 Tcl_ExprDouble( theTclInterp, tclAssignment, &onedudx );
00216                                 dudx( (i-1) ) = onedudx;
00217                         }
00218 
00219                         // Add gradient contribution
00220                         (*grad_g) += onedgdu*dudx;
00221 
00222                 }
00223                 // If a nodal displacement is detected
00224                 else if ( strncmp(tokenPtr, "u", 1) == 0) {
00225 
00226                         // Get node number and dof number
00227                         int nodeNumber, direction;
00228                         sscanf(tempchar,"u_%i_%i", &nodeNumber, &direction);
00229 
00230                         // Keep the original value
00231                         double originalValue;
00232                         sprintf(tclAssignment,"$u_%d_%d", nodeNumber, direction);
00233                         Tcl_ExprDouble( theTclInterp, tclAssignment, &originalValue);
00234 
00235                         // Set perturbed value in the Tcl workspace
00236                         double newValue = originalValue*(1.0+perturbationFactor);
00237                         sprintf(tclAssignment,"set u_%d_%d %35.20f", nodeNumber, direction, newValue);
00238                         Tcl_Eval( theTclInterp, tclAssignment);
00239 
00240                         // Evaluate the limit-state function again
00241                         char *theTokenizedExpression = theLimitStateFunction->getTokenizedExpression();
00242                         Tcl_ExprDouble( theTclInterp, theTokenizedExpression, &g_perturbed );
00243 
00244                         // Compute gradient
00245                         double onedgdu = (g_perturbed-g)/(originalValue*perturbationFactor);
00246 
00247                         // Store the DgDdispl in a matrix
00248                         if (DgDdispl == 0) {
00249                                 DgDdispl = new Matrix(1, 3);
00250                                 (*DgDdispl)(0,0) = (double)nodeNumber;
00251                                 (*DgDdispl)(0,1) = (double)direction;
00252                                 (*DgDdispl)(0,2) = onedgdu;
00253                         }
00254                         else {
00255                                 int oldSize = DgDdispl->noRows();
00256                                 Matrix tempMatrix = *DgDdispl;
00257                                 delete DgDdispl;
00258                                 DgDdispl = new Matrix(oldSize+1, 3);
00259                                 for (i=0; i<oldSize; i++) {
00260                                         (*DgDdispl)(i,0) = tempMatrix(i,0);
00261                                         (*DgDdispl)(i,1) = tempMatrix(i,1);
00262                                         (*DgDdispl)(i,2) = tempMatrix(i,2);
00263                                 }
00264                                 (*DgDdispl)(oldSize,0) = (double)nodeNumber;
00265                                 (*DgDdispl)(oldSize,1) = (double)direction;
00266                                 (*DgDdispl)(oldSize,2) = onedgdu;
00267                         }
00268 
00269 
00270                         // Make assignment back to its original value
00271                         sprintf(tclAssignment,"set u_%d_%d %35.20f", nodeNumber, direction, originalValue);
00272                         Tcl_Eval( theTclInterp, tclAssignment);
00273 
00274                         // Obtain DDM gradient vector
00275                         for (int i=1; i<=nrv; i++) {
00276                                 sprintf(tclAssignment , "set sens [sensNodeDisp %d %d %d ]",nodeNumber,direction,i);
00277                                 Tcl_Eval( theTclInterp, tclAssignment);
00278                                 sprintf(tclAssignment , "$sens ");
00279                                 Tcl_ExprDouble( theTclInterp, tclAssignment, &onedudx );
00280                                 dudx( (i-1) ) = onedudx;
00281                         }
00282 
00283                         // Add gradient contribution
00284                         (*grad_g) += onedgdu*dudx;
00285 
00286                 }
00287                 else if ( strncmp(tokenPtr, "rec",3) == 0) {
00288                 }
00289 
00290                 tokenPtr = strtok( NULL, separators);  // read next token and go up and check the while condition again
00291         } 
00292 
00293         delete [] lsf_copy;
00294 
00295         if (doGradientCheck) {
00296                 char myString[100];
00297                 ofstream outputFile( "DDMgradients.out", ios::out );
00298                 opserr << endln;
00299                 for (int ddm=0; ddm<grad_g->Size(); ddm++) {
00300                         opserr << "DDM("<< (ddm+1) << ") = " << (*grad_g)(ddm) << endln;
00301                         sprintf(myString,"%20.16e ",(*grad_g)(ddm));
00302                         outputFile << myString << endln;
00303                 }
00304                 outputFile.close();
00305                 opserr << "PRESS Ctrl+C TO TERMINATE APPLICATION!" << endln;
00306                 while(true) {
00307                 }
00308         }
00309 
00310 
00311 
00312         return 0;
00313 
00314 }
00315 
00316 
00317 
00318 int
00319 OpenSeesGradGEvaluator::computeAllGradG(Vector gFunValues, Vector passed_x)
00320 {
00321 
00322         // Allocate result matrix
00323         Vector gradG(passed_x.Size());
00324         if (grad_g_matrix == 0) {
00325                 grad_g_matrix = new Matrix(passed_x.Size(), gFunValues.Size());
00326         }
00327         else {
00328                 grad_g_matrix->Zero();
00329         }
00330 
00331 
00332         // Loop over performance functions
00333         for (int j=1; j<=gFunValues.Size(); j++) {
00334 
00335                 // Set tag of active limit-state function
00336                 theReliabilityDomain->setTagOfActiveLimitStateFunction(j);
00337 
00338                 this->computeGradG(gFunValues(j-1),passed_x);
00339                 gradG = this->getGradG();
00340 
00341                 for (int i=1; i<=passed_x.Size(); i++) {
00342         
00343                         (*grad_g_matrix)(i-1,j-1) = gradG(i-1);
00344                 }
00345         }
00346 
00347         return 0;
00348 }
00349 
00350 
00351 Matrix 
00352 OpenSeesGradGEvaluator::getDgDdispl()
00353 {
00354         return (*DgDdispl);
00355 }
00356 

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