OutCrossingAnalysis.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/10/27 23:45:41 $
00027 // $Source: /usr/local/cvs/OpenSees/SRC/reliability/analysis/analysis/OutCrossingAnalysis.cpp,v $
00028 
00029 //
00030 // Written by Terje Haukaas (haukaas@ce.berkeley.edu)
00031 //
00032 
00033 #include <OutCrossingAnalysis.h>
00034 #include <ReliabilityAnalysis.h>
00035 #include <ReliabilityDomain.h>
00036 #include <GFunEvaluator.h>
00037 #include <GradGEvaluator.h>
00038 #include <FindDesignPointAlgorithm.h>
00039 #include <math.h>
00040 #include <tcl.h>
00041 #include <string.h>
00042 #include <NormalRV.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 OutCrossingAnalysis::OutCrossingAnalysis(
00055                                 ReliabilityDomain *theRelDom,
00056                                 GFunEvaluator *theGFunEval,
00057                                 GradGEvaluator *theSensEval,
00058                                 FindDesignPointAlgorithm *theFindDesPt,
00059                                 int pAnalysisType,
00060                                 int p_stepsToStart,
00061                                 int p_stepsToEnd,
00062                                 int p_sampleFreq,
00063                                 double p_littleDeltaT,
00064                                 TCL_Char *passedFileName)
00065 :ReliabilityAnalysis()
00066 {
00067         theFindDesignPointAlgorithm = theFindDesPt;
00068         theReliabilityDomain = theRelDom;
00069         theGFunEvaluator = theGFunEval;
00070         theGradGEvaluator = theSensEval;
00071         analysisType = pAnalysisType;
00072         stepsToStart = p_stepsToStart;
00073         stepsToEnd = p_stepsToEnd;
00074         sampleFreq = p_sampleFreq;
00075         littleDeltaT = p_littleDeltaT;
00076         fileName = new char[256];
00077         strcpy(fileName,passedFileName);
00078 }
00079 
00080 OutCrossingAnalysis::~OutCrossingAnalysis()
00081 {
00082         if (fileName != 0)
00083                 delete [] fileName;
00084 }
00085 
00086 int 
00087 OutCrossingAnalysis::analyze(void)
00088 {
00089 
00090         // Alert the user that the analysis has started
00091         opserr << "Out-Crossing Analysis is running ... " << endln;
00092 
00093         // Declare variables used in this method
00094         int numRV = theReliabilityDomain->getNumberOfRandomVariables();
00095         int numLsf = theReliabilityDomain->getNumberOfLimitStateFunctions();
00096         LimitStateFunction *theLimitStateFunction;
00097         NormalRV aStdNormRV(1,0.0,1.0,0.0);
00098         Matrix DgDdispl;
00099         int numVel, i, j, k, kk, nodeNumber, dofNumber, lsf; 
00100         double dgduValue, accuSum;
00101         Vector uStar, uStar2;
00102         Vector alpha(numRV), alpha2(numRV), alpha_k(numRV), alpha_kk(numRV);
00103         double beta1, beta2;
00104         double pf1, pf2;
00105         int n_2;
00106         double a, b, integral, h, fa, fb, sum_fx2j, sum_fx2j_1, Pmn1;
00107         char string[500];
00108 
00109 
00110         // Determine number of points
00111         double nsteps = stepsToEnd-stepsToStart;
00112         int numPoints = (int)floor(nsteps/sampleFreq);
00113         numPoints++;
00114         double dt = theGFunEvaluator->getDt();
00115         double Dt = dt*sampleFreq;
00116         double T = dt*sampleFreq*numPoints;
00117 
00118 
00119         // Allocate reult vectors
00120         Vector nu(numPoints);
00121         Vector ED(numPoints);
00122         Vector pf(numPoints);
00123         Vector beta(numPoints);
00124         Matrix Pmn2(numPoints,numPoints);
00125         Matrix allAlphas(numRV,numPoints);
00126 
00127 
00128         // Open output file and start writing to it
00129         ofstream outputFile( fileName, ios::out );
00130 
00131 
00132         // Loop over number of limit-state functions and perform analysis
00133         for (lsf=1; lsf<=numLsf; lsf++ ) {
00134 
00135 
00136                 // Inform the user which limit-state function is being evaluated
00137                 opserr << "Limit-state function number: " << lsf << endln;
00138 
00139 
00140                 // Start printing results to the output file
00141                 outputFile << "########################################################R##############" << endln;
00142                 outputFile << "#  OUT-CROSSING RESULTS, LIMIT-STATE FUNCTION NUMBER      "
00143                         <<setiosflags(ios::left)<<setprecision(1)<<setw(4)<<lsf <<"        #" << endln;
00144                 outputFile << "#                                                                     #" << endln;
00145 
00146 
00147 
00148                 // Set tag of "active" limit-state function
00149                 theReliabilityDomain->setTagOfActiveLimitStateFunction(lsf);
00150 
00151 
00152                 // Get the limit-state function pointer
00153                 theLimitStateFunction = 0;
00154                 lsf = theReliabilityDomain->getTagOfActiveLimitStateFunction();
00155                 theLimitStateFunction = theReliabilityDomain->getLimitStateFunctionPtr(lsf);
00156                 if (theLimitStateFunction == 0) {
00157                         opserr << "OutCrossingAnalysis::analyze() - could not find" << endln
00158                                 << " limit-state function with tag #" << lsf << "." << endln;
00159                         return -1;
00160                 }
00161 
00162 
00163                 // Loop over the intervals where probabilities are to be computed
00164                 bool oneFailed = false;
00165                 bool DSPTfailed;
00166                 for (i=1; i<=numPoints; i++) {
00167 
00168                         // First assume that we find the design point(s)
00169                         DSPTfailed = false;
00170 
00171                         // Set 'nsteps' in the GFunEvaluator 
00172                         theGFunEvaluator->setNsteps(stepsToStart+(i-1)*sampleFreq);
00173 
00174 
00175                         // Inform the user
00176                         char printTime[10];
00177                         sprintf(printTime, "%5.3f", ((stepsToStart+(i-1)*sampleFreq)*dt) );
00178                         if (analysisType == 1) {
00179                                 strcpy(string,theLimitStateFunction->getExpression());
00180                                 opserr << " ...evaluating -G1=" << string << " at time " << printTime << " ..." << endln;
00181                         }
00182                         else {
00183                                 opserr << " ...evaluating performance function at time " << printTime << " ..." << endln;
00184                         }
00185 
00186 
00187                         // Find the design point for the original limit-state function
00188                         if (theFindDesignPointAlgorithm->findDesignPoint(theReliabilityDomain) < 0){
00189                                 opserr << "OutCrossingAnalysis::analyze() - failed while finding the" << endln
00190                                         << " design point for limit-state function number " << lsf << "." << endln;
00191                                 DSPTfailed = true;
00192                                 oneFailed = true;
00193                         }
00194 
00195 
00196                         // Start writing to output file
00197                         if (i==1) {
00198                                 outputFile << "#         Reliability    Estimated         Mean         Duration      #" << endln;
00199                                 outputFile << "#           index         failure       out-crossing    of single     #" << endln;
00200                                 outputFile << "#  Time      beta        probability       rate         excursion     #" << endln;
00201                                 outputFile << "#                                                                     #" << endln;
00202                                 outputFile.flush();
00203                         }
00204 
00205                         if (!DSPTfailed) {
00206 
00207 
00208                                 // Get results from the "find design point algorithm"
00209                                 uStar = theFindDesignPointAlgorithm->get_u();
00210                                 alpha = theFindDesignPointAlgorithm->get_alpha();
00211 
00212 
00213                                 // Put all alphas into rows in a matrix
00214                                 for (j=0; j<alpha.Size(); j++) {
00215                                         allAlphas(j,i-1) = alpha(j);
00216                                 }
00217 
00218                 
00219                                 // Postprocessing (note that g = -g1)
00220                                 beta(i-1) = alpha ^ uStar;
00221                                 pf(i-1) = 1.0 - aStdNormRV.getCDFvalue(beta(i-1));
00222                                 beta1 = -beta(i-1);
00223                                 pf1 = 1.0 - pf(i-1);
00224 
00225 
00226                                 if (analysisType == 1) {
00227                                         // Get the 'dgdu' vector from the sensitivity evaluator
00228                                         // (The returned matrix containes 'node#' 'dir#' 'dgdu' in rows)
00229                                         DgDdispl = theGradGEvaluator->getDgDdispl();
00230 
00231 
00232                                         // Add extra term to limit-state function
00233                                         // (should add an alternative option where user give additional limit-state functions)
00234                                         // (... because this works only when g is linear in u)
00235                                         numVel = DgDdispl.noRows();
00236                                         accuSum = 0.0;
00237                                         char *expressionPtr = new char[100];
00238                                         for (j=0; j<numVel; j++) {
00239 
00240                                                 nodeNumber = (int)DgDdispl(j,0);
00241                                                 dofNumber = (int)DgDdispl(j,1);
00242                                                 dgduValue = DgDdispl(j,2);
00243 
00244                                                 char expression[100];
00245                                                 sprintf(expression,"+(%10.8f)*(%8.5f)*{ud_%d_%d}",littleDeltaT, dgduValue, nodeNumber, dofNumber);
00246                                                 strcpy(expressionPtr,expression);
00247 
00248                                                 // Add it to the limit-state function
00249                                                 theLimitStateFunction->addExpression(expressionPtr);
00250                                         }
00251                                         delete []expressionPtr;
00252 
00253 
00254                                         // Inform the user
00255                                         strcpy(string,theLimitStateFunction->getExpression());
00256                                         opserr << " ...evaluating G2=" << string << endln;
00257 
00258 
00259                                         // Find the design point for the edited limit-state function
00260                                         if (theFindDesignPointAlgorithm->findDesignPoint(theReliabilityDomain) < 0){
00261                                                 opserr << "OutCrossingAnalysis::analyze() - failed while finding the" << endln
00262                                                         << " design point for limit-state function number " << lsf << "." << endln;
00263                                                 DSPTfailed = true;
00264                                                 oneFailed = true;
00265                                         }
00266 
00267 
00268                                         // Zero out the added expression in the limit-state function
00269                                         theLimitStateFunction->removeAddedExpression();
00270 
00271 
00272                                         if (!DSPTfailed) {
00273 
00274                                                 // Get results from the "find design point algorithm"
00275                                                 uStar2 = theFindDesignPointAlgorithm->get_u();
00276                                                 alpha2 = theFindDesignPointAlgorithm->get_alpha();
00277 
00278 
00279                                                 // Postprocessing (remember; here is an assumption that the mean point is in the safe domain)
00280                                                 beta2 = (alpha2 ^ uStar2);
00281                                                 pf2 = 1.0 - aStdNormRV.getCDFvalue(beta2);
00282                                         }
00283                                         else {
00284                                                 outputFile << "#  Second limit-state function did not converge.                      #" << endln;
00285                                         }
00286                                 
00287                                         // Post-processing to find parallel system probability
00288                                         a = -(alpha ^ alpha2);  // Interval start
00289                                         b = 0.0;                                // Interval end
00290                                         n_2 = 600;                              // Half the number of intervals
00291                                         h = b-a;
00292                                         fa = functionToIntegrate(a,beta1,beta2);
00293                                         fb = functionToIntegrate(b,beta1,beta2);
00294                                         sum_fx2j = 0.0;
00295                                         sum_fx2j_1 = 0.0;
00296                                         for (int j=1;  j<=n_2;  j++) {
00297                                                 sum_fx2j = sum_fx2j + functionToIntegrate(   (double) (a+(j*2)*h/(2*n_2)) ,beta1, beta2  );
00298                                                 sum_fx2j_1 = sum_fx2j_1 + functionToIntegrate(   (double)(a+(j*2-1)*h/(2*n_2)) , beta1, beta2  );
00299                                         }
00300                                         sum_fx2j = sum_fx2j - functionToIntegrate((double)(b),beta1,beta2);
00301                                         integral = h/(2*n_2)/3.0*(fa + 2.0*sum_fx2j + 4.0*sum_fx2j_1 + fb);
00302                                         Pmn1 = aStdNormRV.getCDFvalue(-beta1)*aStdNormRV.getCDFvalue(-beta2) - integral;
00303                                 
00304                                 }
00305                                 else {
00306                                         // Use Heonsang's method to find new alpha and beta
00307                                         beta2 = -beta1;
00308                                         alpha2(0) = alpha(0) - littleDeltaT/Dt * ( alpha(0)-0.0 );
00309                                         for (j=1; j<alpha.Size(); j++) {
00310                                                 alpha2(j) = alpha(j) - littleDeltaT/Dt * ( alpha(j)-alpha(j-1) );
00311                                         }
00312 
00313                                         // Post-processing to find parallel system probability
00314                                         a = -1.0*(alpha ^ alpha2);
00315                                         double pi = 3.14159265358979;
00316                                         Pmn1 = 1.0/(2.0*pi) * exp(-beta2*beta2*0.5) * (asin(a)+1.570796326794897);
00317                                 
00318                                 
00319                                 }
00320 
00321 
00322                                 // POST-PROCESSING
00323 
00324                                 // Mean out-crossing rate
00325                                 if (Pmn1<1.0e-10) {
00326                                         opserr << "WARNING: Zero or negative parallel probability: " << endln
00327                                                 << " The correlation is probably too high! " << endln;
00328                                 }
00329                                 nu(i-1) = Pmn1 / littleDeltaT;
00330 
00331 
00332                                 // Duration of single excursion
00333                                 if (fabs(nu(i-1))<1.0e-9) {
00334                                         ED(i-1) = 999999.0;
00335                                 }
00336                                 else {
00337                                         ED(i-1) = pf(i-1)/nu(i-1);
00338                                 }
00339 
00340                                 
00341                                 // Print the results to file right away...
00342                                 outputFile.setf( ios::fixed, ios::floatfield );
00343 
00344                                 outputFile << "#  " <<setprecision(2)<<setw(9)<<((stepsToStart+(i-1)*sampleFreq)*dt);
00345                                 
00346                                 if (beta(i-1)<0.0) { outputFile << "-"; }
00347                                 else { outputFile << " "; }
00348                                 outputFile <<setprecision(2)<<setw(11)<<fabs(beta(i-1));
00349                                 
00350                                 outputFile.setf( ios::scientific, ios::floatfield );
00351                                 if (pf(i-1)<0.0) { outputFile << "-"; }
00352                                 else { outputFile << " "; }
00353                                 outputFile <<setprecision(4)<<setw(16)<<fabs(pf(i-1));
00354                                 
00355                                 if (nu(i-1)<0.0) { outputFile << "-"; }
00356                                 else { outputFile << " "; }
00357                                 outputFile <<setprecision(5)<<setw(13)<<fabs(nu(i-1));
00358                                 
00359                                 if (ED(i-1)<0.0) { outputFile << "-"; }
00360                                 else { outputFile << " "; }
00361                                 outputFile <<setprecision(3)<<setw(10)<<fabs(ED(i-1));
00362                                 
00363                                 outputFile.setf( ios::fixed, ios::floatfield );
00364                                 outputFile<<"    #" << endln;
00365                                 outputFile.flush();
00366 
00367 
00368                                 // Inform the user
00369                                 char mystring[200];
00370                                 sprintf(mystring, " ... beta(G1)=%5.3f, beta(G2)=%5.3f, rate=%10.3e, rho=%10.4e",beta1,beta2,nu(i-1),a);
00371                                 opserr << mystring << endln;
00372 
00373                         }
00374                         else {
00375                                 outputFile << "#  First limit-state function did not converge.                       #" << endln;
00376                         }
00377 
00378 
00379                 } // Done looping over points on the time axis
00380 
00381 
00382                 if (!oneFailed) {
00383 
00384                         // Upper bound to probability of excursion during the interval 
00385                         double Upper = 0.0;
00386                         for (j=0; j<nu.Size(); j++) {
00387                                 Upper += nu(j)*Dt;
00388                         }
00389                         if (Upper >= 1.0) {
00390                                 Upper = 1.0;
00391                         }
00392 
00393 
00394                         // Approximation to true probability of failure
00395                         double pTrue = 1.0 - exp(-Upper);
00396                         if (pTrue >= 1.0) {
00397                                 pTrue = 1.0;
00398                         }
00399 
00400 
00401                         // Mean occupancy time
00402                         double Eeta = 0.0;
00403                         for (j=0; j<pf.Size(); j++) {
00404                                 Eeta += pf(j)*Dt;
00405                         }
00406 
00407 
00408                         // Matrix of intersection probabilities between 'g's (not g1 or g2) at all times
00409                         for (k=0; k<pf.Size(); k++) {
00410                                 for (kk=0; kk<pf.Size(); kk++) {
00411                                         // Extract alpha vectors
00412                                         for (j=0; j<alpha.Size(); j++) {
00413                                                 alpha_k(j) = allAlphas(j,k);
00414                                                 alpha_kk(j) = allAlphas(j,kk);
00415                                         }
00416                                         a = 0.0;                                // Interval start
00417                                         b = (alpha_k ^ alpha_kk);       // Interval end
00418                                         n_2 = 100;                                      // Half the number of intervals
00419                                         h = b-a;
00420                                         fa = functionToIntegrate(a, beta(k), beta(kk));
00421                                         fb = functionToIntegrate(b, beta(k), beta(kk));
00422                                         sum_fx2j = 0.0;
00423                                         sum_fx2j_1 = 0.0;
00424                                         for (int j=1;  j<=n_2;  j++) {
00425                                                 sum_fx2j = sum_fx2j + functionToIntegrate(   (double) (a+(j*2)*h/(2*n_2)) , beta(k), beta(kk) );
00426                                                 sum_fx2j_1 = sum_fx2j_1 + functionToIntegrate(   (double)(a+(j*2-1)*h/(2*n_2)) , beta(k), beta(kk)  );
00427                                         }
00428                                         sum_fx2j = sum_fx2j - functionToIntegrate((double)(b), beta(k), beta(kk));
00429                                         integral = h/(2*n_2)/3.0*(fa + 2.0*sum_fx2j + 4.0*sum_fx2j_1 + fb);
00430                                         Pmn2(k,kk) = aStdNormRV.getCDFvalue(-beta(k))*aStdNormRV.getCDFvalue(-beta(kk)) + integral;
00431                                 
00432                                 }
00433                         }
00434 
00435                         // Mean square of occupancy time
00436                         double EetaSquared = 0.0;
00437                         for (j=0; j<pf.Size(); j++) {
00438                                 for (k=0; k<pf.Size(); k++) {
00439                                         EetaSquared += Pmn2(j,k)*Dt;
00440                                 }
00441                         }
00442 
00443 
00444                         // Variance of occupancy time
00445                         double VarEta = EetaSquared - Eeta*Eeta;
00446 
00447 
00448                         // Cumulative area of excursion
00449                         // (Require gfun-parameter sensitivity + evaluation of more lsf's)
00450 
00451 
00452                         
00453 
00454                         outputFile << "#                                                                     #" << endln;
00455                         outputFile << "#                                                                     #" << endln;
00456                         outputFile << "#  ACCUMULATED RESULTS:                                               #" << endln;
00457                         outputFile << "#                                                                     #" << endln;
00458                         outputFile << "#  Total time T: ...................................... " 
00459                                 <<setiosflags(ios::left)<<setprecision(5)<<setw(12)<< T << "  #" << endln;
00460                         
00461                         outputFile.setf( ios::scientific, ios::floatfield );
00462                         outputFile << "#  Upper bound to probability of excursion during T:... " 
00463                                 <<setiosflags(ios::left)<<setprecision(5)<<setw(12)<< Upper << "  #" << endln;
00464                         
00465                         outputFile << "#  Approximation to true failure probability:.......... " 
00466                                 <<setiosflags(ios::left)<<setprecision(5)<<setw(12)<< pTrue << "  #" << endln;
00467                         
00468                         outputFile << "#  Mean occupancy time: ............................... " 
00469                                 <<setiosflags(ios::left)<<setprecision(5)<<setw(12)<< Eeta << "  #" << endln;
00470 
00471                         outputFile << "#  Variance of occupancy time: ........................ " 
00472                                 <<setiosflags(ios::left)<<setprecision(5)<<setw(12)<< VarEta << "  #" << endln;
00473 
00474                         outputFile << "#                                                                     #" << endln;
00475                         outputFile << "#######################################################################" << endln << endln << endln;
00476                 }
00477 
00478         } // Done looping over limit-state functions
00479 
00480 
00481         // Clean up
00482         outputFile.close();
00483 
00484 
00485         // Print summary of results to screen (more here!!!)
00486         opserr << "Out-Crossing Analysis completed." << endln;
00487 
00488         return 0;
00489 }
00490 
00491 
00492 
00493 double
00494 OutCrossingAnalysis::functionToIntegrate(double rho, double beta1, double beta2)
00495 {
00496         double result;
00497 
00498         if (fabs(rho-1.0) < 1.0e-8) {
00499                 result = 0.0;
00500         }
00501         else {
00502                 double pi = 3.14159265358979;
00503                 result = 1.0/(2.0*pi*sqrt(1.0-rho*rho)) 
00504                         * exp(-(beta1*beta1+beta2*beta2-2.0*rho*beta1*beta2)
00505                         /(2.0*(1.0-rho*rho)));
00506         }
00507         return result;
00508 }

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