PolakHeSearchDirectionAndMeritFunction.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:42 $
00027 // $Source: /usr/local/cvs/OpenSees/SRC/reliability/analysis/direction/PolakHeSearchDirectionAndMeritFunction.cpp,v $
00028 
00029 
00030 //
00031 // Written by Terje Haukaas (haukaas@ce.berkeley.edu) 
00032 //
00033 
00034 #include <PolakHeSearchDirectionAndMeritFunction.h>
00035 #include <SearchDirection.h>
00036 #include <MeritFunctionCheck.h>
00037 #include <Vector.h>
00038 
00039 
00040 PolakHeSearchDirectionAndMeritFunction::PolakHeSearchDirectionAndMeritFunction(double pgamma, double pdelta)
00041 :SearchDirection(), MeritFunctionCheck()
00042 {
00043         gamma = pgamma;
00044         delta = pdelta;
00045         alpha = 0.0;
00046 }
00047 
00048 PolakHeSearchDirectionAndMeritFunction::~PolakHeSearchDirectionAndMeritFunction()
00049 {
00050 }
00051 
00052 
00053 
00054 
00055 Vector
00056 PolakHeSearchDirectionAndMeritFunction::getSearchDirection()
00057 {
00058         return searchDirection;
00059 }
00060 
00061 
00062 int
00063 PolakHeSearchDirectionAndMeritFunction::setAlpha(double palpha)
00064 {
00065         alpha = palpha;
00066         
00067         return 0;
00068 }
00069 
00070 
00071 
00072 int
00073 PolakHeSearchDirectionAndMeritFunction::computeSearchDirection(
00074                                                         int stepNumber, 
00075                                                         Vector u, 
00076                                                         double gFunctionValue, 
00077                                                         Vector gradientInStandardNormalSpace)
00078 {
00079         // Advise the user if the start value of the limit-state function 
00080         // is out of the 'ideal range' for the Polak-He algorithm
00081         if (stepNumber == 1) {
00082                 if (gFunctionValue > 15.0 || gFunctionValue < 2.0) {
00083                         opserr << "WARNING: The start value of the limit-state function is outside " << endln
00084                                 << " the ideal range for fastest convergence of the Polak-He algorithm. " << endln;
00085                 }
00086         }
00087 
00088         // Compute elements of the A matrix
00089         double oneOverDelta = 1.0/delta;
00090         double a11 = oneOverDelta * (u ^ u);
00091         double a22 = oneOverDelta * (gradientInStandardNormalSpace ^ gradientInStandardNormalSpace);
00092         double a12 = oneOverDelta * (u ^ gradientInStandardNormalSpace); 
00093 
00094 
00095         // Compute the elements of the b vector:
00096         double b1;
00097         if (gFunctionValue <= 0.0) {
00098                 b1 = 0.0;
00099         }
00100         else {
00101                 b1 = gFunctionValue;
00102         }
00103         double b2 = b1 - gFunctionValue;
00104         b1 = gamma*b1;
00105 
00106 
00107         // Compute factors of second order equation
00108         double a = 0.5*a11 + 0.5*a22 - a12;
00109         double b = b1 - b2 + a12 - a22;
00110         double c = 0.5*a22 + b2;
00111 
00112 
00113         // Find coordinates of minimum point [z1 z2]
00114         double z1, z2;
00115         if (a<0.0) {
00116                 opserr << "ERROR: PolakHeSearchDirectionAndMeritFunction::computeSearchDirection() " << endln
00117                         << " the quadratic term is negative! " << endln;
00118                 return -1;
00119         }
00120         else if (a < 1.0e-9) {
00121 
00122                 // Here the quadratic term is zero, so we use one of the endpoints
00123                 double Fend1 = c;     // x=0.0
00124                 double Fend2 = a+b+c; // x=1.0
00125 
00126                 if (Fend1 < Fend2) {
00127                         z1 = 0.0;
00128                         z2 = 1.0;
00129                         thetaFunction = -Fend1;
00130                 }
00131                 else {
00132                         z1 = 1.0;
00133                         z2 = 0.0;
00134                         thetaFunction = -Fend2;
00135                 }
00136         }
00137         else {
00138 
00139                 // The 'normal' case
00140                 double x = -b/(2.0*a);
00141                 z1 = x;
00142                 z2 = 1.0 - x;
00143                 thetaFunction = -(a*x*x + b*x + c);
00144 
00145 
00146 
00147                 // Check if the minimum point is outside the 'triangle'
00148                 if (z1 < 0.0 || z1 > 1.0 || z2 < 0.0 || z2 > 1.0 ) {
00149 
00150                         // Use one of the endpoints
00151                         double Fend1 = c;     // x=0.0
00152                         double Fend2 = a+b+c; // x=1.0
00153 
00154                         if (Fend1 < Fend2) {
00155                                 z1 = 0.0;
00156                                 z2 = 1.0;
00157                                 thetaFunction = -Fend1;
00158                         }
00159                         else {
00160                                 z1 = 1.0;
00161                                 z2 = 0.0;
00162                                 thetaFunction = -Fend2;
00163                         }
00164                 }
00165         }
00166 
00167 
00168         // With the coordinates of the minimum point the direction now reads
00169         searchDirection = -z1*u - z2*gradientInStandardNormalSpace;
00170         
00171         return 0;
00172 }
00173 
00174 
00175 
00176 
00177 double 
00178 PolakHeSearchDirectionAndMeritFunction::getMeritFunctionValue(Vector u, double g, Vector grad_G)
00179 {
00180         opserr << "WARNING: PolakHeSearchDirectionAndMeritFunction::getMeritFunctionValue() --" << endln
00181                 << " no explicit merit function value is computed." << endln;
00182         return 0.0;
00183 }
00184 
00185 
00186 
00187 int 
00188 PolakHeSearchDirectionAndMeritFunction::updateMeritParameters(Vector u, double g, Vector grad_G)
00189 {
00190         opserr << "WARNING: PolakHeSearchDirectionAndMeritFunction::updateMeritParameters() --" << endln
00191                 << " no explicit merit function value is computed." << endln;
00192 
00193         return 0;
00194 }
00195 
00196 
00197 
00198 
00199 int
00200 PolakHeSearchDirectionAndMeritFunction::check(Vector u_old, 
00201                                                                                           double g_old, 
00202                                                                                           Vector grad_G_old, 
00203                                                                                           double stepSize,
00204                                                                                           Vector stepDirection,
00205                                                                                           double g_new)
00206 {
00207         // New point in standard normal space
00208         Vector u_new = u_old + stepSize*stepDirection;
00209 
00210         // Check that the factor alpha is set (since this is a dual purpose class...)
00211         if (alpha == 0.0) {
00212                 opserr << "ERROR: PolakHeSearchDirectionAndMeritFunction::check()" << endln
00213                         << " the alpha factor is not set! " << endln;
00214         }
00215 
00216 
00217         // Determine the 'g plus' value
00218         double g_old_plus;
00219         if (g_old <= 0.0 ) {
00220                 g_old_plus = 0.0;
00221         }
00222         else {
00223                 g_old_plus = g_old;
00224         }
00225         
00226 
00227         // Evaluate the 'merit' function
00228         double term1 = 0.5*(u_new^u_new) - 0.5*(u_old^u_old) - gamma * g_old_plus;
00229         double term2 = g_new - g_old_plus;
00230         double F;
00231         if (term1 > term2) {
00232                 F = term1;
00233         }
00234         else {
00235                 F = term2;
00236         }
00237 
00238 
00239         // Do the check
00240         if (  F  <=  (alpha*stepSize*thetaFunction)  ) {
00241                 return 0;  // ok
00242         }
00243         else {
00244                 return -1; // not ok
00245         }
00246         
00247 }

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