00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdio.h>
00022 #include <math.h>
00023 #include <utils/utils.h>
00024 #include <sed/sed_sedflux.h>
00025 #include "failure.h"
00026
00027 #include <math.h>
00028
00029 #define FACTOR_OF_SAFETY_ERROR -2
00030 Fail_slice** get_janbu_parameters( const Sed_cube p ,
00031 Fail_slice **slice ,
00032 const Failure_t* failure_const );
00033 double rtsafe_fos( void (*funcd)(double, gconstpointer, double *, double *) ,
00034 gconstpointer data ,
00035 double x1 ,
00036 double x2 ,
00037 double xacc );
00038 void factor_of_safety(double x,gconstpointer,double *fn, double *dfn);
00039 double get_m(const Sed_column,double,double);
00040
00041 double get_factor_of_safety( const Sed_cube p ,
00042 const Failure_t* failure_const )
00043 {
00044 int i;
00045 double fs;
00046 Fail_slice **slice;
00047 Fail_slice **cur_vars;
00048
00049 eh_require( sed_cube_is_1d(p) );
00050
00051 slice = eh_new( Fail_slice* , sed_cube_n_y(p) );
00052 slice[0] = eh_new( Fail_slice , sed_cube_n_y(p) );
00053 for ( i=1 ; i<sed_cube_n_y(p) ; i++ )
00054 slice[i] = slice[i-1] + 1;
00055
00056 if ( !get_janbu_parameters( p , slice , failure_const ) )
00057 {
00058 eh_free(slice[0]);
00059 eh_free(slice);
00060 return FACTOR_OF_SAFETY_ERROR;
00061 }
00062
00063
00064
00065 cur_vars = slice+1;
00066 cur_vars[sed_cube_n_y(p)-2] = NULL;
00067
00068
00069
00070 fs = rtsafe_fos(&factor_of_safety,(gconstpointer)cur_vars,0.005,200.,.01);
00071
00072 eh_free(slice[0]);
00073 eh_free(slice);
00074
00075 return fs;
00076 }
00077
00078 Fail_slice **get_janbu_parameters( const Sed_cube p ,
00079 Fail_slice **slice ,
00080 const Failure_t *failure_const )
00081 {
00082 double volume=0.;
00083 double width, m;
00084 double rhoSolid;
00085 double gravity;
00086 double a_angle;
00087 double hydro_static;
00088 int i, len;
00089 Sed_column this_col;
00090
00091 gravity = 9.81;
00092
00093 len = sed_cube_n_y(p);
00094
00095 a_angle = M_PI/64.;
00096
00097 for ( i=0 ; i<len ; i++ )
00098 {
00099 slice[i]->a_vertical = sed_cube_quake(p)*cos(a_angle);
00100 slice[i]->a_horizontal = sed_cube_quake(p)*sin(a_angle);
00101 }
00102
00103
00104
00105
00106
00107 m = 1.;
00108
00109 width = sed_cube_y_res(p);
00110
00111
00112 for ( i=0 ; i<len ; i++ )
00113 slice[i]->depth = sed_cube_thickness(p,0,i);
00114
00115
00116 for ( i=0 ; i<len-1 ; i++ )
00117 slice[i]->alpha = fabs( atan( ( sed_cube_base_height(p,0,i+1)
00118 - sed_cube_base_height(p,0,i) )
00119 / width ) );
00120
00121 slice[len-1]->alpha = slice[len-2]->alpha;
00122
00123 for (i=0,volume=0.;i<len;i++)
00124 {
00125
00126 this_col = sed_cube_col(p,i);
00127
00128 if ( sed_column_len( this_col ) > 0 )
00129 {
00130 hydro_static = sed_column_water_pressure( this_col );
00131
00132 volume += slice[i]->depth;
00133
00134 rhoSolid = sed_column_top_rho( this_col , slice[i]->depth );
00135
00136
00137 m = get_m( this_col , slice[i]->depth , failure_const->consolidation );
00138 slice[i]->u = (rhoSolid-failure_const->density_sea_water)
00139 * gravity*slice[i]->depth
00140 / m;
00141 slice[i]->c = failure_const->cohesion;
00142 slice[i]->phi = failure_const->frictionAngle;
00143
00144
00145 slice[i]->u = sed_cell_pressure( sed_column_nth_cell( this_col , 0 ) )
00146 - hydro_static;
00147 if ( slice[i]->u < 0 )
00148 slice[i]->u = 0;
00149
00150
00151
00152
00153 slice[i]->b = width;
00154 slice[i]->w = (rhoSolid-failure_const->density_sea_water)
00155 * gravity*slice[i]->b*slice[i]->depth;
00156
00157
00158
00159 if ( slice[i]->u > slice[i]->w/slice[i]->b )
00160 slice[i]->u = slice[i]->w/slice[i]->b;
00161 }
00162 }
00163
00164 if ( volume == 0 )
00165 return NULL;
00166 else
00167 return slice;
00168 }
00169
00170 void factor_of_safety( double x , gconstpointer data , double *fn , double *dfn )
00171 {
00172 int i;
00173 double c1[MAX_FAILURE_LENGTH], c2[MAX_FAILURE_LENGTH];
00174 double numerator, denominator;
00175 double f=1.;
00176 double effective_weight, horizontal_weight;
00177 Fail_slice **col = (Fail_slice**)data;
00178
00179 for ( i=0,numerator=0.,denominator=0. ; col[i] ; i++ )
00180 {
00181
00182
00183
00184
00185
00186 effective_weight = col[i]->w
00187 - col[i]->a_vertical/sed_gravity()*col[i]->w;
00188 horizontal_weight = col[i]->a_horizontal/sed_gravity()*col[i]->w;
00189
00190 denominator += effective_weight*sin(col[i]->alpha)
00191 + horizontal_weight*cos(col[i]->alpha);
00192
00193 c1[i] = col[i]->b
00194 * ( col[i]->c
00195 + (effective_weight/col[i]->b-col[i]->u-horizontal_weight*sin(col[i]->alpha) )
00196 * tan(col[i]->phi) )
00197 / cos(col[i]->alpha);
00198 c2[i] = tan(col[i]->alpha)*tan(col[i]->phi);
00199 numerator += c1[i]/(1.+c2[i]/x);
00200
00201 }
00202 *fn = f*numerator/denominator - x;
00203
00204 for ( i=0,numerator=0. ; col[i] ; i++ )
00205 numerator += c1[i]*c2[i]/pow(x+c2[i]/x,2);
00206
00207 *dfn = f*numerator/denominator - 1.;
00208
00209 return;
00210 }
00211
00212 #define MAXIT 1000
00213
00214 double rtsafe_fos(void (*funcd)(double, gconstpointer, double *, double *), gconstpointer data, double x1, double x2, double xacc)
00215 {
00216 int j;
00217 double df,dx,dxold,f,fh,fl;
00218 double temp,xh,xl,rts;
00219
00220 (*funcd)(x1,data,&fl,&df);
00221 (*funcd)(x2,data,&fh,&df);
00222 if ((fl > 0.0 && fh > 0.0) || (fl < 0.0 && fh < 0.0))
00223 {
00224
00225 return -1;
00226 }
00227 if (fl == 0.0) return x1;
00228 if (fh == 0.0) return x2;
00229 if (fl < 0.0) {
00230 xl=x1;
00231 xh=x2;
00232 } else {
00233 xh=x1;
00234 xl=x2;
00235 }
00236 rts=0.5*(x1+x2);
00237 dxold=fabs(x2-x1);
00238 dx=dxold;
00239 (*funcd)(rts,data,&f,&df);
00240 for (j=1;j<=MAXIT;j++) {
00241 if ((((rts-xh)*df-f)*((rts-xl)*df-f) >= 0.0)
00242 || (fabs(2.0*f) > fabs(dxold*df))) {
00243 dxold=dx;
00244 dx=0.5*(xh-xl);
00245 rts=xl+dx;
00246 if (xl == rts) return rts;
00247 } else {
00248 dxold=dx;
00249 dx=f/df;
00250 temp=rts;
00251 rts -= dx;
00252 if (temp == rts) return rts;
00253 }
00254 if (fabs(dx) < xacc) return rts;
00255 (*funcd)(rts,data,&f,&df);
00256 if (f < 0.0)
00257 xl=rts;
00258 else
00259 xh=rts;
00260 }
00261
00262
00263
00264
00265 return -1;
00266 }
00267 #undef MAXIT
00268