00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
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
00070 double scaleG;
00071 if (fabs(g)>1.0e-4) { scaleG = g;}
00072 else { scaleG = 1.0;}
00073
00074
00075 Vector Direction = pDirection/pDirection.Norm();
00076
00077
00078
00079 double perturbation;
00080 double realMaxStepLength = maxStepLength;
00081 if (space == 1) {
00082
00083
00084
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
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
00120 i++;
00121
00122 if (i!=1) {
00123
00124
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
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
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
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