00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #define EH_LOG_DOMAIN BBL_PROCESS_NAME_S
00022
00023 #include <stdio.h>
00024 #include <math.h>
00025 #include <string.h>
00026 #include <glib.h>
00027 #include <utils/utils.h>
00028 #include <sed/sed_sedflux.h>
00029 #include "my_processes.h"
00030
00031 #include "sedflux.h"
00032
00033 double add_sediment_from_external_source( Sed_cube p ,
00034 Eh_sequence* seq ,
00035 double start ,
00036 double finish );
00037 int rain_sediment_3 ( Sed_cube p , int algorithm , Sed_riv r );
00038 gboolean init_bbl_data ( Sed_process p , Sed_cube prof , GError** error );
00039
00040 Sed_process_info
00041 run_bbl( Sed_process p , Sed_cube prof )
00042 {
00043 Bbl_t* data = sed_process_user_data(p);
00044 Sed_process_info info = SED_EMPTY_INFO;
00045 gint n_rivers;
00046
00047 if ( sed_process_run_count(p)==0 )
00048 init_bbl_data( p , prof , NULL );
00049
00050 if ( data->src_seq )
00051 {
00052 info.mass_added =
00053 add_sediment_from_external_source( prof ,
00054 data->src_seq ,
00055 data->last_year ,
00056 sed_cube_age_in_years(prof) );
00057 data->last_year = sed_cube_age_in_years( prof );
00058 }
00059
00060 n_rivers = sed_cube_n_rivers( prof );
00061
00062 info.mass_lost = 0.;
00063 if ( n_rivers>0 )
00064 {
00065 Sed_riv* all = sed_cube_all_branches( prof );
00066 Sed_riv* r;
00067
00068 if ( all )
00069 {
00070 for ( r=all ; *r ; r++ )
00071 {
00072 eh_debug( "Depositing sediment for river: %s" , sed_river_name_loc(*r) );
00073 rain_sediment_3( prof , data->algorithm , *r );
00074 }
00075
00076 info.mass_lost += sed_cube_mass_in_suspension( prof );
00077
00078
00079 for ( r=all ; *r ; r++ )
00080 sed_cell_grid_clear( sed_cube_in_suspension( prof , *r ) );
00081
00082 eh_free( all );
00083 }
00084 }
00085
00086 eh_message( "time : %f" , sed_cube_age_in_years( prof ) );
00087
00088 return info;
00089 }
00090
00091 #define BBL_ALGORITHM_NONE (0)
00092 #define BBL_ALGORITHM_MUDS (1)
00093
00094 #define BBL_KEY_ALGORITHM "algorithm"
00095 #define BBL_KEY_SOURCE_FILE "external sediment source file"
00096
00097 static gchar* bbl_req_labels[] =
00098 {
00099 BBL_KEY_ALGORITHM ,
00100 BBL_KEY_SOURCE_FILE ,
00101 NULL
00102 };
00103
00104 gboolean
00105 init_bbl( Sed_process p , Eh_symbol_table t , GError** error )
00106 {
00107 Bbl_t* data = sed_process_new_user_data( p , Bbl_t );
00108 GError* tmp_err = NULL;
00109 gboolean is_ok = TRUE;
00110
00111 eh_return_val_if_fail( error==NULL || *error==NULL , FALSE );
00112 eh_require( t );
00113
00114 data->src_seq = NULL;
00115 data->last_year = 0.;
00116
00117 if ( eh_symbol_table_require_labels( t , bbl_req_labels , &tmp_err ) )
00118 {
00119 gchar* src_file = eh_symbol_table_value ( t , BBL_KEY_SOURCE_FILE );
00120 gchar* key = eh_symbol_table_lookup( t , BBL_KEY_ALGORITHM );
00121
00122 if ( g_ascii_strcasecmp( src_file , "NONE" )==0 )
00123 {
00124 eh_free( src_file );
00125 src_file = NULL;
00126 }
00127
00128 data->src_file = src_file;
00129
00130 if ( g_ascii_strcasecmp( key , "MUDS" )==0 ) data->algorithm = BBL_ALGORITHM_MUDS;
00131 else if ( g_ascii_strcasecmp( key , "NONE" )==0 ) data->algorithm = BBL_ALGORITHM_NONE;
00132 else
00133 g_set_error( &tmp_err , SEDFLUX_ERROR , SEDFLUX_ERROR_BAD_ALGORITHM ,
00134 "Invalid bbl algorithm (muds or none): %s" , key );
00135
00136 if ( data->algorithm==BBL_ALGORITHM_MUDS && sed_mode_is_3d() )
00137 {
00138 eh_warning( "Sedflux3D requires bbl algorithm to be 'NONE'." );
00139 data->algorithm = BBL_ALGORITHM_NONE;
00140 }
00141 }
00142
00143 if ( tmp_err )
00144 {
00145 g_propagate_error( error , tmp_err );
00146 is_ok = FALSE;
00147 }
00148
00149 return is_ok;
00150 }
00151
00152 gboolean
00153 init_bbl_data( Sed_process p , Sed_cube prof , GError** error )
00154 {
00155 gboolean is_ok = TRUE;
00156 Bbl_t* data = sed_process_user_data( p );
00157
00158 if ( data )
00159 {
00160 GError* tmp_err = NULL;
00161 double* y = sed_cube_y( prof , NULL );
00162
00163 if ( data->src_file )
00164 {
00165 if ( sed_mode_is_3d() )
00166 data->src_seq = sed_get_floor_sequence_3( data->src_file ,
00167 sed_cube_x_res( prof ) ,
00168 sed_cube_y_res( prof ) ,
00169 &tmp_err );
00170 else
00171 data->src_seq = sed_get_floor_sequence_2( data->src_file ,
00172 y ,
00173 sed_cube_n_y(prof) ,
00174 &tmp_err );
00175 }
00176 else
00177 data->src_seq = NULL;
00178
00179 data->last_year = sed_cube_age_in_years(prof);
00180
00181 eh_free( y );
00182
00183 if ( tmp_err )
00184 {
00185 g_propagate_error( error , tmp_err );
00186 is_ok = FALSE;
00187 }
00188 }
00189
00190 return is_ok;
00191 }
00192
00193 gboolean
00194 destroy_bbl( Sed_process p )
00195 {
00196 if ( p )
00197 {
00198 Bbl_t* data = sed_process_user_data( p );
00199
00200 if ( data )
00201 {
00202 if ( data->src_seq )
00203 {
00204 gint i;
00205 for ( i=0 ; i<data->src_seq->len ; i++ )
00206 eh_grid_destroy( data->src_seq->data[i] , TRUE );
00207
00208 eh_destroy_sequence( data->src_seq , FALSE );
00209 }
00210
00211 eh_free( data );
00212 }
00213 }
00214 return TRUE;
00215 }
00216
00217 double add_sediment_from_external_source( Sed_cube p ,
00218 Eh_sequence* seq ,
00219 double start ,
00220 double finish )
00221 {
00222 double mass_added = 0;
00223 Sed_cell deposit_cell;
00224 double time_step;
00225
00226 eh_require( p );
00227
00228 eh_require( seq && seq->len>0 )
00229 {
00230 Eh_dbl_grid g;
00231 gssize i;
00232 for ( i=0 ; i<seq->len ; i++ )
00233 {
00234 g = seq->data[i];
00235
00236 eh_require( sed_cube_n_x(p)==eh_grid_n_x(g) );
00237 eh_require( sed_cube_n_y(p)==eh_grid_n_y(g) );
00238 }
00239 }
00240
00241 eh_require( start<=finish );
00242
00243 time_step = finish-start;
00244
00245 deposit_cell = sed_cell_new_env( );
00246 sed_cell_set_equal_fraction( deposit_cell );
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 if ( seq->len == 1 && time_step>1e-6 )
00257 {
00258 double **dzdt = eh_dbl_grid_data( seq->data[0] );
00259 double h;
00260 gssize i, j;
00261
00262 for ( i=0 ; i<sed_cube_n_x(p) ; i++ )
00263 for ( j=0 ; j<sed_cube_n_y(p) ; j++ )
00264 {
00265 h = eh_min( dzdt[i][j]*time_step ,
00266 sed_cube_water_depth(p,i,j) );
00267
00268 if ( h>0 )
00269 {
00270 sed_cell_resize( deposit_cell , h );
00271
00272 mass_added += sed_cell_mass(deposit_cell);
00273
00274 sed_column_add_cell( sed_cube_col_ij(p,i,j) , deposit_cell );
00275 }
00276 }
00277 }
00278 else if ( time_step>1e-6 )
00279 {
00280 double **dzdt = eh_dbl_grid_data( seq->data[0] );
00281 gssize i, j, n;
00282 double h, total_time, lower_edge, upper_edge;
00283
00284 for ( n=0,total_time=0 ; n<seq->len ; n++ )
00285 {
00286 lower_edge = seq->t[n];
00287 if ( n<seq->len-1 )
00288 upper_edge = seq->t[n+1];
00289 else
00290 upper_edge = G_MAXDOUBLE;
00291
00292 if ( start >= upper_edge )
00293 time_step = -1;
00294 else if ( start >= lower_edge && finish < upper_edge )
00295 time_step = finish - start;
00296 else if ( start < lower_edge && finish >= upper_edge )
00297 time_step = upper_edge - lower_edge;
00298 else if ( start >= lower_edge && finish >= upper_edge )
00299 time_step = upper_edge - start;
00300 else if ( start < lower_edge && finish < upper_edge )
00301 time_step = finish - lower_edge;
00302 else
00303 time_step = -1;
00304
00305 if ( time_step > 0 )
00306 {
00307 total_time += time_step;
00308 dzdt = eh_dbl_grid_data( seq->data[n] );
00309 for ( i=0 ; i<sed_cube_n_x(p) ; i++ )
00310 for ( j=0 ; j<sed_cube_n_y(p) ; j++ )
00311 {
00312 h = eh_min( dzdt[i][j]*time_step ,
00313 sed_cube_water_depth(p,i,j) );
00314
00315 if ( h>0 )
00316 {
00317 sed_cell_resize( deposit_cell , h );
00318
00319 mass_added += sed_cell_mass(deposit_cell);
00320
00321 sed_column_add_cell( sed_cube_col_ij(p,i,j) , deposit_cell );
00322 }
00323
00324 }
00325 }
00326 }
00327
00328 if ( fabs( total_time - (finish-start) ) > 1e-5 )
00329 {
00330 eh_warning( "The current time interval is not completely contained "
00331 "within the sequence." );
00332 eh_warning( "Start of this time interval: %f" , start );
00333 eh_warning( "End of this time interval: %f" , finish );
00334 eh_warning( "Total time: %f" , total_time );
00335 }
00336 }
00337
00338 mass_added *= sed_cube_x_res(p)*sed_cube_y_res(p);
00339
00340 sed_cell_destroy( deposit_cell );
00341
00342 return mass_added;
00343 }
00344