/Users/huttone/Devel/sedflux-new/sedflux/trunk/ew/sedflux/run_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 #define SED_FAIL_PROC_NAME "failure"
00022 #define EH_LOG_DOMAIN SED_FAIL_PROC_NAME
00023 
00024 #include <stdio.h>
00025 #include <time.h>
00026 
00027 #include <utils/utils.h>
00028 #include <sed/sed_sedflux.h>
00029 #include <failure.h>
00030 #include "my_processes.h"
00031 
00032 #include "sedflux.h"
00033 
00034 int get_tsunami_parameters(Sed_cube fail);
00035 
00036 gboolean init_failure_data( Sed_process proc , Sed_cube prof , GError** error );
00037 
00038 GQuark
00039 failure_profile_data_quark( void )
00040 {
00041    return g_quark_from_string( "failure-profile-data-quark" );
00042 }
00043 
00044 Sed_process_info
00045 run_failure( Sed_process proc , Sed_cube p )
00046 {
00047    Failure_proc_t*  data = sed_process_user_data(proc);
00048    Sed_process_info info = SED_EMPTY_INFO;
00049    Sed_cube fail;
00050    int decision;
00051    int fail_count=0;
00052    int fs_min_start, fs_min_length;
00053    double fs_min;
00054    Sed_process fail_process;
00055    Failure_t failure_const;
00056    GTimer *time;
00057    Fail_profile *fail_prof=NULL;
00058    gboolean flow_ok = TRUE;
00059 
00060    if ( sed_process_run_count(proc)==0 )
00061       init_failure_data( proc , p , NULL );
00062 
00063 /*
00064    prof = sed_create_empty_profile( p->n_y , p->sed );
00065    for ( i=0 ; i<prof->size ; i++ )
00066       prof->col[i] = p->col[0][i];
00067    prof->age = p->age;
00068    prof->time_step = p->time_step;
00069    prof->storm_value = p->storm_value;
00070    prof->quake_value = p->quake_value;
00071    prof->tidal_range = p->tidal_range;
00072    prof->tidal_period = p->tidal_period;
00073    prof->wave[0] = p->wave[0];
00074    prof->wave[1] = p->wave[1];
00075    prof->wave[2] = p->wave[2];
00076    prof->basinWidth = p->dx;
00077    prof->colWidth   = p->dy;
00078    prof->cellHeight = p->cell_height;
00079    prof->sealevel   = p->sea_level;
00080    prof->constants  = p->constants;
00081 */
00082 
00083    time = g_timer_new();
00084 
00085    fail_prof                       = data->fail_prof;
00086    failure_const.consolidation     = data->consolidation;
00087    failure_const.cohesion          = data->cohesion;
00088    failure_const.frictionAngle     = data->friction_angle;
00089    failure_const.gravity           = data->gravity;
00090    failure_const.density_sea_water = data->density_sea_water;
00091 
00092    fprintf( stderr , "\n" );
00093 
00094    eh_debug( "initializing failure profile" );
00095    fail_prof = fail_reinit_fail_profile( fail_prof , p , failure_const );
00096 
00097    do
00098    {
00099 
00100       g_timer_start(time);
00101 
00102       eh_debug( "updating profile for failures" );
00103       fail_update_fail_profile( fail_prof );
00104 
00105       eh_debug( "examining profile for failures" );
00106       fail_examine_fail_profile( fail_prof );
00107 
00108       eh_debug( "examination took %f seconds" , g_timer_elapsed(time,NULL) );
00109 
00110       fs_min        = fail_prof->fs_min_val;
00111       fs_min_start  = fail_prof->fs_min_start;
00112       fs_min_length = fail_prof->fs_min_len;
00113 
00114       eh_message( "time             : %f" , sed_cube_age_in_years(p) );
00115       eh_message( "factor of safety : %f" , fs_min        );
00116       eh_message( "CHOOSING LARGEST FAILURE SURFACE: NO" );
00117       eh_message( "failure location : %d" , fs_min_start  );
00118       eh_message( "failure length   : %d" , fs_min_length );
00119       eh_message( "water depth      : %f" ,
00120          (fs_min_start>=0)?sed_cube_water_depth(p,0,fs_min_start):-999 );
00121 
00122       // Fail the sediment above the ellipse that has the minimum factor
00123       // of safety.
00124       if ( fs_min>0 && fs_min<MIN_FACTOR_OF_SAFETY )
00125       {
00126 
00127          fail = get_failure_surface( p , fs_min_start , fs_min_length );
00128 
00129          get_tsunami_parameters( fail );
00130 
00131          if ( fail )
00132          {
00133             sed_cube_remove(p,fail);
00134 
00135             decision = decider(fail,data->decider_clay_fraction);
00136 /*
00137             if ( decision == DECIDER_TURBIDITY_CURRENT )
00138             {
00139                tc = data->turbidity_current;
00140                //sed_process_data_val(tc,failure,Turbidity_t) = fail;
00141 
00142                ((Turbidity_t*)sed_process_data(tc))->failure = fail;
00143                flow_ok = sed_process_run_now(tc,p);
00144             }
00145             else if ( decision == DECIDER_DEBRIS_FLOW )
00146             {
00147                db = data->debris_flow;
00148                //sed_process_data_val(db,failure,Debris_flow_t) = fail;
00149                ((Debris_flow_t*)sed_process_data(db))->failure = fail;
00150                flow_ok = sed_process_run_now(db,p);
00151             }
00152             else if ( decision == DECIDER_SLUMP )
00153             {
00154                slump = data->slump;
00155                //sed_process_data_val(slump,failure,Slump_t) = fail;
00156                ((Slump_t*)sed_process_data(slump))->failure = fail;
00157                flow_ok = sed_process_run_now(slump,p);
00158             }
00159 */
00160             if      ( decision == DECIDER_TURBIDITY_CURRENT ) fail_process = data->turbidity_current;
00161             else if ( decision == DECIDER_DEBRIS_FLOW       ) fail_process = data->debris_flow;
00162             else if ( decision == DECIDER_SLUMP             ) fail_process = data->slump;
00163 
00164             sed_process_provide( fail_process , FAILURE_PROFILE_DATA , fail );
00165 
00166             flow_ok = sed_process_run_now( fail_process , p );
00167 
00168             sed_process_withhold( fail_process , FAILURE_PROFILE_DATA );
00169 
00170             sed_cube_destroy(fail);
00171 
00172          }
00173 
00174          fail_set_failure_surface_ignore( fail_prof    ,
00175                                           fs_min_start ,
00176                                           fs_min_length );
00177 
00178          if ( !flow_ok )
00179          {
00180             fail_set_failure_surface_ignore( fail_prof ,
00181                                              fs_min_start ,
00182                                              fs_min_length );
00183             flow_ok = TRUE;
00184          }
00185          else
00186          {
00187 //            flow = data->flow;
00188 //            flow_ok = sed_run_process_now(flow,p);
00189             fail_count++;
00190          }
00191      
00192       }
00193       else
00194          get_tsunami_parameters( NULL );
00195 
00196    }
00197    while ( fs_min > 0. && fs_min < MIN_FACTOR_OF_SAFETY && flow_ok && fail_count<100 );
00198 
00199 /*
00200    for ( i=0 ; i<prof->size ; i++ )
00201       sed_destroy_cell( prof->in_suspension[i] );
00202    eh_free(prof->in_suspension);
00203    sed_destroy_cell( prof->erode );
00204    eh_free(prof->col);
00205 */
00206 
00207    g_timer_destroy(time);
00208 
00209    return info;
00210 }
00211 
00212 #define S_KEY_CONSOLIDATION  "coefficient of consolidation"
00213 #define S_KEY_COHESION       "cohesion of sediments"
00214 #define S_KEY_FRICTION_ANGLE "apparent coulomb friction angle"
00215 #define S_KEY_CLAY_FRACTION  "fraction of clay for debris flow"
00216 
00217 gboolean
00218 init_failure( Sed_process p , Eh_symbol_table tab , GError** error )
00219 {
00220    Failure_proc_t* data    = sed_process_new_user_data( p , Failure_proc_t );
00221    GError*         tmp_err = NULL;
00222    gchar**         err_s   = NULL;
00223    gboolean        is_ok   = TRUE;
00224 
00225    eh_return_val_if_fail( error==NULL || *error==NULL , FALSE );
00226 
00227    data->fail_prof             = NULL;
00228    data->turbidity_current     = NULL;
00229    data->debris_flow           = NULL;
00230    data->slump                 = NULL;
00231    data->flow                  = NULL;
00232 
00233    data->consolidation         = eh_symbol_table_dbl_value( tab , S_KEY_CONSOLIDATION  );
00234    data->cohesion              = eh_symbol_table_dbl_value( tab , S_KEY_COHESION       );
00235    data->friction_angle        = eh_symbol_table_dbl_value( tab , S_KEY_FRICTION_ANGLE );
00236    data->decider_clay_fraction = eh_symbol_table_dbl_value( tab , S_KEY_CLAY_FRACTION  );
00237 
00238    data->friction_angle        *= S_RADS_PER_DEGREE;
00239    data->decider_clay_fraction /= 100.;
00240 
00241    data->gravity                = sed_gravity();
00242    data->density_sea_water      = sed_rho_sea_water();
00243 
00244    eh_check_to_s( data->consolidation>=0         , "Sediment consolidation positive" , &err_s );
00245    eh_check_to_s( data->cohesion>=0              , "Sediment cohesion positive"      , &err_s );
00246    eh_check_to_s( data->friction_angle>=0        , "Friction angle positive"         , &err_s );
00247    eh_check_to_s( data->decider_clay_fraction>=0 , "Clay fraction between 0 and 1"   , &err_s );
00248    eh_check_to_s( data->decider_clay_fraction<=1 , "Clay fraction between 0 and 1"   , &err_s );
00249 
00250    if ( !tmp_err && err_s )
00251       eh_set_error_strv( &tmp_err , SEDFLUX_ERROR , SEDFLUX_ERROR_BAD_PARAM , err_s );
00252 
00253    if ( tmp_err )
00254    {
00255       g_propagate_error( error , tmp_err );
00256       is_ok = FALSE;
00257    }
00258 
00259    return is_ok;
00260 }
00261 
00262 gboolean
00263 init_failure_data( Sed_process proc , Sed_cube prof , GError** error )
00264 {
00265    Failure_proc_t* data = sed_process_user_data(proc);
00266 
00267    if ( data )
00268    {
00269       Failure_t failure_const;
00270 
00271       failure_const.consolidation     = data->consolidation;
00272       failure_const.cohesion          = data->cohesion;
00273       failure_const.frictionAngle     = data->friction_angle;
00274       failure_const.gravity           = data->gravity;
00275       failure_const.density_sea_water = data->density_sea_water;
00276 
00277       data->fail_prof = fail_init_fail_profile( prof , failure_const );
00278 
00279       data->turbidity_current = sed_process_child( proc , "TURBIDITY CURRENT" );
00280       data->debris_flow       = sed_process_child( proc , "DEBRIS FLOW"       );
00281       data->slump             = sed_process_child( proc , "SLUMP"             );
00282 
00283    }
00284 
00285    return TRUE;
00286 }
00287 
00288 gboolean
00289 destroy_failure( Sed_process p )
00290 {
00291    if ( p )
00292    {
00293       Failure_proc_t* data = sed_process_user_data( p );
00294 
00295       if ( data )
00296       {
00297          if ( data->fail_prof )
00298             fail_destroy_failure_profile( data->fail_prof );
00299 
00300          eh_free( data );
00301       }
00302    }
00303 
00304    return TRUE;
00305 }
00306 
00307 #include <math.h>
00308 
00309 int get_tsunami_parameters(Sed_cube fail)
00310 {
00311    int i;
00312    double rise;
00313    double b, d, theta, w, T, A, lambda;
00314    double s_0, t_0;
00315    double sin_theta;
00316    double g=sed_gravity();
00317 
00318    eh_require( fail );
00319    eh_require( sed_cube_is_1d(fail) );
00320 
00321    if ( fail )
00322    {
00323       rise  = fabs(    sed_cube_water_depth(fail,0,0)
00324                     - sed_cube_water_depth(fail,0,sed_cube_n_y(fail)-1) );
00325       b     = sed_cube_n_y(fail)*sed_cube_y_res(fail);
00326       theta = atan(rise/b);
00327       w     = .25*b;
00328       d     = sed_cube_water_depth(fail,0,sed_cube_n_y(fail)/2);
00329 
00330       for (i=0,T=0;i<sed_cube_n_y(fail);i++)
00331          if ( sed_cube_thickness(fail,0,i) > T )
00332             T = sed_cube_thickness(fail,0,i);
00333 
00334       sin_theta = sin(fabs(theta));
00335 
00336       if ( d < 0 )
00337       {
00338          eh_debug( "Failure depth is less than zero." );
00339          d = 0;
00340       }
00341 
00342       lambda = 3.87*pow(b*d/sin_theta,.5);
00343       A      = 0.224*T*(w/(w+lambda))
00344              * (         pow(sin_theta,1.29)
00345                  - 0.746*pow(sin_theta,2.29)
00346                  + 0.170*pow(sin_theta,3.29) )
00347              * pow(b/d,1.25);
00348       s_0 = 4.48*b;
00349       t_0 = 3.87*pow(b/(g*sin_theta),.5);
00350 
00351    }
00352    else
00353    {
00354       A      = -999;
00355       lambda = -999;
00356       theta  = -999;
00357       rise   = -999;
00358       T      = -999;
00359       s_0    = -999;
00360       t_0    = -999;
00361    }
00362 
00363    eh_message( "tsunami amplitude (m): %f"       , A      );
00364    eh_message( "tsunami wavelength (m): %f"      , lambda );
00365    eh_message( "sea floor slope (rads): %f"      , theta  );
00366    eh_message( "failure relief (m): %f"          , rise   );
00367    eh_message( "failure thickness (m): %f"       , T      );
00368    eh_message( "characteristic distance (m): %f" , s_0    );
00369    eh_message( "characteristic time (s)    : %f" , t_0    );
00370 
00371    return 0;
00372 }
00373 /*
00374 gboolean dump_failure_data( gpointer ptr , FILE *fp )
00375 {
00376    Failure_proc_t *data = (Failure_proc_t*)ptr;
00377 
00378    fwrite( data , sizeof(Failure_t) , 1 , fp );
00379 
00380    sed_dump_process( fp , data->turbidity_current );
00381    sed_dump_process( fp , data->debris_flow       );
00382    sed_dump_process( fp , data->slump             );
00383 
00384    fail_dump_fail_profile( data->fail_prof , fp );
00385 
00386    return TRUE;
00387 }
00388 
00389 gboolean load_failure_data( gpointer ptr , FILE *fp )
00390 {
00391    Failure_proc_t *data = (Failure_proc_t*)ptr;
00392 
00393    fread( data , sizeof(Failure_t) , 1 , fp );
00394 
00395    sed_load_process( data->turbidity_current , fp );
00396    sed_load_process( data->debris_flow       , fp );
00397    sed_load_process( data->slump             , fp );
00398 
00399    fail_load_fail_profile( fp );
00400 
00401    return TRUE;
00402 }
00403 */
00404 
00405 

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