00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00032 #include <stdio.h>
00033 #include <math.h>
00034 #include <string.h>
00035 #include <glib.h>
00036 #include <utils/utils.h>
00037 #include <sed/sed_sedflux.h>
00038 #include "xshore.h"
00039
00040 double get_closure_depth( Sed_cube p , Sed_wave wave );
00041 double get_h_c( Sed_wave wave );
00042 gssize get_zone_indices( Sed_cube p , double z_0 , double z_1 , gssize i_0 , Sed_grid_func get_val , gssize* ind );
00043
00044 typedef struct
00045 {
00046 double u_0;
00047 Sed_wave w;
00048 Sed_cube p;
00049 gssize* ind;
00050 gssize ind_len;
00051
00052 double x_0;
00053 double x_b;
00054 double h_b;
00055 double dz_dx;
00056 double *k;
00057 }
00058 Bruun_data G_GNUC_INTERNAL;
00059
00060 double get_total_flux( double z ,
00061 double dz_dx ,
00062 Sed_wave w ,
00063 double u_0 ,
00064 double w_s ,
00065 double breaker_depth ,
00066 double h_b ,
00067 double x ,
00068 double x_b ,
00069 double max_qx ) G_GNUC_INTERNAL;
00070 Sed_cell move_sediment ( Sed_cube p ,
00071 double** du ,
00072 double* erosion_limit ,
00073 double z_0 ,
00074 double dt ,
00075 Bruun_data* data ,
00076 Sed_cell lost ,
00077 Sed_cell added ,
00078 Sed_cell in_suspension ) G_GNUC_INTERNAL;
00079
00080 void update_bruun_zone_data( Bruun_data* data )
00081 {
00082 if ( data && data->ind_len>2 )
00083 {
00084 gssize n;
00085 double *w_s, u_om, d_max;
00086 double q_left, q_right;
00087 Sed_cube p = data->p;
00088 double breaker_depth = get_breaking_wave_depth( data->w );
00089 double h_b_left, h_b_right, x_b_left;
00090 gssize i_0 = data->ind[0];
00091 gssize i_b = data->ind[data->ind_len-1];
00092 gssize n_grains = sed_sediment_env_n_types();
00093 Sed_wave this_wave;
00094
00095 eh_require( i_0 >= 0 );
00096 eh_require( i_b >= 0 );
00097 eh_require( i_b-1 >= 0 );
00098
00099 data->x_0 = sed_cube_col_y( p,i_0 );
00100 data->x_b = sed_cube_col_y( p,i_b );
00101
00102 data->h_b = sed_cube_water_depth(p,0,i_b);
00103 data->dz_dx = sed_cube_y_slope( p , 0 , i_b );
00104 h_b_left = sed_cube_water_depth( p,0,i_b-1 );
00105 h_b_right = sed_cube_water_depth( p,0,i_b+1 );
00106 x_b_left = sed_cube_col_y( p,i_b-1 );
00107 this_wave = sed_gravity_wave_new( data->w , data->h_b , NULL );
00108
00109 w_s = sed_sediment_property( NULL , &sed_type_settling_velocity );
00110
00111 for ( n=0 ; n<n_grains ; n++ )
00112 {
00113 w_s[n] /= S_SECONDS_PER_DAY;
00114 u_om = get_near_bed_velocity( data->h_b ,
00115 data->w ,
00116 breaker_depth );
00117 d_max = get_grain_size_threshold( u_om , sed_wave_period( data->w ) );
00118
00119
00120
00121
00122
00123
00124
00125
00126 data->k[n] = get_diffusion_constant( data->h_b ,
00127 this_wave ,
00128 w_s[n] ,
00129 breaker_depth )
00130 * ( h_b_right - data->h_b )/( data->h_b - h_b_left )
00131 * pow( (data->x_b-data->x_0) / (x_b_left-data->x_0) , 1.-XSHORE_BRUUN_M );
00132
00133 q_left = get_total_flux( h_b_left ,
00134 sed_cube_y_slope(p,0,i_b-1) ,
00135 this_wave ,
00136 data->u_0 ,
00137 w_s[n] ,
00138 breaker_depth ,
00139 data->h_b ,
00140 x_b_left-data->x_0 ,
00141 data->x_b-data->x_0 ,
00142 data->k[n] );
00143 q_right = get_total_flux( data->h_b ,
00144 data->dz_dx ,
00145 this_wave ,
00146 data->u_0 ,
00147 w_s[n] ,
00148 breaker_depth ,
00149 data->h_b ,
00150 data->x_b-data->x_0 ,
00151 data->x_b-data->x_0 ,
00152 data->k[n] );
00153
00154 }
00155
00156 sed_wave_destroy( this_wave );
00157 }
00158 }
00159
00160 void diffuse_cols ( Sed_cube p ,
00161 Sed_wave deep_wave ,
00162 double u_0 ,
00163 double* erosion_limit ,
00164 Sed_column* source_col ,
00165 double* bruun_depth ,
00166 Sed_cell along_shore_cell ,
00167 Bruun_data* data ,
00168 double dt ,
00169 double t_total ,
00170 Sed_cell added ,
00171 Sed_cell in ,
00172 Sed_cell out ) G_GNUC_INTERNAL;
00173 double** get_sediment_flux ( Sed_cube p ,
00174 Sed_wave deep_wave ,
00175 double u_0 ,
00176 Bruun_data *data ,
00177 Sed_cell in );
00178 double get_time_step ( Sed_cube p ,
00179 Sed_wave deep_wave ,
00180 double u_0 ,
00181 Bruun_data* data ) G_GNUC_INTERNAL;
00182
00196 Xshore_info xshore( Sed_cube p ,
00197 Sed_cell along_shore_cell ,
00198 double xshore_current ,
00199 Sed_ocean_storm storm )
00200 {
00201 double z_0;
00202 double* zone_dt;
00203 double** bruun_depth;
00204 double** max_erode_depth;
00205 Sed_wave deep_water_wave;
00206 Sed_cube* shelf_zone;
00207 Sed_column* source_col;
00208 gssize n_zones;
00209 Xshore_info info;
00210 Bruun_data bruun_zone_data;
00211
00212 info.added = NULL;
00213 info.lost = NULL;
00214 info.dt = NULL;
00215
00216 eh_require( sed_cube_is_1d(p) );
00217 eh_require( along_shore_cell );
00218 eh_require( storm );
00219
00220 eh_return_val_if_fail( sed_cube_is_1d(p) , info );
00221 eh_return_val_if_fail( sed_cube_n_y(p) > 3 , info );
00222
00223 deep_water_wave = sed_wave_new( sed_ocean_storm_wave_height( storm ) ,
00224 sed_ocean_storm_wave_number( storm ) ,
00225 sed_ocean_storm_wave_freq ( storm ) );
00226
00227 eh_return_val_if_fail( !sed_wave_is_bad(deep_water_wave) , info );
00228
00229 eh_debug( "Is there a Bruun zone?" );
00230 {
00231 gboolean error = FALSE;
00232 gssize i;
00233
00234 Sed_cube* bruun_zones = get_shelf_zones( p , get_h_c( deep_water_wave ) , NULL );
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244 if ( bruun_zones[0]==NULL || sed_cube_n_y(bruun_zones[0])<=3 )
00245 {
00246
00247 error = TRUE;
00248 sed_wave_destroy( deep_water_wave );
00249 }
00250
00251 for ( i=0 ; bruun_zones[i] ; i++ )
00252 sed_cube_free( bruun_zones[i] , FALSE );
00253
00254 if ( error )
00255 return info;
00256 }
00257
00258 eh_debug( "Calculate the water depth of the inner shelf" );
00259 {
00260 z_0 = get_closure_depth( p , deep_water_wave );
00261 z_0 = 100.;
00262 info.z_0 = z_0;
00263 }
00264
00265 eh_debug( "Divide the profile into smaller regions" );
00266 {
00267 shelf_zone = get_shelf_zones( p , z_0 , NULL );
00268 for ( n_zones=0 ; shelf_zone[n_zones] ; n_zones++ );
00269 info.n_zones = n_zones;
00270
00271 eh_require( n_zones>0 );
00272 }
00273
00274 eh_debug( "Calculate the Bruun profile" );
00275 if ( n_zones>0 )
00276 {
00277 gssize i;
00278 double* y;
00279
00280 gssize** bruun_ind = eh_new( gssize* , 2 );
00281 Sed_cube* bruun_zones = get_shelf_zones( p , get_h_c( deep_water_wave ) , bruun_ind );
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 bruun_depth = eh_new0( double* , n_zones );
00292
00293 if ( bruun_zones[0] && sed_cube_n_y(bruun_zones[0])>3 )
00294 {
00295 double bruun_m = XSHORE_BRUUN_M;
00296 double bruun_a = get_bruun_a ( bruun_zones[0] , bruun_m );
00297 double y_0 = get_bruun_y_0( bruun_zones[0] );
00298 double y_b = get_bruun_y_b( bruun_zones[0] );
00299
00300 for ( i=0 ; i<1; i++ )
00301 {
00302 y = sed_cube_y( shelf_zone[i] , NULL );
00303
00304 bruun_depth[i] = get_bruun_profile( y ,
00305 sed_cube_n_y(shelf_zone[i]) ,
00306 bruun_a ,
00307 bruun_m ,
00308 y_0 ,
00309 y_b );
00310
00311 eh_free( y );
00312 }
00313
00314 bruun_zone_data.p = p;
00315 bruun_zone_data.ind_len = sed_cube_n_y(bruun_zones[0]);
00316 bruun_zone_data.ind = g_memdup( bruun_ind[0] , sizeof(gssize)*bruun_zone_data.ind_len );
00317 bruun_zone_data.w = deep_water_wave;
00318 bruun_zone_data.u_0 = xshore_current;
00319 bruun_zone_data.k = g_new( double , sed_sediment_env_n_types() );
00320
00321 update_bruun_zone_data( &bruun_zone_data );
00322
00323 info.bruun_a = bruun_a;
00324 info.bruun_m = bruun_m;
00325 info.bruun_y_0 = y_0;
00326 info.bruun_y_b = y_b;
00327 info.bruun_h_b = sed_cube_water_depth( bruun_zones[0] ,
00328 0 ,
00329 sed_cube_n_y(bruun_zones[0])-1 );
00330 }
00331
00332 for ( i=0 ; i<n_zones ; i++ )
00333 {
00334 sed_cube_free( bruun_zones[i] , FALSE );
00335 eh_free( bruun_ind[i] );
00336 }
00337 eh_free( bruun_zones );
00338 eh_free( bruun_ind );
00339
00340 }
00341
00342 eh_debug( "Find the column where suspended sediment is added" );
00343 {
00344 gssize i;
00345 Sed_cube* zone = get_shelf_zones( p , 30. , NULL );
00346
00347 if ( zone[1] )
00348 {
00349 source_col = g_new0( Sed_column , 2 );
00350 source_col[0] = sed_cube_col(zone[1],0);
00351 }
00352 else
00353 source_col = NULL;
00354
00355 for ( i=0 ; zone[i] ; i++ )
00356 sed_cube_free( zone[i] , FALSE );
00357 eh_free( zone );
00358 }
00359
00360 eh_debug( "Calculate the maximum erosion depth for this storm" );
00361 if ( n_zones>0 )
00362 {
00363 gssize i;
00364
00365 max_erode_depth = eh_new0( double* , n_zones );
00366 for ( i=0 ; i<1 ; i++ )
00367 max_erode_depth[i] = get_max_erosion_profile( shelf_zone[i] , deep_water_wave );
00368 }
00369
00370 eh_debug( "Calculate the time step for each region" );
00371 if ( n_zones>0 )
00372 {
00373 gssize i;
00374 double t_total = sed_ocean_storm_duration(storm);
00375
00376 zone_dt = eh_new( double , n_zones+1 );
00377 for ( i=0 ; i<1 ; i++ )
00378 {
00379 zone_dt[i] = get_time_step( shelf_zone[i] ,
00380 deep_water_wave ,
00381 xshore_current ,
00382 &bruun_zone_data );
00383 if ( zone_dt[i] > t_total )
00384 zone_dt[i] = t_total;
00385 }
00386 zone_dt[n_zones] = zone_dt[n_zones-1];
00387
00388 info.dt = g_memdup( zone_dt , sizeof(double)*n_zones );
00389 }
00390
00391
00392 eh_debug( "Diffuse each region" );
00393 if ( n_zones>0 )
00394 {
00395 double m_0 = sed_cube_mass( p );
00396 double m_added, m_lost, m_1;
00397 gssize i;
00398 double t;
00399 double t_total = sed_ocean_storm_duration(storm);
00400 gssize n_grains = sed_sediment_env_n_types();
00401 Sed_cell total_lost = sed_cell_new( n_grains );
00402 Sed_cell total_added = sed_cell_new( n_grains );
00403 Sed_cell in = sed_cell_new( n_grains );
00404 Sed_cell out = sed_cell_new( n_grains );
00405 Sed_cell added = sed_cell_new( n_grains );
00406
00407 eh_require( t_total>0 );
00408
00409 for ( t=0 ; t<t_total ; )
00410 {
00411 sed_cell_resize( in , 0. );
00412 for ( i=0 ; i<1 ; i++ )
00413 {
00414 diffuse_cols( shelf_zone[i] ,
00415 deep_water_wave , xshore_current ,
00416 max_erode_depth[i] , source_col ,
00417 bruun_depth[i] , along_shore_cell ,
00418 &bruun_zone_data ,
00419 zone_dt[0] , t_total , added ,
00420 NULL , out );
00421 }
00422
00423 t += t_total;
00424
00425 sed_cell_add( total_lost , in );
00426 }
00427 m_1 = sed_cube_mass(p);
00428
00429 sed_cell_add( total_added , out );
00430
00431 m_added = sed_cell_mass(added)*sed_cube_x_res(p)*sed_cube_y_res(p);
00432 m_lost = sed_cell_mass(out)*sed_cube_x_res(p)*sed_cube_y_res(p);
00433 if ( fabs((m_0+m_added-m_lost-m_1)/m_1) > .01 )
00434 {
00435 eh_watch_dbl( m_0 );
00436 eh_watch_dbl( m_1 );
00437 eh_watch_dbl( m_added );
00438 eh_watch_dbl( m_lost );
00439 exit(0);
00440 }
00441
00442 sed_cell_destroy( in );
00443 sed_cell_destroy( total_added );
00444 sed_cell_destroy( total_lost );
00445
00446 info.lost = out;
00447 info.added = added;
00448 }
00449
00450 eh_debug( "Free memory" );
00451 {
00452 gssize i;
00453
00454 eh_free( zone_dt );
00455 sed_wave_destroy( deep_water_wave );
00456 for ( i=0 ; i<n_zones ; i++ )
00457 {
00458 sed_cube_free( shelf_zone[i] , FALSE );
00459 eh_free( bruun_depth[i] );
00460 eh_free( max_erode_depth[i] );
00461 }
00462 eh_free( shelf_zone );
00463 eh_free( bruun_depth );
00464 eh_free( max_erode_depth );
00465 eh_free( source_col );
00466
00467 eh_free( bruun_zone_data.ind );
00468 eh_free( bruun_zone_data.k );
00469 }
00470 eh_debug( "Done xshore" );
00471
00472 return info;
00473 }
00474
00475
00476
00477
00478
00479
00480
00481 double wave_break_helper( double z , gpointer user_data ) G_GNUC_INTERNAL;
00482
00483 double get_breaking_wave_depth( Sed_wave deep_water )
00484 {
00485 Sed_wave waves[2];
00486 Sed_wave this_wave = sed_wave_new( 0,0,0 );
00487 double min_h, max_h;
00488
00489 eh_require( deep_water );
00490 eh_require( !sed_wave_is_bad(deep_water) );
00491
00492 waves[0] = deep_water;
00493 waves[1] = this_wave;
00494
00495 min_h = sed_wave_height( deep_water )/2.;
00496 max_h = sed_wave_height( deep_water )*2.;
00497
00498
00499
00500 return eh_bisection( &wave_break_helper , min_h , max_h , .1 , waves );
00501 }
00502
00503 double wave_break_helper( double z , gpointer user_data )
00504 {
00505 double ans;
00506 Sed_wave deep_wave = ((Sed_wave*)(user_data))[0];
00507 Sed_wave this_wave = ((Sed_wave*)(user_data))[1];
00508 sed_gravity_wave_new( deep_wave , z , this_wave );
00509 ans = sed_wave_height(this_wave)/z - .78;
00510
00511 return ans;
00512 }
00513
00522 Sed_cube* get_shelf_zones( Sed_cube p , double z_0 , gssize** shelf_ind )
00523 {
00524 const gssize n_zones = 2;
00525 double boundary[3];
00526 Sed_cube* shelf_zones, *all_zones;
00527 gssize** zone_ind;
00528
00529 eh_require( p );
00530
00531 eh_clamp( z_0 , .1 , G_MAXDOUBLE );
00532
00533 boundary[0] = .1;
00534 boundary[1] = z_0;
00535 boundary[2] = G_MAXDOUBLE;
00536
00537 if ( shelf_ind )
00538 memset( shelf_ind , 0 , n_zones*sizeof(gssize*) );
00539
00540 zone_ind = eh_new( gssize* , n_zones );
00541 all_zones = get_zones( p , boundary , n_zones , S_WATER_DEPTH_FUNC , zone_ind );
00542
00543 eh_debug( "Get rid of NULL zones" );
00544 {
00545 gssize i;
00546
00547 shelf_zones = eh_new0( Sed_cube , n_zones+1 );
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558 memcpy( shelf_zones , all_zones , sizeof(Sed_cube)*n_zones );
00559 shelf_zones[n_zones] = NULL;
00560
00561 if ( shelf_ind )
00562 memcpy( shelf_ind , zone_ind , sizeof(gssize*)*n_zones );
00563 else
00564 {
00565 for ( i=0 ; i<n_zones ; i++ )
00566 eh_free( zone_ind[i] );
00567 }
00568 }
00569
00570 eh_free( all_zones );
00571 eh_free( zone_ind );
00572
00573 return shelf_zones;
00574 }
00575
00576 Sed_cube* get_bruun_zones( Sed_cube p , double y_0 )
00577 {
00578 Sed_cube* shelf_zones;
00579 Sed_cube* all_zones;
00580 const gssize n_zones = 2;
00581 gssize i_rm;
00582
00583 eh_require( p );
00584
00585 eh_debug( "Find the start of the Bruun profile" );
00586 {
00587 double sea_level = sed_cube_sea_level( p );
00588
00589 sed_cube_set_sea_level( p , sea_level );
00590
00591 i_rm = sed_cube_river_mouth_1d( p ) - 1;
00592 eh_lower_bound( i_rm , 0 );
00593
00594 sed_cube_set_sea_level( p , sea_level );
00595 }
00596
00597 eh_debug( "Get the zones of the Bruun profile" );
00598 {
00599 double boundary[3];
00600 double y_rm = sed_cube_col_y( p , i_rm );
00601
00602 boundary[0] = 0 + y_rm;
00603 boundary[1] = y_0 + y_rm;
00604 boundary[2] = G_MAXDOUBLE;
00605
00606 all_zones = get_zones( p , boundary , n_zones , S_Y_FUNC , NULL );
00607 }
00608
00609 eh_debug( "Get rid of NULL zones" );
00610 {
00611 gssize i;
00612 gssize n = 0;
00613 shelf_zones = eh_new0( Sed_cube , n_zones+1 );
00614
00615 for ( i=0 ; i<n_zones ; i++ )
00616 if ( all_zones[i] )
00617 {
00618 shelf_zones[n] = all_zones[i];
00619 n = n+1;
00620 }
00621 shelf_zones[n] = NULL;
00622 }
00623
00624 eh_free( all_zones );
00625
00626 return shelf_zones;
00627 }
00628
00629
00644 Sed_cube* get_zones( Sed_cube p , double* z , gssize n_zones , Sed_grid_func f , gssize** ind )
00645 {
00646 Sed_cube* sub_cube;
00647 gssize **zones;
00648 gssize n;
00649
00650 eh_require( p );
00651 eh_require( z );
00652 eh_require( sed_cube_is_1d(p) );
00653 eh_require( n_zones>0 );
00654
00655 eh_require( eh_dbl_array_is_monotonic( z , n_zones+1 ) );
00656
00657 zones = eh_new( gssize* , n_zones );
00658 for ( n=0 ; n<n_zones ; n++ )
00659 zones[n] = eh_new( gssize , sed_cube_n_y(p) );
00660
00661 eh_require( zones )
00662 {
00663 gssize len = get_zone_indices( p , z[0] , z[1] , 0 , f , zones[0] );
00664 for ( n=1 ; n<n_zones ; n++ )
00665 len = get_zone_indices( p , z[n] , z[n+1] , zones[n-1][len-1] , f , zones[n] );
00666 }
00667
00668 sub_cube = eh_new0( Sed_cube , n_zones+1 );
00669 for ( n=0 ; n<n_zones ; n++ )
00670 {
00671 if ( zones[n][0]>0 )
00672 sub_cube[n] = sed_cube_cols( p , zones[n] );
00673 else
00674 sub_cube[n] = NULL;
00675 }
00676
00677 if ( ind )
00678 memcpy( ind , zones , sizeof(gssize*)*n_zones );
00679 else
00680 for ( n=0 ; n<n_zones ; n++ )
00681 eh_free(zones[n]);
00682
00683 eh_free( zones );
00684
00685 return sub_cube;
00686 }
00687
00688 gssize get_zone_indices( Sed_cube p ,
00689 double z_0 ,
00690 double z_1 ,
00691 gssize i_0 ,
00692 Sed_grid_func get_val ,
00693 gssize* ind )
00694 {
00695 gssize max_i;
00696 gssize n = 0;
00697
00698 eh_require( p );
00699 eh_require( z_1>z_0 );
00700 eh_require( i_0>=0 );
00701 eh_require( ind );
00702
00703 max_i = sed_cube_n_y(p)-1;
00704
00705
00706 if ( get_val( p,0,max_i)>z_0 )
00707 {
00708 gssize i;
00709
00710
00711 for ( ; get_val(p,0,i_0)<z_0 ; i_0++ );
00712
00713
00714
00715 if ( get_val(p,0,max_i)>z_1 )
00716 for ( i=i_0,n=0 ; get_val(p,0,i)<z_1 ; i++ )
00717 {
00718 ind[n] = i;
00719 n = n+1;
00720 }
00721 else
00722 for ( i=i_0,n=0 ; i<sed_cube_n_y(p) && get_val(p,0,i)<z_1 ; i++ )
00723 {
00724 ind[n] = i;
00725 n = n+1;
00726 }
00727 ind[n] = -1;
00728 }
00729 else
00730 ind[0] = -1;
00731
00732 return n;
00733 }
00734
00774 double get_time_step( Sed_cube p , Sed_wave deep_wave , double u_0 , Bruun_data* data )
00775 {
00776 double dt;
00777 double breaker_depth;
00778 double k_max = 0;
00779
00780 eh_require( p );
00781 eh_require( deep_wave );
00782 eh_require( !sed_wave_is_bad(deep_wave) );
00783
00784 breaker_depth = get_breaking_wave_depth( deep_wave );
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800 {
00801 gssize n_grains = sed_sediment_env_n_types();
00802 double* w_s = sed_sediment_property( NULL , &sed_type_settling_velocity );
00803 Sed_wave this_wave = sed_gravity_wave_new( deep_wave , data->h_b , NULL );
00804
00805 k_max = get_diffusion_constant( data->h_b ,
00806 this_wave ,
00807
00808 w_s[n_grains-1] ,
00809 breaker_depth )
00810 * S_SECONDS_PER_DAY;
00811
00812 eh_free( w_s );
00813 sed_wave_destroy( this_wave );
00814 }
00815
00816 eh_debug( "Find the time step necessary for stability" );
00817 {
00818 double dy = sed_cube_y_res(p);
00819 double fos = .9;
00820
00821 dt = fos*dy*dy/(2*k_max);
00822
00823 if ( dt*u_0*S_SECONDS_PER_DAY > dy )
00824 dt = fos*dy/(u_0*S_SECONDS_PER_DAY);
00825 }
00826
00827 return dt;
00828 }
00829
00830 double get_constant( double z , Sed_wave w , double w_s , double h_b )
00831 {
00832 double rho = sed_rho_sea_water();
00833 double rho_s = sed_rho_quartz();
00834 double c_fs = .01;
00835 double eps_ss = .01;
00836 double g = sed_gravity();
00837 double u_om = get_near_bed_velocity( z , w , h_b );
00838 double i_s = 1.;
00839
00840 return 16./(3*M_PI)
00841 * rho/(rho_s-rho)
00842 * c_fs*eps_ss/g
00843 * i_s*pow(u_om,3.)/w_s;
00844 }
00845
00846 double get_diffusion_constant( double z ,
00847 Sed_wave w ,
00848 double w_s ,
00849 double h_b )
00850 {
00851 double u_om = get_near_bed_velocity( z , w , h_b );
00852 return get_constant( z , w , w_s , h_b )
00853 * pow(u_om,2.)/(5.*w_s);
00854 }
00855
00866 double get_diffusion_flux( double z ,
00867 double dz_dx ,
00868 Sed_wave w ,
00869 double w_s ,
00870 double h_b )
00871 {
00872 return get_diffusion_constant( z , w , w_s , h_b )*dz_dx;
00873 }
00874
00885 double get_advection_flux( double z ,
00886 Sed_wave w ,
00887 double u_0 ,
00888 double w_s ,
00889 double h_b )
00890 {
00891 return get_constant( z , w , w_s , h_b ) * u_0;
00892 }
00893
00916 double
00917 get_total_flux_outer_shelf( double z ,
00918 double dz_dx ,
00919 Sed_wave w ,
00920 double u_0 ,
00921 double w_s ,
00922 double h_b )
00923 {
00924 double u_om = get_near_bed_velocity( z , w , h_b );
00925 return get_constant( z , w , w_s , h_b )
00926 * ( u_0 + pow(u_om,2.)/(5.*w_s)*dz_dx );
00927 }
00928
00936 double
00937 get_total_flux_bruun_zone( double x , double dz_dx , double x_0 , double k_0 )
00938 {
00939 eh_require( x>=0 );
00940 eh_require( x_0>0 );
00941 eh_require( x<=x_0 );
00942 eh_require( k_0>=0 );
00943
00944 return k_0*pow(x/x_0,1.-XSHORE_BRUUN_M)*dz_dx;
00945 }
00946
00947 double get_total_flux( double z ,
00948 double dz_dx ,
00949 Sed_wave w ,
00950 double u_0 ,
00951 double w_s ,
00952 double breaker_depth ,
00953 double h_b ,
00954 double x ,
00955 double x_b ,
00956 double max_k )
00957 {
00958 return get_total_flux_outer_shelf( z , dz_dx , w , u_0 , w_s , breaker_depth );
00959 }
00960
00983 void diffuse_cols( Sed_cube p ,
00984 Sed_wave deep_wave ,
00985 double u_0 ,
00986 double* erosion_limit ,
00987 Sed_column* source_col ,
00988 double* bruun_depth ,
00989 Sed_cell along_shore_cell ,
00990 Bruun_data* data ,
00991 double dt ,
00992 double t_total ,
00993 Sed_cell added ,
00994 Sed_cell in ,
00995 Sed_cell out )
00996 {
00997 eh_require( p );
00998 eh_require( deep_wave );
00999 eh_require( !sed_wave_is_bad(deep_wave) );
01000 eh_require( dt>0 );
01001 eh_require( t_total>0 );
01002
01003 if ( dt>t_total )
01004 dt = t_total;
01005
01006 if ( sed_cube_n_y(p)>1 )
01007 {
01008 double t, **qy;
01009 Sed_cell suspended_cell = sed_cell_new_env( );
01010 double z_0 = get_closure_depth( p , deep_wave );
01011 double m_0 = sed_cube_mass(p), m_1;
01012 double m_added, m_lost;
01013
01014
01015
01016 for ( t=dt ; t<t_total ; t+=dt )
01017 {
01018 qy = get_sediment_flux( p , deep_wave , u_0 , data , in );
01019 move_sediment( p , qy , erosion_limit , z_0 , dt , data , out , added , suspended_cell );
01020 m_added = sed_cell_mass( added )*sed_cube_x_res(p)*sed_cube_y_res(p);
01021 m_lost = sed_cell_mass( out )*sed_cube_x_res(p)*sed_cube_y_res(p);
01022 m_1=sed_cube_mass( p );
01023
01024
01025
01026
01027 if ( fabs((m_0+m_added-m_lost-m_1)/m_1) > .01 )
01028 {
01029 eh_watch_dbl( sed_cell_mass( added ) );
01030 eh_watch_dbl( dt );
01031 eh_watch_dbl( m_0 );
01032 eh_watch_dbl( m_1 );
01033 eh_watch_dbl( m_added );
01034 eh_watch_dbl( m_lost );
01035 exit(0);
01036 }
01037 update_bruun_zone_data( data );
01038 sed_cell_resize( suspended_cell , 0. );
01039 eh_free_2( qy );
01040 }
01041
01042
01043 if ( t>=t_total )
01044 {
01045 dt = t_total-(t-dt);
01046 qy = get_sediment_flux( p , deep_wave , u_0 , data , in );
01047 move_sediment( p , qy , erosion_limit , z_0 , dt , data , out , added , suspended_cell );
01048 m_added = sed_cell_mass( added )*sed_cube_x_res(p)*sed_cube_y_res(p);
01049 m_lost = sed_cell_mass( out )*sed_cube_x_res(p)*sed_cube_y_res(p);
01050 m_1=sed_cube_mass( p );
01051
01052
01053
01054
01055 if ( fabs((m_0+m_added-m_lost-m_1)/m_1) > .01 )
01056 {
01057 eh_watch_dbl( sed_cell_mass( added ) );
01058 eh_watch_dbl( dt );
01059 eh_watch_dbl( m_0 );
01060 eh_watch_dbl( m_1 );
01061 eh_watch_dbl( m_added );
01062 eh_watch_dbl( m_lost );
01063 exit(0);
01064 }
01065 update_bruun_zone_data( data );
01066 sed_cell_resize( suspended_cell , 0. );
01067 eh_free_2( qy );
01068 }
01069 eh_debug( "DONE" );
01070
01071 sed_cell_destroy( suspended_cell );
01072 }
01073
01074 return;
01075 }
01076
01077 double** get_sediment_flux( Sed_cube p , Sed_wave deep_wave , double u_0 , Bruun_data *data , Sed_cell in )
01078 {
01079 double** du;
01080
01081 eh_require( p );
01082 eh_require( deep_wave );
01083 eh_require( u_0>=0 );
01084
01085 du = eh_new_2( double , sed_cube_n_y(p) , sed_sediment_env_n_types() );
01086
01087 eh_require( du )
01088 {
01089 gssize i, n;
01090 double u_om, d_max, qy;
01091 gssize n_grains = sed_sediment_env_n_types();
01092 Sed_wave this_wave = sed_wave_new( 0 , 0 , 0 );
01093 double wave_period = sed_wave_period( deep_wave );
01094 double breaker_depth = get_breaking_wave_depth( deep_wave );
01095 double dy = sed_cube_y_res( p );
01096 Eh_dbl_grid z_grid = sed_cube_water_depth_grid( p , NULL );
01097 Eh_dbl_grid dz_dy_grid = sed_cube_y_slope_grid( p , NULL );
01098 double* z = eh_grid_data_start( z_grid );
01099 double* dz_dy = eh_grid_data_start( dz_dy_grid );
01100 double depth, y_b, y, *k_b;
01101 double* gz = sed_sediment_property( NULL , &sed_type_grain_size_in_meters );
01102 double* w_s = sed_sediment_property( NULL , &sed_type_settling_velocity );
01103
01104 for ( n=0 ; n<n_grains ; n++ )
01105 w_s[n] /= S_SECONDS_PER_DAY;
01106
01107 eh_dbl_array_set( du[0] , n_grains*sed_cube_n_y(p) , 0. );
01108
01109 y_b = data->x_b - data->x_0;
01110 k_b = data->k;
01111
01112 for ( i=0 ; i<sed_cube_n_y(p) ; i++ )
01113 {
01114 if ( i!=sed_cube_n_y(p)-1 )
01115 depth = (z[i]+z[i+1])*.5;
01116 else
01117 depth = z[i];
01118
01119 y = sed_cube_col_y( p , i ) - data->x_0;
01120
01121 if ( depth>.01 )
01122 {
01123
01124 this_wave = sed_gravity_wave_new( deep_wave , depth , this_wave );
01125
01126 eh_require( !sed_wave_is_bad( this_wave ) );
01127
01128 u_om = get_near_bed_velocity( depth ,
01129 this_wave ,
01130 breaker_depth );
01131 d_max = get_grain_size_threshold( u_om , wave_period );
01132
01133
01134
01135 for ( n=0 ; n<n_grains ; n++ )
01136 {
01137 if ( gz[n] > d_max )
01138 qy = 0;
01139 else
01140 {
01141 qy = get_total_flux( depth ,
01142 dz_dy[i] ,
01143 this_wave ,
01144 u_0 ,
01145 w_s[n] ,
01146 breaker_depth ,
01147 data->h_b ,
01148 y ,
01149 y_b ,
01150 k_b[n] )
01151 * S_SECONDS_PER_DAY
01152 / dy
01153 / (double)n_grains;
01154 }
01155
01156 du[i][n] = qy;
01157 }
01158
01159 }
01160
01161 }
01162
01163 eh_free( gz );
01164 eh_free( w_s );
01165 eh_grid_destroy( dz_dy_grid , TRUE );
01166 eh_grid_destroy( z_grid , TRUE );
01167 }
01168
01169 {
01170 gssize i, n;
01171 gssize n_grains = sed_sediment_env_n_types();
01172 gssize* bruun_ind = data->ind;
01173 gssize ind_len = data->ind_len;
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183 double y_b, y_0, y;
01184 double* k_max = eh_new( double , sed_sediment_env_n_types() );
01185
01186 if ( ind_len>0 )
01187 {
01188 gssize i_b = bruun_ind[ind_len-1] - bruun_ind[0];
01189
01190 i = bruun_ind[ind_len-1] + 1;
01191 for ( n=0 ; n<n_grains ; n++ )
01192 k_max[n] = du[i_b+1][n]/sed_cube_y_slope( p , 0 , i_b );
01193
01194
01195
01196
01197
01198 y_0 = sed_cube_col_y( p , 0 ) - sed_cube_y_res(p);
01199 y_b = sed_cube_col_y( p , i_b ) - y_0;
01200
01201 for ( i=0 ; i<=i_b ; i++ )
01202 {
01203 y = sed_cube_col_y( p , i ) - y_0;
01204 for ( n=0 ; n<n_grains ; n++ )
01205 {
01206 du[i][n] = k_max[n]*pow( y / y_b , 1.-XSHORE_BRUUN_M )*sed_cube_y_slope(p,0,i);
01207
01208 }
01209 }
01210 }
01211
01212
01213
01214
01215
01216 }
01217
01218 if ( in )
01219 {
01220 gssize n;
01221 gssize n_grains = sed_sediment_env_n_types();
01222 double t = sed_cell_size(in);
01223
01224 for ( n=0 ; n<n_grains ; n++ )
01225 du[0][n] += t*sed_cell_nth_fraction(in,n);
01226 }
01227
01228 return du;
01229 }
01230
01231 Sed_cell move_sediment( Sed_cube p ,
01232 double** du ,
01233 double* erosion_limit ,
01234 double z_0 ,
01235 double dt ,
01236 Bruun_data* data ,
01237 Sed_cell lost ,
01238 Sed_cell added ,
01239 Sed_cell in_suspension )
01240 {
01241 gssize n_grains;
01242 Sed_cell* rem_cell;
01243
01244 eh_require( p );
01245 eh_require( du );
01246 eh_require( lost );
01247
01248 n_grains = sed_sediment_env_n_types();
01249
01250
01251
01252 {
01253 gssize i, n;
01254 for ( i=0 ; i<sed_cube_n_y(p) ; i++ )
01255 for ( n=0 ; n<n_grains ; n++ )
01256 {
01257 du[i][n] *= dt;
01258 if ( du[i][n] > 10 )
01259 {
01260 eh_watch_int( i );
01261 eh_watch_int( n );
01262 eh_watch_int( sed_cube_n_y(p) );
01263 eh_watch_dbl( du[i][n] );
01264 eh_watch_dbl( sed_cube_y_slope(p,0,i) );
01265 eh_watch_dbl( data->x_0 );
01266 eh_watch_dbl( data->x_b );
01267 eh_watch_dbl( data->h_b );
01268 eh_watch_int( data->ind_len );
01269 eh_watch_int( data->ind[0] );
01270 eh_watch_int( data->ind[data->ind_len-1] );
01271 exit(0);
01272 }
01273 }
01274 rem_cell = eh_new( Sed_cell , sed_cube_n_y(p) );
01275 for ( i=0 ; i<sed_cube_n_y(p) ; i++ )
01276 rem_cell[i] = sed_cell_new_env( );
01277 }
01278
01279
01280
01281
01282 {
01283 gssize i, add_index, remove_index;
01284 double du_tot;
01285 gssize top_i = sed_cube_n_y(p)-1;
01286 Sed_cell add_cell = sed_cell_new_env();
01287 Sed_cell fill_cell;
01288 double* dh_max = eh_new( double , sed_cube_n_y(p) );
01289
01290
01291 double total = 0;
01292 gssize ind_len = data->ind_len;
01293
01294 {
01295 double* f = eh_new0( double , n_grains );
01296
01297 f[0] = 1.;
01298
01299 fill_cell = sed_cell_new_sized( n_grains , G_MINDOUBLE , f );
01300
01301 sed_cell_destroy( fill_cell );
01302 fill_cell = NULL;
01303
01304 eh_free( f );
01305 }
01306
01307 for ( i=0 ; i<sed_cube_n_y(p) ; i++ )
01308 {
01309 dh_max[i] = erosion_limit[i]-sed_cube_water_depth(p,0,i);
01310 if ( dh_max[i]<0 )
01311 dh_max[i] = 0;
01312 total += dh_max[i];
01313 }
01314 for ( i=0 ; i<top_i ; i++ )
01315 {
01316 du_tot = eh_dbl_array_sum( du[i] , n_grains );
01317 eh_dbl_array_fabs( du[i] , n_grains );
01318
01319 remove_index = (du_tot>0)?(i):(i+1);
01320 add_index = (du_tot>0)?(i+1):(i);
01321
01322 if ( fabs(du_tot) > 0 )
01323 {
01324 double m_0 = sed_column_mass( sed_cube_col(p,remove_index) );
01325 double m_1, dm;
01326 if ( fabs(du_tot)>dh_max[i] )
01327 {
01328 du_tot = dh_max[i];
01329 }
01330
01331
01332 sed_column_separate_top_amounts_fill(
01333 sed_cube_col(p,remove_index) ,
01334 fabs(du_tot) ,
01335 du[i] ,
01336 fill_cell ,
01337 add_cell );
01338 m_1 = sed_column_mass( sed_cube_col(p,remove_index) );
01339 dm = sed_cell_mass( add_cell );
01340
01341 if ( fabs(m_1+dm-m_0) > 1e-6 )
01342 {
01343 eh_watch_int( i );
01344 eh_watch_int( remove_index );
01345 eh_watch_dbl( sed_column_thickness( sed_cube_col(p,remove_index) ) );
01346 eh_watch_dbl( du_tot );
01347 eh_watch_dbl( m_0 );
01348 eh_watch_dbl( m_1 );
01349 eh_watch_dbl( dm );
01350 exit( 0 );
01351 }
01352 sed_cell_add( rem_cell[add_index] , add_cell );
01353 sed_cell_add( added , fill_cell );
01354 }
01355 }
01356
01357 {
01358 if ( ind_len > 0 )
01359 {
01360
01361 gssize i_0 = 0;
01362
01363
01364 sed_cell_copy( rem_cell[i_0] , rem_cell[i_0+1] );
01365
01366
01367
01368 sed_cell_add ( added , rem_cell[i_0] );
01369 }
01370 }
01371
01372
01373
01374 du_tot = eh_dbl_array_sum( du[0] , n_grains );
01375 eh_dbl_array_fabs( du[0] , n_grains );
01376 if ( du_tot < 0 )
01377 {
01378 du_tot = -dh_max[0];
01379 sed_column_separate_top_amounts_fill( sed_cube_col(p,0) ,
01380 -du_tot ,
01381 du[0] ,
01382 fill_cell ,
01383 add_cell );
01384 sed_cell_add( added , fill_cell );
01385 }
01386
01387 du_tot = eh_dbl_array_sum( du[top_i] , n_grains );
01388 eh_dbl_array_fabs( du[top_i] , n_grains );
01389 if ( du_tot > 0 )
01390 {
01391 if ( du_tot>dh_max[top_i] )
01392 du_tot = dh_max[top_i];
01393
01394 sed_column_separate_top_amounts_fill( sed_cube_col(p,top_i) ,
01395 du_tot ,
01396 du[top_i],
01397 fill_cell ,
01398 add_cell );
01399 sed_cell_add( added , fill_cell );
01400 sed_cell_add( lost , add_cell );
01401 }
01402 else
01403 sed_cell_copy( rem_cell[top_i] , rem_cell[top_i-1] );
01404
01405 sed_cell_destroy( fill_cell );
01406 sed_cell_destroy( add_cell );
01407 eh_free( dh_max );
01408 }
01409
01410
01411
01412 {
01413 gssize i;
01414
01415
01416
01417
01418
01419
01420
01421 for ( i=0 ; i<sed_cube_n_y(p) ; i++ )
01422 {
01423 sed_cell_set_facies( rem_cell[i] , S_FACIES_WAVE );
01424 sed_cell_set_age( rem_cell[i] , sed_cube_age_in_years(p) );
01425
01426 sed_column_add_cell( sed_cube_col(p,i) , rem_cell[i] );
01427 }
01428
01429
01430
01431
01432 }
01433
01434
01435 {
01436 gssize i;
01437 for ( i=0 ; i<sed_cube_n_y(p) ; i++ )
01438 sed_cell_destroy( rem_cell[i] );
01439 eh_free( rem_cell );
01440 }
01441
01442 return lost;
01443 }
01444
01450 void add_suspended_sediment( Sed_column* col , Sed_cell cell )
01451 {
01452 if ( col )
01453 {
01454 gssize i;
01455
01456 eh_require( cell );
01457 for ( i=0 ; col[i] ; i++ )
01458 sed_column_add_cell( col[i] , cell );
01459 }
01460 return;
01461 }
01462
01480 double get_bruun_depth( double y , double y_0 , double bruun_a , double bruun_m)
01481 {
01482 return bruun_a*pow( fabs(y-y_0) , bruun_m );
01483 }
01484
01492 double get_bruun_a( Sed_cube p , double bruun_m )
01493 {
01494 double bruun_a;
01495
01496 eh_require( p );
01497
01498 if ( p )
01499 {
01500 double h_b = sed_cube_water_depth( p , 0 , sed_cube_n_y(p)-1 );
01501 double y_0 = sed_cube_col_y( p , 0 ) - sed_cube_y_res(p);
01502 double y_b = sed_cube_col_y( p , sed_cube_n_y(p)-1 );
01503
01504 bruun_a = h_b / pow(y_b-y_0,bruun_m);
01505 }
01506 else
01507 bruun_a = eh_nan();
01508
01509 return bruun_a;
01510 }
01511
01512 double get_bruun_y_0( Sed_cube p )
01513 {
01514 return sed_cube_col_y( p , 0 ) - sed_cube_y_res(p);
01515 }
01516
01517 double get_bruun_y_b( Sed_cube p )
01518 {
01519 return sed_cube_col_y( p , sed_cube_n_y(p)-1 );
01520 }
01521
01522 double* get_bruun_profile( double* y , gssize len ,
01523 double bruun_a , double bruun_m ,
01524 double y_0 , double y_b )
01525 {
01526 double* h = NULL;
01527
01528 eh_require( y );
01529 eh_require( len>0 );
01530 eh_require( y_b>y_0 );
01531
01532 eh_debug( "Is there an inner shelf?" );
01533 if ( y_b>y_0 )
01534 {
01535 h = eh_new( double , len );
01536
01537 eh_debug( "Calculate the depths of the Bruun profile" );
01538 {
01539 gssize i;
01540 for ( i=0 ; i<len ; i++ )
01541 {
01542 if ( y[i] < y_0 || y[i]>y_b )
01543 h[i] = eh_nan();
01544 else
01545 h[i] = get_bruun_depth( y[i] , y_0 , bruun_a , bruun_m );
01546 }
01547 }
01548
01549 eh_debug( "Check if all points are outside of inner shelf" );
01550 {
01551 gssize i;
01552 for ( i=0 ; i<len && eh_isnan(h[i]) ; i++ );
01553 if ( i==len )
01554 {
01555 eh_free( h );
01556 h = NULL;
01557 }
01558 }
01559 }
01560
01561 eh_debug( "Done." );
01562
01563 return h;
01564 }
01565
01582 void fill_to_bruun( Sed_cube p ,
01583 double* h ,
01584 Sed_cell fill_cell )
01585 {
01586 double total = 0;
01587
01588 eh_require( p );
01589 eh_require( fill_cell );
01590
01591 if ( h )
01592 {
01593 gssize i;
01594 double dh;
01595
01596 sed_cell_set_age ( fill_cell , sed_cube_age_in_years(p) );
01597 sed_cell_set_facies( fill_cell , S_FACIES_ALONG_SHORE );
01598
01599 for ( i=0 ; i<sed_cube_n_y(p) ; i++ )
01600 {
01601 if ( !eh_isnan(h[i]) )
01602 {
01603 dh = sed_cube_water_depth( p , 0 , i ) - h[i];
01604
01605 if ( dh > 0 )
01606 {
01607 sed_cell_resize( fill_cell , dh );
01608
01609 sed_column_add_cell( sed_cube_col(p,i) , fill_cell );
01610
01611 total += dh;
01612 }
01613 }
01614 }
01615 }
01616
01617 sed_cell_resize( fill_cell , total );
01618
01619 return;
01620 }
01621
01622 void fill_to_bruun_profile( Sed_cube p ,
01623 Sed_wave deep_wave ,
01624 double bruun_m ,
01625 Sed_cell fill_cell ,
01626 Sed_cell added_fill_cell )
01627 {
01628 eh_require( p );
01629
01630 sed_cell_set_facies( fill_cell , S_FACIES_BEDLOAD );
01631 sed_cell_set_age ( fill_cell , sed_cube_age_in_years(p) );
01632
01633 if ( sed_cube_n_y(p)>2 )
01634 {
01635 double bruun_a, h_b;
01636 double y_0, y_b;
01637
01638 h_b = sed_cube_water_depth( p , 0 , sed_cube_n_y(p)-1 );
01639 y_0 = sed_cube_col_y( p , 0 );
01640 y_b = sed_cube_col_y( p , sed_cube_n_y(p)-1 );
01641
01642
01643
01644
01645
01646 bruun_a = h_b / pow(y_b-y_0,bruun_m);
01647
01648
01649
01650
01651
01652 {
01653 gssize i;
01654 double h, dh, h_total = 0.;
01655
01656 for ( i=0 ; i<sed_cube_n_y(p) ; i++ )
01657 {
01658 h = bruun_a * pow( sed_cube_col_y(p,i) - y_0 , bruun_m );
01659
01660 dh = sed_cube_water_depth( p , 0 , i ) - h;
01661
01662 if ( dh > 0 )
01663 {
01664 sed_cell_resize( fill_cell , dh );
01665
01666 sed_column_add_cell( sed_cube_col(p,i) , fill_cell );
01667
01668 h_total += dh;
01669 }
01670 }
01671
01672 sed_cell_resize( fill_cell , h_total );
01673 }
01674
01675 if ( added_fill_cell )
01676 sed_cell_add( added_fill_cell , fill_cell );
01677 }
01678
01679 return;
01680 }
01681
01689 double get_closure_depth( Sed_cube p , Sed_wave wave )
01690 {
01691
01692 return 3.*sed_wave_break_depth( wave );
01693
01694
01695 }
01696
01697 double get_h_c( Sed_wave w )
01698 {
01699 double g = sed_gravity();
01700 double h = 1.25*sed_wave_height( w );
01701 double t = sed_wave_period( w );
01702 return 2.28*h - 6.85*( h*h / ( g * t*t ) );
01703 }
01704
01711 double get_erosion_depth( double u )
01712 {
01713 double sua = 400;
01714 double sub = 0;
01715 double C_d = .004;
01716
01717 eh_require( u>=0 );
01718
01719 return (C_d*sed_rho_sea_water()*u*u-sub)/sua;
01720 }
01721
01722 double* get_max_erosion_profile( Sed_cube p , Sed_wave w )
01723 {
01724 double* z_max = NULL;
01725
01726 eh_require( p );
01727 eh_require( sed_cube_n_y(p)>0 );
01728 eh_require( w );
01729
01730 z_max = eh_new( double , sed_cube_n_y(p) );
01731
01732 if ( p && w )
01733 {
01734 gssize i;
01735 double z;
01736 double u;
01737 double h_b = sed_wave_break_depth( w );
01738
01739
01740 for ( i=0 ; i<sed_cube_n_y(p) ; i++ )
01741 {
01742 z = sed_cube_water_depth( p , 0 , i );
01743 if ( z>.1 )
01744 {
01745 u = get_near_bed_velocity( z , w , h_b );
01746 z_max[i] = get_erosion_depth( u ) + z;
01747 }
01748 else
01749 z_max[i] = z;
01750 }
01751 }
01752
01753 return z_max;
01754 }
01755
01767 double get_near_bed_velocity( double water_depth , Sed_wave w , double breaker_depth )
01768 {
01769 double u;
01770
01771
01772
01773 if ( water_depth < breaker_depth )
01774 u = near_bed_velocity_func_mean( breaker_depth , w , breaker_depth )
01775 * pow( water_depth / breaker_depth , 1. ) ;
01776 else
01777 u = near_bed_velocity_func_mean( water_depth , w , breaker_depth );
01778
01779 return u;
01780 }
01781
01782 double near_bed_velocity_func_mean( double water_depth , Sed_wave w , double breaker_depth )
01783 {
01784
01785 double alpha = (-atan(5*( sed_wave_height(w)/water_depth-.5 ) ) + G_PI_2 )/G_PI;
01786
01787 alpha = 0.;
01788
01789 return (1.-alpha) * near_bed_velocity_func ( water_depth , w , breaker_depth )
01790 + alpha * near_bed_velocity_func_komar( water_depth , w , breaker_depth );
01791 }
01792
01808 double near_bed_velocity_func( double water_depth , Sed_wave w , double breaker_depth )
01809 {
01810 double gamma_b = .6;
01811
01812 return .5*gamma_b
01813 * sqrt(sed_gravity()*breaker_depth)
01814 * pow(water_depth/breaker_depth,-.75);
01815 }
01816
01831 double near_bed_velocity_func_komar( double water_depth ,
01832 Sed_wave w ,
01833 double breaker_depth )
01834 {
01835 return sed_wave_frequency(w)*sed_wave_height(w) / ( 2.*sinh( sed_wave_number(w)*water_depth ) );
01836 }
01837
01852 double near_bed_velocity_func_stokes( double water_depth ,
01853 Sed_wave w ,
01854 double breaker_depth )
01855 {
01856 return .5*pow( sed_wave_number(w)*sed_wave_height(w)*.5/sinh(sed_wave_number(w)*water_depth) , 2. )
01857 * sed_wave_phase_velocity( w );
01858 }
01859
01879 double get_grain_size_threshold( double orbital_velocity , double wave_period )
01880 {
01881 double rho = sed_rho_sea_water();
01882 double rho_s = sed_rho_quartz();
01883 double g = sed_gravity();
01884 double c_sq = pow( rho/(.21*g*(rho_s-rho) ),2.);
01885 double orbital_diameter = orbital_velocity*wave_period/G_PI;
01886
01887 return c_sq * pow(orbital_velocity,4.) / orbital_diameter;
01888 }
01889
01890
01891