00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #define SED_BEDLOAD_PROC_NAME "bedload dumping"
00022 #define EH_LOG_DOMAIN SED_BEDLOAD_PROC_NAME
00023
00024 #include <stdio.h>
00025 #include <limits.h>
00026 #include <string.h>
00027 #include <math.h>
00028 #include <utils/utils.h>
00029 #include <sed/sed_sedflux.h>
00030 #include "my_processes.h"
00031 #include "sedflux.h"
00032
00033 #define BED_LOAD_SPREADING_ANGLE (14.*S_RADS_PER_DEGREE)
00034
00035 typedef struct
00036 {
00037 double x_0;
00038 double y_0;
00039 double dx;
00040 double dy;
00041 double r_max;
00042 double min_angle;
00043 double max_angle;
00044 }
00045 Bed_load_data;
00046
00047 double deposit_in_ocean ( Sed_cube p , Sed_riv r , double vol , Eh_dbl_grid fraction_grid );
00048 double deposit_in_river ( Sed_cube p , Sed_riv r , double vol );
00049 gboolean bed_load_2d_domain( double x , double y , Bed_load_data *user_data );
00050 gboolean bed_load_1d_domain( double x , double y , Bed_load_data *user_data );
00051
00052 Sed_process_info
00053 run_bedload( Sed_process p , Sed_cube prof )
00054 {
00055 Bedload_dump_t* data = sed_process_user_data(p);
00056 Sed_process_info info = SED_EMPTY_INFO;
00057 Sed_riv this_river = sed_cube_river_by_name( prof , data->river_name );
00058
00059 if ( this_river )
00060 {
00061 Eh_pt_2* river_mouth;
00062
00063
00064 if ( sed_mode_is_3d() )
00065 river_mouth = sed_cube_river_mouth_position( prof , this_river );
00066 else
00067 {
00068 river_mouth = eh_new( Eh_pt_2 , 1 );
00069 river_mouth->x = sed_cube_col_x(prof,0);
00070 river_mouth->y = sed_cube_col_y(prof,sed_cube_river_mouth_1d( prof ) );
00071 }
00072
00073
00074 if ( river_mouth )
00075 {
00076
00077 gint bed_load_n_x = data->bed_load_dump_length / sed_cube_x_res( prof ) + 1;
00078 gint bed_load_n_y = data->bed_load_dump_length / sed_cube_y_res( prof ) + 1;
00079 double mass_ocean = 0;
00080 double mass_delta = 0;
00081 Eh_dbl_grid fraction_grid;
00082
00083 eh_upper_bound( bed_load_n_x , sed_cube_n_x(prof) );
00084 eh_upper_bound( bed_load_n_y , sed_cube_n_y(prof) );
00085
00086
00087
00088
00089
00090 fraction_grid = eh_grid_new( double , 2.*bed_load_n_x , 2.*bed_load_n_y );
00091
00092 if ( fraction_grid )
00093 {
00094 Bed_load_data bed_load_data;
00095 double bed_load_spreading_angle = BED_LOAD_SPREADING_ANGLE;
00096
00097 fraction_grid = eh_grid_reindex( fraction_grid , -bed_load_n_x , -bed_load_n_y );
00098
00099 river_mouth->x /= sed_cube_x_res( prof );
00100 river_mouth->y /= sed_cube_y_res( prof );
00101 river_mouth->x -= sed_river_mouth(this_river).i;
00102 river_mouth->y -= sed_river_mouth(this_river).j;
00103
00104 bed_load_data.x_0 = river_mouth->x;
00105 bed_load_data.y_0 = river_mouth->y;
00106 bed_load_data.dx = sed_cube_x_res( prof );
00107 bed_load_data.dy = sed_cube_y_res( prof );
00108 bed_load_data.r_max = data->bed_load_dump_length;
00109 bed_load_data.min_angle = sed_river_angle( this_river )
00110 - bed_load_spreading_angle;
00111 bed_load_data.max_angle = sed_river_angle( this_river )
00112 + bed_load_spreading_angle;
00113
00114
00115
00116
00117
00118 if ( sed_mode_is_3d() )
00119 eh_dbl_grid_populate( fraction_grid ,
00120 (Populate_func)&bed_load_2d_domain ,
00121 &bed_load_data );
00122 else
00123 eh_dbl_grid_populate( fraction_grid ,
00124 (Populate_func)&bed_load_1d_domain ,
00125 &bed_load_data );
00126 }
00127
00128 {
00129 gint i, j;
00130 const gint low_x = eh_grid_low_x(fraction_grid);
00131 const gint low_y = eh_grid_low_y(fraction_grid);
00132 const gint high_x = low_x + eh_grid_n_x(fraction_grid);
00133 const gint high_y = low_y + eh_grid_n_y(fraction_grid);
00134
00135
00136 for ( i=low_x ; i<high_x ; i++ )
00137 for ( j=low_y ; j<high_y ; j++ )
00138 {
00139 if ( eh_dbl_grid_val(fraction_grid,i,j) > 0 )
00140 eh_dbl_grid_set_val( fraction_grid , i , j , 1. );
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 double vol_total = (sed_river_bedload(this_river)*S_SECONDS_PER_DAY)
00174 * sed_cube_time_step_in_days( prof )
00175 / sed_type_rho_sat( sed_sediment_type( NULL , 0 ) );
00176
00177 double vol_delta = vol_total*data->f_retained;
00178 double vol_ocean = vol_total*(1.-data->f_retained);
00179
00180 if ( vol_ocean>0 ) mass_ocean = deposit_in_ocean( prof , this_river , vol_ocean , fraction_grid );
00181 if ( vol_delta>0 ) mass_delta = deposit_in_river( prof , this_river , vol_delta );
00182 }
00183
00184 {
00185 double input_mass = sed_river_bedload( this_river )
00186 * sed_cube_time_step_in_seconds( prof );
00187 double add_mass = mass_ocean + mass_delta;
00188
00189
00190
00191 info.mass_added = sed_river_bedload( this_river )
00192 * sed_cube_time_step_in_seconds( prof );
00193 info.mass_lost = 0.;
00194
00195
00196 eh_message( "bedload input (kg): %g" , input_mass );
00197 eh_message( "bedload added (kg): %g" , add_mass );
00198 eh_message( "mass added to delta plain (kg): %g" , mass_delta );
00199 eh_message( "mass added to ocean (kg): %g" , mass_ocean );
00200 }
00201
00202 eh_grid_destroy ( fraction_grid , TRUE );
00203
00204 }
00205
00206 eh_free( river_mouth );
00207 }
00208
00209 return info;
00210 }
00211
00212 #define BEDLOAD_KEY_DUMP_LEN "distance to dump bedload"
00213 #define BEDLOAD_KEY_RATIO "ratio of flood plain to bedload rate"
00214 #define BEDLOAD_KEY_RETAINED "fraction of bedload retained in the delta plain"
00215 #define BEDLOAD_KEY_RIVER_NAME "river name"
00216
00217 static gchar* bedload_req_labels[] =
00218 {
00219 BEDLOAD_KEY_DUMP_LEN ,
00220 BEDLOAD_KEY_RATIO ,
00221 BEDLOAD_KEY_RETAINED ,
00222 BEDLOAD_KEY_RIVER_NAME ,
00223 NULL
00224 };
00225
00226 gboolean
00227 init_bedload( Sed_process p , Eh_symbol_table t , GError** error )
00228 {
00229 Bedload_dump_t* data = sed_process_new_user_data( p , Bedload_dump_t );
00230 GError* tmp_err = NULL;
00231 gboolean is_ok = TRUE;
00232 gchar** err_s = NULL;
00233
00234 if ( eh_symbol_table_require_labels( t , bedload_req_labels , &tmp_err ) )
00235 {
00236 data->bed_load_dump_length = eh_symbol_table_dbl_value( t , BEDLOAD_KEY_DUMP_LEN );
00237 data->bedload_ratio = eh_symbol_table_dbl_value( t , BEDLOAD_KEY_RATIO );
00238 data->f_retained = eh_symbol_table_dbl_value( t , BEDLOAD_KEY_RETAINED );
00239 data->river_name = eh_symbol_table_value ( t , BEDLOAD_KEY_RIVER_NAME );
00240
00241 eh_check_to_s( data->bed_load_dump_length>0 , "Dump length positive" , &err_s );
00242 eh_check_to_s( data->bedload_ratio>=0 , "Bedload ratio positive" , &err_s );
00243 eh_check_to_s( data->f_retained>=0 , "Bedload retention positive" , &err_s );
00244 eh_check_to_s( data->f_retained<=1. , "Bedload retention less than one" , &err_s );
00245
00246 if ( !tmp_err && err_s )
00247 eh_set_error_strv( &tmp_err , SEDFLUX_ERROR , SEDFLUX_ERROR_BAD_PARAM , err_s );
00248 }
00249
00250 if ( tmp_err )
00251 {
00252 g_propagate_error( error , tmp_err );
00253 is_ok = FALSE;
00254 }
00255
00256 return is_ok;
00257 }
00258
00259 gboolean
00260 destroy_bedload( Sed_process p )
00261 {
00262 if ( p )
00263 {
00264 Bedload_dump_t* data = sed_process_user_data( p );
00265
00266 if ( data )
00267 {
00268 eh_free( data->river_name );
00269 eh_free( data );
00270 }
00271 }
00272
00273 return TRUE;
00274 }
00275
00276 double
00277 deposit_in_ocean( Sed_cube p , Sed_riv r , double vol , Eh_dbl_grid fraction_grid )
00278 {
00279 double dep_vol = 0.;
00280
00281 eh_require( p );
00282 eh_require( r );
00283 eh_require( fraction_grid );
00284 eh_require( vol>=0 );
00285
00286 if ( vol>0 )
00287 {
00288 Sed_cell_grid in_suspension = sed_cube_in_suspension( p , r );
00289
00290 if ( in_suspension )
00291 {
00292 const double area = eh_dbl_grid_sum( fraction_grid )
00293 * sed_cube_x_res( p )
00294 * sed_cube_y_res( p );
00295
00296 if ( area>0 )
00297 {
00298 Sed_cell c = sed_cell_new_bedload( NULL , area/vol );
00299
00300 {
00301
00302
00303
00304
00305 }
00306
00307 {
00308 gint i, j;
00309 const gint low_x = eh_grid_low_x(fraction_grid);
00310 const gint low_y = eh_grid_low_y(fraction_grid);
00311 const gint high_x = low_x + eh_grid_n_x(fraction_grid);
00312 const gint high_y = low_y + eh_grid_n_y(fraction_grid);
00313 const double t = area / vol;
00314
00315 for ( i=low_x ; i<high_x ; i++ )
00316 for ( j=low_y ; j<high_y ; j++ )
00317 {
00318 if( eh_dbl_grid_val(fraction_grid,i,j) > 0 )
00319 {
00320 sed_cell_resize( c , t*eh_dbl_grid_val(fraction_grid,i,j) );
00321 sed_cell_add ( sed_cell_grid_val(in_suspension,i,j) , c );
00322 }
00323 }
00324
00325 sed_cell_destroy( c );
00326 }
00327 }
00328 }
00329 else
00330 eh_require_not_reached();
00331 }
00332
00333 return dep_vol;
00334 }
00335
00344 double
00345 deposit_in_river( Sed_cube p , Sed_riv r , double vol )
00346 {
00347 double vol_dep = 0;
00348
00349 eh_require( p );
00350 eh_require( r );
00351 eh_require( vol>=0 );
00352
00353 if ( p && r && vol>0 )
00354 {
00355 gssize* river_path = sed_cube_river_path_id( p , r , TRUE );
00356
00357 eh_require( river_path );
00358
00359 if ( river_path )
00360 {
00361 Sed_cube river_profile = sed_cube_cols( p , river_path );
00362 Sed_hydro river_data = sed_river_hydro( r );
00363 gint i_river = sed_cube_river_mouth_1d( river_profile ) - 1;
00364
00365 eh_require( river_data );
00366 eh_require( river_profile );
00367
00368 if ( i_river>0 )
00369 {
00370
00371 if ( sed_mode_is_3d() )
00372 {
00373 sed_cube_set_x_res( river_profile , sed_river_width(r) );
00374 sed_cube_set_y_res( river_profile , .5*(sed_cube_x_res(p)+sed_cube_y_res(p)) );
00375 }
00376 else
00377 {
00378 sed_cube_set_x_res( river_profile , sed_cube_x_res(p) );
00379 sed_cube_set_y_res( river_profile , sed_cube_y_res(p) );
00380 }
00381
00382 {
00383 gint i;
00384 double area = sed_cube_x_res( river_profile )
00385 * sed_cube_y_res( river_profile )
00386 * i_river;
00387 Sed_cell c = sed_cell_new_bedload( NULL , area/vol );
00388
00389 for ( i=0 ; i<i_river ; i++ )
00390 sed_column_add_cell( sed_cube_col(river_profile,i) , c );
00391 vol_dep = vol;
00392
00393 sed_cell_destroy( c );
00394 }
00395
00396 }
00397
00398 eh_free ( river_path );
00399 sed_cube_free ( river_profile , FALSE );
00400 }
00401 }
00402
00403 return vol_dep;
00404 }
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467 gboolean bed_load_1d_domain( double x , double y , Bed_load_data *user_data )
00468 {
00469 double y_0 = user_data->y_0;
00470 double dy = user_data->dy;
00471 double r_max = user_data->r_max;
00472
00473 y*=dy;
00474
00475 if ( y >= y_0 && y <= y_0+r_max && x>0 )
00476 return TRUE;
00477
00478 return FALSE;
00479 }
00480
00481 gboolean bed_load_2d_domain( double x , double y , Bed_load_data *user_data )
00482 {
00483 double x_0 = user_data->x_0;
00484 double y_0 = user_data->y_0;
00485 double dx = user_data->dx;
00486 double dy = user_data->dy;
00487 double r_max = user_data->r_max;
00488 double a_min = user_data->min_angle;
00489 double a_max = user_data->max_angle;
00490 double r, a;
00491
00492 r = sqrt( pow( (x - x_0)*dx , 2. ) + pow( (y - y_0)*dy , 2. ) );
00493
00494 if ( r < r_max )
00495 {
00496 a_min = eh_reduce_angle( a_min );
00497 a_max = eh_reduce_angle( a_max );
00498
00499 a = atan2( (y - y_0)*dy , (x - x_0)*dx );
00500 if ( a_min > a_max )
00501 {
00502 if ( a < a_max )
00503 a += 2.*M_PI;
00504 a_max += 2.*M_PI;
00505 }
00506 if ( a > a_min && a < a_max )
00507 return TRUE;
00508 }
00509 return FALSE;
00510 }
00511