FragilityAnalysis.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.4 $
00026 // $Date: 2003/04/28 20:51:25 $
00027 // $Source: /usr/local/cvs/OpenSees/SRC/reliability/analysis/analysis/FragilityAnalysis.cpp,v $
00028 
00029 
00030 //
00031 // Written by Terje Haukaas (haukaas@ce.berkeley.edu)
00032 //
00033 
00034 #include <FragilityAnalysis.h>
00035 #include <ReliabilityAnalysis.h>
00036 #include <ReliabilityDomain.h>
00037 #include <FindDesignPointAlgorithm.h>
00038 #include <GradGEvaluator.h>
00039 #include <ParameterPositioner.h>
00040 #include <NormalRV.h>
00041 #include <tcl.h>
00042 
00043 #include <fstream>
00044 #include <iomanip>
00045 #include <iostream>
00046 using std::ifstream;
00047 using std::ios;
00048 using std::setw;
00049 using std::setprecision;
00050 using std::setiosflags;
00051 
00052 FragilityAnalysis::FragilityAnalysis(ReliabilityDomain *passedReliabilityDomain,
00053                                                                          FindDesignPointAlgorithm *passedFindDesignPointAlgorithm,
00054                                                                          GradGEvaluator *passedGradGEvaluator,
00055                                                                          int pParameterNumber,
00056                                                                          double pFirst,
00057                                                                          double pLast,
00058                                                                          int pNumIntervals,
00059                                                                          const char *passedFileName,
00060                                                                          Tcl_Interp *passedTclInterp)
00061 :ReliabilityAnalysis()
00062 {
00063         parameterNumber = pParameterNumber;
00064         first = pFirst;
00065         last = pLast;
00066         numIntervals = pNumIntervals;
00067 
00068         theReliabilityDomain = passedReliabilityDomain;
00069         theFindDesignPointAlgorithm = passedFindDesignPointAlgorithm;
00070         theGradGEvaluator = passedGradGEvaluator;
00071 
00072         fileName = new char[256];
00073         strcpy(fileName,passedFileName);
00074 
00075         theTclInterp = passedTclInterp;
00076 }
00077 
00078 
00079 FragilityAnalysis::~FragilityAnalysis()
00080 {
00081         if (fileName != 0)
00082         delete [] fileName;
00083 }
00084 
00085 
00086 
00087 int 
00088 FragilityAnalysis::analyze(void)
00089 {
00090         
00091         // Alert the user that the FORM analysis has started
00092         opserr << "Fragility Analysis is running ... " << endln;
00093 
00094 
00095         // The relevant commands are now, for instance, given like this
00096         // performanceFunction 1 "{par_1}-{u_7_1}"
00097         // runFragilityAnalysis output.out -par 1 -range 14.0 16.0 -num 10
00098 
00099 
00100         // Open output file
00101         ofstream outputFile( fileName, ios::out );
00102 
00103 
00104         // Get number of limit-state functions
00105         int numLsf = theReliabilityDomain->getNumberOfLimitStateFunctions();
00106 
00107         // Initial declarations
00108         Vector pf(numIntervals+1);
00109         Vector pdf(numIntervals+1);
00110         Vector uStar, alpha;
00111         double beta;
00112         NormalRV aStdNormRV(1,0.0,1.0,0.0);
00113         Matrix dGdPar;
00114         int numPars;
00115         double thedGdPar;
00116         Vector gradient;
00117         double currentValue;
00118         Vector currentValues(numIntervals+1);
00119         int numPos;
00120         ParameterPositioner *theParameterPositioner = 0;
00121 
00122 
00123         // Loop over number of limit-state functions and perform FORM analysis
00124         int lsf = 1; // Boris Jeremic moved this out of the loop since it is
00125               // non-portable (C++ standard is violated) to change loop counter in the loop (lsf)
00126  for ( ; lsf<=numLsf; lsf++ ) {
00127 
00128 
00129                 // Inform the user which limit-state function is being evaluated
00130                 opserr << "Limit-state function number: " << lsf << endln;
00131 
00132 
00133                 // Set tag of "active" limit-state function
00134                 theReliabilityDomain->setTagOfActiveLimitStateFunction(lsf);
00135 
00136 
00137                 // "Download" limit-state function from reliability domain
00138                 int lsf = theReliabilityDomain->getTagOfActiveLimitStateFunction();
00139                 LimitStateFunction *theLimitStateFunction = theReliabilityDomain->getLimitStateFunctionPtr(lsf);
00140                 if (theLimitStateFunction == 0) {
00141                         opserr << "FragilityAnalysis::analyze() - could not find" << endln
00142                                 << " limit-state function with tag #" << lsf << "." << endln;
00143                         return -1;
00144                 }
00145 
00146 
00147                 // Print results to output file
00148                 outputFile << "#######################################################################" << endln;
00149                 outputFile << "#  FORM ANALYSIS RESULTS, LIMIT-STATE FUNCTION NUMBER "
00150                         <<setiosflags(ios::left)<<setprecision(1)<<setw(4)<<lsf <<"            #" << endln;
00151                 outputFile << "#                                                                     #" << endln;
00152                 outputFile << "#                                                                     #" << endln;
00153                 outputFile << "#                    Failure probability     Estimated probability    #" << endln;
00154                 outputFile << "#    Parameter       estimate (fragility)     densitity function      #" << endln;
00155                 outputFile << "#     value               (CDF)                    (PDF)              #" << endln;
00156                 outputFile.setf(ios::scientific, ios::floatfield);
00157                 outputFile.flush();
00158 
00159 
00160                 // Range over parameter values
00161                 currentValue = first;
00162                 for (int counter=0; counter<(numIntervals+1); counter++) {
00163 
00164                         currentValues(counter) = currentValue;
00165 
00166                         // Detect parameter and set value, first the 
00167                         // case where the parameter is represented by a 
00168                         // parameterPositioner
00169                         numPos = theReliabilityDomain->getNumberOfParameterPositioners();
00170                         if (numPos != 0) {
00171                                 theParameterPositioner = theReliabilityDomain->getParameterPositionerPtr(parameterNumber);
00172                                 if (theParameterPositioner == 0) {
00173                                         opserr << "FragilityAnalysis::analyze() -- The parameter number in the " << endln
00174                                                 << " fragility analysis object does not match the parameter number " << endln
00175                                                 << " being set by the parameter positioner." << endln;
00176                                 }
00177                         }
00178                         else {
00179                                 char separators[5] = "_}{";
00180                                 char *theExpression = theLimitStateFunction->getExpression();
00181                                 char *lsf_forTokenizing = new char[1000];
00182                                 strcpy(lsf_forTokenizing,theExpression);
00183                                 char *tokenPtr = strtok( lsf_forTokenizing, separators);
00184                                 while ( tokenPtr != NULL ) {
00185                                         if ( strcmp(tokenPtr, "par") == 0) {
00186                                                 tokenPtr = strtok( NULL, separators);
00187                                                 int par = atoi( tokenPtr );
00188                                                 if (par==parameterNumber) {
00189                                                         char tclAssignment[100];
00190                                                         sprintf(tclAssignment , "set par_%d  %15.5f", parameterNumber, currentValue);
00191                                                         Tcl_Eval( theTclInterp, tclAssignment);
00192                                                 }
00193                                                 else {
00194                                                         opserr << "FragilityAnalysis::analyze() -- The parameter number " << endln
00195                                                                 << " in the limit-state function does not match the parameter " << endln
00196                                                                 << " number in the fragility analysis object." << endln;
00197                                                 }
00198                                         }
00199                                         tokenPtr = strtok( NULL, separators);
00200                                 }
00201                         }
00202 
00203 
00204                         // Possibly set the parameter value in the FE domain
00205                         if (theParameterPositioner != 0) {
00206                                 theParameterPositioner->update(currentValue);
00207                         }
00208 
00209 
00210                         // Find the design point
00211                         if (theFindDesignPointAlgorithm->findDesignPoint(theReliabilityDomain) < 0){
00212 
00213                                 // Set detectable 'crazy' values when the design point wasn't found
00214                                 pf(counter) = -1.0;
00215                                 pdf(counter) = -1.0;
00216                         }
00217                         else {
00218 
00219                                 // Store probability of failure
00220                                 uStar                           = theFindDesignPointAlgorithm->get_u();
00221                                 alpha                           = theFindDesignPointAlgorithm->get_alpha();
00222                                 beta = alpha ^ uStar;
00223                                 pf(counter) = 1.0 - aStdNormRV.getCDFvalue(beta);
00224 
00225                                 // Compute PDF, first; derivative of lsf wrt. parameter
00226                                 dGdPar = theGradGEvaluator->getDgDpar();
00227 
00228                                 // Find the right element
00229                                 numPars = dGdPar.noRows();
00230                                 for (int i=0; i<numPars; i++) {
00231                                         if (((int)(dGdPar(i,0))) == parameterNumber) {
00232                                                 thedGdPar = dGdPar(i,1);
00233                                         }
00234                                 }
00235 
00236                                 // Gradient of limit-state function
00237                                 gradient = theFindDesignPointAlgorithm->getGradientInStandardNormalSpace();
00238 
00239                                 // Compute PDF value
00240                                 pdf(counter) = aStdNormRV.getPDFvalue(-beta) / gradient.Norm() * thedGdPar;
00241 
00242                         }
00243 
00244                         currentValue = currentValue + (last-first)/numIntervals;
00245 
00246 
00247                         // Print results to output file
00248                         outputFile << "#   " << setprecision(3)<<setw(11)<<currentValues(counter)<<"         ";
00249                         if (pf(counter)==-1.0) {
00250                                 outputFile << "--failed--              ";
00251                                 outputFile << "--failed--            #" << endln;
00252                         }
00253                         else {
00254                                 outputFile <<setprecision(3)<<setw(11)<<pf(counter)<<"             ";
00255                                 outputFile <<setprecision(3)<<setw(11)<<pdf(counter)<<"           #" << endln;
00256                         }
00257                         outputFile.flush();
00258 
00259                 } // Done looping over parameter range
00260 
00261 
00262                 outputFile << "#                                                                     #" << endln;
00263                 outputFile << "#######################################################################" << endln << endln << endln;
00264 
00265         } // Done looping over limit-state functions
00266                 
00267 
00268         // Print summary of results to screen (more here!!!)
00269         opserr << "Fragility Analysis completed." << endln;
00270 
00271 
00272         // Clean up
00273         outputFile.close();
00274 
00275         return 0;
00276 }
00277 

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