00001 #include "inflow.h"
00002 #include "inflow_local.h"
00003 #include <glib.h>
00004 #include <utils/utils.h>
00005 #include <sed/sed_sedflux.h>
00006
00007 GQuark
00008 inflow_error_quark( void )
00009 {
00010 return g_quark_from_static_string( "inflow-error-quark" );
00011 }
00012
00013 static Inflow_param_st p;
00014
00015 static Eh_key_file_entry template[] =
00016 {
00017 { "Length of basin" , EH_ARG_DBL , &p.basin_len } ,
00018 { "Bin spacing" , EH_ARG_DBL , &p.dx } ,
00019 { "Density of sea water" , EH_ARG_DBL , &p.rho_sea_water } ,
00020 { "Density of river water" , EH_ARG_DBL , &p.rho_river_water } ,
00021 { "Removal rate constant" , EH_ARG_DARRAY , &p.lambda , &p.n_grains } ,
00022 { "Equivalent grain diameter" , EH_ARG_DARRAY , &p.size_equiv , &p.n_grains } ,
00023 { "Component grain diameter" , EH_ARG_DARRAY , &p.size_comp , &p.n_grains } ,
00024 { "Fraction of each grain in river" , EH_ARG_DARRAY , &p.grain_fraction , &p.n_grains } ,
00025 { "Fraction of flow occupied by each grain" , EH_ARG_DARRAY , &p.flow_fraction , &p.n_grains } ,
00026 { "Bulk density" , EH_ARG_DARRAY , &p.bulk_density , &p.n_grains } ,
00027 { "Grain density" , EH_ARG_DARRAY , &p.grain_density , &p.n_grains } ,
00028 { "Distance from river to start deposition" , EH_ARG_DBL , &p.dep_start } ,
00029 { "Average grain size of bottom sediments" , EH_ARG_DBL , &p.size_bottom } ,
00030 { "Average bulk density of bottom sediments" , EH_ARG_DBL , &p.rho_bottom } ,
00031 { "Fraction of each grain size in bottom sediments" , EH_ARG_DARRAY , &p.bottom_fraction , &p.n_grains } ,
00032 { "sua" , EH_ARG_DBL , &p.sua } ,
00033 { "sub" , EH_ARG_DBL , &p.sub } ,
00034 { "Entrainment constant, Ea" , EH_ARG_DBL , &p.e_a } ,
00035 { "Entrainment constant, Eb" , EH_ARG_DBL , &p.e_b } ,
00036 { "Coefficient of drag" , EH_ARG_DBL , &p.c_drag } ,
00037 { "Angle of internal friction" , EH_ARG_DBL , &p.tan_phi } ,
00038 { "Kinematic viscosity of clear water" , EH_ARG_DBL , &p.mu_water } ,
00039 { "Flood data file" , EH_ARG_FILENAME , &p.flood_file } ,
00040 };
00041
00042 void inflow_get_phe( Inflow_phe_query_st* query_data , Inflow_bottom_st* bed_data );
00043
00044 gboolean
00045 inflow_wrapper( Inflow_bathy_st* b ,
00046 Inflow_flood_st* f ,
00047 Inflow_sediment_st* s ,
00048 Inflow_const_st* c ,
00049 double** deposition ,
00050 double** erosion )
00051 {
00052 FILE* fp_debug = g_getenv("INFLOW_DEBUG")?stderr:NULL;
00053
00054 return inflow( f->duration , b->x , b->slope ,
00055 b->width , b->len , b->x[1]-b->x[0] ,
00056 c->dep_start , f->width , f->velocity ,
00057 f->depth , f->q , f->fraction ,
00058 s->size_equiv , s->lambda , s->bulk_density ,
00059 s->grain_density , s->n_grains , c->rho_river_water ,
00060 f->rho_flow , c , deposition ,
00061 erosion , fp_debug );
00062 }
00063
00064 Inflow_param_st*
00065 inflow_scan_parameter_file( const gchar* file , GError** error )
00066 {
00067 Inflow_param_st* p_new = NULL;
00068 GError* tmp_error = NULL;
00069
00070 eh_return_val_if_fail( error==NULL || *error==NULL , NULL );
00071
00072 if ( !file )
00073 {
00074 file = INFLOW_TEST_PARAM_FILE;
00075 eh_message( "Reading parameter from default file: %s" , file );
00076 }
00077
00078 eh_key_file_scan_from_template( file , "INFLOW" , template , &tmp_error );
00079
00080 if ( !tmp_error )
00081 {
00082 p_new = eh_new( Inflow_param_st , 1 );
00083
00084 *p_new = p;
00085
00086 p_new->basin_len *= 1000;
00087 p_new->dep_start *= 1000;
00088 p_new->mu_water *= 1e-6;
00089 p_new->tan_phi = tan( p.tan_phi*G_PI/180. );
00090
00091 eh_dbl_array_mult( p_new->lambda , p_new->n_grains , S_DAYS_PER_SECOND );
00092 eh_dbl_array_mult( p_new->size_equiv , p_new->n_grains , 1e-6 );
00093 eh_dbl_array_mult( p_new->size_comp , p_new->n_grains , 1e-6 );
00094
00095 inflow_check_params( p_new , &tmp_error );
00096 }
00097
00098 if ( tmp_error )
00099 {
00100 eh_free( p_new );
00101 p_new = NULL;
00102 g_propagate_error( error , tmp_error );
00103 }
00104
00105 return p_new;
00106 }
00107
00108 Inflow_param_st*
00109 inflow_check_params( Inflow_param_st* p , GError** error )
00110 {
00111 eh_require( p );
00112 eh_return_val_if_fail( error==NULL || *error==NULL , NULL );
00113
00114 if ( p )
00115 {
00116 gchar** err_s = NULL;
00117
00118 eh_check_to_s( p->basin_len > 0. , "Basin length positive" , &err_s );
00119 eh_check_to_s( p->dx > 0. , "Spacing positive" , &err_s );
00120 eh_check_to_s( p->dx < p->basin_len , "Spacing less than basin_length" , &err_s );
00121 eh_check_to_s( p->basin_len/p->dx>5 , "Not enough nodes" , &err_s );
00122 eh_check_to_s( p->rho_sea_water >= p->rho_river_water ,
00123 "Sea water density greater than river water" , &err_s );
00124
00125 eh_check_to_s( p->rho_river_water>=1000. , "River water density greater than 1000 kg/m^3." , &err_s );
00126 eh_check_to_s( eh_dbl_array_each_ge( 0. , p->lambda , p->n_grains ) ,
00127 "Removal rates positive" , &err_s );
00128
00129 eh_check_to_s( eh_dbl_array_cmp_ge( p->size_equiv , p->size_comp , p->n_grains ) ,
00130 "Equivalent diameters >= component diameters" , &err_s );
00131 eh_check_to_s( eh_dbl_array_each_ge( 0. , p->flow_fraction , p->n_grains ) ,
00132 "Fraction of flow >= 0." , &err_s );
00133 eh_check_to_s( eh_dbl_array_each_le( 1. , p->flow_fraction , p->n_grains ) ,
00134 "Fraction of flow <= 1." , &err_s );
00135 eh_check_to_s( eh_dbl_array_each_ge( p->rho_sea_water , p->bulk_density , p->n_grains ) ,
00136 "Bulk density greater than sea water" , &err_s );
00137 eh_check_to_s( eh_dbl_array_cmp_ge( p->grain_density , p->bulk_density , p->n_grains ) ,
00138 "Grain density greater than bulk density" , &err_s );
00139 eh_check_to_s( p->dep_start>=0 , "Start of deposition greater than zero" , &err_s );
00140 eh_check_to_s( p->dep_start<p->basin_len , "Start of deposition less than basin length" , &err_s );
00141 eh_check_to_s( p->size_bottom>0. , "Grain size of bottom sediments greater than zero" , &err_s );
00142 eh_check_to_s( p->rho_bottom>p->rho_sea_water ,
00143 "Bulk density of bottom sediments >= Density of sea water" , &err_s );
00144 eh_check_to_s( eh_dbl_array_each_ge( 0. , p->bottom_fraction , p->n_grains ) ,
00145 "Fraction of bottom sediment >= 0." , &err_s );
00146 eh_check_to_s( eh_dbl_array_each_le( 1. , p->bottom_fraction , p->n_grains ) ,
00147 "Fraction of bottom sediment <= 1." , &err_s );
00148
00149 eh_check_to_s( p->sua>0. , "sua positive" , &err_s );
00150 eh_check_to_s( p->sub>0. , "sub positive" , &err_s );
00151 eh_check_to_s( p->e_a>0. , "Ea positive" , &err_s );
00152 eh_check_to_s( p->e_b>0. , "Eb positve" , &err_s );
00153 eh_check_to_s( p->c_drag>0. , "Drag coefficient positive" , &err_s );
00154 eh_check_to_s( p->tan_phi>0. , "Internal friction angle positive" , &err_s );
00155 eh_check_to_s( p->tan_phi<90. , "Internal friction angle < 90 degrees" , &err_s );
00156 eh_check_to_s( p->mu_water>0. , "Viscosity of water > 0" , &err_s );
00157
00158 if ( err_s )
00159 eh_set_error_strv( error ,
00160 INFLOW_ERROR ,
00161 INFLOW_ERROR_BAD_PARAMETER , err_s );
00162
00163 g_strfreev( err_s );
00164 }
00165
00166 return p;
00167 }
00168
00169 Inflow_bathy_st*
00170 inflow_scan_bathy_file( const gchar* file , Inflow_param_st* p , GError** error )
00171 {
00172 Inflow_bathy_st* b = NULL;
00173 GError* tmp_error = NULL;
00174
00175 eh_return_val_if_fail( error==NULL || *error==NULL , NULL );
00176
00177 eh_require( p );
00178
00179 if ( !file )
00180 {
00181 file = INFLOW_TEST_BATHY_FILE;
00182 eh_message( "Reading bathymetry from default file: %s" , file );
00183 }
00184
00185 {
00186 double** bathy;
00187 gint n_rows, n_cols;
00188
00189 bathy = eh_dlm_read_swap( file , ",;" , &n_rows , &n_cols , &tmp_error );
00190
00191 eh_require( n_rows==3 );
00192
00193 if ( !tmp_error )
00194 b = inflow_set_bathy_data( bathy , n_cols , p->dx , p->basin_len );
00195 else
00196 g_propagate_error( error , tmp_error );
00197
00198 eh_free_2( bathy );
00199 }
00200
00201 return b;
00202 }
00203
00204 Inflow_bathy_st*
00205 inflow_update_bathy_data( Inflow_bathy_st* b , double** deposition , double** erosion , gint n_grains )
00206 {
00207
00208 if ( b )
00209 {
00210 gint i, n;
00211 double sum;
00212
00213 for ( i=0 ; i<b->len-1 ; i++ )
00214 {
00215 for ( n=0,sum=0. ; n<n_grains ; n++ )
00216 sum += deposition[n][i] - erosion[n][i];
00217 b->depth[i] += sum;
00218 }
00219
00220 for ( i=0 ; i<b->len-1 ; i++ )
00221 b->slope[i] = atan( (b->depth[i+1]-b->depth[i]) / (b->x[i+1]-b->x[i]) );
00222 b->slope[b->len-1] = b->slope[b->len-2];
00223 }
00224
00225 return b;
00226
00227 }
00228
00229 Inflow_bathy_st*
00230 inflow_set_bathy_data( double** bathy , gint len , double dx , double basin_len )
00231 {
00232 Inflow_bathy_st* b = NULL;
00233
00234 if ( bathy )
00235 {
00236 gint i;
00237 double x_0 = bathy[0][0];
00238 double x_1 = x_0 + basin_len;
00239
00240 b = eh_new( Inflow_bathy_st , 1 );
00241 b->x = eh_uniform_array( x_0 , x_1 , dx , &(b->len) );
00242
00243 eh_require( b->len>1 );
00244
00245 b->depth = eh_new( double , b->len );
00246 b->width = eh_new( double , b->len );
00247 b->slope = eh_new( double , b->len );
00248
00249 interpolate( bathy[0] , bathy[1] , len , b->x , b->depth , b->len );
00250 interpolate( bathy[0] , bathy[2] , len , b->x , b->width , b->len );
00251
00252 for ( i=0 ; i<b->len-1 ; i++ )
00253 b->slope[i] = atan( (b->depth[i+1]-b->depth[i]) / (b->x[i+1]-b->x[i]) );
00254 b->slope[b->len-1] = b->slope[b->len-2];
00255
00256 for ( i=0 ; i<b->len ; i++ )
00257 b->x[i] -= x_0;
00258 }
00259
00260 return b;
00261 }
00262
00263 Inflow_bathy_st*
00264 inflow_destroy_bathy_data( Inflow_bathy_st* b )
00265 {
00266 if ( b )
00267 {
00268 eh_free( b->x );
00269 eh_free( b->depth );
00270 eh_free( b->width );
00271 eh_free( b->slope );
00272 eh_free( b );
00273 }
00274 return NULL;
00275 }
00276
00277 Inflow_flood_st**
00278 inflow_scan_flood_file( const gchar* file , Inflow_param_st* p , GError** error )
00279 {
00280 Inflow_flood_st** river_data = NULL;
00281
00282 eh_return_val_if_fail( error==NULL || *error==NULL , NULL );
00283
00284 if ( !file )
00285 {
00286 file = INFLOW_TEST_FLOOD_FILE;
00287 eh_message( "Reading flood data from default file: %s" , file );
00288 }
00289
00290 {
00291 GError* tmp_error = NULL;
00292 Sed_hydro* river = sed_hydro_scan( file , &tmp_error );
00293 gint i, len;
00294
00295 if ( river )
00296 {
00297 for ( len=0 ; river[len] ; len++ );
00298
00299 river_data = eh_new0( Inflow_flood_st* , len+1 );
00300
00301 for ( i=0 ; i<len && !tmp_error; i++ )
00302 river_data[i] = inflow_set_flood_data( river[i] , p->rho_river_water );
00303 river_data[len] = NULL;
00304
00305 for ( i=0 ; river[i] ; i++ )
00306 sed_hydro_destroy( river[i] );
00307 eh_free( river );
00308 }
00309 else
00310 g_propagate_error( error , tmp_error );
00311 }
00312
00313 return river_data;
00314 }
00315
00316 Inflow_flood_st*
00317 inflow_set_flood_data( Sed_hydro h , double rho_river_water )
00318 {
00319 Inflow_flood_st* r = NULL;
00320
00321 {
00322 r = eh_new( Inflow_flood_st , 1 );
00323
00324 r->duration = sed_hydro_duration_in_seconds( h );
00325 r->width = sed_hydro_width ( h );
00326 r->depth = sed_hydro_depth ( h );
00327 r->velocity = sed_hydro_velocity ( h );
00328 r->q = sed_hydro_water_flux ( h );
00329 r->rho_flow = sed_hydro_flow_density ( h , rho_river_water );
00330 r->fraction = sed_hydro_fraction ( h );
00331 r->n_grains = sed_hydro_size ( h ) - 1;
00332 }
00333
00334 return r;
00335 }
00336
00337 Inflow_flood_st*
00338 inflow_destroy_flood_data( Inflow_flood_st* f )
00339 {
00340 if ( f )
00341 {
00342 eh_free( f->fraction );
00343 eh_free( f );
00344 }
00345 return NULL;
00346 }
00347
00348 Inflow_sediment_st*
00349 inflow_set_sediment_data( Inflow_param_st* p )
00350 {
00351 Inflow_sediment_st* s = eh_new( Inflow_sediment_st , 1 );
00352 gint n;
00353
00354 s->size_equiv = eh_dbl_array_dup( p->size_equiv , p->n_grains );
00355 s->lambda = eh_dbl_array_dup( p->lambda , p->n_grains );
00356 s->bulk_density = eh_dbl_array_dup( p->bulk_density , p->n_grains );
00357 s->grain_density = eh_dbl_array_dup( p->grain_density , p->n_grains );
00358 s->n_grains = p->n_grains;
00359
00360
00361
00362
00363
00364
00365 for ( n=0 ; n<p->n_grains ; n++ )
00366 s->lambda[n] /= p->flow_fraction[n];
00367
00368 return s;
00369 }
00370
00371 Inflow_const_st*
00372 inflow_set_constant_data( Inflow_param_st* p )
00373 {
00374 Inflow_const_st* c = eh_new( Inflow_const_st , 1 );
00375 Inflow_bottom_st* b = eh_new( Inflow_bottom_st , 1 );
00376
00377 c->e_a = p->e_a;
00378 c->e_b = p->e_b;
00379 c->sua = p->sua;
00380 c->sub = p->sub;
00381 c->c_drag = p->c_drag;
00382 c->tan_phi = p->tan_phi;
00383 c->mu_water = p->mu_water;
00384 c->rho_river_water = p->rho_river_water;
00385 c->rho_sea_water = p->rho_sea_water;
00386 c->channel_len = p->channel_len;
00387 c->channel_width = p->channel_width;
00388
00389 c->dep_start = p->dep_start;
00390
00391 b->phe_bottom = p->bottom_fraction;
00392 b->n_grains = p->n_grains;
00393 c->get_phe_data = b;
00394 c->get_phe = inflow_get_phe;
00395
00396 return c;
00397 }
00398
00399 gint
00400 inflow_write_output( const gchar* file ,
00401 Inflow_bathy_st* b ,
00402 double** deposit ,
00403 gssize n_grains )
00404 {
00405 gint bytes = 0;
00406 FILE* fp;
00407
00408 if ( file )
00409 fp = eh_open_file( file , "w" );
00410 else
00411 fp = stdout;
00412
00413 if ( fp )
00414 {
00415 gint i, n;
00416 double sum;
00417
00418 fprintf( fp , "# Inflow input/output bathymetry file.\n" );
00419 fprintf( fp , "# Columns are :\n" );
00420 fprintf( fp , "# Position (m), Water Depth (m), Width (m)\n" );
00421
00422 for ( i=0 ; i<b->len ; i++ )
00423 {
00424 for ( n=0,sum=0 ; n<n_grains ; n++ )
00425 sum += deposit[n][i];
00426 bytes += fprintf( fp , "%f %f %f\n" , b->x[i] , b->depth[i]+sum , b->width[i] );
00427
00428 }
00429 }
00430
00431 fclose( fp );
00432
00433 return bytes;
00434 }
00435
00436 void
00437 inflow_get_phe( Inflow_phe_query_st* query_data , Inflow_bottom_st* bed_data )
00438 {
00439 double* phe_out = query_data->phe;
00440 double* phe_bottom = bed_data->phe_bottom;
00441 gint n_grains = bed_data->n_grains;
00442
00443 memcpy( phe_out , phe_bottom , sizeof(double)*n_grains );
00444
00445 return;
00446 }
00447