/Users/huttone/Devel/sedflux-new/sedflux/trunk/ew/inflow/inflow_sedflux_interface.c

Go to the documentation of this file.
00001 #include <sed/sed_sedflux.h>
00002 #include "inflow_local.h"
00003 #include "inflow.h"
00004 
00005 #define INFLOW_VELOCITY_RANGE               (3.0)
00006 #define INFLOW_INITIAL_WIDTH                (1000.0)
00007 #define INFLOW_INITIAL_HEIGHT               (6.0)
00008 #define INFLOW_INITIAL_VELOCITY             (1.0)
00009 #define INFLOW_INITIAL_CONCENTRATION        (.01)
00010 #define INFLOW_GRAIN_DENSITY                (2650.)
00011 #define INFLOW_SPREADING_ANGLE              (14.)
00012 #define INFLOW_DENSITY_OF_SEDIMENT_GRAINS   (2650.)
00013 
00014 void
00015 inflow_erode_sediment( Sed_cube         p          ,
00016                        Inflow_bathy_st* bathy_data ,
00017                        gssize           i_start    ,
00018                        double**         erosion_in_m );
00019 void
00020 inflow_deposit_sediment( Sed_cube p                  ,
00021                          Inflow_bathy_st* bathy_data ,
00022                          gssize           i_start    ,
00023                          double** deposit_in_m );
00024 double*
00025 inflow_set_width_from_cube( Sed_cube p , gssize i_start );
00026 Inflow_bathy_st*
00027 inflow_set_bathy_data_from_cube( Sed_cube p ,
00028                                  double* width ,
00029                                  gssize ind_start ,
00030                                  double dx );
00031 Inflow_sediment_st* inflow_set_sediment_data_from_env( );
00032 void sed_get_phe( Inflow_phe_query_st* data , Sed_cube p );
00033 
00034 double inflow_get_equivalent_diameter(double real_diameter);
00035 
00036 gboolean
00037 sed_inflow( Sed_cube         p       ,
00038             Sed_hydro        f       ,
00039             gint             i_start ,
00040             double           dx      ,
00041             Inflow_const_st* c )
00042 {
00043    gboolean ok = TRUE;
00044 
00045    if ( p && f && c )
00046    {
00047       double**            deposit_in_m   = NULL;
00048       double**            erosion_in_m   = NULL;
00049       Inflow_flood_st*    daily_flood    = NULL;
00050       Inflow_bathy_st*    bathy_data     = NULL;
00051       Inflow_sediment_st* sediment_data  = NULL;
00052       double*             width          = NULL;
00053       double              total_t        = sed_hydro_duration(f)*S_SECONDS_PER_DAY;
00054       double              dt             = S_SECONDS_PER_DAY;
00055       double              t;
00056 
00057       c->get_phe      = sed_get_phe;
00058       c->get_phe_data = p;
00059 
00060       width         = inflow_set_width_from_cube       ( p , i_start );
00061       bathy_data    = inflow_set_bathy_data_from_cube  ( p , width , i_start , dx );
00062       sediment_data = inflow_set_sediment_data_from_env( );
00063 
00064       eh_require( width         );
00065       eh_require( bathy_data    );
00066       eh_require( sediment_data );
00067 
00068       deposit_in_m = eh_new_2( double , sediment_data->n_grains , bathy_data->len );
00069       erosion_in_m = eh_new_2( double , sediment_data->n_grains , bathy_data->len );
00070 
00071       for ( t=0 ; t<total_t ; t+=dt )
00072       {
00073          daily_flood = inflow_set_flood_data( f , c->rho_river_water );
00074 
00075          if ( t+dt > total_t )
00076             dt = total_t-t;
00077 
00078          daily_flood->duration  = dt;
00079 //         daily_flood->velocity += INFLOW_VELOCITY_RANGE*g_random_double();
00080 
00081          ok = inflow_wrapper( bathy_data , daily_flood , sediment_data , c , deposit_in_m , erosion_in_m );
00082 
00083          if ( ok )
00084          {
00085             inflow_erode_sediment  ( p , bathy_data , i_start , erosion_in_m );
00086             inflow_deposit_sediment( p , bathy_data , i_start , deposit_in_m );
00087 
00088             inflow_destroy_bathy_data( bathy_data );
00089             bathy_data = inflow_set_bathy_data_from_cube( p , width , i_start , dx );
00090          }
00091 
00092          inflow_destroy_flood_data( daily_flood );
00093       }
00094 
00095       inflow_destroy_bathy_data( bathy_data );
00096       eh_free_2( deposit_in_m );
00097       eh_free_2( erosion_in_m );
00098    }
00099 
00100    return ok;
00101 }
00102 
00103 void
00104 inflow_erode_sediment( Sed_cube         p          ,
00105                        Inflow_bathy_st* bathy_data ,
00106                        gssize           i_start    ,
00107                        double**         erosion_in_m )
00108 {
00109    if ( p && erosion_in_m )
00110    {
00111       gint i,  len;
00112       gint n,  n_grains = sed_sediment_env_n_types();
00113       double** erosion  = eh_new( double* , n_grains );
00114       double   total_t;
00115       double   dx       = bathy_data->x[1] - bathy_data->x[0];
00116       double   bin_size = sed_cube_y_res(p) / dx;
00117 
00118       for ( n=0 ; n<n_grains ; n++ )
00119       {
00120          eh_dbl_array_mult_each( erosion_in_m[n] , bathy_data->len , bathy_data->width );
00121          eh_dbl_array_mult     ( erosion_in_m[n] , bathy_data->len , dx/(sed_cube_x_res(p)*sed_cube_y_res(p)) );
00122          erosion[n] = eh_dbl_array_rebin( erosion_in_m[n] , bathy_data->len , bin_size , &len );
00123       }
00124 
00125       // Remove the sediment from the profile.
00126       for ( i=0 ; i<len ; i++ )
00127       {
00128          for ( n=0,total_t=0. ; n<n_grains ; n++ )
00129             total_t += fabs( erosion[n][i] );
00130          sed_column_remove_top( sed_cube_col(p,i+i_start) , total_t );
00131       }
00132 
00133       for ( n=0 ; n<n_grains ; n++ )
00134          eh_free( erosion[n] );
00135       eh_free( erosion );
00136    }
00137 }
00138 
00139 void
00140 inflow_deposit_sediment( Sed_cube p                  ,
00141                          Inflow_bathy_st* bathy_data ,
00142                          gssize           i_start    ,
00143                          double** deposit_in_m )
00144 {
00145    if ( p && deposit_in_m )
00146    {
00147       gint i,  len          = bathy_data->len;
00148       gint n,  n_grains     = sed_sediment_env_n_types();
00149       double*  deposit_at_x = eh_new( double , n_grains );
00150       double** deposit      = eh_new( double* , n_grains );
00151       Sed_cell deposit_cell = sed_cell_new_env( );
00152       double   dx           = bathy_data->x[1] - bathy_data->x[0];
00153       double   bin_size     = sed_cube_y_res(p) / dx;
00154 
00155       for ( n=0 ; n<n_grains ; n++ )
00156       {
00157          eh_dbl_array_mult_each( deposit_in_m[n] , bathy_data->len , bathy_data->width );
00158          eh_dbl_array_mult     ( deposit_in_m[n] , bathy_data->len , dx/(sed_cube_x_res(p)*sed_cube_y_res(p)) );
00159 
00160          deposit[n] = eh_dbl_array_rebin( deposit_in_m[n] , bathy_data->len , bin_size , &len );
00161       }
00162 
00163       // Add the sediment to the profile.
00164       for ( i=0 ; i<len ; i++ )
00165       {
00166          for ( n=0 ; n<n_grains ; n++ )
00167             deposit_at_x[n] = deposit[n][i];
00168 
00169          sed_cell_clear     ( deposit_cell );
00170          sed_cell_set_age   ( deposit_cell      , sed_cube_age(p) );
00171          sed_cell_set_facies( deposit_cell      , S_FACIES_TURBIDITE );
00172          sed_cell_add_amount( deposit_cell      , deposit_at_x );
00173 
00174          sed_column_add_cell( sed_cube_col(p,i+i_start) , deposit_cell );
00175       }
00176       sed_cell_destroy( deposit_cell );
00177       eh_free( deposit_at_x );
00178 
00179       for ( n=0 ; n<n_grains ; n++ )
00180          eh_free( deposit[n] );
00181       eh_free( deposit );
00182    }
00183 }
00184 
00185 double*
00186 inflow_set_width_from_cube( Sed_cube p , gssize i_start )
00187 {
00188    double* width = NULL;
00189 
00190    {
00191       gint   i;
00192       double flow_width;
00193       gint   len   = sed_cube_n_y(p);
00194       double dx    = sed_cube_y_res(p);
00195       double alpha = tan( INFLOW_SPREADING_ANGLE*S_RADS_PER_DEGREE );
00196 
00197       width = eh_dbl_array_new_set( len , INFLOW_INITIAL_WIDTH );
00198 
00199       // Create a spreading angle.
00200       for ( i=i_start+1 ; i<len ; i++ )
00201       {
00202          flow_width = width[i-1] + alpha*dx;
00203          if ( flow_width < sed_cube_x_res(p) )
00204             width[i] = flow_width;
00205       }
00206    }
00207 
00208    return width;
00209 }
00210 
00211 Sed_hydro
00212 inflow_flood_from_cell( Sed_cell c , double area )
00213 {
00214    Sed_hydro h = NULL;
00215 
00216    if ( c )
00217    {
00218       h = sed_hydro_new( sed_cell_n_types(c)-1 );
00219 
00220       sed_hydro_set_width   ( h , INFLOW_INITIAL_WIDTH    );
00221       sed_hydro_set_depth   ( h , INFLOW_INITIAL_HEIGHT   );
00222       sed_hydro_set_velocity( h , INFLOW_INITIAL_VELOCITY );
00223       sed_hydro_set_bedload ( h , 0.                                 );
00224 
00225       {
00226          gint n;
00227          double* f = sed_cell_copy_fraction( NULL , c );
00228 
00229          eh_dbl_array_mult( f , sed_hydro_size(h) , INFLOW_INITIAL_CONCENTRATION );
00230 
00231          for ( n=0 ; n<sed_hydro_size(h) ; n++ )
00232             sed_hydro_set_nth_concentration( h , n , f[n] );
00233 
00234          eh_free( f );
00235       }
00236 
00237       {
00238          double volume_of_sediment = sed_cell_size_0( c )
00239                                    * area
00240                                    * sed_cell_density( c )
00241                                    / INFLOW_GRAIN_DENSITY;
00242          gint   n_days             = volume_of_sediment
00243                                    / sed_hydro_suspended_flux(h)
00244                                    * S_DAYS_PER_SECOND;
00245 
00246          sed_hydro_set_duration( h , n_days );
00247       }
00248 
00249       eh_require( sed_hydro_check( h , NULL ) );
00250    }
00251 
00252    return h;
00253 }
00254 
00255 Inflow_bathy_st*
00256 inflow_set_bathy_data_from_cube( Sed_cube p , double* width , gssize ind_start , double dx )
00257 {
00258    Inflow_bathy_st* b = NULL;
00259 
00260    if ( p )
00261    {
00262       gssize      len;
00263       gssize*     id        = eh_id_array( ind_start , sed_cube_size(p)-1 , &len );
00264       double**    bathy     = eh_new_2( double , 3 , sed_cube_size(p) );
00265       Eh_dbl_grid g         = sed_cube_water_depth_grid( p , id );
00266       double      basin_len;
00267 
00268       eh_require( id       );
00269       eh_require( bathy    );
00270       eh_require( bathy[0] );
00271       eh_require( bathy[1] );
00272       eh_require( bathy[2] );
00273       eh_require( g        );
00274 
00275       eh_require( len>=0                     );
00276       eh_require( len<sed_cube_size(p)       );
00277       eh_require( ind_start>=0               );
00278       eh_require( ind_start<sed_cube_size(p) );
00279 
00280       bathy[0] = sed_cube_y( p , id );
00281       bathy[1] = eh_dbl_grid_data(g)[0];
00282       bathy[2] = width + ind_start;
00283 
00284       eh_require( bathy[0] );
00285       eh_require( bathy[1] );
00286       eh_require( bathy[2] );
00287 
00288       basin_len = bathy[0][len-2] - bathy[0][0];
00289 
00290       b = inflow_set_bathy_data( bathy , len , dx , basin_len );
00291 
00292       eh_free( bathy[0] );
00293       eh_free( bathy    );
00294       eh_free( id       );
00295       eh_grid_destroy( g , TRUE );
00296    }
00297 
00298    return b;
00299 }
00300 
00301 Inflow_sediment_st*
00302 inflow_set_sediment_data_from_env( )
00303 {
00304    Inflow_sediment_st* s = eh_new( Inflow_sediment_st , 1 );
00305    gint n;
00306 
00307    s->n_grains      = sed_sediment_env_n_types();
00308    s->size_equiv    = sed_sediment_property( NULL , &sed_type_grain_size_in_meters );
00309    s->lambda        = sed_sediment_property( NULL , &sed_type_lambda_in_per_seconds );
00310    s->bulk_density  = sed_sediment_property( NULL , &sed_type_rho_sat );
00311    s->grain_density = eh_dbl_array_new_set( s->n_grains , INFLOW_GRAIN_DENSITY );
00312 
00313    for ( n=0 ; n<s->n_grains ; n++ )
00314       s->size_equiv[n] = inflow_get_equivalent_diameter( s->size_equiv[n] );
00315 
00316    return s;
00317 }
00318 
00338 void
00339 sed_get_phe( Inflow_phe_query_st* data , Sed_cube p )
00340 {
00341    Sed_cube prof  = (Sed_cube)p;
00342    double dx      = data->dx;
00343    double x       = data->x;
00344    double depth   = data->erode_depth;
00345    double *phe    = data->phe;
00346    Sed_cell avg;
00347    double volume;
00348    int i, n, n_grains;
00349    
00350    n_grains = sed_sediment_env_n_types();
00351    avg      = sed_cell_new_env( );
00352 
00353    if ( depth > 0 )
00354    {
00355       // Determine which column of the profile to remove sediment from.
00356       i = (int)(x/sed_cube_y_res(prof));
00357       if ( i<0 ) i=0;
00358       eh_lower_bound( i , 0 );
00359       eh_upper_bound( i , sed_cube_n_y(prof)-1 );
00360 
00361       // The grid used by inflow will be smaller than that used by sedflux.
00362       // As such, we reduce the erosion depth but remove from the entire width
00363       // of the cell in such a way that mass is conserved.
00364       depth *= dx/sed_cube_y_res( prof );
00365 
00366       eh_upper_bound( depth , sed_cube_thickness(prof,0,i) );
00367    
00368       // Remove different grain sizes equally.  We can change this so that
00369       // sands are more easily eroded than clays -- or whatever we want,
00370       // really.
00371       sed_column_extract_top( sed_cube_col(prof,i) , depth , avg );
00372 
00373       for ( n=0 ; n<n_grains ; n++ )
00374          phe[n] = sed_cell_nth_fraction( avg , n );
00375 
00376       // We want to return the amount of sediment that was removed.  That is,
00377       // sediment - JUST SEDIMENT, DRY SEDIMENT - not sediment plus water.
00378       for ( n=0 , volume=0. ; n<n_grains ; n++ )
00379          volume += depth
00380                  * phe[n]
00381                  * sed_type_rho_sat( sed_sediment_type( NULL , n ) )
00382                  / INFLOW_DENSITY_OF_SEDIMENT_GRAINS;
00383    }
00384    else
00385    {
00386       for ( n=0 ; n<n_grains ; n++ )
00387          phe[n] = 0.;
00388       volume = 0.;
00389    }
00390 
00391    sed_cell_destroy( avg );
00392 
00393    // save the volume that was actually eroded.
00394    data->erode_depth = volume;
00395 
00396    return;
00397 }
00398 
00411 double inflow_get_equivalent_diameter(double real_diameter)
00412 {
00413 /* double m=0.2,b=220e-6;
00414    double m=0.2,b=100e-6;
00415    double m=0.2,b=200e-6;
00416    return m*real_diameter+b;
00417 */
00418    double a=39.8e-3, b=.6;
00419    return a*pow(real_diameter,b);
00420 }
00421 

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