00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
00032
00033 #define RIVER_SLOPE 0.001
00034
00035
00036
00037 #define A_DELTA 6.1
00038 #define B_DELTA .000059
00039
00040
00041
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
00063
00064
00065
00066
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
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
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
00400
00401
00402
00403
00404
00405 lost_cell = diffuse_sediment( river_profile , k_land ,
00406 0 , dt ,
00407 DIFFUSION_OPT_LAND|DIFFUSION_OPT_FILL );
00408
00409
00410
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
00417
00418
00419
00420
00421
00422 sed_cell_separate_cell( lost_cell[1] , lost_cell[3] );
00423
00424
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
00433
00434
00435
00436
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
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
00510
00511
00512
00513
00514
00515
00516
00517 sed_cell_resize( eroded_sed , sed_cell_size(eroded_sed)*dx*width );
00518
00519
00520
00521
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
00556
00557
00558 #include <math.h>
00559
00560
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
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
00594
00595
00596
00597
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
00607
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