/Users/huttone/Devel/sedflux-new/sedflux/trunk/ew/sakura/sakura_sedflux_interface.c

Go to the documentation of this file.
00001 #include <sed/sed_sedflux.h>
00002 #include "sakura_local.h"
00003 #include "sakura.h"
00004 
00005 #define SAKURA_VELOCITY_RANGE               (3.0)
00006 #define SAKURA_INITIAL_WIDTH                (1000.0)
00007 #define SAKURA_INITIAL_HEIGHT               (6.0)
00008 #define SAKURA_INITIAL_VELOCITY             (1.0)
00009 #define SAKURA_INITIAL_CONCENTRATION        (.01)
00010 #define SAKURA_GRAIN_DENSITY                (2650.)
00011 #define SAKURA_SPREADING_ANGLE              (14.)
00012 #define SAKURA_DENSITY_OF_SEDIMENT_GRAINS   (2650.)
00013 
00014 void
00015 sakura_erode_sediment( Sed_cube         p          ,
00016                        Sakura_bathy_st* bathy_data ,
00017                        gssize           i_start    ,
00018                        double**         erosion_in_m );
00019 void
00020 sakura_deposit_sediment( Sed_cube p                  ,
00021                          Sakura_bathy_st* bathy_data ,
00022                          gssize           i_start    ,
00023                          double** deposit_in_m );
00024 double*
00025 sakura_set_width_from_cube( Sed_cube p , gssize i_start );
00026 Sakura_bathy_st*
00027 sakura_set_bathy_data_from_cube( Sed_cube p ,
00028                                  double* width ,
00029                                  gssize ind_start ,
00030                                  double dx );
00031 Sakura_sediment_st* sakura_set_sediment_data_from_env( );
00032 /*
00033 void   sed_get_phe  ( Sakura_array_st* bed_data    , Sed_cube p );
00034 double sed_add      ( Sakura_array_st* add_data    , gint ind , double dh );
00035 double sed_remove   ( Sakura_array_st* remove_data , gint ind , double dh );
00036 double sed_get_depth( Sakura_array_st* depth_data  , gint ind );
00037 */
00038 
00039 double sakura_get_equivalent_diameter(double real_diameter);
00040 
00041 gboolean
00042 sed_sakura( Sed_cube         p       ,
00043             Sed_hydro        f       ,
00044             gint             i_start ,
00045             double           dx      ,
00046             Sakura_const_st* c )
00047 {
00048    gboolean ok = TRUE;
00049 
00050    if ( p && f && c )
00051    {
00052       double**            deposit_in_m   = NULL;
00053       Sakura_flood_st*    daily_flood    = NULL;
00054       Sakura_bathy_st*    bathy_data     = NULL;
00055       Sakura_sediment_st* sediment_data  = NULL;
00056       double*             width          = NULL;
00057       double              total_t        = sed_hydro_duration(f)*S_SECONDS_PER_DAY;
00058       double              dt             = S_SECONDS_PER_DAY;
00059       double              t;
00060       gint                n_grains;
00061       gint                len;
00062       const double        spreading_angle = tan(14.*G_PI/180.);
00063 
00064       c->get_phe      = (Sakura_phe_func)sakura_sed_get_phe;
00065       c->add          = (Sakura_add_func)sakura_sed_add_sediment;
00066       c->remove       = (Sakura_add_func)sakura_sed_remove_sediment;
00067       c->get_depth    = (Sakura_get_func)sakura_sed_get_depth;
00068 
00069       c->get_phe_data = p;
00070       c->add_data     = p;
00071       c->remove_data  = p;
00072       c->depth_data   = p;
00073 
00074       width         = sakura_set_width_from_cube       ( p , i_start );
00075       bathy_data    = sakura_set_bathy_data_from_cube  ( p , width , i_start , dx );
00076       sediment_data = sakura_set_sediment_data_from_env( );
00077 
00078       eh_require( width         );
00079       eh_require( bathy_data    );
00080       eh_require( sediment_data );
00081 
00082       //deposit_in_m = eh_new_2( double , sediment_data->n_grains , bathy_data->len );
00083 
00084       for ( t=0 ; t<total_t ; t+=dt )
00085       {
00086          daily_flood = sakura_sed_set_flood_data( f , c->rho_river_water );
00087 
00088          sakura_set_width( bathy_data , daily_flood->width , spreading_angle );
00089 
00090          eh_require( daily_flood );
00091 
00092          if ( t+dt > total_t )
00093             dt = total_t-t;
00094 
00095          daily_flood->duration  = dt;
00096 //         daily_flood->velocity += SAKURA_VELOCITY_RANGE*g_random_double();
00097 
00098          deposit_in_m = sakura_wrapper( bathy_data , daily_flood , sediment_data , c , &n_grains , &len );
00099 
00100          eh_require( n_grains==sediment_data->n_grains );
00101          eh_require( len==bathy_data->len );
00102 
00103          sakura_destroy_flood_data( daily_flood );
00104       }
00105 
00106       sakura_destroy_bathy_data( bathy_data );
00107       eh_free_2( deposit_in_m );
00108    }
00109 
00110    return ok;
00111 }
00112 
00113 void
00114 sakura_erode_sediment( Sed_cube         p          ,
00115                        Sakura_bathy_st* bathy_data ,
00116                        gssize           i_start    ,
00117                        double**         erosion_in_m )
00118 {
00119    if ( p && erosion_in_m )
00120    {
00121       gint i,  len;
00122       gint n,  n_grains = sed_sediment_env_n_types();
00123       double** erosion  = eh_new( double* , n_grains );
00124       double   total_t;
00125       double   dx       = bathy_data->x[1] - bathy_data->x[0];
00126       double   bin_size = sed_cube_y_res(p) / dx;
00127 
00128       for ( n=0 ; n<n_grains ; n++ )
00129       {
00130          eh_dbl_array_mult_each( erosion_in_m[n] , bathy_data->len , bathy_data->width );
00131          eh_dbl_array_mult     ( erosion_in_m[n] , bathy_data->len , dx/(sed_cube_x_res(p)*sed_cube_y_res(p)) );
00132 
00133          erosion[n] = eh_dbl_array_rebin( erosion_in_m[n] , bathy_data->len , bin_size , &len );
00134       }
00135 
00136       // Remove the sediment from the profile.
00137       for ( i=0 ; i<len ; i++ )
00138       {
00139          for ( n=0,total_t=0. ; n<n_grains ; n++ )
00140             total_t += erosion[n][i];
00141          sed_column_remove_top( sed_cube_col(p,i+i_start) , total_t );
00142       }
00143 
00144       for ( n=0 ; n<n_grains ; n++ )
00145          eh_free( erosion[n] );
00146       eh_free( erosion );
00147    }
00148 }
00149 
00150 void
00151 sakura_deposit_sediment( Sed_cube p                  ,
00152                          Sakura_bathy_st* bathy_data ,
00153                          gssize           i_start    ,
00154                          double** deposit_in_m )
00155 {
00156    if ( p && deposit_in_m )
00157    {
00158       gint i,  len          = bathy_data->len;
00159       gint n,  n_grains     = sed_sediment_env_n_types();
00160       double*  deposit_at_x = eh_new( double , n_grains );
00161       double** deposit      = eh_new( double* , n_grains );
00162       Sed_cell deposit_cell = sed_cell_new_env( );
00163       double   dx           = bathy_data->x[1] - bathy_data->x[0];
00164       double   bin_size     = sed_cube_y_res(p) / dx;
00165 
00166       for ( n=0 ; n<n_grains ; n++ )
00167       {
00168          eh_dbl_array_mult_each( deposit_in_m[n] , bathy_data->len , bathy_data->width );
00169          eh_dbl_array_mult     ( deposit_in_m[n] , bathy_data->len , dx/(sed_cube_x_res(p)*sed_cube_y_res(p)) );
00170 
00171          deposit[n] = eh_dbl_array_rebin( deposit_in_m[n] , bathy_data->len , bin_size , &len );
00172       }
00173 
00174       // Add the sediment to the profile.
00175       for ( i=0 ; i<len ; i++ )
00176       {
00177          for ( n=0 ; n<n_grains ; n++ )
00178             deposit_at_x[n] = deposit[n][i];
00179 
00180          sed_cell_clear     ( deposit_cell );
00181          sed_cell_set_age   ( deposit_cell      , sed_cube_age(p) );
00182          sed_cell_set_facies( deposit_cell      , S_FACIES_TURBIDITE );
00183          sed_cell_add_amount( deposit_cell      , deposit_at_x );
00184 
00185          sed_column_add_cell( sed_cube_col(p,i+i_start) , deposit_cell );
00186       }
00187       sed_cell_destroy( deposit_cell );
00188       eh_free( deposit_at_x );
00189 
00190       for ( n=0 ; n<n_grains ; n++ )
00191          eh_free( deposit[n] );
00192       eh_free( deposit );
00193    }
00194 }
00195 
00196 double*
00197 sakura_set_width_from_cube( Sed_cube p , gssize i_start )
00198 {
00199    double* width = NULL;
00200 
00201    {
00202       gint   i;
00203       double flow_width;
00204       gint   len   = sed_cube_n_y(p);
00205       double dx    = sed_cube_y_res(p);
00206       double alpha = tan( SAKURA_SPREADING_ANGLE*S_RADS_PER_DEGREE );
00207 
00208       width = eh_dbl_array_new_set( len , SAKURA_INITIAL_WIDTH );
00209 
00210       // Create a spreading angle.
00211       for ( i=i_start+1 ; i<len ; i++ )
00212       {
00213          flow_width = width[i-1] + alpha*dx;
00214          if ( flow_width < sed_cube_x_res(p) )
00215             width[i] = flow_width;
00216       }
00217    }
00218 
00219    return width;
00220 }
00221 
00222 Sed_hydro
00223 sakura_flood_from_cell( Sed_cell c , double area )
00224 {
00225    Sed_hydro h = NULL;
00226 
00227    if ( c )
00228    {
00229       h = sed_hydro_new( sed_cell_n_types(c)-1 );
00230 
00231       sed_hydro_set_width   ( h , SAKURA_INITIAL_WIDTH    );
00232       sed_hydro_set_depth   ( h , SAKURA_INITIAL_HEIGHT   );
00233       sed_hydro_set_velocity( h , SAKURA_INITIAL_VELOCITY );
00234       sed_hydro_set_bedload ( h , 0.                                 );
00235 
00236       {
00237          gint n;
00238          double* f = sed_cell_copy_fraction( NULL , c );
00239 
00240          eh_dbl_array_mult( f , sed_hydro_size(h) , SAKURA_INITIAL_CONCENTRATION );
00241 
00242          for ( n=0 ; n<sed_hydro_size(h) ; n++ )
00243             sed_hydro_set_nth_concentration( h , n , f[n] );
00244 
00245          eh_free( f );
00246       }
00247 
00248       {
00249          double volume_of_sediment = sed_cell_size_0( c )
00250                                    * area
00251                                    * sed_cell_density( c )
00252                                    / SAKURA_GRAIN_DENSITY;
00253          gint   n_days             = volume_of_sediment
00254                                    / sed_hydro_suspended_flux(h)
00255                                    * S_DAYS_PER_SECOND;
00256 
00257          sed_hydro_set_duration( h , n_days );
00258       }
00259 
00260       eh_require( sed_hydro_check( h , NULL ) );
00261    }
00262 
00263    return h;
00264 }
00265 
00266 Sakura_bathy_st*
00267 sakura_set_bathy_data_from_cube( Sed_cube p , double* width , gssize ind_start , double dx )
00268 {
00269    Sakura_bathy_st* b = NULL;
00270 
00271    if ( p )
00272    {
00273       gssize      len;
00274       gssize*     id        = eh_id_array( ind_start , sed_cube_size(p)-1 , &len );
00275       double**    bathy     = eh_new_2( double , 3 , sed_cube_size(p) );
00276       double      basin_len;
00277       Eh_dbl_grid g         = sed_cube_water_depth_grid( p , id );
00278       gint        n;
00279 
00280       eh_require( ind_start>=0               );
00281       eh_require( ind_start<sed_cube_size(p) );
00282 
00283       bathy[0] = sed_cube_y( p , id );
00284       bathy[1] = eh_dbl_grid_data(g)[0];
00285       bathy[2] = width + ind_start;
00286 
00287       basin_len = bathy[0][len-2] - bathy[0][0];
00288 
00289       for ( n=0 ; n<sed_cube_size(p) ; n++ )
00290          bathy[1][n] *= -1;
00291 
00292       b = sakura_set_bathy_data( bathy , len , dx , sed_sediment_env_n_types() );
00293 
00294       eh_free( bathy[0] );
00295       eh_free( bathy    );
00296       eh_free( id       );
00297       eh_grid_destroy( g , TRUE );
00298    }
00299 
00300    return b;
00301 }
00302 
00303 /* Include for g_memmove */
00304 #include <string.h>
00305 
00306 Sakura_sediment_st*
00307 sakura_set_sediment_data_from_env( )
00308 {
00309 /*
00310    Sakura_sediment_st* s = eh_new( Sakura_sediment_st , 1 );
00311    gint n;
00312 
00313    s->n_grains      = sed_sediment_env_n_types();
00314    s->size_equiv    = sed_sediment_property( NULL , &sed_type_grain_size_in_meters );
00315    s->lambda        = sed_sediment_property( NULL , &sed_type_lambda_in_per_seconds );
00316    s->bulk_density  = sed_sediment_property( NULL , &sed_type_rho_sat );
00317    s->grain_density = eh_dbl_array_new_set( s->n_grains , SAKURA_GRAIN_DENSITY );
00318    s->u_settling    = eh_dbl_array_new_set( s->n_grains , 0.                   );
00319    s->reynolds_no   = eh_dbl_array_new_set( s->n_grains , 0.                   );
00320 
00321    for ( n=0 ; n<s->n_grains ; n++ )
00322    {
00323       s->size_equiv[n]  = sakura_get_equivalent_diameter( s->size_equiv[n] );
00324       s->u_settling[n]  = sakura_settling_velocity      ( s->grain_density[n]   , s->size_equiv[n] ,
00325                                                           sed_rho_fresh_water() , sed_mu_water() );
00326       s->reynolds_no[n] = sakura_reynolds_number        ( s->grain_density[n]   , s->size_equiv[n] ,
00327                                                           sed_rho_fresh_water() , sed_mu_water() );
00328    }
00329 */
00330    Sakura_sediment_st* s = eh_new( Sakura_sediment_st , 1 );
00331    gint n;
00332 
00333    s->n_grains      = sed_sediment_env_n_types();
00334    s->lambda        = sed_sediment_property( NULL , &sed_type_lambda_in_per_seconds );
00335    s->bulk_density  = sed_sediment_property( NULL , &sed_type_rho_sat   );
00336    s->grain_density = sed_sediment_property( NULL , &sed_type_rho_grain );
00337    s->u_settling    = eh_new( double , s->n_grains );
00338    s->size_equiv    = NULL;
00339    s->reynolds_no   = NULL;
00340 
00341    /* Shift these array by one.  The first type is bedload and we don't want
00342       bedload in the turbidity current. */
00343    //g_memmove( s->lambda        , s->lambda+1        , sizeof(double)*s->n_grains );
00344    //g_memmove( s->bulk_density  , s->bulk_density+1  , sizeof(double)*s->n_grains );
00345    //g_memmove( s->grain_density , s->grain_density+1 , sizeof(double)*s->n_grains );
00346 
00347    /* Divide the lambdas by the equivalentHeights.  This is added
00348       to account for different grains occupying different portions
00349       of the flow height (ie sands mostly near the bottom, clays 
00350       distributed evenly bottom to top).
00351    */
00352    for ( n=0 ; n<s->n_grains ; n++ )
00353    {
00354       //s->lambda[n]      /= p->flow_fraction[n];
00355       s->u_settling[n]   = sed_removal_rate_to_settling_velocity( s->lambda[n]*S_SECONDS_PER_DAY )
00356                          * S_DAYS_PER_SECOND;
00357 
00358 if ( TRUE )
00359    eh_message( "Settling velocity (cm/s): %f" , s->u_settling[n]*100. );
00360 
00361    }
00362 
00363    return s;
00364 }
00365 
00382 void
00383 sakura_sed_get_phe( Sed_cube p , double y , Sakura_phe_st* phe_data )
00384 {
00385    eh_require( p        );
00386    eh_require( phe_data );
00387 
00388    if ( FALSE && p && phe_data )
00389    {
00390       double   volume   = 0.;
00391       gint     ind      = sed_cube_column_id( p , 0 , y );
00392       double*  phe      = phe_data->phe;
00393       double   depth    = phe_data->val / ( sed_cube_x_res(p)*sed_cube_y_res(p) );
00394       gint     n_grains = sed_sediment_env_n_types();
00395 
00396       eh_require( ind>=0 );
00397       eh_require( sed_cube_is_in_domain( p , 0 , ind ) );
00398 
00399       if ( depth > 0 )
00400       {
00401          Sed_cell avg = sed_cell_new_env( );
00402 /*
00403          // The grid used by sakura will be smaller than that used by sedflux.
00404          // As such, we reduce the erosion depth but remove from the entire width
00405          // of the cell in such a way that mass is conserved.
00406          //depth *= dx/sed_cube_y_res( p );
00407          depth /= sed_cube_y_res( p );
00408 */
00409          eh_upper_bound( depth , sed_cube_thickness(p,0,ind) );
00410    
00411          // Remove different grain sizes equally.  We can change this so that
00412          // sands are more easily eroded than clays -- or whatever we want,
00413          // really.
00414          sed_column_extract_top( sed_cube_col(p,ind) , depth , avg );
00415 
00416          phe = sed_cell_copy_fraction( phe , avg );
00417 
00418 /*
00419          for ( n=0 , volume=0. ; n<n_grains ; n++ )
00420             volume += depth
00421                     * phe[n]
00422                     * sed_type_rho_sat( sed_sediment_type( NULL , n ) )
00423                     / SAKURA_DENSITY_OF_SEDIMENT_GRAINS;
00424 */
00425 
00426          // We want to return the amount of sediment plus water that is available
00427          volume = sed_cell_size(avg)*sed_cube_x_res(p)*sed_cube_y_res(p);
00428 
00429          sed_cell_destroy( avg );
00430       }
00431       else
00432          phe = eh_dbl_array_set( phe , n_grains , 0. );
00433 
00434    // save the volume that was actually eroded.
00435 //   data->erode_depth = volume;
00436       phe_data->val = volume;
00437    }
00438 
00439    return;
00440 }
00441 
00442 double
00443 sakura_sed_remove_sediment( Sed_cube p , double y , Sakura_cell_st* s )
00444 {
00445    double vol_rem = 0.;
00446 
00447    eh_require( p );
00448    eh_require( s );
00449 
00450    if ( FALSE && p && s && s->t>0 )
00451    {
00452       Sed_column col      = sed_cube_col_pos( p , 0 , y );
00453       gint       n_grains = sed_sediment_env_n_types();
00454       double*    f        = eh_new0( double , n_grains );
00455       Sed_cell   cell     = NULL;
00456       double     dz       = s->t / ( sed_cube_y_res(p) * sed_cube_x_res(p) );
00457 
00458       f[s->id]   = 1.;
00459       cell       = sed_column_separate_top( col , dz , f , NULL );
00460       vol_rem    = sed_cell_size( cell ) * sed_cube_y_res(p) * sed_cube_x_res(p);
00461 
00462       sed_cell_destroy( cell );
00463       eh_free( f );
00464    }
00465 
00466    return vol_rem;
00467 }
00468 
00469 double
00470 sakura_sed_add_sediment( Sed_cube p , double y , Sakura_cell_st* s )
00471 {
00472    double vol_add = 0;
00473 
00474    eh_require( p );
00475    eh_require( s );
00476 
00477    if ( p && s && s->t>0 )
00478    {
00479       Sed_column col      = sed_cube_col_pos( p , 0 , y );
00480       gint       n_grains = sed_sediment_env_n_types();
00481       double*    amount   = eh_new0( double , n_grains );
00482 //      double     dz       = s->t / sed_cube_y_res(p);
00483       double     dz       = s->t / ( sed_cube_y_res(p) * sed_cube_x_res(p) );
00484       double     depth    = sed_column_water_depth( col );
00485 
00486       if ( dz > depth ) dz = depth;
00487 
00488       amount[s->id]  = dz;
00489 
00490       sed_column_add_vec( col , amount );
00491 
00492       vol_add = dz * sed_cube_x_res(p) * sed_cube_y_res(p);
00493 
00494       eh_free( amount );
00495    }
00496 
00497    return vol_add;
00498 }
00499 
00500 double
00501 sakura_sed_get_depth( Sed_cube p , double y )
00502 {
00503    double depth = 0.;
00504 
00505    eh_require( p );
00506 
00507    if ( p )
00508    {
00509       gint ind = sed_cube_column_id( p , 0 , y );
00510 
00511       if ( ind>=0 ) depth = -sed_cube_water_depth( p , 0 , ind );
00512    }
00513 
00514    return depth;
00515 }
00516 
00529 double sakura_get_equivalent_diameter(double real_diameter)
00530 {
00531 /* double m=0.2,b=220e-6;
00532    double m=0.2,b=100e-6;
00533    double m=0.2,b=200e-6;
00534    return m*real_diameter+b;
00535 */
00536    double a=39.8e-3, b=.6;
00537    return a*pow(real_diameter,b);
00538 }
00539 

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