SecantRootFinding.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.1 $
00026 // $Date: 2003/03/04 00:39:31 $
00027 // $Source: /usr/local/cvs/OpenSees/SRC/reliability/analysis/rootFinding/SecantRootFinding.cpp,v $
00028 
00029 
00030 //
00031 // Written by Terje Haukaas (haukaas@ce.berkeley.edu) 
00032 //
00033 
00034 #include <SecantRootFinding.h>
00035 #include <RootFinding.h>
00036 #include <GFunEvaluator.h>
00037 #include <ProbabilityTransformation.h>
00038 #include <ReliabilityDomain.h>
00039 #include <RandomVariable.h>
00040 #include <math.h>
00041 #include <Vector.h>
00042 
00043 
00044 SecantRootFinding::SecantRootFinding(
00045                                                 ReliabilityDomain *passedReliabilityDomain,
00046                                                 ProbabilityTransformation *passedProbabilityTransformation,
00047                                                 GFunEvaluator *passedGFunEvaluator,
00048                                                 int passedMaxIter,
00049                                                 double ptol,
00050                                                 double pmaxStepLength)
00051 :RootFinding()
00052 {
00053         theReliabilityDomain = passedReliabilityDomain;
00054         theProbabilityTransformation = passedProbabilityTransformation;
00055         theGFunEvaluator = passedGFunEvaluator;
00056         maxIter = passedMaxIter;
00057         tol = ptol;
00058         maxStepLength = pmaxStepLength;
00059 }
00060 
00061 SecantRootFinding::~SecantRootFinding()
00062 {
00063 }
00064 
00065 
00066 Vector
00067 SecantRootFinding::findLimitStateSurface(int space, double g, Vector pDirection, Vector thePoint)
00068 {
00069         // Set scale factor for 'g' for convergence check
00070         double scaleG;
00071         if (fabs(g)>1.0e-4) { scaleG = g;}
00072         else {          scaleG = 1.0;}
00073 
00074         // Normalize the direction vector
00075         Vector Direction = pDirection/pDirection.Norm();
00076 
00077         // Scale 'maxStepLength' by standard deviation
00078         // (only if the user has specified to "walk" in original space)
00079         double perturbation;
00080         double realMaxStepLength = maxStepLength;
00081         if (space == 1) {
00082 
00083                 // Go through direction vector and see which element is biggest
00084                 // compared to its standard deviation
00085                 int nrv = theReliabilityDomain->getNumberOfRandomVariables();
00086                 RandomVariable *theRV;
00087                 double stdv, theStdv;
00088                 int theBiggest;
00089                 double maxRatio = 0.0;
00090                 for (int i=0; i<nrv; i++) {
00091                         theRV = theReliabilityDomain->getRandomVariablePtr(i+1);
00092                         stdv = theRV->getStdv();
00093                         if (Direction(i)/stdv > maxRatio) {
00094                                 maxRatio = Direction(i)/stdv;
00095                                 theStdv = stdv;
00096                                 theBiggest = i+1;
00097                         }
00098                 }
00099 
00100                 // Now scale so that 'maxStepSize' is related to the real stdv
00101                 perturbation = maxStepLength * theStdv;
00102                 realMaxStepLength = perturbation;
00103         }
00104         else {
00105                 perturbation = maxStepLength;
00106         }
00107 
00108         Vector theTempPoint;
00109         double g_old, g_new;
00110         bool didNotConverge=true;
00111         double result;
00112         double tangent;
00113 
00114 
00115         int i=0;
00116         while (i<=maxIter && didNotConverge) {
00117 
00118 
00119                 // Increment counter right away...
00120                 i++;
00121 
00122                 if (i!=1) {
00123 
00124                         // Transform the point into x-space if the user has given it in 2-space
00125                         if (space==2) {
00126                                 result = theProbabilityTransformation->set_u(thePoint);
00127                                 if (result < 0) {
00128                                         opserr << "GFunVisualizationAnalysis::analyze() - " << endln
00129                                                 << " could not set u in the xu-transformation." << endln;
00130                                         return -1;
00131                                 }
00132 
00133                                 result = theProbabilityTransformation->transform_u_to_x();
00134                                 if (result < 0) {
00135                                         opserr << "GFunVisualizationAnalysis::analyze() - " << endln
00136                                                 << " could not transform from u to x and compute Jacobian." << endln;
00137                                         return -1;
00138                                 }
00139                                 theTempPoint = theProbabilityTransformation->get_x();
00140                         }
00141                         else {
00142                                 theTempPoint = thePoint;
00143                         }
00144 
00145 
00146                         // Evaluate limit-state function
00147                         result = theGFunEvaluator->runGFunAnalysis(theTempPoint);
00148                         if (result < 0) {
00149                                 opserr << "GFunVisualizationAnalysis::analyze() - " << endln
00150                                         << " could not run analysis to evaluate limit-state function. " << endln;
00151                                 return -1;
00152                         }
00153                         result = theGFunEvaluator->evaluateG(theTempPoint);
00154                         if (result < 0) {
00155                                 opserr << "GFunVisualizationAnalysis::analyze() - " << endln
00156                                         << " could not tokenize limit-state function. " << endln;
00157                                 return -1;
00158                         }
00159                         g_new = theGFunEvaluator->getG();
00160                 }
00161                 else {
00162                         g_new = g;
00163                 }
00164 
00165                 
00166 
00167                 // Check convergence
00168                 if (fabs(g_new/scaleG) < tol) {
00169                         didNotConverge = false;
00170                 }
00171                 else {
00172                         if (i==maxIter) {
00173                                 opserr << "WARNING: Projection scheme failed to find surface..." << endln;
00174                         }
00175                         else if (i==1) {
00176                                 thePoint = thePoint - perturbation * Direction;
00177                                 g_old = g_new;
00178                         }
00179                         else {
00180 
00181                                 // Take a step
00182                                 tangent = (g_new-g_old)/perturbation;
00183                                 perturbation = -g_new/tangent;
00184                                 if (fabs(perturbation) > realMaxStepLength) {
00185                                         perturbation = perturbation/fabs(perturbation)*realMaxStepLength;
00186                                 }
00187                                 thePoint = thePoint - perturbation * Direction;
00188                                 g_old = g_new;
00189                         }
00190                 }
00191         }
00192 
00193         return thePoint;
00194 }
00195 
00196 

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