/Users/huttone/Devel/sedflux-new/sedflux/trunk/ew/failure/failure.c

Go to the documentation of this file.
00001 //---
00002 //
00003 // This file is part of sedflux.
00004 //
00005 // sedflux is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation; either version 2 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // sedflux is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with sedflux; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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    // don't do the first slice and last slice.  their depths are zero which
00064    // causes problems.
00065    cur_vars = slice+1;
00066    cur_vars[sed_cube_n_y(p)-2] = NULL;
00067 
00068 //   fsPoints_ = p->size-2;
00069 //   fs  = rtsafe(&factor_of_safety,0.0001,2000.,.01);
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 // NOTE: 'm' is taken from D.A.Sangrey in Eleventh Annual Offshore Technology 
00104 // Conference -- 1979 Proceedings Volume 1.  It's the slope relating (H/h) and
00105 // (delta u / gamma' h).  For large values of the quantity (m^2 t / Cv) and for
00106 // values of (H/h) < 0.2 it can be approximated as 1.
00107    m = 1.;
00108 
00109    width = sed_cube_y_res(p);
00110 
00111    // Depth (m) of sediment in this slice of the failure.
00112    for ( i=0 ; i<len ; i++ )
00113       slice[i]->depth = sed_cube_thickness(p,0,i);
00114 
00115    // Get slopes at the failure surface.
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 //      slice[i].alpha = fabs(atan((slice[i+1].depth-slice[i].depth)/width));
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 // the global model.
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 // the local model.
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 //      slice[i]->c   = sed_get_column_property_with_load( S_COHESION , p->col[0][i] );
00151 //      slice[i]->phi = sed_get_column_property( S_FRICTION_ANGLE , p->col[0][i] )*S_RADS_PER_DEGREE;
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       // If the excess pore pressure exceeds the weight of the sediment,
00158       // reduce the excess pore pressure to match the sediment weight.
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.; /* this is the shape factor.  We just set it to 1 now. */
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       // The effective weight is the normal weight minus the weight
00183       // relieved by the vertical accelerations of an earthquake.  
00184       // The horizontal weight is just the weight of the sediment 
00185       // adjusted to the horizontal accelerations of the earthquake.
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 //           eh_message("Root must be bracketed in rtsafe");
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 //   eh_message("Maximum number of iterations exceeded in rtsafe");
00263 //   return 0.0;
00264 
00265    return -1;
00266 }
00267 #undef MAXIT
00268 

Generated on Fri Jan 4 18:04:13 2008 for sedflux by  doxygen 1.5.2