Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 275 | fmk | 1 | /* ****************************************************************** ** |
| 2 | ** OpenSees - Open System for Earthquake Engineering Simulation ** |
||
| 3 | ** Pacific Earthquake Engineering Research Center ** |
||
| 4 | ** ** |
||
| 5 | ** ** |
||
| 6 | ** (C) Copyright 2001, The Regents of the University of California ** |
||
| 7 | ** All Rights Reserved. ** |
||
| 8 | ** ** |
||
| 9 | ** Commercial use of this program without express permission of the ** |
||
| 10 | ** University of California, Berkeley, is strictly prohibited. See ** |
||
| 11 | ** file 'COPYRIGHT' in main directory for information on usage and ** |
||
| 12 | ** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** |
||
| 13 | ** ** |
||
| 14 | ** Developed by: ** |
||
| 15 | ** Frank McKenna (fmckenna@ce.berkeley.edu) ** |
||
| 16 | ** Gregory L. Fenves (fenves@ce.berkeley.edu) ** |
||
| 17 | ** Filip C. Filippou (filippou@ce.berkeley.edu) ** |
||
| 18 | ** ** |
||
| 19 | ** Reliability module developed by: ** |
||
| 20 | ** Terje Haukaas (haukaas@ce.berkeley.edu) ** |
||
| 21 | ** Armen Der Kiureghian (adk@ce.berkeley.edu) ** |
||
| 22 | ** ** |
||
| 23 | ** ****************************************************************** */ |
||
| 24 | |||
| 25 | // $Revision: 1.1 $ |
||
| 26 | // $Date: 2001-06-13 05:06:18 $ |
||
| 27 | // $Source: /usr/local/cvs/OpenSees/SRC/reliability/analysis/sensitivity/OpenSeesSensitivityEvaluator.cpp,v $ |
||
| 28 | |||
| 29 | |||
| 30 | // |
||
| 31 | // Written by Terje Haukaas (haukaas@ce.berkeley.edu) during Spring 2000 |
||
| 32 | // Revised: haukaas 06/00 (core code) |
||
| 33 | // haukaas 06/01 (made part of official OpenSees) |
||
| 34 | // |
||
| 35 | |||
| 36 | #include <OpenSeesSensitivityEvaluator.h> |
||
| 37 | #include <Vector.h> |
||
| 38 | #include <Matrix.h> |
||
| 39 | #include <SensitivityEvaluator.h> |
||
| 40 | #include <ReliabilityDomain.h> |
||
| 41 | #include <LimitStateFunction.h> |
||
| 42 | #include <GFunEvaluator.h> |
||
| 43 | #include <RandomVariable.h> |
||
| 44 | |||
| 45 | #include <fstream.h> |
||
| 46 | #include <tcl.h> |
||
| 47 | #include <string.h> |
||
| 48 | |||
| 49 | |||
| 50 | OpenSeesSensitivityEvaluator::OpenSeesSensitivityEvaluator( |
||
| 51 | Tcl_Interp *passedTclInterp, |
||
| 52 | ReliabilityDomain *passedReliabilityDomain) |
||
| 53 | :SensitivityEvaluator() |
||
| 54 | { |
||
| 55 | theTclInterp = passedTclInterp; |
||
| 56 | theReliabilityDomain = passedReliabilityDomain; |
||
| 57 | |||
| 58 | int nrv = theReliabilityDomain->getNumberOfRandomVariables(); |
||
| 59 | grad_g = new Vector(nrv); |
||
| 60 | } |
||
| 61 | |||
| 62 | OpenSeesSensitivityEvaluator::~OpenSeesSensitivityEvaluator() |
||
| 63 | { |
||
| 64 | delete grad_g; |
||
| 65 | } |
||
| 66 | |||
| 67 | |||
| 68 | |||
| 69 | |||
| 70 | Vector |
||
| 71 | OpenSeesSensitivityEvaluator::get_grad_g() |
||
| 72 | { |
||
| 73 | return (*grad_g); |
||
| 74 | } |
||
| 75 | |||
| 76 | |||
| 77 | int |
||
| 78 | OpenSeesSensitivityEvaluator::evaluate_grad_g(double gFunValue, Vector passed_x) |
||
| 79 | { |
||
| 80 | //////////////////////////////////// |
||
| 81 | // Notation: |
||
| 82 | // g: the limit-state function |
||
| 83 | // The gradient of the limit-state function: |
||
| 84 | // dgdx(m,1) = [ dgdu(1,n) * dudx(n,m) ]^T + dgdxufixed(m,1) |
||
| 85 | // m: number of random variables x(i) |
||
| 86 | // n: number of response quantities u(i) |
||
| 87 | //////////////////////////////////// |
||
| 88 | |||
| 89 | // Some initial declaractions |
||
| 90 | char tclAssignment[500]; |
||
| 91 | double g; |
||
| 92 | double onedgdxufixed; |
||
| 93 | double onedgdu; |
||
| 94 | double onedudx; |
||
| 95 | |||
| 96 | // "Download" limit-state function from reliability domain |
||
| 97 | int lsf = theReliabilityDomain->getTagOfActiveLimitStateFunction(); |
||
| 98 | LimitStateFunction *theLimitStateFunction = |
||
| 99 | theReliabilityDomain->getLimitStateFunctionPtr(lsf); |
||
| 100 | char *theExpression = theLimitStateFunction->getExpression(); |
||
| 101 | |||
| 102 | // Declare some much used tokens |
||
| 103 | char *dollarSign = "$"; |
||
| 104 | char *underscore = "_"; |
||
| 105 | |||
| 106 | // Declare strings for the strings to be evaluated by Tcl |
||
| 107 | char lsf_expression[500] = ""; |
||
| 108 | char grad_lsf_expression[500] = ""; |
||
| 109 | |||
| 110 | // Create copies of the limit-state function to be tokenized |
||
| 111 | char *lsf_copy1 = new char[500]; |
||
| 112 | char *lsf_copy2 = new char[500]; |
||
| 113 | strcpy(lsf_copy1,theExpression); |
||
| 114 | strcpy(lsf_copy2,theExpression); |
||
| 115 | |||
| 116 | // Have a counter to see how many response quantities are in the lsf |
||
| 117 | int count_u = 0; |
||
| 118 | |||
| 119 | // Tokenize the limit-state function and assign values to the found quantities. |
||
| 120 | char *tokenPtr1 = strtok( lsf_copy1, " _"); // read first token |
||
| 121 | while ( tokenPtr1 != NULL ) { |
||
| 122 | |||
| 123 | // If a basic random variable is detected |
||
| 124 | if ( strcmp(tokenPtr1, "x") == 0) { |
||
| 125 | strcat(lsf_expression, dollarSign); |
||
| 126 | strcat(lsf_expression, tokenPtr1); |
||
| 127 | strcat(lsf_expression, underscore); |
||
| 128 | tokenPtr1 = strtok( NULL, " _"); // read a token |
||
| 129 | strcat(lsf_expression, tokenPtr1); |
||
| 130 | int basicRandomVariableNumber = atoi( tokenPtr1 ); |
||
| 131 | sprintf(tclAssignment , "set x_%d %15.5f", basicRandomVariableNumber, passed_x(basicRandomVariableNumber-1) ); |
||
| 132 | Tcl_Eval( theTclInterp, tclAssignment); |
||
| 133 | } |
||
| 134 | |||
| 135 | // If a nodal displacement is detected |
||
| 136 | else if ( strcmp(tokenPtr1, "nd") == 0) { |
||
| 137 | count_u++; |
||
| 138 | strcat(lsf_expression, dollarSign); |
||
| 139 | strcat(lsf_expression, tokenPtr1); |
||
| 140 | strcat(lsf_expression, underscore); |
||
| 141 | tokenPtr1 = strtok( NULL, " _"); // read a token |
||
| 142 | strcat(lsf_expression, tokenPtr1); |
||
| 143 | strcat(lsf_expression, underscore); |
||
| 144 | int nodeNumber = atoi( tokenPtr1 ); |
||
| 145 | tokenPtr1 = strtok( NULL, " _"); // read a token |
||
| 146 | strcat(lsf_expression, tokenPtr1); |
||
| 147 | int direction = atoi( tokenPtr1 ); |
||
| 148 | sprintf(tclAssignment,"set nd_%d_%d [nodeDisp %d %d ]",nodeNumber,direction,nodeNumber,direction); |
||
| 149 | Tcl_Eval( theTclInterp, tclAssignment); |
||
| 150 | } |
||
| 151 | else { |
||
| 152 | strcat(lsf_expression, tokenPtr1); |
||
| 153 | } |
||
| 154 | |||
| 155 | tokenPtr1 = strtok( NULL, " _"); // read a token |
||
| 156 | } |
||
| 157 | |||
| 158 | // Assign value of of limit-state function to 'lsfvalue' in Tcl |
||
| 159 | Tcl_ExprDouble( theTclInterp, lsf_expression, &g ); |
||
| 160 | sprintf(tclAssignment,"set lsfvalue %35.20f", g); |
||
| 161 | Tcl_Eval( theTclInterp, tclAssignment); |
||
| 162 | |||
| 163 | // Declaration of quantities used in the gradient computations |
||
| 164 | int nrv = theReliabilityDomain->getNumberOfRandomVariables(); |
||
| 165 | Vector dgdx(nrv); |
||
| 166 | Vector dgdu(count_u); |
||
| 167 | Matrix dudx(count_u, nrv); |
||
| 168 | Vector dgdxufixed(nrv); // this must be initialized to zero: is it??? |
||
| 169 | RandomVariable *theRandomVariable; |
||
| 170 | |||
| 171 | // Tokenize the limit-state function and COMPUTE GRADIENTS |
||
| 172 | count_u = 0; |
||
| 173 | char *tokenPtr2 = strtok( lsf_copy2, " _"); // read first token |
||
| 174 | while ( tokenPtr2 != NULL ) { |
||
| 175 | |||
| 176 | // If a basic random variable is detected |
||
| 177 | if ( strcmp(tokenPtr2, "x") == 0) { |
||
| 178 | tokenPtr2 = strtok( NULL, " _"); // read a token |
||
| 179 | int basicRandomVariableNumber = atoi( tokenPtr2 ); |
||
| 180 | // Get the standard deviation of the random variable |
||
| 181 | theRandomVariable = theReliabilityDomain->getRandomVariablePtr(basicRandomVariableNumber); |
||
| 182 | double stdv = theRandomVariable->getStdv(); |
||
| 183 | // Assign a perturbed value |
||
| 184 | sprintf(tclAssignment , "set x_%d %35.20f", basicRandomVariableNumber, |
||
| 185 | (passed_x(basicRandomVariableNumber-1)+0.005*stdv) ); |
||
| 186 | Tcl_Eval( theTclInterp, tclAssignment); |
||
| 187 | // Evaluate limit-state function again |
||
| 188 | Tcl_ExprDouble( theTclInterp, lsf_expression, &g ); |
||
| 189 | sprintf(tclAssignment,"set lsfperturbed %35.20f", g); |
||
| 190 | Tcl_Eval( theTclInterp, tclAssignment); |
||
| 191 | // Compute the gradient 'dgdxufixed' by finite difference |
||
| 192 | sprintf(tclAssignment , "($lsfperturbed-$lsfvalu)/%35.20f", (0.005*stdv) ); |
||
| 193 | Tcl_ExprDouble( theTclInterp, tclAssignment, &onedgdxufixed ); |
||
| 194 | dgdxufixed(basicRandomVariableNumber-1)=onedgdxufixed; |
||
| 195 | // Make assignment back to its original value |
||
| 196 | sprintf(tclAssignment , "set x_%d %35.20f", basicRandomVariableNumber, passed_x(basicRandomVariableNumber-1) ); |
||
| 197 | Tcl_Eval( theTclInterp, tclAssignment); |
||
| 198 | } |
||
| 199 | |||
| 200 | // If a nodal displacement is detected |
||
| 201 | else if ( strcmp(tokenPtr2, "nd") == 0) { |
||
| 202 | count_u++; |
||
| 203 | tokenPtr2 = strtok( NULL, " _"); // read a token |
||
| 204 | int nodeNumber = atoi( tokenPtr2 ); |
||
| 205 | tokenPtr2 = strtok( NULL, " _"); // read a token |
||
| 206 | int direction = atoi( tokenPtr2 ); |
||
| 207 | // Assign a perturbed value |
||
| 208 | sprintf(tclAssignment,"set nd_%d_%d [ expr [nodeDisp %d %d ]*1.001 ]",nodeNumber,direction,nodeNumber,direction); |
||
| 209 | Tcl_Eval( theTclInterp, tclAssignment); |
||
| 210 | // Evaluate the limit-state function again |
||
| 211 | Tcl_ExprDouble( theTclInterp, lsf_expression, &g ); |
||
| 212 | sprintf(tclAssignment,"set lsfperturbed %35.20f", g); |
||
| 213 | Tcl_Eval( theTclInterp, tclAssignment); |
||
| 214 | // Compute the gradient 'dgdu' by finite difference |
||
| 215 | sprintf(tclAssignment , "($lsfperturbed-$lsfvalue)/([nodeDisp %d %d ]*0.001)",nodeNumber,direction); |
||
| 216 | Tcl_ExprDouble( theTclInterp, tclAssignment, &onedgdu ); |
||
| 217 | dgdu(count_u-1)=onedgdu; |
||
| 218 | // Make assignment back to its original value |
||
| 219 | sprintf(tclAssignment,"set nd_%d_%d [nodeDisp %d %d ]",nodeNumber,direction,nodeNumber,direction); |
||
| 220 | Tcl_Eval( theTclInterp, tclAssignment); |
||
| 221 | // Assign one row in the 'dudx' matrix |
||
| 222 | for (int i=1; i<=nrv; i++) { |
||
| 223 | sprintf(tclAssignment , "set sens [sensNodeDisp %d %d %d ]",nodeNumber,direction,i); |
||
| 224 | Tcl_Eval( theTclInterp, tclAssignment); |
||
| 225 | sprintf(tclAssignment , "$sens "); |
||
| 226 | Tcl_ExprDouble( theTclInterp, tclAssignment, &onedudx ); |
||
| 227 | dudx( (count_u-1), (i-1) ) = onedudx; |
||
| 228 | } |
||
| 229 | |||
| 230 | } |
||
| 231 | |||
| 232 | tokenPtr2 = strtok( NULL, " _"); // read next token and go up and check the while condition again |
||
| 233 | |||
| 234 | } |
||
| 235 | |||
| 236 | // Evaluate the product that yields 'dgdx' |
||
| 237 | Vector temp; |
||
| 238 | temp = dudx ^ dgdu; |
||
| 239 | dgdx = temp + dgdxufixed; |
||
| 240 | |||
| 241 | delete lsf_copy1; |
||
| 242 | delete lsf_copy2; |
||
| 243 | |||
| 244 | (*grad_g) = dgdx; |
||
| 245 | |||
| 246 | return 0; |
||
| 247 | |||
| 248 | } |