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
00033
00034 #include <FiniteDifferenceGradGEvaluator.h>
00035 #include <Vector.h>
00036 #include <Matrix.h>
00037 #include <GradGEvaluator.h>
00038 #include <ReliabilityDomain.h>
00039 #include <LimitStateFunction.h>
00040 #include <GFunEvaluator.h>
00041 #include <RandomVariable.h>
00042 #include <tcl.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 FiniteDifferenceGradGEvaluator::FiniteDifferenceGradGEvaluator(
00055 GFunEvaluator *passedGFunEvaluator,
00056 ReliabilityDomain *passedReliabilityDomain,
00057 Tcl_Interp *passedTclInterp,
00058 double passedPerturbationFactor,
00059 bool PdoGradientCheck,
00060 bool pReComputeG)
00061 :GradGEvaluator(passedReliabilityDomain, passedTclInterp)
00062 {
00063 theGFunEvaluator = passedGFunEvaluator;
00064 perturbationFactor = passedPerturbationFactor;
00065 doGradientCheck = PdoGradientCheck;
00066 reComputeG = pReComputeG;
00067
00068 int nrv = passedReliabilityDomain->getNumberOfRandomVariables();
00069 grad_g = new Vector(nrv);
00070 grad_g_matrix = 0;
00071
00072 DgDdispl = 0;
00073 DgDpar = 0;
00074 }
00075
00076 FiniteDifferenceGradGEvaluator::~FiniteDifferenceGradGEvaluator()
00077 {
00078 delete grad_g;
00079
00080 if (DgDdispl != 0)
00081 delete DgDdispl;
00082 if (DgDpar != 0)
00083 delete DgDpar;
00084 if (grad_g_matrix != 0)
00085 delete grad_g_matrix;
00086 }
00087
00088
00089
00090 Vector
00091 FiniteDifferenceGradGEvaluator::getGradG()
00092 {
00093 return (*grad_g);
00094 }
00095
00096
00097
00098
00099 Matrix
00100 FiniteDifferenceGradGEvaluator::getAllGradG()
00101 {
00102 if (grad_g_matrix==0) {
00103 Matrix dummy(1,1);
00104 return dummy;
00105 }
00106 else {
00107 return (*grad_g_matrix);
00108 }
00109 }
00110
00111 int
00112 FiniteDifferenceGradGEvaluator::computeGradG(double gFunValue, Vector passed_x)
00113 {
00114
00115 computeParameterDerivatives(gFunValue);
00116
00117
00118
00119 int result;
00120 if (reComputeG) {
00121 result = theGFunEvaluator->runGFunAnalysis(passed_x);
00122 if (result < 0) {
00123 opserr << "FiniteDifferenceGradGEvaluator::evaluate_grad_g() - " << endln
00124 << " could not run analysis to evaluate limit-state function. " << endln;
00125 return -1;
00126 }
00127 result = theGFunEvaluator->evaluateG(passed_x);
00128 if (result < 0) {
00129 opserr << "FiniteDifferenceGradGEvaluator::evaluate_grad_g() - " << endln
00130 << " could not tokenize limit-state function. " << endln;
00131 return -1;
00132 }
00133 gFunValue = theGFunEvaluator->getG();
00134 }
00135
00136
00137
00138 int numberOfRandomVariables = passed_x.Size();
00139 Vector perturbed_x(numberOfRandomVariables);
00140 RandomVariable *theRandomVariable;
00141 int i;
00142 double h;
00143 double gFunValueAStepAhead;
00144 double stdv;
00145
00146
00147
00148 for ( i=0 ; i<numberOfRandomVariables ; i++ )
00149 {
00150
00151 theRandomVariable = theReliabilityDomain->getRandomVariablePtr(i+1);
00152
00153
00154
00155 stdv = theRandomVariable->getStdv();
00156
00157
00158
00159 h = stdv/perturbationFactor;
00160
00161
00162
00163 perturbed_x = passed_x;
00164 perturbed_x(i) = perturbed_x(i) + h;
00165
00166
00167
00168 result = theGFunEvaluator->runGFunAnalysis(perturbed_x);
00169 if (result < 0) {
00170 opserr << "FiniteDifferenceGradGEvaluator::evaluate_grad_g() - " << endln
00171 << " could not run analysis to evaluate limit-state function. " << endln;
00172 return -1;
00173 }
00174 result = theGFunEvaluator->evaluateG(perturbed_x);
00175 if (result < 0) {
00176 opserr << "FiniteDifferenceGradGEvaluator::evaluate_grad_g() - " << endln
00177 << " could not tokenize limit-state function. " << endln;
00178 return -1;
00179 }
00180 gFunValueAStepAhead = theGFunEvaluator->getG();
00181
00182
00183
00184 (*grad_g)(i) = (gFunValueAStepAhead - gFunValue) / h;
00185 }
00186
00187
00188 if (doGradientCheck) {
00189 char myString[100];
00190 ofstream outputFile( "FFDgradients.out", ios::out );
00191 opserr << endln;
00192 for (int ffd=0; ffd<grad_g->Size(); ffd++) {
00193 opserr << "FFD("<< (ffd+1) << ") = " << (*grad_g)(ffd) << endln;
00194 sprintf(myString,"%20.16e ",(*grad_g)(ffd));
00195 outputFile << myString << endln;
00196 }
00197 outputFile.close();
00198 opserr << "PRESS Ctrl+C TO TERMINATE APPLICATION!" << endln;
00199 while(true) {
00200 }
00201 }
00202
00203 return 0;
00204 }
00205
00206
00207
00208
00209 int
00210 FiniteDifferenceGradGEvaluator::computeAllGradG(Vector gFunValues, Vector passed_x)
00211 {
00212
00213
00214 int nrv = theReliabilityDomain->getNumberOfRandomVariables();
00215 int lsf = theReliabilityDomain->getNumberOfLimitStateFunctions();
00216
00217
00218
00219 if (grad_g_matrix == 0) {
00220 grad_g_matrix = new Matrix(nrv,lsf);
00221 }
00222 else {
00223 grad_g_matrix->Zero();
00224 }
00225
00226
00227
00228 Vector perturbed_x(nrv);
00229 RandomVariable *theRandomVariable;
00230 double h;
00231 double gFunValueAStepAhead;
00232 double stdv;
00233 int result;
00234
00235
00236
00237
00238 for (int i=1; i<=nrv; i++) {
00239
00240
00241 theRandomVariable = theReliabilityDomain->getRandomVariablePtr(i);
00242
00243
00244
00245 stdv = theRandomVariable->getStdv();
00246
00247
00248
00249 h = stdv/perturbationFactor;
00250
00251
00252
00253 perturbed_x = passed_x;
00254 perturbed_x(i-1) = perturbed_x(i-1) + h;
00255
00256
00257
00258 result = theGFunEvaluator->runGFunAnalysis(perturbed_x);
00259 if (result < 0) {
00260 opserr << "FiniteDifferenceGradGEvaluator::evaluate_grad_g() - " << endln
00261 << " could not run analysis to evaluate limit-state function. " << endln;
00262 return -1;
00263 }
00264
00265
00266
00267 for (int j=1; j<=lsf; j++) {
00268
00269
00270 theReliabilityDomain->setTagOfActiveLimitStateFunction(j);
00271
00272
00273 result = theGFunEvaluator->evaluateG(perturbed_x);
00274 if (result < 0) {
00275 opserr << "FiniteDifferenceGradGEvaluator::evaluate_grad_g() - " << endln
00276 << " could not tokenize limit-state function. " << endln;
00277 return -1;
00278 }
00279 gFunValueAStepAhead = theGFunEvaluator->getG();
00280
00281
00282 (*grad_g_matrix)(i-1,j-1) = (gFunValueAStepAhead - gFunValues(j-1)) / h;
00283
00284 }
00285 }
00286
00287 return 0;
00288 }
00289
00290
00291
00292
00293
00294 Matrix
00295 FiniteDifferenceGradGEvaluator::getDgDdispl()
00296 {
00297
00298
00299
00300
00301
00302
00303 Matrix *DgDdispl = 0;
00304
00305
00306
00307 double perturbationFactor = 0.001;
00308 char tclAssignment[500];
00309 char *dollarSign = "$";
00310 char *underscore = "_";
00311 char lsf_expression[500] = "";
00312 char separators[5] = "}{";
00313 char tempchar[100]="";
00314 char newSeparators[5] = "_";
00315 double g, g_perturbed;
00316 int i;
00317
00318
00319 int lsf = theReliabilityDomain->getTagOfActiveLimitStateFunction();
00320 LimitStateFunction *theLimitStateFunction =
00321 theReliabilityDomain->getLimitStateFunctionPtr(lsf);
00322 char *theExpression = theLimitStateFunction->getExpression();
00323 char *lsf_copy = new char[500];
00324 strcpy(lsf_copy,theExpression);
00325
00326
00327
00328 char *tokenPtr = strtok( lsf_copy, separators);
00329 while ( tokenPtr != NULL ) {
00330
00331 strcpy(tempchar,tokenPtr);
00332
00333
00334 if ( strncmp(tokenPtr, "u", 1) == 0) {
00335
00336
00337 int nodeNumber, direction;
00338 sscanf(tempchar,"u_%i_%i", &nodeNumber, &direction);
00339
00340
00341 char *theTokenizedExpression = theLimitStateFunction->getTokenizedExpression();
00342 Tcl_ExprDouble( theTclInterp, theTokenizedExpression, &g );
00343
00344
00345 double originalValue;
00346 sprintf(tclAssignment,"$u_%d_%d", nodeNumber, direction);
00347 Tcl_ExprDouble( theTclInterp, tclAssignment, &originalValue);
00348
00349
00350 double newValue = originalValue*(1.0+perturbationFactor);
00351 sprintf(tclAssignment,"set u_%d_%d %35.20f", nodeNumber, direction, newValue);
00352 Tcl_Eval( theTclInterp, tclAssignment);
00353
00354
00355 Tcl_ExprDouble( theTclInterp, theTokenizedExpression, &g_perturbed );
00356
00357
00358 double onedgdu = (g_perturbed-g)/(originalValue*perturbationFactor);
00359
00360
00361 if (DgDdispl == 0) {
00362 DgDdispl = new Matrix(1, 3);
00363 (*DgDdispl)(0,0) = (double)nodeNumber;
00364 (*DgDdispl)(0,1) = (double)direction;
00365 (*DgDdispl)(0,2) = onedgdu;
00366 }
00367 else {
00368 int oldSize = DgDdispl->noRows();
00369 Matrix tempMatrix = *DgDdispl;
00370 delete DgDdispl;
00371 DgDdispl = new Matrix(oldSize+1, 3);
00372 for (i=0; i<oldSize; i++) {
00373 (*DgDdispl)(i,0) = tempMatrix(i,0);
00374 (*DgDdispl)(i,1) = tempMatrix(i,1);
00375 (*DgDdispl)(i,2) = tempMatrix(i,2);
00376 }
00377 (*DgDdispl)(oldSize,0) = (double)nodeNumber;
00378 (*DgDdispl)(oldSize,1) = (double)direction;
00379 (*DgDdispl)(oldSize,2) = onedgdu;
00380 }
00381
00382
00383
00384 sprintf(tclAssignment,"set u_%d_%d %35.20f", nodeNumber, direction, originalValue);
00385 Tcl_Eval( theTclInterp, tclAssignment);
00386
00387
00388 }
00389
00390 tokenPtr = strtok( NULL, separators);
00391 }
00392
00393 delete [] lsf_copy;
00394
00395 return (*DgDdispl);
00396 }
00397