00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
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
00086 depth = sed_cube_water_depth( p , mouth_pos.i , mouth_pos.j )+1e-5;
00087
00088
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
00104 construct_deposit_array_3( p , fraction , deposit , this_river );
00105
00106
00107 error = rain_3( p , deposit );
00108
00109
00110 sed_cell_grid_clear( deposit_grid );
00111
00112
00113 time_left = time_left*(1.-fraction);
00114 time_elapsed = time_step-time_left;
00115
00116
00117 dz = get_tidal_level( time_elapsed , tidal_range , tidal_period );
00118
00119
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
00168
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
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
00216
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
00261
00262
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
00282
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