SafeGuardedZeroFindingAlgorithm.cpp
Upload User: sunhao438
Upload Date: 2018-06-06
Package Size: 13643k
Code Size: 7k
Category:

source in ebook

Development Platform:

Windows_Unix

  1. /* ****************************************************************** **
  2. **    OpenSees - Open System for Earthquake Engineering Simulation    **
  3. **          Pacific Earthquake Engineering Research Center            **
  4. **                                                                    **
  5. **                                                                    **
  6. ** (C) Copyright 2001, The Regents of the University of California    **
  7. ** All Rights Reserved.                                               **
  8. **                                                                    **
  9. ** Commercial use of this program without express permission of the   **
  10. ** University of California, Berkeley, is strictly prohibited.  See   **
  11. ** file 'COPYRIGHT'  in main directory for information on usage and   **
  12. ** redistribution,  and for a DISCLAIMER OF ALL WARRANTIES.           **
  13. **                                                                    **
  14. ** Developed by:                                                      **
  15. **   Frank McKenna (fmckenna@ce.berkeley.edu)                         **
  16. **   Gregory L. Fenves (fenves@ce.berkeley.edu)                       **
  17. **   Filip C. Filippou (filippou@ce.berkeley.edu)                     **
  18. **                                                                    **
  19. ** Reliability module developed by:                                   **
  20. **   Terje Haukaas (haukaas@ce.berkeley.edu)                          **
  21. **   Armen Der Kiureghian (adk@ce.berkeley.edu)                       **
  22. **                                                                    **
  23. **   Quan Gu (qgu@ucsd.edu)                                           **
  24. **   Joel P. Conte (jpconte@ucsd.edu)                                 **
  25. ** ****************************************************************** */
  26.                                                                         
  27.  
  28. //
  29. // Written by  Quan Gu UCSD
  30. //
  31. #include <stdio.h> 
  32. #include <math.h>
  33. #include "SafeGuardedZeroFindingAlgorithm.h"
  34. #include <OPS_Globals.h>
  35. SafeGuardedZeroFindingAlgorithm::SafeGuardedZeroFindingAlgorithm()
  36. {
  37. }
  38. SafeGuardedZeroFindingAlgorithm::~SafeGuardedZeroFindingAlgorithm()
  39. {
  40. if (x_1 !=0) delete [] x_1;
  41. if (x_2 !=0) delete [] x_2;
  42. if (G_1 !=0) delete [] G_1;
  43. if (G_2 !=0) delete [] G_2;
  44. }
  45. int SafeGuardedZeroFindingAlgorithm::findZeroPoint(double x0)
  46. {
  47. if (! theSamplingAnalysis->getContribution()) return 0;  //Gu 2007 Dec 23
  48.  
  49. // note:  1, the point x0 is not used for this algorithm
  50. //        2, a & Fa must be set before calling. Fa must be positive (safe domain).
  51. //        3, either b& Fb set,  or FEconvergence is set to be false (unsafe domain, either G<0 or diverge)
  52. //        4, isFbValid decide whether Fb is converged value;
  53.     
  54. //create new array to save history
  55. double * Xs;
  56. double * Fs;
  57. int ii;
  58. if (functionType ==1) {
  59. Xs = x_1;
  60.     Fs = G_1;
  61. ii=ii_1;
  62. }
  63. else if (functionType ==2) {
  64. Xs = x_2;
  65.     Fs = G_2;
  66. ii=ii_2;
  67. }
  68. /////////////////////////////////////////////////////////
  69. double TOL=variableTol/1000.0;
  70. double x1,x_new, last_x_new;
  71. double Fx0, Fx1,Fx_new;
  72. if (Fa < -functionTol) {
  73. opserr<<"error in SafeGuardedZeroFindingAlgorithm::findZeroPoint. Fa<0"<<endln; 
  74. return -1;
  75. }
  76. if (FEconvergence) {  //save data
  77. isFbValid = true; 
  78. x_new = -Fb*(b-a)/(Fb-Fa)+b;
  79. if ((x_new<a-TOL)||(x_new<b+TOL)){  
  80. x_new=(a+b)/2.0;
  81. }
  82. }
  83. else {  // !FEconvergence, bisection
  84. x_new = (a+b)/2.0;
  85. // improve  ??????????????????????????????????????????????????????????????????????
  86. // x_new = a+0.15;
  87. isFbValid = false; 
  88. }
  89. if (this->functionType == 1){
  90. iterationNum =2; // here is function evaluation number
  91. }
  92. else if (this->functionType == 2){
  93. iterationNum =0; // here is function evaluation number
  94. }
  95. last_x_new = x_new+999;
  96.  
  97. Fx_new=myFunction(x_new);
  98. iterationNum++;
  99. if (FEconvergence) {
  100. if (fabs(Fx_new)<functionTol) {
  101. zeroPoint = x_new; 
  102. opserr<<"Return: x_new is:"<<x_new<<" Fx_new is: "<<Fx_new<<endln;
  103. return 1;
  104. }
  105. if (Fx_new * Fa >functionTol*functionTol){ //good
  106. a = x_new;
  107. Fa = Fx_new;
  108. }
  109. else if (Fx_new * Fa < -functionTol*functionTol){
  110. b = x_new;
  111. Fb = Fx_new;
  112. isFbValid = true;
  113. }
  114. else { 
  115. opserr<<"wrong bound!"<<endln; return -1;
  116. }
  117. }
  118. else {//diverge
  119. b=x_new; Fb=-1.0;
  120. isFbValid = false;
  121. }
  122. if (maxIterNum>100) {
  123. opserr<<"warning: SafeGuardedZeroFindingAlgorithm::findZeroPoint may couse member ";
  124. opserr<<" error since maxIterNum:"<<maxIterNum<<" exceed the limit 100..."<<endln;
  125. }
  126. while (theSamplingAnalysis->getContribution() && /*fabs(Fx_new)>functionTol &&*/ iterationNum < maxIterNum && (b-a)>variableTol) {
  127. iterationNum++;
  128. if (isFbValid ) { // select x0 and x1..
  129. if(fabs(Fa)>fabs(Fb)+functionTol) {
  130. x1=b; Fx1=Fb;
  131. }
  132. else {
  133. x1=a; Fx1=Fa;
  134. }
  135. }
  136. else {// ! isFbValid , begin from a
  137. x1=a; Fx1=Fa;
  138. }
  139. // --------- select best x0, which is closest to x1 ---------
  140. double  interval =999;
  141. for(int i=0;i<ii;i++){
  142. if ((fabs(Xs[i]-x1)<interval)&&(fabs(Xs[i]-x1)>TOL/1000.0)) 
  143. {x0= Xs[i];Fx0=Fs[i]; interval=fabs(Xs[i]-x1); }
  144. }
  145. last_x_new = x_new;  // save old x_new
  146. // --- newton secant method 
  147. if (fabs(Fx1-Fx0)> 1.0e-10){
  148. x_new = -Fx1*(x1-x0)/(Fx1-Fx0)+x1;
  149. }
  150. else {
  151. x_new = (a+b)/2.0;
  152. }
  153. // --- make sure it is in trust region
  154. if ((x_new>b+TOL)||(x_new<a-TOL)) {
  155. x_new=(a+b)/2.0;
  156. }
  157. //correction if starked! ----
  158. if ((fabs(x_new-a)< TOL/1000.)||(fabs(x_new-b)< TOL/1000.))  x_new=(a+b)/2.0;
  159. if (fabs(last_x_new-x_new)<TOL/1000.) x_new=(a+b)/2.0;
  160. // check x_new, is not solution 
  161. Fx_new=myFunction(x_new);
  162. if (FEconvergence){
  163. if(fabs(Fx_new)<functionTol){
  164. zeroPoint = x_new;
  165. opserr<<"Return: x_new is:"<<x_new<<" Fx_new is: "<<Fx_new<<endln;
  166. return 1;
  167. else if (Fx_new*Fa > functionTol*functionTol){ //good
  168. a = x_new;
  169. Fa = Fx_new;
  170. }
  171. else if (Fx_new * Fa < -functionTol*functionTol){
  172. b = x_new;
  173. Fb = Fx_new;
  174. isFbValid = true;
  175. }
  176. else { opserr<<"bound wrong"<<endln; return -1; }//opserr<<"wrong bound!"<<endln; return -1;}
  177. printf("a: %f, b: %f, Fa: %f, Fb: %f,x_new: %9.4f, Fx_new: %14.7f n",a,b,Fa,Fb,x_new,Fx_new );
  178. }
  179. else { //FEdivergence
  180. b=x_new;
  181. Fb=-1.0;
  182. isFbValid = false;
  183. printf("diverge-- a: %f, b: %f, Fa: %f, Fb: %f,x_new: %9.4f, Fx_new: %14.7f n",a,b,Fa,Fb,x_new,Fx_new );
  184. }
  185. };//while
  186. if (iterationNum == maxIterNum) {//not converge
  187. return -1;
  188. }
  189. zeroPoint = x_new;
  190. return 0;
  191. } ;
  192. double SafeGuardedZeroFindingAlgorithm::myFunction(double x){
  193. return theSamplingAnalysis->getSampledValue(x);
  194. };
  195. SafeGuardedZeroFindingAlgorithm::SafeGuardedZeroFindingAlgorithm(SamplingAnalysis * thePassedAnalysis)
  196. {
  197. theSamplingAnalysis = thePassedAnalysis;
  198. functionType=1;
  199. FEconvergence = true;
  200. if (functionType ==1){  // failure prob.
  201. x_1 = new double [100];
  202. G_1 = new double [100];
  203. }
  204. else if (functionType ==2){  // upcrossing
  205. x_1 = new double [100];
  206. G_1 = new double [100];
  207. x_2 = new double [100];
  208. G_2 = new double [100];
  209. }
  210. }