SearchWithStepSizeAndStepDirection.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.7 $
00026 // $Date: 2003/10/27 23:45:42 $
00027 // $Source: /usr/local/cvs/OpenSees/SRC/reliability/analysis/designPoint/SearchWithStepSizeAndStepDirection.cpp,v $
00028 
00029 
00030 //
00031 // Written by Terje Haukaas (haukaas@ce.berkeley.edu) 
00032 //
00033 
00034 #include <SearchWithStepSizeAndStepDirection.h>
00035 #include <FindDesignPointAlgorithm.h>
00036 #include <StepSizeRule.h>
00037 #include <SearchDirection.h>
00038 #include <ProbabilityTransformation.h>
00039 #include <NatafProbabilityTransformation.h>
00040 #include <GFunEvaluator.h>
00041 #include <GradGEvaluator.h>
00042 #include <RandomVariable.h>
00043 #include <CorrelationCoefficient.h>
00044 #include <MatrixOperations.h>
00045 #include <HessianApproximation.h>
00046 #include <ReliabilityConvergenceCheck.h>
00047 #include <Matrix.h>
00048 #include <Vector.h>
00049 #include <GammaRV.h>
00050 
00051 #include <fstream>
00052 #include <iomanip>
00053 #include <iostream>
00054 
00055 using std::ifstream;
00056 using std::ios;
00057 
00058 using std::setw;
00059 using std::setprecision;
00060 
00061 
00062 
00063 SearchWithStepSizeAndStepDirection::SearchWithStepSizeAndStepDirection(
00064                                         int passedMaxNumberOfIterations, 
00065                                         GFunEvaluator *passedGFunEvaluator,
00066                                         GradGEvaluator *passedGradGEvaluator,
00067                                         StepSizeRule *passedStepSizeRule,
00068                                         SearchDirection *passedSearchDirection,
00069                                         ProbabilityTransformation *passedProbabilityTransformation,
00070                                         HessianApproximation *passedHessianApproximation,
00071                                         ReliabilityConvergenceCheck *passedReliabilityConvergenceCheck,
00072                                         int pprintFlag,
00073                                         char *pFileNamePrint,
00074                                         Vector *pStartPoint)
00075 :FindDesignPointAlgorithm()
00076 {
00077         maxNumberOfIterations                   = passedMaxNumberOfIterations;
00078         theGFunEvaluator                                = passedGFunEvaluator;
00079         theGradGEvaluator                               = passedGradGEvaluator;
00080         theStepSizeRule                                 = passedStepSizeRule;
00081         theSearchDirection                              = passedSearchDirection;
00082         theProbabilityTransformation    = passedProbabilityTransformation;
00083         theHessianApproximation                 = passedHessianApproximation;
00084         theReliabilityConvergenceCheck  = passedReliabilityConvergenceCheck;
00085         startPoint                                              = pStartPoint;
00086         printFlag                                               = pprintFlag;
00087         numberOfEvaluations =0;
00088         fileNamePrint = new char[256];
00089         if (printFlag != 0) {
00090                 strcpy(fileNamePrint,pFileNamePrint);
00091         }
00092         else {
00093                 strcpy(fileNamePrint,"searchpoints.out");
00094         }
00095 }
00096 
00097 
00098 
00099 SearchWithStepSizeAndStepDirection::~SearchWithStepSizeAndStepDirection()
00100 {
00101         if (fileNamePrint!=0)
00102                 delete [] fileNamePrint;
00103 }
00104 
00105 
00106 int
00107 SearchWithStepSizeAndStepDirection::findDesignPoint(ReliabilityDomain *passedReliabilityDomain)
00108 {
00109 
00110         // Set the reliability domain (a data member of this class)
00111         theReliabilityDomain = passedReliabilityDomain;
00112 
00113         // Declaration of data used in the algorithm
00114         int numberOfRandomVariables = theReliabilityDomain->getNumberOfRandomVariables();
00115         int j;
00116         int zeroFlag;
00117         Vector dummy(numberOfRandomVariables);
00118         x = dummy;
00119         u = dummy;
00120         Vector u_old(numberOfRandomVariables);
00121         uSecondLast(numberOfRandomVariables);
00122         Vector uNew(numberOfRandomVariables);
00123         alpha (numberOfRandomVariables);
00124         gamma (numberOfRandomVariables);
00125         alphaSecondLast(numberOfRandomVariables);
00126         double gFunctionValue = 1.0;
00127         double gFunctionValue_old = 1.0;
00128         Vector gradientOfgFunction(numberOfRandomVariables);
00129         gradientInStandardNormalSpace(numberOfRandomVariables);
00130         Vector gradientInStandardNormalSpace_old(numberOfRandomVariables);
00131         double normOfGradient =0;
00132         double stepSize;
00133         Matrix jacobian_x_u(numberOfRandomVariables,numberOfRandomVariables);
00134         int evaluationInStepSize = 0;
00135         int result;
00136         theGFunEvaluator->initializeNumberOfEvaluations();
00137 
00138         
00139         // Prepare output file to store the search points
00140         ofstream outputFile2( fileNamePrint, ios::out );
00141         if (printFlag == 0) {
00142                 outputFile2 << "The user has not specified to store any search points." << endln;
00143                 outputFile2 << "This is just a dummy file. " << endln;
00144         }
00145 
00146 
00147         if (startPoint == 0) {
00148 
00149                 // Here we want to start at the origin in the standard normal space. 
00150                 // Hence, just leave 'u' as being initialized to zero. 
00151                 // (Note; this is slightly different from the mean point, as done earlier)
00152         }
00153         else {
00154 
00155                 // Get starting point
00156                 x = (*startPoint);
00157 
00158 
00159                 // Transform starting point into standard normal space
00160                 result = theProbabilityTransformation->set_x(x);
00161                 if (result < 0) {
00162                         opserr << "SearchWithStepSizeAndStepDirection::doTheActualSearch() - " << endln
00163                                 << " could not set x in the xu-transformation." << endln;
00164                         return -1;
00165                 }
00166 
00167 
00168                 result = theProbabilityTransformation->transform_x_to_u();
00169                 if (result < 0) {
00170                         opserr << "SearchWithStepSizeAndStepDirection::doTheActualSearch() - " << endln
00171                                 << " could not transform from x to u." << endln;
00172                         return -1;
00173                 }
00174                 u = theProbabilityTransformation->get_u();
00175         }
00176 
00177         // Loop to find design point
00178         i = 1;
00179         while ( i <= maxNumberOfIterations )
00180         {
00181 
00182                 // Transform from u to x space
00183                 result = theProbabilityTransformation->set_u(u);
00184                 if (result < 0) {
00185                         opserr << "SearchWithStepSizeAndStepDirection::doTheActualSearch() - " << endln
00186                                 << " could not set u in the xu-transformation." << endln;
00187                         return -1;
00188                 }
00189 
00190                 result = theProbabilityTransformation->transform_u_to_x_andComputeJacobian();
00191                 if (result < 0) {
00192                         opserr << "SearchWithStepSizeAndStepDirection::doTheActualSearch() - " << endln
00193                                 << " could not transform from u to x and compute Jacobian." << endln;
00194                         return -1;
00195                 }
00196                 x = theProbabilityTransformation->get_x();
00197                 jacobian_x_u = theProbabilityTransformation->getJacobian_x_u();
00198 
00199 
00200                 // Possibly print the point to output file
00201                 int iii;
00202                 if (printFlag != 0) {
00203 
00204                         if (printFlag == 1) {
00205                                 outputFile2.setf(ios::scientific, ios::floatfield);
00206                                 for (iii=0; iii<x.Size(); iii++) {
00207                                         outputFile2<<setprecision(5)<<setw(15)<<x(iii)<<endln;
00208                                 }
00209                         }
00210                         else if (printFlag == 2) {
00211                                 outputFile2.setf(ios::scientific, ios::floatfield);
00212                                 for (iii=0; iii<u.Size(); iii++) {
00213                                         outputFile2<<setprecision(5)<<setw(15)<<u(iii)<<endln;
00214                                 }
00215                         }
00216                 }
00217 
00218 
00219                 // Evaluate limit-state function unless it has been done in 
00220                 // a trial step by the "stepSizeAlgorithm"
00221                 if (evaluationInStepSize == 0) {
00222                         result = theGFunEvaluator->runGFunAnalysis(x);
00223                         if (result < 0) {
00224                                 opserr << "SearchWithStepSizeAndStepDirection::doTheActualSearch() - " << endln
00225                                         << " could not run analysis to evaluate limit-state function. " << endln;
00226                                 return -1;
00227                         }
00228                         result = theGFunEvaluator->evaluateG(x);
00229                         if (result < 0) {
00230                                 opserr << "SearchWithStepSizeAndStepDirection::doTheActualSearch() - " << endln
00231                                         << " could not tokenize limit-state function. " << endln;
00232                                 return -1;
00233                         }
00234                         gFunctionValue_old = gFunctionValue;
00235                         gFunctionValue = theGFunEvaluator->getG();
00236                 }
00237 
00238 
00239                 // Set scale parameter
00240                 if (i == 1)     {
00241                         Gfirst = gFunctionValue;
00242                         opserr << " Limit-state function value at start point, g=" << gFunctionValue << endln;
00243                         opserr << " STEP #0: ";
00244                         theReliabilityConvergenceCheck->setScaleValue(gFunctionValue);
00245                 }
00246 
00247 
00248                 // Gradient in original space
00249                 result = theGradGEvaluator->computeGradG(gFunctionValue,x);
00250                 if (result < 0) {
00251                         opserr << "SearchWithStepSizeAndStepDirection::doTheActualSearch() - " << endln
00252                                 << " could not compute gradients of the limit-state function. " << endln;
00253                         return -1;
00254                 }
00255                 gradientOfgFunction = theGradGEvaluator->getGradG();
00256 
00257 
00258                 // Check if all components of the vector is zero
00259                 zeroFlag = 0;
00260                 for (j=0; j<gradientOfgFunction.Size(); j++) {
00261                         if (gradientOfgFunction[j] != 0.0) {
00262                                 zeroFlag = 1;
00263                         }
00264                 }
00265                 if (zeroFlag == 0) {
00266                         opserr << "SearchWithStepSizeAndStepDirection::doTheActualSearch() - " << endln
00267                                 << " all components of the gradient vector is zero. " << endln;
00268                         return -1;
00269                 }
00270 
00271 
00272                 // Gradient in standard normal space
00273                 gradientInStandardNormalSpace_old = gradientInStandardNormalSpace;
00274                 gradientInStandardNormalSpace = jacobian_x_u ^ gradientOfgFunction;
00275 
00276 
00277                 // Compute the norm of the gradient in standard normal space
00278                 normOfGradient = gradientInStandardNormalSpace.Norm();
00279 
00280 
00281                 // Check that the norm is not zero
00282                 if (normOfGradient == 0.0) {
00283                         opserr << "SearchWithStepSizeAndStepDirection::doTheActualSearch() - " << endln
00284                                 << " the norm of the gradient is zero. " << endln;
00285                         return -1;
00286                 }
00287 
00288                 
00289                 // Compute alpha-vector
00290                 alpha = gradientInStandardNormalSpace *  ( (-1.0) / normOfGradient );
00291 
00292 
00293                 // Check convergence
00294                 result = theReliabilityConvergenceCheck->check(u,gFunctionValue,gradientInStandardNormalSpace);
00295                 if (result > 0)  {
00296                 
00297 
00298                         // Inform the user of the happy news!
00299                         opserr << "Design point found!" << endln;
00300 
00301 
00302                         // Print the design point to file, if desired
00303                         int iii;
00304                         if (printFlag != 0) {
00305                                 if (printFlag == 3) {
00306 
00307                                         result = theProbabilityTransformation->set_u(u);
00308                                         if (result < 0) {
00309                                                 opserr << "SearchWithStepSizeAndStepDirection::doTheActualSearch() - " << endln
00310                                                         << " could not set u in the xu-transformation." << endln;
00311                                                 return -1;
00312                                         }
00313 
00314                                         result = theProbabilityTransformation->transform_u_to_x();
00315                                         if (result < 0) {
00316                                                 opserr << "SearchWithStepSizeAndStepDirection::doTheActualSearch() - " << endln
00317                                                         << " could not transform from u to x." << endln;
00318                                                 return -1;
00319                                         }
00320                                         x = theProbabilityTransformation->get_x();
00321 
00322                                         outputFile2.setf(ios::scientific, ios::floatfield);
00323                                         for (iii=0; iii<x.Size(); iii++) {
00324                                                 outputFile2<<setprecision(5)<<setw(15)<<x(iii)<<endln;
00325                                         }
00326                                 }
00327                                 else if (printFlag == 4) {
00328                                         static ofstream outputFile2( fileNamePrint, ios::out );
00329                                         outputFile2.setf(ios::scientific, ios::floatfield);
00330                                         for (iii=0; iii<u.Size(); iii++) {
00331                                                 outputFile2<<setprecision(5)<<setw(15)<<u(iii)<<endln;
00332                                         }
00333                                 }
00334                         }
00335 
00336 
00337                         // Compute the gamma vector
00338                         MatrixOperations theMatrixOperations(jacobian_x_u);
00339 
00340                         result = theMatrixOperations.computeTranspose();
00341                         if (result < 0) {
00342                                 opserr << "SearchWithStepSizeAndStepDirection::doTheActualSearch() - " << endln
00343                                         << " could not compute transpose of jacobian matrix. " << endln;
00344                                 return -1;
00345                         }
00346                         Matrix transposeOfJacobian_x_u = theMatrixOperations.getTranspose();
00347 
00348                         Matrix jacobianProduct = jacobian_x_u * transposeOfJacobian_x_u;
00349 
00350                         Matrix D_prime(numberOfRandomVariables,numberOfRandomVariables);
00351                         for (j=0; j<numberOfRandomVariables; j++) {
00352                                 D_prime(j,j) = sqrt(jacobianProduct(j,j));
00353                         }
00354 
00355 
00356                         Matrix jacobian_u_x = theProbabilityTransformation->getJacobian_u_x();
00357 
00358                         Vector tempProduct = jacobian_u_x ^ alpha;
00359 
00360                         gamma = D_prime ^ tempProduct;
00361                         
00362                         Glast = gFunctionValue;
00363 
00364                         numberOfEvaluations = theGFunEvaluator->getNumberOfEvaluations();
00365 
00366                         return 1;
00367                 }
00368 
00369 
00370                 // Store 'u' and 'alpha' at the second last iteration point
00371                 uSecondLast = u;
00372                 alphaSecondLast = alpha;
00373 
00374 
00375                 // Let user know that we have to take a new step
00376                 opserr << " STEP #" << i <<": ";
00377 
00378 
00379                 // Update Hessian approximation, if any
00380                 if (  (theHessianApproximation!=0) && (i!=1)  ) {
00381                         theHessianApproximation->updateHessianApproximation(u_old,
00382                                                                                             gFunctionValue_old,
00383                                                                                             gradientInStandardNormalSpace_old,
00384                                                                                             stepSize,
00385                                                                                             searchDirection,
00386                                                                                             gFunctionValue,
00387                                                                                             gradientInStandardNormalSpace);
00388                 }
00389 
00390 
00391                 // Determine search direction
00392                 result = theSearchDirection->computeSearchDirection(i,
00393                         u, gFunctionValue, gradientInStandardNormalSpace );
00394                 if (result < 0) {
00395                         opserr << "SearchWithStepSizeAndStepDirection::doTheActualSearch() - " << endln
00396                                 << " could not compute search direction. " << endln;
00397                         return -1;
00398                 }
00399                 searchDirection = theSearchDirection->getSearchDirection();
00400 
00401 
00402                 // Determine step size
00403                 result = theStepSizeRule->computeStepSize(
00404                         u, gradientInStandardNormalSpace, gFunctionValue, searchDirection, i);
00405                 if (result < 0) {  // (something went wrong)
00406                         opserr << "SearchWithStepSizeAndStepDirection::doTheActualSearch() - " << endln
00407                                 << " could not compute step size. " << endln;
00408                         return -1;
00409                 }
00410                 else if (result == 0) {  // (nothing was evaluated in step size)
00411                         evaluationInStepSize = 0;
00412                 }
00413                 else if (result == 1) {  // (the gfun was evaluated)
00414                         evaluationInStepSize = 1;
00415                         gFunctionValue_old = gFunctionValue;
00416                         gFunctionValue = theStepSizeRule->getGFunValue();
00417                 }
00418                 stepSize = theStepSizeRule->getStepSize();
00419 
00420 
00421                 // Determine new iteration point (take the step)
00422                 u_old = u;
00423                 u = u_old + (searchDirection * stepSize);
00424 
00425 
00426                 // Increment the loop parameter
00427                 i++;
00428 
00429         }
00430 
00431 
00432         // Print a message if max number of iterations was reached
00433         // (Note: in this case the last trial point was never transformed/printed)
00434         opserr << "Maximum number of iterations was reached before convergence." << endln;
00435 
00436         
00437         return -1;
00438 }
00439 
00440 
00441 
00442 Vector
00443 SearchWithStepSizeAndStepDirection::get_x()
00444 {
00445         return x;
00446 }
00447 
00448 Vector
00449 SearchWithStepSizeAndStepDirection::get_u()
00450 {
00451         return u;
00452 }
00453 
00454 Vector
00455 SearchWithStepSizeAndStepDirection::get_alpha()
00456 {
00457         return alpha;
00458 }
00459 
00460 Vector
00461 SearchWithStepSizeAndStepDirection::get_gamma()
00462 {
00463         return gamma*(1.0/gamma.Norm());
00464 }
00465 
00466 int
00467 SearchWithStepSizeAndStepDirection::getNumberOfSteps()
00468 {
00469         return (i-1);
00470 }
00471 
00472 Vector
00473 SearchWithStepSizeAndStepDirection::getSecondLast_u()
00474 {
00475         return uSecondLast;
00476 }
00477 
00478 Vector
00479 SearchWithStepSizeAndStepDirection::getSecondLast_alpha()
00480 {
00481         return alphaSecondLast;
00482 }
00483 
00484 Vector
00485 SearchWithStepSizeAndStepDirection::getLastSearchDirection()
00486 {
00487         return searchDirection;
00488 }
00489 
00490 double
00491 SearchWithStepSizeAndStepDirection::getFirstGFunValue()
00492 {
00493         return Gfirst;
00494 }
00495 
00496 double
00497 SearchWithStepSizeAndStepDirection::getLastGFunValue()
00498 {
00499         return Glast;
00500 }
00501 
00502 
00503 Vector
00504 SearchWithStepSizeAndStepDirection::getGradientInStandardNormalSpace()
00505 {
00506         return gradientInStandardNormalSpace;
00507 }
00508 
00509 
00510 
00511 int
00512 SearchWithStepSizeAndStepDirection::getNumberOfEvaluations()
00513 {
00514         return numberOfEvaluations;
00515 }
00516 
00517 
00518 
00519 
00520 
00521 

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