/Users/huttone/Devel/sedflux-new/sedflux/trunk/ew/sedflux/rain_sediment.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 #include <stdio.h>
00022 
00023 #include <utils/utils.h>
00024 #include <sed/sed_sedflux.h>
00025 #include <muds.h>
00026 
00027 Sed_cell **construct_deposit_array_3( Sed_cube   p        ,
00028                                       double     fraction ,
00029                                       Sed_cell** deposit  ,
00030                                       Sed_riv    r );
00031 int rain_3( Sed_cube p , Sed_cell **deposit );
00032 double get_tidal_time_step( double t0 ,
00033                             double tidal_range ,
00034                             double tidal_period ,
00035                             double dz );
00036 double get_tidal_time( double dz ,
00037                        double tidal_range ,
00038                        double tidal_period ,
00039                        gboolean waning );
00040 double get_tidal_level( double t , double tidal_range , double tidal_period );
00041 
00042 gint
00043 rain_sediment_3( Sed_cube p , int algorithm , Sed_riv this_river )
00044 {
00045    gint error = 0;
00046 
00047    eh_require( p          );
00048    eh_require( this_river );
00049 
00050    if ( p && this_river )
00051    {
00052       Eh_ind_2 mouth_pos;
00053 
00054       this_river = sed_cube_find_river_mouth( p , this_river );
00055       mouth_pos  = sed_river_mouth( this_river );
00056 
00057       if ( sed_cube_water_depth( p , mouth_pos.i , mouth_pos.j ) >= 0 )
00058       {
00059          const double  v_res         = sed_cube_z_res            ( p );
00060          const double  sea_level     = sed_cube_sea_level        ( p );
00061          const double  tidal_range   = sed_cube_tidal_range      ( p );
00062          const double  time_step     = sed_cube_time_step_in_days( p );
00063          Sed_cell      erode_cell    = sed_cell_new_env();
00064          Sed_cell_grid in_suspension = sed_cube_in_suspension( p , this_river );
00065          Sed_cell_grid deposit_grid  = sed_cell_grid_new_env( sed_cube_n_x(p) , sed_cube_n_y(p) );
00066          Sed_cell**    deposit       = eh_grid_data( deposit_grid );
00067          double        time_elapsed  = 0.;
00068          double        time_left     = time_step;
00069          const double  tidal_period  = time_step;
00070          double fraction;
00071          double depth;
00072          double tidal_dt;
00073          double dz;
00074 
00075          eh_require( erode_cell    );
00076          eh_require( in_suspension );
00077          eh_require( deposit_grid  );
00078          eh_require( deposit       );
00079 
00080          // Add sediment to profile.  Start depositing at the river mouth.
00081          while (    time_left>1e-3
00082                  && sed_cube_is_in_domain( p , mouth_pos.i , mouth_pos.j ) 
00083                  && sed_cube_water_depth( p , mouth_pos.i , mouth_pos.j ) > 0 )
00084          {
00085             // The water depth at the river mouth.
00086             depth = sed_cube_water_depth( p , mouth_pos.i , mouth_pos.j )+1e-5;
00087 
00088             // The fraction of the water column that is going to get filled.
00089             fraction = depth / sed_cell_size( sed_cell_grid_val(in_suspension,0,0) );
00090 
00091             eh_clamp( fraction , 1e-5 , 1. );
00092 
00093             if ( tidal_range>0 )
00094             {
00095                tidal_dt = get_tidal_time_step( time_elapsed ,
00096                                                tidal_range  ,
00097                                                tidal_period ,
00098                                                v_res );
00099                if ( tidal_dt<time_left*fraction )
00100                   fraction = tidal_dt/time_left;
00101             }
00102 
00103             // construct an array of cells to pass to the deposit routine.
00104             construct_deposit_array_3( p , fraction , deposit , this_river );
00105 
00106             // call the appropriate deposit routine.
00107             error = rain_3( p , deposit );
00108 
00109             // clear the deposit array.
00110             sed_cell_grid_clear( deposit_grid );
00111 
00112             // this is the time required to deposit this sediment.
00113             time_left    = time_left*(1.-fraction);
00114             time_elapsed = time_step-time_left;
00115 
00116             // get the new sea level.
00117             dz = get_tidal_level( time_elapsed , tidal_range , tidal_period );
00118 
00119             // adjust sea level and river mouth.
00120             sed_cube_set_sea_level( p , sea_level+dz );
00121             this_river = sed_cube_find_river_mouth( p , this_river );
00122 
00123             eh_require( this_river );
00124 
00125             mouth_pos = sed_river_mouth( this_river );
00126          }
00127 
00128          sed_cube_set_sea_level( p , sea_level );
00129 
00130          sed_cell_destroy     ( erode_cell   );
00131          sed_cell_grid_destroy( deposit_grid );
00132       }
00133    }
00134 
00135    return error;
00136 }
00137 
00138 Sed_cell**
00139 construct_deposit_array_3( Sed_cube   p        ,
00140                            double     fraction ,
00141                            Sed_cell** deposit  ,
00142                            Sed_riv    this_river )
00143 {
00144    int i, j;
00145    double deposit_amount;
00146    double erode_amount;
00147    double remain_amount;
00148    double water_depth;
00149    Sed_cell erode_cell;
00150    Sed_cell_grid in_suspension;
00151    Eh_ind_2 mouth_pos;
00152 
00153    in_suspension = sed_cube_in_suspension( p , this_river );
00154    erode_cell    = sed_cell_new_env( );
00155 
00156    mouth_pos = sed_river_mouth( this_river );
00157 
00158    for ( i=0 ; i<sed_cube_n_x(p) ; i++ )
00159    {
00160       for ( j=0 ; j<sed_cube_n_y(p) ; j++ )
00161       {
00162          deposit_amount = sed_cell_size(
00163                              sed_cell_grid_val(in_suspension,i-mouth_pos.i,j-mouth_pos.j) )
00164                         * fraction;
00165    
00166          //---
00167          // Any sediment that is deposited above sea level is now added to the
00168          // river sediment for the next time step.
00169          //---
00170          water_depth = sed_cube_water_depth( p , i , j );
00171          if (    deposit_amount > 0
00172               && deposit_amount > water_depth-1e-5 )
00173          {
00174             if ( water_depth < 0 )
00175                water_depth = 0;
00176 
00177             erode_amount   = deposit_amount - water_depth;
00178             deposit_amount = water_depth + 1e-5;
00179    
00180             sed_cell_copy( erode_cell ,
00181                            sed_cell_grid_val(in_suspension,i-mouth_pos.i,j-mouth_pos.j) );
00182             sed_cell_resize( erode_cell , erode_amount );
00183 //            sed_add_cell_to_cell( p->erode , erode_cell , sed_size( p->sed ) );
00184    
00185          }
00186          remain_amount = sed_cell_size(
00187                             sed_cell_grid_val(in_suspension,i-mouth_pos.i,j-mouth_pos.j) )
00188                        - deposit_amount;
00189    
00190          sed_cell_copy   ( deposit[i][j] ,
00191                            sed_cell_grid_val(in_suspension,i-mouth_pos.i,j-mouth_pos.j) );
00192          sed_cell_resize ( deposit[i][j] , deposit_amount );
00193          sed_cell_resize ( sed_cell_grid_val(in_suspension,i-mouth_pos.i,j-mouth_pos.j) ,
00194                            remain_amount );
00195          sed_cell_set_age( deposit[i][j] , sed_cube_age( p ) );
00196 
00197       }
00198    }
00199 
00200    sed_cell_destroy( erode_cell );
00201 
00202    return deposit;
00203 }
00204 
00205 int rain_3( Sed_cube p , Sed_cell **deposit )
00206 {
00207    int i;
00208    gssize len = sed_cube_size(p);
00209    for ( i=0 ; i<len ; i++ )
00210       sed_column_add_cell( sed_cube_col(p,i) , deposit[0][i] );
00211    return 0;
00212 }
00213 
00214 //---
00215 // calculate the amount of time that the elevation of the tide will change
00216 // by an increment dz (m).  the current time is given as t0.
00217 //---
00218 double get_tidal_time_step( double t0 ,
00219                             double tidal_range ,
00220                             double tidal_period ,
00221                             double dz )
00222 {
00223    double z0, t1;
00224    gboolean is_waning=FALSE;
00225 
00226    eh_require( t0<=tidal_period );
00227    eh_require( t0>=0 );
00228 
00229    z0 = get_tidal_level( t0 , tidal_range , tidal_period );
00230 
00231    if ( t0>tidal_period/2. )
00232    {
00233       dz *= -1;
00234       is_waning = TRUE;
00235    }
00236 
00237    if ( fabs( z0+dz ) > tidal_range )
00238    {
00239       dz = 0;
00240       is_waning = is_waning?FALSE:TRUE;
00241    }
00242 
00243    t1 = get_tidal_time( z0+dz , tidal_range , tidal_period , is_waning );
00244    if ( t1<t0 )
00245       t1 += tidal_period;
00246 
00247    if ( t1<=t0 )
00248    {
00249       eh_watch_dbl( tidal_period );
00250       eh_watch_dbl( tidal_range );
00251       eh_watch_dbl( t1 );
00252       eh_watch_dbl( t0 );
00253    }
00254    eh_require( t1>t0 );
00255 
00256    return t1-t0;
00257 }
00258 
00259 //---
00260 // calculate the time required for the tide to reach a certain elevation, z.
00261 // given a tidal range (m) and tidal period (s).  in order for there to be a
00262 // single solution, we specify if the tide is waxing or waning.
00263 //---
00264 double get_tidal_time( double z ,
00265                        double tidal_range ,
00266                        double tidal_period ,
00267                        gboolean waning )
00268 {
00269    double dt;
00270 
00271    eh_require( fabs(z)<=tidal_range );
00272 
00273    dt = asin(z/tidal_range)*tidal_period/2./M_PI + tidal_period/4.;
00274    if ( waning )
00275       dt = tidal_period - dt;
00276 
00277    return dt;
00278 }
00279 
00280 //---
00281 // calculate tide elevation at some time, t given a tidal range (m) and 
00282 // tidal period (s).
00283 //---
00284 double get_tidal_level( double t , double tidal_range , double tidal_period )
00285 {
00286    eh_require( t<=tidal_period );
00287    eh_require( t>=0 );
00288    t -= tidal_period/4.;
00289    return tidal_range*sin(t*2.*M_PI/tidal_period);
00290 }
00291 
00292 

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