/Users/huttone/Devel/sedflux-new/sedflux/trunk/ew/sedflux/run_erosion.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 EH_LOG_DOMAIN EROSION_PROCESS_NAME_S
00022 
00023 #include <stdio.h>
00024 #include <string.h>
00025 
00026 #include <utils/utils.h>
00027 #include <sed/sed_sedflux.h>
00028 #include <diffusion.h>
00029 #include "my_processes.h"
00030 
00031 //#include "erosion.h"
00032 
00033 #define RIVER_SLOPE 0.001
00034 
00035 /* These are values that were measured for the Homathko.
00036 */
00037 #define A_DELTA 6.1
00038 #define B_DELTA .000059
00039 /* These are values that were measured for the Kliniklini.
00040 #define A_DELTA 5.7
00041 #define B_DELTA .000093
00042 */
00043 #define OMEGA_DELTA 6
00044 #define H_DELTA 10
00045 #define L_DELTA 10000
00046 
00047 #define PAOLA_MEANDERING (1)
00048 #define PAOLA_BRAIDED    (2)
00049 
00050 #define EROSION_ALGORITHM_DIFFUSION (1)
00051 #define EROSION_ALGORITHM_SLOPE     (2)
00052 
00053 Sed_cell erode_river_profile( Sed_cube p , Sed_riv r , double slope , gint method );
00054 
00055 Sed_process_info
00056 run_erosion( Sed_process proc , Sed_cube p )
00057 {
00058    Erosion_t*       data = sed_process_user_data(proc);
00059    Sed_process_info info = SED_EMPTY_INFO;
00060    Sed_riv* all;
00061 
00062 //   for ( this_river=sed_cube_river_list(p) ; this_river ; this_river=this_river->next )
00063 /*
00064    for ( n=0,this_river = sed_cube_nth_river(p,n) ;
00065          n<n_rivers ;
00066          n++,this_river = sed_cube_nth_river(p,n) )
00067 */
00068 
00069    all = sed_cube_all_leaves( p );
00070 
00071    if ( all )
00072    {
00073       Sed_riv* r;
00074       Sed_cell eroded_sed = NULL;
00075 
00076       for ( r=all ; *r ; r++ )
00077       {
00078          eh_debug( "Eroding along river %s" , sed_river_name_loc( *r ) );
00079 
00080          eroded_sed = erode_river_profile( p , *r , data->slope , data->method );
00081          sed_cell_destroy( eroded_sed );
00082 /*
00083          river_path = sed_cube_river_path_id( p , *r , TRUE );
00084       
00085          river_profile = sed_cube_cols( p , river_path );
00086 
00087          if ( sed_mode_is_3d() )
00088          {
00089             sed_cube_set_x_res( river_profile , 1. );
00090             sed_cube_set_y_res( river_profile , .5*(sed_cube_x_res(p)+sed_cube_y_res(p)) );
00091          }
00092          else
00093          {
00094             sed_cube_set_x_res( river_profile , sed_cube_x_res(p) );
00095             sed_cube_set_y_res( river_profile , sed_cube_y_res(p) );
00096          }
00097    
00098          eh_free( river_path );
00099       
00100    //      river_data    = ((Sed_river*)(this_river->data))->data;
00101          river_data = sed_river_hydro( *r );
00102    
00103          if ( data->method == EROSION_ALGORITHM_DIFFUSION )
00104             eroded_sed = diffuse_profile( river_profile , river_data );
00105          else
00106             eroded_sed = erode_profile( river_profile , river_data );
00107 
00108          sed_hydro_add_cell( river_data , eroded_sed );
00109 
00110          sed_river_set_hydro( *r , river_data );
00111          sed_hydro_destroy  ( river_data );
00112    
00113          sed_cube_free( river_profile , FALSE );
00114 */
00115 
00116 /*
00117          if ( data->method == EROSION_ALGORITHM_DIFFUSION )
00118          {
00119 
00120             dt            = sed_cube_time_step_in_days( river_profile );
00121    //         time_fraction = 1e-1;
00122             time_fraction = 1e-0;
00123             if ( sed_mode_is_3d() )
00124                basin_width   = sed_cube_x_res( river_profile );
00125             else
00126                basin_width   = sed_cube_x_res( p );
00127       
00128             k_land  = get_paola_diffusion( river_data    , basin_width ,
00129                                            time_fraction , PAOLA_BRAIDED )
00130                     * S_SECONDS_PER_DAY;
00131             k_land *= sed_cube_storm( river_profile );
00132       
00133    //         k_land = 200;
00134    //         dt = 15;
00135    
00136             eh_message( "diffusion coefficient : %.3e m^2/day" , k_land );
00137             eh_message( "time step : %.3e days"                , dt     );
00138    
00139             lost_cell = diffuse_sediment( river_profile , k_land ,
00140                                           0             , dt     ,
00141                                           DIFFUSION_OPT_LAND|DIFFUSION_OPT_FILL );
00142              
00143             // convert time step to seconds.
00144    //         dt = sed_get_profile_time_step_in_seconds(p);
00145             if ( lost_cell )
00146             {
00147                dx    = sed_cube_y_res( river_profile );
00148                width = sed_hydro_width( river_data );
00149       
00150                // add the eroded sediment to the river discharge.
00151                volume_eroded = sed_cell_size(lost_cell[1])*dx*width;
00152       
00153                sed_cell_separate_cell( lost_cell[1] , lost_cell[3] );
00154       
00155                dt *= S_SECONDS_PER_DAY;
00156 
00157                sed_hydro_add_cell( river_data , lost_cell[2] , volume_eroded );
00158                sed_hydro_add_cell( river_data , lost_cell[1] , volume_eroded );
00159       
00160                sed_cell_destroy( lost_cell[0] );
00161                sed_cell_destroy( lost_cell[1] );
00162                sed_cell_destroy( lost_cell[2] );
00163                sed_cell_destroy( lost_cell[3] );
00164                eh_free( lost_cell );
00165             }
00166       
00167             eh_message( "eroded sediment (m^3): %.3g" , volume_eroded );
00168       
00169          }
00170          else
00171          {
00172             eroded_fraction = eh_new( double , n_grains );
00173          
00174             for (i=0;i<n_grains;i++)
00175                eroded_fraction[i] = 1.;
00176          
00177             total  = sed_cell_new( n_grains );
00178             eroded = sed_cell_new( n_grains );
00179          
00180             if ( sed_cube_river_mouth_1d( river_profile )<0 )
00181                return info;
00182          
00183             dx    = sed_cube_y_res( river_profile );
00184             width = sed_cube_x_res( river_profile );
00185          
00186             i_river = sed_cube_river_mouth_1d( river_profile ) - 1;
00187             if ( i_river < 0 )
00188                return info;
00189          
00190             river_height = sed_cube_top_height(river_profile,0,i_river);
00191    //         log_const = getLogConstants( OMEGA_DELTA         ,
00192    //                                      data->stream_relief ,
00193    //                                      data->stream_reach);
00194             linear_const = get_linear_constants(   data->stream_relief
00195                                                  / data->stream_reach );
00196       
00197             for (i=i_river-1;i>=0;i--)
00198             {
00199                x = (i-i_river)*dx;
00200    //            height = getLogHeight(x,log_const) + river_height;
00201                height = get_linear_height( x , linear_const ) + river_height;
00202          
00203                eroded_height = sed_cube_top_height(river_profile,0,i)-height;
00204                if ( eroded_height > 1e-12 )
00205                {
00206                   sed_column_extract_top( sed_cube_col(river_profile,i) ,
00207                                           eroded_height                 ,
00208                                           eroded);
00209                   sed_cell_add( total , eroded );
00210                }
00211             }
00212          
00213             if ( sed_cube_river_mouth_1d( river_profile )<0 )
00214                return info;
00215          
00216             // convert time step to seconds.
00217             dt = sed_cube_time_step_in_seconds( river_profile );
00218          
00219             // add the eroded sediment to the river discharge.
00220    //         river_data = sed_cube_river_data( river_profile );
00221          
00222             volume_eroded = sed_cell_size(total)*dx*width;
00223          
00224             sed_hydro_add_cell( river_data  , total , volume_eroded );
00225          
00226             eh_message( "eroded sediment (m^3): %.3g" , volume_eroded );
00227          
00228             sed_cell_destroy( eroded );
00229             sed_cell_destroy( total  );
00230             eh_free( eroded_fraction );
00231          }
00232    
00233          sed_river_set_hydro( *r , river_data );
00234          sed_hydro_destroy  ( river_data );
00235    
00236          sed_cube_free( river_profile , FALSE );
00237 */
00238       }
00239 
00240       eh_free( all );
00241    }
00242 
00243    return info;
00244 }
00245 
00246 #define EROSION_KEY_REACH           "reach of highest order stream"
00247 #define EROSION_KEY_RELIEF          "relief of highest order stream"
00248 #define EROSION_KEY_METHOD          "method"
00249 
00250 static gchar* erosion_req_labels[] =
00251 {
00252    EROSION_KEY_METHOD ,
00253    NULL
00254 };
00255 
00256 static gchar* erosion_slope_req_labels[] =
00257 {
00258    EROSION_KEY_REACH  ,
00259    EROSION_KEY_RELIEF ,
00260    NULL
00261 };
00262 
00263 gboolean
00264 init_erosion( Sed_process p , Eh_symbol_table tab , GError** error )
00265 {
00266    Erosion_t* data    = sed_process_new_user_data( p , Erosion_t );
00267    GError*    tmp_err = NULL;
00268    gchar**    err_s   = NULL;
00269    gboolean   is_ok   = TRUE;
00270 
00271    eh_return_val_if_fail( error==NULL || *error==NULL , FALSE );
00272 
00273    if ( eh_symbol_table_require_labels( tab , erosion_req_labels , &tmp_err ) )
00274    {
00275       gchar*     key = eh_symbol_table_lookup( tab , EROSION_KEY_METHOD );
00276 
00277       if      ( strcasecmp( key , "DIFFUSION" )==0 ) data->method = EROSION_ALGORITHM_DIFFUSION;
00278       else if ( strcasecmp( key , "SLOPE"     )==0 ) data->method = EROSION_ALGORITHM_SLOPE;
00279       else
00280          g_set_error( &tmp_err , SEDFLUX_ERROR , SEDFLUX_ERROR_BAD_ALGORITHM ,
00281                       "Invalid erosion algorithm (diffusion or slope): %s" , key );
00282 
00283       if (    !tmp_err 
00284            && eh_symbol_table_require_labels( tab , erosion_slope_req_labels , &tmp_err ) )
00285       {
00286          data->stream_reach  = eh_symbol_table_dbl_value( tab , EROSION_KEY_REACH  );
00287          data->stream_relief = eh_symbol_table_dbl_value( tab , EROSION_KEY_RELIEF );
00288 
00289          eh_check_to_s( data->stream_reach>=0  , "Stream reach positive"  , &err_s );
00290          eh_check_to_s( data->stream_relief>=0 , "Stream relief positive" , &err_s );
00291 
00292          data->slope         = data->stream_relief / data->stream_reach;
00293 
00294          if ( !tmp_err && err_s )
00295             eh_set_error_strv( &tmp_err , SEDFLUX_ERROR , SEDFLUX_ERROR_BAD_PARAM , err_s );
00296       }
00297    }
00298 
00299    if ( tmp_err )
00300    {
00301       g_propagate_error( error , tmp_err );
00302       is_ok = FALSE;
00303    }
00304 
00305    return is_ok;
00306 }
00307 
00308 gboolean
00309 destroy_erosion( Sed_process p )
00310 {
00311    if ( p )
00312    {
00313       Erosion_t* data = sed_process_user_data( p );
00314 
00315       if ( data ) eh_free( data );
00316    }
00317 
00318    return TRUE;
00319 }
00320 
00321 Sed_cell erode_profile  ( Sed_cube river_profile , double    slope      );
00322 Sed_cell diffuse_profile( Sed_cube river_profile , Sed_hydro river_data );
00323 
00324 Sed_cell
00325 erode_river_profile( Sed_cube p , Sed_riv r , double slope , gint method )
00326 {
00327    Sed_cell eroded_sed = NULL;
00328 
00329    if ( p && r )
00330    {
00331       gssize*  river_path = sed_cube_river_path_id( p , r , TRUE );
00332 
00333       eh_require( river_path );
00334 
00335       if ( river_path )
00336       {
00337          Sed_cube  river_profile = sed_cube_cols( p , river_path );
00338          Sed_hydro river_data    = sed_river_hydro( r );
00339 
00340          eh_require( river_data    );
00341          eh_require( river_profile );
00342 
00343          if ( sed_mode_is_3d() )
00344          {
00345             sed_cube_set_x_res( river_profile , 1. );
00346             sed_cube_set_y_res( river_profile , .5*(sed_cube_x_res(p)+sed_cube_y_res(p)) );
00347          }
00348          else
00349          {
00350             sed_cube_set_x_res( river_profile , sed_cube_x_res(p) );
00351             sed_cube_set_y_res( river_profile , sed_cube_y_res(p) );
00352          }
00353    
00354          switch ( method )
00355          {
00356             case EROSION_ALGORITHM_DIFFUSION:
00357                eroded_sed  = diffuse_profile( river_profile , river_data ); break;
00358             case EROSION_ALGORITHM_SLOPE:
00359                eroded_sed  = erode_profile  ( river_profile , slope      ); break;
00360             default:
00361                eh_require_not_reached();
00362          }
00363 
00364          sed_hydro_add_cell( river_data , eroded_sed );
00365 
00366          sed_river_set_hydro( r , river_data );
00367 
00368          sed_hydro_destroy( river_data );
00369          eh_free          ( river_path );
00370          sed_cube_free    ( river_profile , FALSE );
00371       }
00372    }
00373 
00374    return eroded_sed;
00375 }
00376 
00377 double get_paola_diffusion( Sed_hydro river_data    ,
00378                             double    basin_width   ,
00379                             double    time_fraction ,
00380                             int       river_type );
00381 Sed_cell
00382 diffuse_profile( Sed_cube river_profile , Sed_hydro river_data )
00383 {
00384    Sed_cell eroded_sed = NULL;
00385 
00386    eh_require( river_profile );
00387 
00388    if ( river_profile )
00389    {
00390       double    time_fraction = 1e-0;
00391       double    dt            = sed_cube_time_step_in_days( river_profile );
00392       double    width         = sed_cube_x_res( river_profile );
00393       Sed_cell* lost_cell     = NULL;
00394       double    k_land;
00395       
00396       k_land  = get_paola_diffusion( river_data , width , time_fraction , PAOLA_BRAIDED )
00397               * S_SECONDS_PER_DAY
00398               * sed_cube_storm( river_profile );
00399    //         k_land = 200;
00400    //         dt = 15;
00401 /*
00402       eh_message( "diffusion coefficient : %.3e m^2/day" , k_land );
00403       eh_message( "time step : %.3e days"                , dt     );
00404 */
00405       lost_cell = diffuse_sediment( river_profile , k_land ,
00406                                     0             , dt     ,
00407                                     DIFFUSION_OPT_LAND|DIFFUSION_OPT_FILL );
00408 
00409       // convert time step to seconds.
00410    //         dt = sed_get_profile_time_step_in_seconds(p);
00411       if ( lost_cell )
00412       {
00413          double dx          = sed_cube_y_res ( river_profile );
00414          double river_width = sed_hydro_width( river_data    );
00415       
00416          /* The volume of sediment diffused through the right boundary.  This
00417             is the sediment that has made it to the ocean. */
00418 //         volume_eroded = sed_cell_size(lost_cell[1])*dx*river_width;
00419 
00420          /* Bedload may have been added along the profile ([3]).  Remove this from the sediment
00421             that is diffused through the right boundary ([1]). */
00422          sed_cell_separate_cell( lost_cell[1] , lost_cell[3] );
00423       
00424 //         dt *= S_SECONDS_PER_DAY;
00425 
00426          eroded_sed = sed_cell_new_env();
00427 
00428          sed_cell_add   ( eroded_sed , lost_cell[1] );
00429          sed_cell_add   ( eroded_sed , lost_cell[2] );
00430          sed_cell_resize( eroded_sed , sed_cell_size(eroded_sed)*dx*river_width );
00431 /*
00432          // Add suspended sediment to the river
00433          sed_hydro_add_cell( river_data , lost_cell[2] , volume_eroded );
00434 
00435          // Add sediment diffused out of the right boundary to the river
00436          sed_hydro_add_cell( river_data , lost_cell[1] , volume_eroded );
00437 */
00438          sed_cell_destroy( lost_cell[0] );
00439          sed_cell_destroy( lost_cell[1] );
00440          sed_cell_destroy( lost_cell[2] );
00441          sed_cell_destroy( lost_cell[3] );
00442 
00443          eh_free( lost_cell );
00444       }
00445       
00446 //      eh_message( "eroded sediment (m^3): %.3g" , volume_eroded );
00447    }
00448 
00449    return eroded_sed;
00450 }
00451       
00452 typedef struct
00453 {
00454    double x0, y0;
00455    double H1, Rl, b;
00456 } Erosion_log_st;
00457 
00458 typedef struct
00459 {
00460    double a, b;
00461 } Erosion_lin_st;
00462 
00463 typedef struct
00464 {
00465    double a, b;
00466 } Erosion_exp_st;
00467 
00468 Erosion_lin_st erosion_get_linear_constants(double slope);
00469 double         erosion_get_linear_height   (double x , Erosion_lin_st c);
00470 
00471 Sed_cell
00472 erode_profile( Sed_cube river_profile , double slope )
00473 {
00474    Sed_cell eroded_sed = sed_cell_new_env();
00475 
00476    eh_require( river_profile );
00477 
00478    if (    river_profile 
00479         && sed_cube_river_mouth_1d( river_profile) > 0 )
00480    {
00481       Sed_cell eroded  = sed_cell_new_env( );
00482       gint     i_river = sed_cube_river_mouth_1d( river_profile ) - 1;
00483       double   dx      = sed_cube_y_res( river_profile );
00484       double   width   = sed_cube_x_res( river_profile );
00485       Erosion_lin_st linear_const = erosion_get_linear_constants( slope );
00486       gint i;
00487       double x;
00488       double height;
00489       double river_height;
00490       double erode_height;
00491          
00492       river_height = sed_cube_top_height( river_profile , 0 , i_river );
00493       
00494       for ( i=i_river-1 ; i>=0 ; i-- )
00495       {
00496          x      = (i-i_river)*dx;
00497          height = erosion_get_linear_height( x , linear_const ) + river_height;
00498          
00499          erode_height = sed_cube_top_height(river_profile,0,i)-height;
00500          if ( erode_height > 1e-12 )
00501          {
00502             sed_column_extract_top( sed_cube_col(river_profile,i) ,
00503                                     erode_height                 ,
00504                                     eroded);
00505             sed_cell_add( eroded_sed , eroded );
00506          }
00507       }
00508          
00509       // convert time step to seconds.
00510       //dt = sed_cube_time_step_in_seconds( river_profile );
00511          
00512             // add the eroded sediment to the river discharge.
00513    //         river_data = sed_cube_river_data( river_profile );
00514          
00515 //      volume_eroded = sed_cell_size(eroded_sed)*dx*width;
00516 
00517       sed_cell_resize( eroded_sed , sed_cell_size(eroded_sed)*dx*width );
00518          
00519       //sed_hydro_add_cell( river_data  , eroded_sed );
00520          
00521 //      eh_message( "eroded sediment (m^3): %.3g" , volume_eroded );
00522          
00523       sed_cell_destroy( eroded );
00524    }
00525 
00526    return eroded_sed;
00527 }
00528 
00529 double get_paola_diffusion( Sed_hydro river_data ,
00530                             double basin_width   ,
00531                             double time_fraction ,
00532                             int river_type )
00533 {
00534    double q, c_0, a, c_f, s;
00535 
00536    eh_require( river_data!=NULL );
00537 
00538    q = time_fraction
00539      * sed_hydro_water_flux( river_data )
00540      / sed_hydro_width( river_data )
00541      / basin_width;
00542 
00543    c_0 = sed_hydro_suspended_concentration( river_data );
00544 
00545    if      ( river_type==PAOLA_MEANDERING ) a = 1.;
00546    else if ( river_type==PAOLA_BRAIDED    ) a = pow( .4 / (1+.4) , 1.5 );
00547    else eh_require_not_reached();
00548 
00549    c_f = .01;
00550    s   = sed_rho_quartz()/sed_rho_sea_water();
00551 
00552    return 8*q*a*sqrt(c_f)/( c_0*(s-1) );
00553 }
00554 
00555 /* Various functions used to generate a longitudinal stream profile.
00556 */
00557 
00558 #include <math.h>
00559 
00560 /* A linear profile.
00561 */
00562 Erosion_lin_st
00563 erosion_get_linear_constants(double slope)
00564 {
00565    Erosion_lin_st c;
00566    c.a = slope;
00567    return c;
00568 }
00569 
00570 double
00571 erosion_get_linear_height(double x, Erosion_lin_st c)
00572 {
00573    return -x*c.a;
00574 }
00575 
00576 /* An exponential profile.
00577 */
00578 Erosion_exp_st
00579 erosion_get_exp_constants(double a, double b)
00580 {
00581    Erosion_exp_st c;
00582    c.a = a;
00583    c.b = b;
00584    return c;
00585 }
00586 
00587 double
00588 erosion_get_exp_profile(double x, Erosion_exp_st c)
00589 {
00590    return c.b*(exp(-c.a*x)-1);
00591 }
00592 
00593 /* A -log profile.
00594 */
00595 
00596 /* Constants for a specific stream used to estimate it's 
00597    longitudinal profile.
00598 */
00599 
00600 Erosion_log_st
00601 erosion_get_log_constants(double omega,double h,double l)
00602 {
00603    Erosion_log_st c;
00604    int i;
00605 
00606    /* x0,y0 will be the location of the order 1 stream from the 
00607       river mouth.
00608    */
00609    c.y0 = omega*h;
00610    for (i=1,c.x0=0;i<=omega;i++)
00611       c.x0 -= l/pow(2,i-1);
00612    c.H1 = h;
00613    c.Rl = 2;
00614    c.b  = l/pow(2,omega-1)/(2-1.);
00615 
00616    return c;
00617 }
00618 
00619 double
00620 eroion_get_log_height( double x , Erosion_log_st c )
00621 {
00622    double constant;
00623    constant = 1+(x-c.x0)/c.b;
00624    if ( constant < .0001 )
00625       constant = .0001;
00626    return c.y0-(c.H1/log(c.Rl))*log(constant);
00627 }
00628 

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