00001 #include "sakura.h"
00002 #include "sakura_local.h"
00003 #include <glib.h>
00004 #include <utils/utils.h>
00005 #include <sed/sed_sedflux.h>
00006
00007 GQuark
00008 sakura_error_quark( void )
00009 {
00010 return g_quark_from_static_string( "sakura-error-quark" );
00011 }
00012
00013 static Sakura_param_st p;
00014
00015 static Eh_key_file_entry template[] =
00016 {
00017
00018 { "Bin spacing" , EH_ARG_DBL , &p.dx } ,
00019 { "Time step" , EH_ARG_DBL , &p.dt } ,
00020
00021
00022 { "Density of sea water" , EH_ARG_DBL , &p.rho_sea_water } ,
00023 { "Density of river water" , EH_ARG_DBL , &p.rho_river_water } ,
00024 { "Removal rate constant" , EH_ARG_DARRAY , &p.lambda , &p.n_grains } ,
00025
00026
00027
00028 { "Fraction of flow occupied by each grain" , EH_ARG_DARRAY , &p.flow_fraction , &p.n_grains } ,
00029 { "Bulk density" , EH_ARG_DARRAY , &p.bulk_density , &p.n_grains } ,
00030 { "Grain density" , EH_ARG_DARRAY , &p.grain_density , &p.n_grains } ,
00031 { "Distance from river to start deposition" , EH_ARG_DBL , &p.dep_start } ,
00032
00033
00034 { "Fraction of each grain size in bottom sediments" , EH_ARG_DARRAY , &p.bottom_fraction , &p.n_grains } ,
00035 { "sua" , EH_ARG_DBL , &p.sua } ,
00036 { "sub" , EH_ARG_DBL , &p.sub } ,
00037 { "Entrainment constant, Ea" , EH_ARG_DBL , &p.e_a } ,
00038 { "Entrainment constant, Eb" , EH_ARG_DBL , &p.e_b } ,
00039 { "Coefficient of drag" , EH_ARG_DBL , &p.c_drag } ,
00040 { "Angle of internal friction" , EH_ARG_DBL , &p.tan_phi } ,
00041 { "Kinematic viscosity of clear water" , EH_ARG_DBL , &p.mu_water } ,
00042
00043 { NULL }
00044 };
00045
00046
00047
00048 double**
00049 sakura_wrapper( Sakura_bathy_st* b ,
00050 Sakura_flood_st* f ,
00051 Sakura_sediment_st* s ,
00052 Sakura_const_st* c ,
00053 gint* n_grains ,
00054 gint* len )
00055 {
00056 double** deposit = NULL;
00057 gboolean is_ok;
00058
00059 eh_require( b );
00060 eh_require( f );
00061 eh_require( s );
00062 eh_require( c );
00063 eh_require( n_grains );
00064 eh_require( len );
00065
00066 {
00067 FILE* fp_debug = g_getenv("SAKURA_DEBUG")?stderr:NULL;
00068
00069 double dx = b->dx;
00070 double* init_u = eh_new( double , 2 );
00071 double* init_c = eh_new( double , 2 );
00072
00073 init_u[0] = f->velocity;
00074 init_u[1] = -1.;
00075 init_c[0] = f->rho_flow;
00076 init_c[1] = -1.;
00077
00078 eh_require( b->x );
00079 eh_require( b->depth );
00080 eh_require( b->width );
00081 eh_require( init_u );
00082 eh_require( init_c );
00083 eh_require( s->lambda );
00084 eh_require( s->u_settling );
00085
00086 eh_require( s->grain_density );
00087 eh_require( s->bulk_density );
00088 eh_require( f->fraction );
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100 deposit =
00101 sakura( f->velocity , f->rho_flow , f->depth , f->fraction ,
00102 c->dt , f->duration ,
00103 b->x , b->depth , b->width , b->len ,
00104 s->grain_density , s->bulk_density , s->u_settling , s->n_grains ,
00105 c );
00106
00107 *n_grains = s->n_grains;
00108 *len = b->len;
00109
00110 eh_free( init_u );
00111 eh_free( init_c );
00112 }
00113
00114 return deposit;
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125 }
00126
00127 Sakura_param_st*
00128 sakura_scan_parameter_file( const gchar* file , GError** error )
00129 {
00130 Sakura_param_st* p_new = NULL;
00131 GError* tmp_error = NULL;
00132
00133 eh_return_val_if_fail( error==NULL || *error==NULL , NULL );
00134
00135 if ( !file )
00136 {
00137 file = SAKURA_TEST_PARAM_FILE;
00138 eh_message( "Reading parameter from default file: %s" , file );
00139 }
00140
00141 eh_key_file_scan_from_template( file , "SAKURA" , template , &tmp_error );
00142
00143 if ( !tmp_error )
00144 {
00145 p_new = eh_new( Sakura_param_st , 1 );
00146
00147 *p_new = p;
00148
00149
00150 p_new->dep_start *= 1000;
00151 p_new->mu_water *= 1e-6;
00152 p_new->tan_phi = tan( p.tan_phi*G_PI/180. );
00153
00154
00155 eh_dbl_array_mult( p_new->lambda , p_new->n_grains , S_DAYS_PER_SECOND );
00156
00157
00158
00159 sakura_check_params( p_new , &tmp_error );
00160 }
00161
00162 if ( tmp_error )
00163 {
00164 eh_free( p_new );
00165 p_new = NULL;
00166 g_propagate_error( error , tmp_error );
00167 }
00168
00169 return p_new;
00170 }
00171
00172 Sakura_param_st*
00173 sakura_check_params( Sakura_param_st* p , GError** error )
00174 {
00175 eh_require( p );
00176 eh_return_val_if_fail( error==NULL || *error==NULL , NULL );
00177
00178 if ( p )
00179 {
00180 gchar** err_s = NULL;
00181
00182
00183 eh_check_to_s( p->dx > 0. , "Spacing positive" , &err_s );
00184
00185 eh_check_to_s( p->dt > 0. , "Time step positive" , &err_s );
00186
00187
00188
00189 eh_check_to_s( p->rho_sea_water >= p->rho_river_water ,
00190 "Sea water density greater than river water" , &err_s );
00191
00192 eh_check_to_s( p->rho_river_water>=1000. , "River water density greater than 1000 kg/m^3." , &err_s );
00193 eh_check_to_s( eh_dbl_array_each_ge( 0. , p->lambda , p->n_grains ) ,
00194 "Removal rates positive" , &err_s );
00195
00196
00197
00198 eh_check_to_s( eh_dbl_array_each_ge( 0. , p->flow_fraction , p->n_grains ) ,
00199 "Fraction of flow >= 0." , &err_s );
00200 eh_check_to_s( eh_dbl_array_each_le( 1. , p->flow_fraction , p->n_grains ) ,
00201 "Fraction of flow <= 1." , &err_s );
00202 eh_check_to_s( eh_dbl_array_each_ge( p->rho_sea_water , p->bulk_density , p->n_grains ) ,
00203 "Bulk density greater than sea water" , &err_s );
00204 eh_check_to_s( eh_dbl_array_cmp_ge( p->grain_density , p->bulk_density , p->n_grains ) ,
00205 "Grain density greater than bulk density" , &err_s );
00206 eh_check_to_s( p->dep_start>=0 , "Start of deposition greater than zero" , &err_s );
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 eh_check_to_s( p->sua>0. , "sua positive" , &err_s );
00217 eh_check_to_s( p->sub>0. , "sub positive" , &err_s );
00218 eh_check_to_s( p->e_a>0. , "Ea positive" , &err_s );
00219 eh_check_to_s( p->e_b>0. , "Eb positve" , &err_s );
00220 eh_check_to_s( p->c_drag>0. , "Drag coefficient positive" , &err_s );
00221 eh_check_to_s( p->tan_phi>0. , "Internal friction angle positive" , &err_s );
00222 eh_check_to_s( p->tan_phi<90. , "Internal friction angle < 90 degrees" , &err_s );
00223 eh_check_to_s( p->mu_water>0. , "Viscosity of water > 0" , &err_s );
00224
00225 if ( err_s )
00226 eh_set_error_strv( error ,
00227 SAKURA_ERROR ,
00228 SAKURA_ERROR_BAD_PARAMETER , err_s );
00229
00230 g_strfreev( err_s );
00231 }
00232
00233 return p;
00234 }
00235
00236 Sakura_bathy_st*
00237 sakura_scan_bathy_file( const gchar* file , Sakura_param_st* p , GError** error )
00238 {
00239 Sakura_bathy_st* b = NULL;
00240 GError* tmp_error = NULL;
00241
00242 eh_return_val_if_fail( error==NULL || *error==NULL , NULL );
00243
00244 eh_require( p );
00245
00246 if ( !file )
00247 {
00248 file = SAKURA_TEST_BATHY_FILE;
00249 eh_message( "Reading bathymetry from default file: %s" , file );
00250 }
00251
00252 {
00253 double** bathy;
00254 gint n_rows;
00255 gint n_cols;
00256
00257 bathy = eh_dlm_read_swap( file , ",;" , &n_rows , &n_cols , &tmp_error );
00258
00259 eh_require( n_rows==3 );
00260
00261 if ( !tmp_error )
00262
00263 b = sakura_set_bathy_data( bathy , n_cols , p->dx , p->n_grains );
00264 else
00265 g_propagate_error( error , tmp_error );
00266
00267 eh_free_2( bathy );
00268 }
00269
00270 return b;
00271 }
00272
00273 Sakura_bathy_st*
00274 sakura_update_bathy_data( Sakura_bathy_st* b , double** deposition , double** erosion , gint n_grains )
00275 {
00276
00277 if ( b )
00278 {
00279 gint i, n;
00280 double sum;
00281
00282 for ( i=0 ; i<b->len-1 ; i++ )
00283 {
00284 for ( n=0,sum=0. ; n<n_grains ; n++ )
00285 sum += deposition[n][i] - erosion[n][i];
00286 b->depth[i] += sum;
00287 }
00288
00289 for ( i=0 ; i<b->len-1 ; i++ )
00290 b->slope[i] = atan( (b->depth[i+1]-b->depth[i]) / (b->x[i+1]-b->x[i]) );
00291 b->slope[b->len-1] = b->slope[b->len-2];
00292 }
00293
00294 return b;
00295
00296 }
00297
00298 Sakura_bathy_st*
00299 sakura_set_bathy_data( double** bathy , gint len , double dx , gint n_grains )
00300 {
00301 Sakura_bathy_st* b = NULL;
00302
00303 eh_require( bathy );
00304 eh_require( bathy[0] );
00305 eh_require( bathy[1] );
00306 eh_require( bathy[2] );
00307 eh_require( len >=2 );
00308 eh_require( dx > 0. );
00309 eh_require( n_grains > 0. );
00310
00311
00312 if ( bathy )
00313 {
00314 gint i;
00315
00316 double x_0 = bathy[0][0];
00317
00318 double x_1 = bathy[0][len-1];
00319
00320 b = eh_new( Sakura_bathy_st , 1 );
00321
00322 b->x = eh_uniform_array( x_0 , x_1 , dx , &(b->len) );
00323 b->dx = dx;
00324
00325 b->n_grains = n_grains;
00326
00327 eh_require( b->len>1 );
00328
00329 b->depth = eh_new( double , b->len );
00330 b->width = eh_new( double , b->len );
00331 b->slope = eh_new( double , b->len );
00332
00333 b->dep = eh_new_2( double , n_grains , b->len );
00334
00335 interpolate( bathy[0] , bathy[1] , len , b->x , b->depth , b->len );
00336 interpolate( bathy[0] , bathy[2] , len , b->x , b->width , b->len );
00337
00338 for ( i=0 ; i<b->len-1 ; i++ )
00339 b->slope[i] = atan( (b->depth[i+1]-b->depth[i]) / (b->x[i+1]-b->x[i]) );
00340 b->slope[b->len-1] = b->slope[b->len-2];
00341
00342
00343
00344 }
00345
00346 return b;
00347 }
00348
00349 Sakura_bathy_st*
00350 sakura_new_bathy_data( gint n_grains , gint len )
00351 {
00352 Sakura_bathy_st* b=NULL;
00353
00354 if ( len>0 )
00355 {
00356 b = eh_new( Sakura_bathy_st , 1 );
00357
00358 b->x = eh_new( double , len );
00359 b->depth = eh_new( double , len );
00360 b->width = eh_new( double , len );
00361 b->slope = eh_new( double , len );
00362
00363 b->dep = eh_new_2( double , n_grains , len );
00364
00365 b->n_grains = n_grains;
00366 b->len = len;
00367 b->dx = 0;
00368 }
00369 return b;
00370 }
00371
00372 Sakura_bathy_st*
00373 sakura_copy_bathy_data( Sakura_bathy_st* d , const Sakura_bathy_st* s )
00374 {
00375 eh_require( s );
00376
00377 if ( s )
00378 {
00379 gint n;
00380
00381 if ( !d ) d = sakura_new_bathy_data( s->n_grains , s->len );
00382
00383 eh_require( d );
00384 eh_require( d->len==s->len );
00385
00386 d->dx = s->dx;
00387
00388 memcpy( d->x , s->x , sizeof(double)*s->len );
00389 memcpy( d->depth , s->depth , sizeof(double)*s->len );
00390 memcpy( d->width , s->width , sizeof(double)*s->len );
00391 memcpy( d->slope , s->slope , sizeof(double)*s->len );
00392 for ( n=0 ; n<s->n_grains ; n++ )
00393 memcpy( d->dep[n] , s->dep[n] , sizeof(double)*s->len );
00394 }
00395
00396 return d;
00397 }
00398
00399 Sakura_bathy_st*
00400 sakura_destroy_bathy_data( Sakura_bathy_st* b )
00401 {
00402 if ( b )
00403 {
00404 eh_free( b->x );
00405 eh_free( b->depth );
00406 eh_free( b->width );
00407 eh_free( b->slope );
00408 eh_free_2( b->dep );
00409 eh_free( b );
00410 }
00411 return NULL;
00412 }
00413
00414 Sakura_flood_st**
00415 sakura_scan_flood_file( const gchar* file , Sakura_param_st* p , GError** error )
00416 {
00417 Sakura_flood_st** river_data = NULL;
00418
00419 eh_return_val_if_fail( error==NULL || *error==NULL , NULL );
00420
00421 if ( !file )
00422 {
00423 file = SAKURA_TEST_FLOOD_FILE;
00424 eh_message( "Reading flood data from default file: %s" , file );
00425 }
00426
00427 {
00428 GError* tmp_error = NULL;
00429 Sed_hydro* river = sed_hydro_scan( file , &tmp_error );
00430 gint i, len;
00431
00432 if ( river )
00433 {
00434 for ( len=0 ; river[len] ; len++ );
00435
00436 river_data = eh_new0( Sakura_flood_st* , len+1 );
00437
00438 for ( i=0 ; i<len && !tmp_error; i++ )
00439 river_data[i] = sakura_set_flood_data( river[i] , p->rho_river_water );
00440 river_data[len] = NULL;
00441
00442 for ( i=0 ; river[i] ; i++ )
00443 sed_hydro_destroy( river[i] );
00444 eh_free( river );
00445 }
00446 else
00447 g_propagate_error( error , tmp_error );
00448 }
00449
00450 return river_data;
00451 }
00452
00453 Sakura_flood_st*
00454 sakura_set_flood_data( Sed_hydro h , double rho_river_water )
00455 {
00456 Sakura_flood_st* r = NULL;
00457
00458 {
00459 r = eh_new( Sakura_flood_st , 1 );
00460
00461 r->duration = sed_hydro_duration_in_seconds( h );
00462 r->width = sed_hydro_width ( h );
00463 r->depth = sed_hydro_depth ( h );
00464 r->velocity = sed_hydro_velocity ( h );
00465 r->q = sed_hydro_water_flux ( h );
00466 r->rho_flow = sed_hydro_flow_density ( h , rho_river_water ) - rho_river_water;
00467 r->fraction = sed_hydro_fraction ( h );
00468 r->n_grains = sed_hydro_size ( h );
00469 }
00470
00471 return r;
00472 }
00473
00474 Sakura_flood_st*
00475 sakura_sed_set_flood_data( Sed_hydro h , double rho_river_water )
00476 {
00477 Sakura_flood_st* r = NULL;
00478
00479 {
00480
00481 r = eh_new( Sakura_flood_st , 1 );
00482
00483 r->duration = sed_hydro_duration_in_seconds( h );
00484 r->width = sed_hydro_width ( h );
00485 r->depth = sed_hydro_depth ( h );
00486 r->velocity = sed_hydro_velocity ( h );
00487 r->q = sed_hydro_water_flux ( h );
00488 r->rho_flow = sed_hydro_flow_density ( h , rho_river_water ) - rho_river_water;
00489 r->n_grains = sed_hydro_size ( h ) + 1;
00490
00491 {
00492 gint n;
00493 double* f = sed_hydro_fraction(h);
00494
00495 r->fraction = eh_new(double , r->n_grains );
00496 r->fraction[0] = 0;
00497 for ( n=1 ; n<r->n_grains ; n++ )
00498 r->fraction[n] = f[n-1];
00499
00500 eh_free( f );
00501 }
00502 }
00503
00504 return r;
00505 }
00506
00507
00508 Sakura_flood_st*
00509 sakura_destroy_flood_data( Sakura_flood_st* f )
00510 {
00511 if ( f )
00512 {
00513 eh_free( f->fraction );
00514 eh_free( f );
00515 }
00516 return NULL;
00517 }
00518
00519 Sakura_sediment_st*
00520 sakura_destroy_sediment_data( Sakura_sediment_st* s )
00521 {
00522 if ( s )
00523 {
00524 eh_free( s->size_equiv );
00525 eh_free( s->lambda );
00526 eh_free( s->bulk_density );
00527 eh_free( s->grain_density );
00528 eh_free( s->u_settling );
00529 eh_free( s->reynolds_no );
00530 eh_free( s );
00531 }
00532 return NULL;
00533 }
00534
00535 Sakura_sediment_st*
00536 sakura_set_sediment_data( Sakura_param_st* p )
00537 {
00538 Sakura_sediment_st* s = eh_new( Sakura_sediment_st , 1 );
00539 gint n;
00540
00541
00542 s->lambda = eh_dbl_array_dup( p->lambda , p->n_grains );
00543 s->bulk_density = eh_dbl_array_dup( p->bulk_density , p->n_grains );
00544 s->grain_density = eh_dbl_array_dup( p->grain_density , p->n_grains );
00545 s->u_settling = eh_new( double , p->n_grains );
00546
00547 s->n_grains = p->n_grains;
00548
00549
00550
00551
00552
00553
00554 for ( n=0 ; n<p->n_grains ; n++ )
00555 {
00556 s->lambda[n] /= p->flow_fraction[n];
00557
00558 s->u_settling[n] = sed_removal_rate_to_settling_velocity( s->lambda[n]*S_SECONDS_PER_DAY )
00559 * S_DAYS_PER_SECOND;
00560
00561
00562
00563
00564 if ( TRUE )
00565 {
00566 eh_message( "Settling velocity (cm/s): %f" , s->u_settling[n]*100. );
00567 }
00568 }
00569
00570 return s;
00571 }
00572
00573 void
00574 sakura_set_width( Sakura_bathy_st* bathy_data ,
00575 double river_width ,
00576 double spreading_angle )
00577 {
00578 gint i;
00579 double dx = bathy_data->x[1] - bathy_data->x[0];
00580 double flow_width;
00581
00582
00583 bathy_data->width[0] = river_width;
00584 for ( i=1 ; i<bathy_data->len ; i++ )
00585 {
00586 bathy_data->width[i] = river_width;
00587
00588
00589
00590
00591
00592
00593 }
00594
00595 return;
00596 }
00597 #include <math.h>
00598
00599 double
00600 sakura_settling_velocity( double rho_grain , double equiv_dia , double rho_river_water , double mu_river_water )
00601 {
00602 double u = 0.;
00603
00604 eh_require( rho_grain >0. );
00605 eh_require( equiv_dia >0. );
00606 eh_require( rho_river_water>0. );
00607 eh_require( mu_river_water >0. );
00608
00609 {
00610 double Rden = rho_grain/rho_river_water;
00611 double Dstar = sed_gravity() * Rden * pow(equiv_dia, 3.0) / pow(mu_river_water, 2.0);
00612 double Wstar = -3.76715
00613 + (1.92944 * log10(Dstar))
00614 - (0.09815 * pow(log10(Dstar), 2.0))
00615 - (0.00575 * pow(log10(Dstar), 3.0))
00616 + (0.00056 * pow(log10(Dstar), 4.0));
00617
00618 Wstar = pow(10.0, Wstar);
00619
00620 u = pow((Rden * G * mu_river_water * Wstar), 0.33333);
00621
00622 eh_watch_dbl( u*100 );
00623 u = 0.005;
00624 eh_watch_dbl( u*100 );
00625
00626 }
00627
00628 return u;
00629 }
00630
00631 double
00632 sakura_reynolds_number( double rho_grain , double equiv_dia , double rho_river_water , double mu_river_water )
00633 {
00634 double r = 0.;
00635
00636 eh_require( rho_grain >0. );
00637 eh_require( equiv_dia >0. );
00638 eh_require( rho_river_water>0. );
00639 eh_require( mu_river_water >0. );
00640
00641 {
00642 double Rden = rho_grain/rho_river_water;
00643 double Dstar = sed_gravity() * Rden * pow(equiv_dia, 3.0) / pow(mu_river_water, 2.0);
00644 double Wstar = -3.76715
00645 + (1.92944 * log10(Dstar))
00646 - (0.09815 * pow(log10(Dstar), 2.0))
00647 - (0.00575 * pow(log10(Dstar), 3.0))
00648 + (0.00056 * pow(log10(Dstar), 4.0));
00649
00650 Wstar = pow(10.0, Wstar);
00651
00652 r = sqrt(Rden * G * pow(equiv_dia, 3.0)) / mu_river_water;
00653 }
00654
00655 return r;
00656 }
00657
00658 Sakura_const_st*
00659 sakura_set_constant_data( Sakura_param_st* p , Sakura_bathy_st* b )
00660 {
00661 Sakura_const_st* c = eh_new( Sakura_const_st , 1 );
00662 Sakura_arch_st* arch = eh_new( Sakura_arch_st , 1 );
00663
00664 c->dt = p->dt;
00665
00666 c->e_a = p->e_a;
00667 c->e_b = p->e_b;
00668 c->sua = p->sua;
00669 c->sub = p->sub;
00670 c->c_drag = p->c_drag;
00671 c->tan_phi = p->tan_phi;
00672 c->mu_water = p->mu_water;
00673 c->rho_river_water = p->rho_river_water;
00674 c->rho_sea_water = p->rho_sea_water;
00675 c->channel_len = p->channel_len;
00676 c->channel_width = p->channel_width;
00677
00678 c->dep_start = p->dep_start;
00679
00680 c->get_phe = (Sakura_phe_func)sakura_get_phe;
00681 c->add = (Sakura_add_func)sakura_add;
00682 c->remove = (Sakura_add_func)sakura_remove;
00683 c->get_depth = (Sakura_get_func)sakura_get_depth;
00684
00685 arch->b = b;
00686 arch->phe = p->bottom_fraction;
00687 arch->n_grains = p->n_grains;
00688
00689 c->get_phe_data = arch;
00690 c->depth_data = arch;
00691 c->add_data = arch;
00692 c->remove_data = arch;
00693
00694 return c;
00695 }
00696
00697 Sakura_const_st*
00698 sakura_set_constant_output_data( Sakura_const_st* c , const gchar* file , gint* id , gint dt )
00699 {
00700 eh_require( c );
00701
00702 if ( c )
00703 {
00704 if ( file && id && dt>0 )
00705 {
00706 c->data_fp = eh_fopen( file , "w" );
00707 c->data_id = id;
00708 c->data_int = dt;
00709 }
00710 else
00711 {
00712 c->data_fp = NULL;
00713 c->data_id = NULL;
00714 c->data_int = -1;
00715 }
00716 }
00717
00718 return c;
00719 }
00720
00721 gint
00722 sakura_write_data( const gchar* file ,
00723 Eh_dbl_grid deposit )
00724 {
00725 gint n = 0;
00726
00727 eh_require( deposit );
00728
00729 if ( file && deposit )
00730 {
00731 gint i, j;
00732 FILE* fp = eh_open_file( file , "a" );
00733 double** d = eh_dbl_grid_data(deposit);
00734 gint n_grains = eh_grid_n_x(deposit);
00735 gint len = eh_grid_n_y(deposit);
00736 double width = 30000;
00737 double dx = 100.;
00738
00739 for ( j=0 ; j<n_grains ; j++ )
00740 {
00741 n += fprintf( fp , "%f" , d[j][0]/(width*dx) );
00742 for ( i=1 ; i<len ; i++ )
00743 n += fprintf( fp , "; %f" , d[j][i]/(width*dx) );
00744 n += fprintf( fp , "\n" );
00745 }
00746
00747 fclose( fp );
00748 }
00749
00750 return n;
00751 }
00752
00753 gint
00754 sakura_write_output( const gchar* file ,
00755 Sakura_bathy_st* b ,
00756 double** deposit ,
00757 gssize n_grains )
00758 {
00759 gint bytes = 0;
00760 FILE* fp;
00761
00762 if ( file ) fp = eh_open_file( file , "w" );
00763 else fp = stdout;
00764
00765 if ( fp )
00766 {
00767 gint i, n;
00768 double sum;
00769
00770 fprintf( fp , "# Sakura input/output bathymetry file.\n" );
00771 fprintf( fp , "# Columns are :\n" );
00772 fprintf( fp , "# Position (m), Water Depth (m), Width (m)\n" );
00773
00774 for ( i=0 ; i<b->len ; i++ )
00775 {
00776 for ( n=0,sum=0 ; n<n_grains ; n++ )
00777 sum += deposit[n][i];
00778 bytes += fprintf( fp , "%f; %f; %f\n" , b->x[i] , b->depth[i]+sum , b->width[i] );
00779
00780 }
00781 }
00782
00783 fclose( fp );
00784
00785 return bytes;
00786 }
00787
00810 #if defined( EXCLUDE_THIS )
00811 void
00812 sakura_get_phe( Sakura_phe_query_st* query_data , Sakura_bottom_st* bed_data )
00813 {
00814 double* phe_out = query_data->phe;
00815 double* phe_bottom = bed_data->phe_bottom;
00816 gint n_grains = bed_data->n_grains;
00817
00818 memcpy( phe_out , phe_bottom , sizeof(double)*n_grains );
00819
00820 return;
00821 }
00822
00823 void
00824 sakura_remove( Sakura_erode_query_st remove_query , gpointer data )
00825 {
00826 double remove = EH_STRUCT_MEMBER( Sak_erode_query_t , remove_query , dh );
00827 int i = EH_STRUCT_MEMBER( Sak_erode_query_t , remove_query , i );
00828
00829 double *x = EH_STRUCT_MEMBER( Sak_bathy_t , data , x );
00830 double *depth = EH_STRUCT_MEMBER( Sak_bathy_t , data , depth );
00831 double *slope = EH_STRUCT_MEMBER( Sak_bathy_t , data , slope );
00832 int n_nodes = EH_STRUCT_MEMBER( Sak_bathy_t , data , n_nodes );
00833
00834 remove = (remove>0)?remove:-remove;
00835 depth[i] -= remove;
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846 return;
00847 }
00848
00849 void sakura_add( gpointer add_query , gpointer data )
00850 {
00851 double add = EH_STRUCT_MEMBER( Sak_add_query_t , add_query , dh );
00852 int i = EH_STRUCT_MEMBER( Sak_add_query_t , add_query , i );
00853 double *x = EH_STRUCT_MEMBER( Sak_bathy_t , data , x );
00854 double *depth = EH_STRUCT_MEMBER( Sak_bathy_t , data , depth );
00855 double *slope = EH_STRUCT_MEMBER( Sak_bathy_t , data , slope );
00856 int n_nodes = EH_STRUCT_MEMBER( Sak_bathy_t , data , n_nodes );
00857
00858 add = (add>0)?add:-add;
00859 depth[i] += add;
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871 return;
00872 }
00873
00874 void sakura_get_depth( gpointer depth_query , gpointer data )
00875 {
00876 int i = EH_STRUCT_MEMBER( Sak_depth_query_t , depth_query , i );
00877 double *depth = EH_STRUCT_MEMBER( Sak_bathy_t , data , depth );
00878
00879 EH_STRUCT_MEMBER( Sak_depth_query_t , depth_query , depth ) = depth[i];
00880
00881 return;
00882 }
00883
00884 void sakura_set_depth( gpointer depth_query , gpointer data )
00885 {
00886 int i = EH_STRUCT_MEMBER( Sak_depth_query_t ,
00887 depth_query ,
00888 i );
00889 double new_depth = EH_STRUCT_MEMBER( Sak_depth_query_t ,
00890 depth_query ,
00891 depth );
00892 double *depth = EH_STRUCT_MEMBER( Sak_bathy_t , data , depth );
00893
00894 depth[i] = new_depth;
00895
00896 return;
00897 }
00898 #endif
00899
00900 void
00901 sakura_get_phe( Sakura_arch_st* data , double x , Sakura_phe_st* phe_data )
00902 {
00903 eh_require( data );
00904 eh_require( phe_data );
00905
00906 if ( data && phe_data)
00907 {
00908 double* phe_out = phe_data->phe;
00909 gint n_grains = phe_data->n_grains;
00910 double* phe_bottom = data->phe;
00911
00912 eh_require( phe_bottom );
00913 eh_require( n_grains>0 );
00914 eh_require( n_grains == data->n_grains );
00915
00916 if ( !phe_out )
00917 phe_out = eh_new( double , n_grains );
00918
00919 memcpy( phe_out , phe_bottom , sizeof(double)*n_grains );
00920
00921 phe_data->phe = phe_out;
00922 }
00923
00924 return;
00925 }
00926
00927 double
00928 sakura_add( Sakura_arch_st* data , double x , Sakura_cell_st* s )
00929 {
00930 double vol_add = 0.;
00931
00932 eh_require( data );
00933 eh_require( data->b );
00934 eh_require( s );
00935
00936 if ( data && s && s->t>0 )
00937 {
00938 Sakura_bathy_st* b = data->b;
00939 gint len = b->len;
00940 double* depth = b->depth;
00941 gint ind = (x-b->x[0])/b->dx;
00942 double dh;
00943 const double width = 30000.;
00944
00945
00946
00947 eh_require( ind>=0 );
00948 eh_require( ind<len );
00949 eh_require( depth );
00950
00951
00952
00953
00954 dh = s->t/(b->dx*width);
00955
00956 if ( depth[ind]+dh>0 ) dh = -depth[ind];
00957
00958 if ( dh<0 ) dh = 0;
00959
00960 depth[ind] += fabs( dh );
00961
00962 b->dep[s->id][ind] += fabs(dh);
00963
00964
00965 vol_add = dh*b->dx*width;
00966 }
00967
00968 return vol_add;
00969 }
00970
00971 double
00972 sakura_remove( Sakura_arch_st* data , double x , Sakura_cell_st* s )
00973 {
00974 double vol_rem = 0.;
00975
00976 eh_require( data );
00977 eh_require( data->b );
00978 eh_require( s );
00979
00980 if ( data && s && s->t>0 )
00981 {
00982 Sakura_bathy_st* b = data->b;
00983 gint len = b->len;
00984 double* depth = b->depth;
00985 gint ind = (x-b->x[0])/(b->dx);
00986 double dh;
00987
00988 eh_require( ind>=0 );
00989 eh_require( ind<len );
00990 eh_require( depth );
00991
00992 vol_rem = s->t;
00993 dh = vol_rem/(b->dx*b->width[ind]);
00994 depth[ind] -= fabs( dh );
00995
00996 b->dep[s->id][ind] -= fabs( dh );
00997 }
00998
00999 return vol_rem;
01000 }
01001
01002 double
01003 sakura_get_depth( Sakura_arch_st* data , double x )
01004 {
01005 double depth_val = 0.;
01006
01007 eh_require( data );
01008 eh_require( data->b );
01009
01010 if ( data )
01011 {
01012 Sakura_bathy_st* b = data->b;
01013 gint len = b->len;
01014 double* depth = b->depth;
01015
01016 gint ind = (x-b->x[0])/b->dx;
01017
01018 eh_require( depth );
01019 eh_require( ind>=0 );
01020 eh_require( ind< len );
01021
01022 depth_val = depth[ind];
01023 }
01024
01025 return depth_val;
01026 }
01027