XC::Vector XC::SecantRootFinding::findLimitStateSurface(int space, double g, Vector pDirection, Vector thePoint) { // Set scale factor for 'g' for convergence check double scaleG; if (fabs(g)>1.0e-4) { scaleG = g;} else { scaleG = 1.0;} // Normalize the direction vector Vector Direction = pDirection/pDirection.Norm(); // Scale 'maxStepLength' by standard deviation // (only if the user has specified to "walk" in original space) double perturbation; double realMaxStepLength = maxStepLength; if (space == 1) { // Go through direction vector and see which element is biggest // compared to its standard deviation int nrv = theReliabilityDomain->getNumberOfRandomVariables(); RandomVariable *theRV; double stdv, theStdv= 0.0; int theBiggest; double maxRatio = 0.0; for(int i=0; i<nrv; i++) { theRV = theReliabilityDomain->getRandomVariablePtr(i+1); stdv = theRV->getStdv(); if (Direction(i)/stdv > maxRatio) { maxRatio = Direction(i)/stdv; theStdv = stdv; theBiggest = i+1; } } // Now scale so that 'maxStepSize' is related to the real stdv perturbation = maxStepLength * theStdv; realMaxStepLength = perturbation; } else { perturbation = maxStepLength; } Vector theTempPoint; double g_old= 0.0, g_new; bool didNotConverge=true; double result; double tangent; int i=0; while (i<=maxIter && didNotConverge) { // Increment counter right away... i++; if (i!=1) { // Transform the point into x-space if the user has given it in 2-space if (space==2) { result = theProbabilityTransformation->set_u(thePoint); if (result < 0) { std::cerr << "XC::GFunVisualizationAnalysis::analyze() - " << std::endl << " could not set u in the xu-transformation." << std::endl; //return -1; Comentado LCPT. } result = theProbabilityTransformation->transform_u_to_x(); if (result < 0) { std::cerr << "XC::GFunVisualizationAnalysis::analyze() - " << std::endl << " could not transform from u to x and compute Jacobian." << std::endl; //return -1; Comentado LCPT. } theTempPoint = theProbabilityTransformation->get_x(); } else { theTempPoint = thePoint; } // Evaluate limit-state function result = theGFunEvaluator->runGFunAnalysis(theTempPoint); if (result < 0) { std::cerr << "XC::GFunVisualizationAnalysis::analyze() - " << std::endl << " could not run analysis to evaluate limit-state function. " << std::endl; //return -1; Comentado LCPT. } result = theGFunEvaluator->evaluateG(theTempPoint); if (result < 0) { std::cerr << "XC::GFunVisualizationAnalysis::analyze() - " << std::endl << " could not tokenize limit-state function. " << std::endl; //return -1; Comentado LCPT. } g_new = theGFunEvaluator->getG(); } else { g_new = g; } // Check convergence if (fabs(g_new/scaleG) < tol) { didNotConverge = false; } else { if (i==maxIter) { std::cerr << "WARNING: Projection scheme failed to find surface..." << std::endl; } else if (i==1) { thePoint = thePoint - perturbation * Direction; g_old = g_new; } else { // Take a step tangent = (g_new-g_old)/perturbation; perturbation = -g_new/tangent; if (fabs(perturbation) > realMaxStepLength) { perturbation = perturbation/fabs(perturbation)*realMaxStepLength; } thePoint = thePoint - perturbation * Direction; g_old = g_new; } } } return thePoint; }
int MVFOSMAnalysis::analyze(void) { // Alert the user that the FORM analysis has started opserr << "MVFOSM Analysis is running ... " << endln; // Initial declarations int i,j,k; // Open output file ofstream outputFile( fileName, ios::out ); // Get number of random variables int nrv = theReliabilityDomain->getNumberOfRandomVariables(); // Get mean point RandomVariable *aRandomVariable; Vector meanVector(nrv); for (i=1; i<=nrv; i++) { aRandomVariable = theReliabilityDomain->getRandomVariablePtr(i); if (aRandomVariable == 0) { opserr << "MVFOSMAnalysis::analyze() -- Could not find" << endln << " random variable with tag #" << i << "." << endln; return -1; } meanVector(i-1) = aRandomVariable->getMean(); } // Establish vector of standard deviations Vector stdvVector(nrv); for (i=1; i<=nrv; i++) { aRandomVariable = theReliabilityDomain->getRandomVariablePtr(i); stdvVector(i-1) = aRandomVariable->getStdv(); } // Evaluate limit-state function int result; result = theGFunEvaluator->runGFunAnalysis(meanVector); if (result < 0) { opserr << "SearchWithStepSizeAndStepDirection::doTheActualSearch() - " << endln << " could not run analysis to evaluate limit-state function. " << endln; return -1; } // Establish covariance matrix Matrix covMatrix(nrv,nrv); for (i=1; i<=nrv; i++) { covMatrix(i-1,i-1) = stdvVector(i-1)*stdvVector(i-1); } int ncorr = theReliabilityDomain->getNumberOfCorrelationCoefficients(); CorrelationCoefficient *theCorrelationCoefficient; double covariance, correlation; int rv1, rv2; for (i=1 ; i<=ncorr ; i++) { theCorrelationCoefficient = theReliabilityDomain->getCorrelationCoefficientPtr(i); correlation = theCorrelationCoefficient->getCorrelation(); rv1 = theCorrelationCoefficient->getRv1(); rv2 = theCorrelationCoefficient->getRv2(); covariance = correlation*stdvVector(rv1-1)*stdvVector(rv2-1); covMatrix(rv1-1,rv2-1) = covariance; covMatrix(rv2-1,rv1-1) = covariance; } // 'Before loop' declarations int numLsf = theReliabilityDomain->getNumberOfLimitStateFunctions(); Vector gradient(nrv); Matrix matrixOfGradientVectors(nrv,numLsf); Vector meanEstimates(numLsf); Vector responseStdv(numLsf); double responseVariance; // Loop over limit-state functions for (int lsf=1; lsf<=numLsf; lsf++ ) { // Inform the user which limit-state function is being evaluated opserr << "Limit-state function number: " << lsf << endln; // Set tag of active limit-state function theReliabilityDomain->setTagOfActiveLimitStateFunction(lsf); // Get limit-state function value (=estimation of the mean) result = theGFunEvaluator->evaluateG(meanVector); if (result < 0) { opserr << "SearchWithStepSizeAndStepDirection::doTheActualSearch() - " << endln << " could not tokenize limit-state function. " << endln; return -1; } meanEstimates(lsf-1) = theGFunEvaluator->getG(); // Evaluate (and store) gradient of limit-state function result = theGradGEvaluator->evaluateGradG(meanEstimates(lsf-1),meanVector); if (result < 0) { opserr << "MVFOSMAnalysis::analyze() -- could not" << endln << " compute gradients of the limit-state function. " << endln; return -1; } gradient = theGradGEvaluator->getGradG(); for (i=1 ; i<=nrv ; i++) { matrixOfGradientVectors(i-1,lsf-1) = gradient(i-1); } // Estimate of standard deviation responseVariance = (covMatrix^gradient)^gradient; if (responseVariance <= 0.0) { opserr << "ERROR: Response variance of limit-state function number "<< lsf << endln << " is zero! " << endln; } else { responseStdv(lsf-1) = sqrt(responseVariance); } // Print MVFOSM results to the output file outputFile << "#######################################################################" << endln; outputFile << "# MVFOSM ANALYSIS RESULTS, LIMIT-STATE FUNCTION NUMBER " <<setiosflags(ios::left)<<setprecision(1)<<setw(4)<<lsf <<" #" << endln; outputFile << "# #" << endln; outputFile << "# Estimated mean: .................................... " <<setiosflags(ios::left)<<setprecision(5)<<setw(12)<<meanEstimates(lsf-1) << " #" << endln; outputFile << "# Estimated standard deviation: ...................... " <<setiosflags(ios::left)<<setprecision(5)<<setw(12)<<responseStdv(lsf-1) << " #" << endln; outputFile << "# #" << endln; outputFile << "#######################################################################" << endln << endln << endln; // Inform the user that we are done with this limit-state function opserr << "Done analyzing limit-state function " << lsf << endln; } // Estimation of response covariance matrix Matrix responseCovMatrix(numLsf,numLsf); double responseCovariance; Vector gradientVector1(nrv), gradientVector2(nrv); for (i=1; i<=numLsf; i++) { for (k=0; k<nrv; k++) { gradientVector1(k) = matrixOfGradientVectors(k,i-1); } for (j=i+1; j<=numLsf; j++) { for (k=0; k<nrv; k++) { gradientVector2(k) = matrixOfGradientVectors(k,j-1); } responseCovariance = (covMatrix^gradientVector1)^gradientVector2; responseCovMatrix(i-1,j-1) = responseCovariance; } } for (i=1; i<=numLsf; i++) { for (j=1; j<i; j++) { responseCovMatrix(i-1,j-1) = responseCovMatrix(j-1,i-1); } } // Corresponding correlation matrix Matrix correlationMatrix(numLsf,numLsf); for (i=1; i<=numLsf; i++) { for (j=i+1; j<=numLsf; j++) { correlationMatrix(i-1,j-1) = responseCovMatrix(i-1,j-1)/(responseStdv(i-1)*responseStdv(j-1)); } } for (i=1; i<=numLsf; i++) { for (j=1; j<i; j++) { correlationMatrix(i-1,j-1) = correlationMatrix(j-1,i-1); } } // Print correlation results outputFile << "#######################################################################" << endln; outputFile << "# RESPONSE CORRELATION COEFFICIENTS #" << endln; outputFile << "# #" << endln; if (numLsf <=1) { outputFile << "# Only one limit-state function! #" << endln; } else { outputFile << "# gFun gFun Correlation #" << endln; outputFile.setf(ios::fixed, ios::floatfield); for (i=0; i<numLsf; i++) { for (j=i+1; j<numLsf; j++) { // outputFile.setf(ios::fixed, ios::floatfield); outputFile << "# " <<setw(3)<<(i+1)<<" "<<setw(3)<<(j+1)<<" "; if (correlationMatrix(i,j)<0.0) { outputFile << "-"; } else { outputFile << " "; } // outputFile.setf(ios::scientific, ios::floatfield); outputFile <<setprecision(7)<<setw(11)<<fabs(correlationMatrix(i,j)); outputFile << " #" << endln; } } } outputFile << "# #" << endln; outputFile << "#######################################################################" << endln << endln << endln; // Print summary of results to screen (more here!!!) opserr << "MVFOSMAnalysis completed." << endln; return 0; }