/Users/huttone/Devel/sedflux-new/sedflux/trunk/ew/muds/muds.c

Go to the documentation of this file.
00001 //---
00002 //
00003 // This file is part of sedflux.
00004 //
00005 // sedflux is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation; either version 2 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // sedflux is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with sedflux; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 //
00019 //---
00020 
00021 // Name :
00022 //
00023 // muds -- simulate the transport of muds in the bbl
00024 //
00025 //
00026 // Synopsis :
00027 //
00028 // define            SKIN_DEPTH_PERCENT               ( 1. )
00029 //
00030 // Sed_cube*      muddy                            ( Sed_cube *prof,
00031 //                                                      double kmax,
00032 //                                                      double skin_depth,
00033 //                                                      double dt )
00034 // double            get_orbital_velocity             ( double d,
00035 //                                                      double H,
00036 //                                                      double T,
00037 //                                                      double L )
00038 //
00039 // Description :
00040 //
00041 //  first we introduce hemiplagic muds into the bottom boundary layer.  from
00042 //  wright et al., 2001 (equation 4 & 9) we can calculate the maximum load
00043 //  that the gravity driven current can hold:
00044 //
00045 //                   2
00046 //             Ri   u 
00047 //               cr  max
00048 //  load_max = ---------
00049 //                s g
00050 //
00051 //  where:
00052 //    Ri    - richardson number
00053 //    u_max - velocity at top of bbl
00054 //    s     - submerged weight of sediment (~1.6)
00055 //    g     - gravity
00056 //  
00057 //  for locations where the bbl is over-full, the muds are deposited there.
00058 //  for locations where the bbl is not yet full, and the near-bed velocities
00059 //  are greater than the critical velocity for erosion, sediment is eroded
00060 //  until the bbl is full or there is no more sediment to erode.
00061 //
00062 //  we now calculate the velocity at which the current will move down-slope
00063 //  (wright et al., 2001 equation 12):
00064 //
00065 //          Ri Umax alpha     2       2     2
00066 //    u  = --------------- , U     = u   + u
00067 //     g         Cd           max     g     w
00068 //
00069 //  where:
00070 //    ug    - down-slope gravity driven velocity
00071 //    uw    - down-slope wave orbital velocity at bed
00072 //    Umax  - total down-slope velocity
00073 //    alpha - sea-floor slope
00074 //    Cd    - drag coefficient
00075 //
00076 //  we now move the sediment down slope until there is no more sediment
00077 //  suspended in the bbl.  for every iteration we use a variable time step
00078 //  that is determined by:
00079 //
00080 //    dt = dx / u_max
00081 //
00082 //  where:
00083 //    dt    - time step
00084 //    dx    - grid spacing
00085 //    u_max - maximum ug over the entire profile
00086 //
00087 //  this will be the maximum time step so that sediment will only travel a
00088 //  maximum of one grid cell.
00089 //  
00090 //
00091 
00092 #include <stdio.h>
00093 #include <math.h>
00094 #include <string.h>
00095 #include <glib.h>
00096 #include <utils/utils.h>
00097 #include <sed/sed_sedflux.h>
00098 #include "muds.h"
00099 
00100 //#define ERODE_DEPTH_IN_YEARS (7./365.)
00101 #define ERODE_DEPTH_IN_YEARS (200.)
00102 
00103 #define sign( a ) ( (a)>0?1:((a)==0?0:-1) )
00104 #define EROSION_IS_ON ( TRUE )
00105 
00106 double get_orbital_velocity( double d , double H , double T , double L );
00107 
00108 int test_in_suspension( double *in_suspension , double thickness , int n_grains );
00109 
00110 int muddy(Sed_cube prof,Sed_cell *in_suspension_cell, double *wave , double duration )
00111 {
00112    int i, n;
00113    int n_grains;
00114    int i_start;
00115    gssize river_mouth;
00116    double s=1.65, g=9.81, Ri=.25, Cd=.003, u_wave_critical=.15;
00117    double dt, dx, alpha, beta;
00118    double extra, flux, initial_sediment, sediment_in_suspension;
00119    double wave_height, wave_period, wave_length;
00120    double max_erode_depth;
00121    double time_elapsed=0.;
00122    double deposit_fraction, flux_fraction;
00123    double *max_load;
00124    double *u_max, *u_grav, *u_wave, u_grav_max;
00125    double *k_grain;
00126    double **in_suspension, *in_suspension_thickness;
00127    double **temp;
00128    Sed_cell temp_cell;
00129 
00130    wave_height = wave[0];
00131    wave_period = wave[1];
00132 // for deep water waves.
00133 //   wave_length = sed_gravity()*wave_period*wave_period/2/M_PI;
00134 
00135 // set the wave length so that the orbital velocities match at depth = wave_length/20.
00136    wave_length = 5.*sed_gravity()*pow(wave_period*sinh(M_PI/10.)/M_PI,2.);
00137 
00138    n_grains = sed_sediment_env_n_types( );
00139    dx = sed_cube_y_res( prof );
00140 
00141    max_load = eh_new( double , sed_cube_n_y(prof) );
00142    u_max    = eh_new( double , sed_cube_n_y(prof) );
00143    u_grav   = eh_new( double , sed_cube_n_y(prof) );
00144    u_wave   = eh_new( double , sed_cube_n_y(prof) );
00145 
00146    // a k_grain of 1 will move all of the sediment possible.
00147    k_grain = sed_sediment_property( NULL , &sed_type_diff_coef );
00148 
00149    temp_cell     = sed_cell_new( n_grains );
00150 
00151    in_suspension_thickness = eh_new0( double  , sed_cube_n_y(prof) );
00152    in_suspension           = eh_new ( double* , sed_cube_n_y(prof) );
00153    in_suspension[0]        = eh_new ( double  , sed_cube_n_y(prof)*n_grains );
00154    temp                    = eh_new ( double* , sed_cube_n_y(prof) );
00155    temp[0]                 = eh_new0( double  , sed_cube_n_y(prof)*n_grains );
00156 
00157    for ( i=1 ; i<sed_cube_n_y(prof) ; i++ )
00158    {
00159       in_suspension[i] = in_suspension[i-1]+n_grains;
00160       temp[i]          = temp[i-1]+n_grains;
00161    }
00162 
00163    river_mouth = sed_cube_river_mouth_1d( prof );
00164    for ( i=0 ; i<river_mouth ; i++ )
00165    {
00166       in_suspension_thickness[i] = 0.;
00167       for ( n=0 ; n<n_grains ; n++ )
00168          in_suspension[i][n] = 0.;
00169    }
00170    for ( i=river_mouth ; i<sed_cube_n_y(prof) ; i++ )
00171    {
00172       in_suspension_thickness[i] = sed_cell_size( in_suspension_cell[i] );
00173       for ( n=0 ; n<n_grains ; n++ )
00174          in_suspension[i][n] = sed_cell_fraction( in_suspension_cell[i] , n )
00175                              * in_suspension_thickness[i];
00176    }
00177 
00178    initial_sediment = 0.;
00179    for ( i=0 ; i<sed_cube_n_y(prof) ; i++ )
00180       initial_sediment += in_suspension_thickness[i];
00181 
00182    do
00183    {
00184       river_mouth = sed_cube_river_mouth_1d( prof );
00185 
00186       // calculate the wave orbital velocities at the sea floor.
00187       for ( i=0 ; i<river_mouth ; i++ )
00188          u_wave[i] = 0.;
00189       for ( i=river_mouth ; i<sed_cube_n_y(prof) ; i++ )
00190          u_wave[i] = get_orbital_velocity( sed_cube_water_depth( prof , 0 , i ) ,
00191                                            wave_height                             ,
00192                                            wave_period                             ,
00193                                            wave_length );
00194 
00195       // determine the maximum load that a gravity driven current can sustain.
00196       for ( i=0 ; i<sed_cube_n_y(prof)-1 ; i++ )
00197       {
00198          alpha     = sed_cube_slope( prof , 0 , i );
00199          beta      = Ri*alpha/Cd;
00200          if ( fabs(beta)>.9 )
00201             beta = (beta>0)?.9:-.9;
00202          u_max[i]  = u_wave[i]/sqrt(1-beta*beta);
00203 //u_max[i] = u_wave[i];
00204          u_grav[i] = beta*u_max[i];
00205       }
00206       u_max[i]  = u_max[i-1];
00207       u_grav[i] = u_grav[i-1];
00208    
00209       for ( i=0 ; i<sed_cube_n_y(prof) ; i++ )
00210          max_load[i] = Ri * u_max[i]*u_max[i] / s / g;
00211 
00212       i_start = sed_cube_river_mouth_1d( prof );
00213 
00214       // check if the maximum load is exceeded.  if so, deposit the extra.  if
00215       // more space is available, and there is enough wave energy to erode
00216       // sediment then erode enough sediment to reach the maximum load (or as
00217       // much sediment as is available).
00218       for ( i=i_start ; i<sed_cube_n_y(prof) ; i++ )
00219       {
00220          extra = in_suspension_thickness[i] - max_load[i];
00221          // deposit the extra sediment.
00222          if ( extra>0 && in_suspension_thickness[i]>0 )
00223          {
00224             deposit_fraction = extra/in_suspension_thickness[i];
00225             for ( n=0 ; n<n_grains ; n++ )
00226                in_suspension[i][n] *= deposit_fraction;
00227             sed_column_add_vec( sed_cube_col(prof,i) , in_suspension[i] );
00228             in_suspension_thickness[i] = 0.;
00229             for ( n=0 ; n<n_grains ; n++ )
00230             {
00231                in_suspension[i][n] /= deposit_fraction;
00232                in_suspension[i][n] *= (1.-deposit_fraction);
00233                in_suspension_thickness[i] += in_suspension[i][n];
00234             }
00235             //in_suspension_thickness[i] = max_load[i];
00236          }
00237          // erode sediment.
00238          else if ( u_wave[i]>u_wave_critical && extra<0 && EROSION_IS_ON )
00239          {
00240             extra *= -1.;
00241 
00242             max_erode_depth = sed_column_depth_age( sed_cube_col(prof,i) ,
00243                                                       sed_cube_age(prof)
00244                                                     - ERODE_DEPTH_IN_YEARS );
00245 //            max_erode_depth = .25;
00246 
00247             if ( extra > max_erode_depth )
00248                extra = max_erode_depth;
00249             if ( extra>0 )
00250             {
00251 
00252 //if ( extra>.25 )
00253 //   extra = .25;
00254 
00255                sed_column_extract_top( sed_cube_col(prof,i) , extra , temp_cell );
00256                for ( n=0 ; n<n_grains ; n++ )
00257                   in_suspension[i][n] +=   sed_cell_fraction ( temp_cell , n )
00258                                          * sed_cell_size( temp_cell );
00259                in_suspension_thickness[i] += sed_cell_size( temp_cell );
00260             }
00261          }
00262       }
00263    
00264       // determine the maximum u_grav in the profile and the largest time step for
00265       // stability.
00266       u_grav_max = 0.;
00267       for ( i=i_start ; i<sed_cube_n_y(prof) ; i++ )
00268       {
00269          flux = in_suspension_thickness[i]*u_grav[i];
00270          for ( n=0 ; n<n_grains ; n++ )
00271             if ( fabs(u_grav[i]*k_grain[n]) > u_grav_max && fabs(flux)>0. )
00272                u_grav_max = fabs(u_grav[i]*k_grain[n]);
00273       }
00274 
00275       if ( u_grav_max<=0. )
00276          break;
00277 
00278       dt = dx / u_grav_max;
00279 
00280       // now move the sediment still in suspension.
00281       for ( i=i_start ; i<sed_cube_n_y(prof)-1 ; i++ )
00282       {
00283          flux_fraction = u_grav[i]*dt/dx;
00284          if ( flux_fraction>0 && u_grav[i]>0 )
00285             for ( n=0 ; n<n_grains ; n++ )
00286             {
00287                temp[i+1][n]        += in_suspension[i][n]*flux_fraction*k_grain[n];
00288                in_suspension[i][n] -= in_suspension[i][n]*flux_fraction*k_grain[n];
00289             }
00290          else if ( flux_fraction<0 && u_grav[i]<0 )
00291          {
00292             flux_fraction *= -1.;
00293             for ( n=0 ; n<n_grains ; n++ )
00294             {
00295                temp[i-1][n]        += in_suspension[i][n]*flux_fraction*k_grain[n];
00296                in_suspension[i][n] -= in_suspension[i][n]*flux_fraction*k_grain[n];
00297             }
00298          }
00299       }
00300 
00301       // do the last cell.
00302       flux_fraction = u_grav[i]*dt/dx;
00303       if ( u_grav[i] < 0 )
00304       {
00305          flux_fraction *= -1.;
00306          for ( n=0 ; n<n_grains ; n++ )
00307          {
00308             temp[i-1][n]        += in_suspension[i][n]*flux_fraction*k_grain[n];
00309             in_suspension[i][n] -= in_suspension[i][n]*flux_fraction*k_grain[n];
00310          }
00311       }
00312       else if ( u_grav[i]>0 )
00313       {
00314          for ( n=0 ; n<n_grains ; n++ )
00315             in_suspension[i][n] -= in_suspension[i][n]*flux_fraction*k_grain[n];
00316       }
00317 
00318       // do the first cell.
00319       flux_fraction = u_grav[0]*dt/dx;
00320       if ( u_grav[0] > 0 )
00321       {
00322          for ( n=0 ; n<n_grains ; n++ )
00323          {
00324             temp[1][n]          += in_suspension[0][n]*flux_fraction*k_grain[n];
00325             in_suspension[0][n] -= in_suspension[0][n]*flux_fraction*k_grain[n];
00326          }
00327       }
00328       else
00329          for ( n=0 ; n<n_grains ; n++ )
00330             in_suspension[0][n] -= in_suspension[0][n]*flux_fraction*k_grain[n];
00331    
00332       for ( i=0 ; i<sed_cube_n_y(prof) ; i++ )
00333       {
00334          in_suspension_thickness[i] = 0.;
00335          for ( n=0 ; n<n_grains ; n++ )
00336          {
00337             in_suspension[i][n]        += temp[i][n];
00338             in_suspension_thickness[i] += temp[i][n];
00339             temp[i][n]                  = 0.;
00340          }
00341       }
00342    
00343       sediment_in_suspension = 0.;
00344       for ( i=0 ; i<sed_cube_n_y(prof)-1 ; i++ )
00345          sediment_in_suspension += in_suspension_thickness[i];
00346 
00347       time_elapsed += dt;
00348    }
00349    while ( sediment_in_suspension>.01*initial_sediment && time_elapsed<duration );
00350 
00351    // deposit any sediment that might still be in suspension.
00352    for ( i=0 ; i<sed_cube_n_y(prof) ; i++ )
00353       sed_column_add_vec( sed_cube_col(prof,i) , in_suspension[i] );
00354 
00355    sed_cell_destroy( temp_cell );
00356 
00357    eh_free( in_suspension_thickness );
00358    eh_free( in_suspension[0]        );
00359    eh_free( in_suspension           );
00360    eh_free( temp[0]                 );
00361    eh_free( temp                    );
00362 
00363    eh_free( k_grain  );
00364    eh_free( max_load );
00365    eh_free( u_max    );
00366    eh_free( u_grav   );
00367    eh_free( u_wave   );
00368 
00369    return 0;
00370 }
00371 
00386 double get_orbital_velocity( double d , double H , double T , double L )
00387 {
00388    double g=9.81;
00389    double u;
00390 
00391    if ( H>d/2. )
00392       H = d/2.;
00393 
00394    if ( d<=.5 )
00395       u = 0;
00396    else if ( d<L/20. )
00397       u = H/2.*sqrt(g/d);
00398 //   else if ( d<L/2 )
00399    else
00400       u = M_PI*H/(T*sinh(2.*M_PI*d/L));
00401 /*
00402    else
00403       u = 0.;
00404 */
00405    return u;
00406 }
00407 
00408 int test_in_suspension( double *in_suspension , double thickness , int n_grains )
00409 {
00410    int n;
00411    int error = 0;
00412    double total = 0;
00413    if ( thickness > 1e-3 )
00414    {
00415       for ( n=0 ; n<n_grains ; n++ )
00416          total += in_suspension[n];
00417       if ( fabs(total-thickness)/total > 1e-3 )
00418           error++;
00419       if ( error )
00420       {
00421          eh_watch_dbl( total );
00422          eh_watch_dbl( thickness );
00423       }
00424    }
00425    return error;
00426 }

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