00001 #include "sed_river.h"
00002 #include "sed_cube.h"
00003
00007 typedef struct
00008 {
00009 double angle;
00010 gint i;
00011 gint j;
00012 double min_angle;
00013 double max_angle;
00014 double std_dev;
00015 }
00016 Sed_riv_hinge;
00017
00021 CLASS( Sed_riv )
00022 {
00023 Sed_hydro data;
00024 Sed_riv_hinge* hinge;
00025 gint x_ind;
00026 gint y_ind;
00027 gchar* name;
00028 Sed_riv l;
00029 Sed_riv r;
00030 };
00031
00032 Sed_riv_hinge* sed_river_hinge_new( );
00033 Sed_riv_hinge* sed_river_hinge_copy( Sed_riv_hinge* d , Sed_riv_hinge* s );
00034 Sed_riv_hinge* sed_river_hinge_destroy( Sed_riv_hinge* h );
00035
00036 Sed_riv_hinge*
00037 sed_river_hinge_new( )
00038 {
00039 Sed_riv_hinge* h = eh_new( Sed_riv_hinge , 1 );
00040
00041 h->angle = 0.;
00042 h->i = 0;
00043 h->j = 0;
00044 h->min_angle = -G_PI;
00045 h->max_angle = G_PI;
00046 h->std_dev = 0.;
00047
00048 return h;
00049 }
00050
00051 Sed_riv_hinge*
00052 sed_river_hinge_copy( Sed_riv_hinge* d , Sed_riv_hinge* s )
00053 {
00054 eh_return_val_if_fail( s , NULL );
00055
00056 if ( !d )
00057 d = sed_river_hinge_new();
00058
00059 d->angle = s->angle;
00060 d->i = s->i;
00061 d->j = s->j;
00062 d->min_angle = s->min_angle;
00063 d->max_angle = s->max_angle;
00064 d->std_dev = s->std_dev;
00065
00066 return d;
00067 }
00068
00069 Sed_riv_hinge*
00070 sed_river_hinge_destroy( Sed_riv_hinge* h )
00071 {
00072 if ( h )
00073 eh_free( h );
00074 return NULL;
00075 }
00076
00077 Sed_riv
00078 sed_river_new( gchar* name )
00079 {
00080 Sed_riv r;
00081
00082 NEW_OBJECT( Sed_riv , r );
00083
00084 r->data = NULL;
00085 r->hinge = sed_river_hinge_new();
00086 r->x_ind = 0;
00087 r->y_ind = 0;
00088 r->name = g_strdup( name );
00089 r->l = NULL;
00090 r->r = NULL;
00091
00092 return r;
00093 }
00094
00095 Sed_riv
00096 sed_river_copy( Sed_riv d , Sed_riv s )
00097 {
00098 eh_return_val_if_fail( s , NULL );
00099
00100 {
00101 if ( !d )
00102 d = sed_river_new( s->name );
00103
00104 d->x_ind = s->x_ind;
00105 d->y_ind = s->y_ind;
00106
00107 d->data = sed_hydro_copy ( d->data , s->data );
00108 d->hinge = sed_river_hinge_copy( d->hinge , s->hinge );
00109 sed_river_copy ( d->l , s->l );
00110 sed_river_copy ( d->r , s->r );
00111
00112 eh_free( d->name );
00113 d->name = g_strdup( s->name );
00114 }
00115
00116 return d;
00117 }
00118
00119 Sed_riv
00120 sed_river_dup ( Sed_riv s )
00121 {
00122 return sed_river_copy( NULL , s );
00123 }
00124
00125 Sed_riv
00126 sed_river_set_hydro( Sed_riv s , const Sed_hydro h )
00127 {
00128 if ( s && h )
00129 s->data = sed_hydro_copy( s->data , h );
00130 return s;
00131 }
00132
00133 Sed_riv
00134 sed_river_set_width( Sed_riv s , double width )
00135 {
00136 if ( s && s->data )
00137 {
00138 sed_hydro_set_width( s->data , width );
00139 }
00140 return s;
00141 }
00142
00143 Sed_riv
00144 sed_river_set_depth( Sed_riv s , double depth )
00145 {
00146 if ( s && s->data )
00147 {
00148 sed_hydro_set_depth( s->data , depth );
00149 }
00150 return s;
00151 }
00152
00153 Sed_riv
00154 sed_river_set_velocity( Sed_riv s , double velocity )
00155 {
00156 if ( s && s->data )
00157 {
00158 sed_hydro_set_velocity( s->data , velocity );
00159 }
00160 return s;
00161 }
00162
00163 Sed_riv
00164 sed_river_set_bedload( Sed_riv s , double bedload )
00165 {
00166 if ( s && s->data )
00167 {
00168 sed_hydro_set_bedload( s->data , bedload );
00169 }
00170 return s;
00171 }
00172
00173 Sed_riv
00174 sed_river_set_angle( Sed_riv s , double a )
00175 {
00176 if ( s && s->hinge )
00177 {
00178 if ( eh_compare_dbl( a , G_PI , 1e-12 ) )
00179 a -= 1e-12;
00180 s->hinge->angle = eh_reduce_angle( a );
00181
00182 eh_clamp( s->hinge->angle , s->hinge->min_angle , s->hinge->max_angle );
00183 }
00184 return s;
00185 }
00186
00187 Sed_riv
00188 sed_river_increment_angle( Sed_riv s , double da )
00189 {
00190 if ( s && s->hinge )
00191 sed_river_set_angle( s , s->hinge->angle + da );
00192 return s;
00193 }
00194
00195 Sed_riv
00196 sed_river_set_angle_limit( Sed_riv s , double a_min , double a_max )
00197 {
00198 if ( s && s->hinge )
00199 {
00200 if ( eh_compare_dbl( a_max , G_PI , 1e-12 ) )
00201 a_max -= 1e-12;
00202
00203 a_min = eh_reduce_angle( a_min );
00204 a_max = eh_reduce_angle( a_max );
00205
00206 if ( a_min<=a_max )
00207 {
00208 s->hinge->min_angle = a_min;
00209 s->hinge->max_angle = a_max;
00210 }
00211 else
00212 eh_require_not_reached();
00213 }
00214 return s;
00215 }
00216
00217 Sed_riv
00218 sed_river_set_hinge( Sed_riv r , gint i , gint j )
00219 {
00220 if ( r )
00221 {
00222 r->hinge->i = i;
00223 r->hinge->j = j;
00224 }
00225 return r;
00226 }
00227
00228 Sed_riv
00229 sed_river_set_mouth( Sed_riv r , gint i , gint j )
00230 {
00231 if ( r )
00232 {
00233 r->x_ind = i;
00234 r->y_ind = j;
00235 }
00236 return r;
00237 }
00238
00239 Sed_riv
00240 sed_river_adjust_mass( Sed_riv s , double f )
00241 {
00242 eh_return_val_if_fail( s , NULL );
00243
00244 sed_hydro_adjust_mass( s->data , f );
00245 return s;
00246 }
00247
00248 double
00249 sed_river_water_flux( Sed_riv s )
00250 {
00251 eh_return_val_if_fail( s , 0. );
00252 eh_return_val_if_fail( s->data , 0. );
00253
00254 return sed_hydro_water_flux( s->data );
00255 }
00256
00257 double
00258 sed_river_sediment_load( Sed_riv s )
00259 {
00260 eh_return_val_if_fail( s , 0. );
00261 eh_return_val_if_fail( s->data , 0. );
00262
00263 return sed_hydro_total_load( s->data );
00264 }
00265
00266 double
00267 sed_river_suspended_load( Sed_riv s )
00268 {
00269 eh_return_val_if_fail( s , 0. );
00270 eh_return_val_if_fail( s->data , 0. );
00271
00272 return sed_hydro_suspended_load( s->data );
00273 }
00274
00275 Sed_hydro
00276 sed_river_hydro ( Sed_riv s )
00277 {
00278 eh_return_val_if_fail( s , NULL );
00279 eh_return_val_if_fail( s->data , NULL );
00280
00281 return sed_hydro_dup( s->data );
00282 }
00283
00284 gboolean
00285 sed_river_is_hyperpycnal( Sed_riv s )
00286 {
00287 eh_require( s );
00288
00289 return sed_hydro_is_hyperpycnal( s->data );
00290 }
00291
00292 double
00293 sed_river_concentration( Sed_riv s )
00294 {
00295 eh_require( s );
00296 return sed_hydro_flow_density( s->data , sed_rho_fresh_water() );
00297 }
00298
00299 gint*
00300 sed_river_n_branches_helper( Sed_riv s , gint* n )
00301 {
00302 if ( s )
00303 {
00304 sed_river_n_branches_helper( s->l , n );
00305 sed_river_n_branches_helper( s->r , n );
00306
00307 (*n) += 1;
00308 }
00309
00310 return n;
00311 }
00312
00323 gint
00324 sed_river_n_branches( Sed_riv s )
00325 {
00326 gint n = 0;
00327
00328 if ( s )
00329 sed_river_n_branches_helper( s , &n );
00330
00331 return n;
00332 }
00333
00334 double
00335 sed_river_width ( Sed_riv s )
00336 {
00337 eh_return_val_if_fail( s , 0. );
00338 eh_return_val_if_fail( s->data , 0. );
00339
00340 return sed_hydro_width( s->data );
00341 }
00342
00343 double
00344 sed_river_depth ( Sed_riv s )
00345 {
00346 eh_return_val_if_fail( s , 0. );
00347 eh_return_val_if_fail( s->data , 0. );
00348
00349 return sed_hydro_depth( s->data );
00350 }
00351
00352 double
00353 sed_river_velocity( Sed_riv s )
00354 {
00355 eh_return_val_if_fail( s , 0. );
00356 eh_return_val_if_fail( s->data , 0. );
00357
00358 return sed_hydro_velocity( s->data );
00359 }
00360
00361 double
00362 sed_river_bedload( Sed_riv s )
00363 {
00364 eh_return_val_if_fail( s , 0. );
00365 eh_return_val_if_fail( s->data , 0. );
00366
00367 return sed_hydro_velocity( s->data );
00368 }
00369
00370 double
00371 sed_river_angle ( Sed_riv s )
00372 {
00373 eh_return_val_if_fail( s , 0. );
00374 eh_return_val_if_fail( s->hinge , 0. );
00375
00376 return s->hinge->angle;
00377 }
00378
00379 double
00380 sed_river_angle_to_deg( Sed_riv s )
00381 {
00382 return sed_river_angle(s)*S_DEGREES_PER_RAD;
00383 }
00384
00385 double
00386 sed_river_min_angle( Sed_riv s )
00387 {
00388 eh_return_val_if_fail( s , 0. );
00389 eh_return_val_if_fail( s->hinge , 0. );
00390
00391 return s->hinge->min_angle;
00392 }
00393
00394 double
00395 sed_river_max_angle( Sed_riv s )
00396 {
00397 eh_return_val_if_fail( s , 0. );
00398 eh_return_val_if_fail( s->hinge , 0. );
00399
00400 return s->hinge->max_angle;
00401 }
00402
00403 Eh_ind_2
00404 sed_river_hinge( Sed_riv s )
00405 {
00406 Eh_ind_2 pos = {-1,-1};
00407 if ( s )
00408 {
00409 pos.i = s->hinge->i;
00410 pos.j = s->hinge->j;
00411 }
00412 return pos;
00413 }
00414
00415 Eh_ind_2
00416 sed_river_mouth( Sed_riv s )
00417 {
00418 Eh_ind_2 pos = {-1,-1};
00419 if ( s )
00420 {
00421 pos.i = s->x_ind;
00422 pos.j = s->y_ind;
00423 }
00424 return pos;
00425 }
00426
00427 gboolean
00428 sed_river_mouth_is( Sed_riv s , gint i , gint j )
00429 {
00430 eh_return_val_if_fail( s , FALSE );
00431 return s->x_ind==i && s->y_ind==j;
00432 }
00433
00434 gchar*
00435 sed_river_name( Sed_riv s )
00436 {
00437 eh_return_val_if_fail( s , NULL );
00438
00439 return g_strdup( s->name );
00440 }
00441
00442 gchar*
00443 sed_river_name_loc( Sed_riv s )
00444 {
00445 eh_return_val_if_fail( s , NULL );
00446
00447 return s->name;
00448 }
00449
00450 gboolean
00451 sed_river_name_is( Sed_riv s , gchar* name )
00452 {
00453 eh_return_val_if_fail( s && name , FALSE );
00454
00455 return g_ascii_strcasecmp( s->name , name )==0;
00456 }
00457
00458 gint
00459 sed_river_name_cmp( Sed_riv s , const gchar* name )
00460 {
00461 eh_return_val_if_fail( s && s->name , -1 );
00462 return g_ascii_strcasecmp( s->name , name );
00463 }
00464
00465 gboolean
00466 sed_river_has_children( Sed_riv s )
00467 {
00468 eh_return_val_if_fail( s , FALSE );
00469
00470 return s->l && s->r;
00471 }
00472
00473 Sed_riv
00474 sed_river_left( Sed_riv s )
00475 {
00476 eh_return_val_if_fail( s , NULL );
00477 return s->l;
00478 }
00479
00480 Sed_riv
00481 sed_river_right( Sed_riv s )
00482 {
00483 eh_return_val_if_fail( s , NULL );
00484 return s->r;
00485 }
00486
00487 Sed_riv
00488 sed_river_split_discharge( Sed_riv s )
00489 {
00490 eh_return_val_if_fail( s , NULL );
00491 eh_return_val_if_fail( s->data , s );
00492
00493 sed_hydro_set_width ( s->data , sed_hydro_width(s->data)/2. );
00494 sed_hydro_set_bedload( s->data , sed_hydro_bedload(s->data)/2. );
00495 return s;
00496 }
00497
00498 Sed_riv
00499 sed_river_split( Sed_riv s )
00500 {
00501 if ( s )
00502 {
00503 if ( !sed_river_has_children(s) )
00504 {
00505 Sed_riv child = sed_river_dup( s );
00506
00507 s->l = sed_river_split_discharge( child );
00508 s->r = sed_river_dup( s->l );
00509
00510 sed_river_set_angle( s->l , .5*(sed_river_angle(s)+sed_river_max_angle(s)) );
00511 sed_river_set_angle( s->r , .5*(sed_river_angle(s)+sed_river_min_angle(s)) );
00512 }
00513 }
00514
00515 return s;
00516 }
00517
00528 Sed_riv
00529 sed_river_longest_branch( Sed_riv s )
00530 {
00531 Sed_riv longest = NULL;
00532
00533 if ( s )
00534 {
00535 if ( !sed_river_has_children(s) )
00536 longest = s;
00537 else if ( sed_river_n_branches(s->l) > sed_river_n_branches(s->r) )
00538 longest = sed_river_longest_branch( s->r );
00539 else
00540 longest = sed_river_longest_branch( s->l );
00541 }
00542
00543 return longest;
00544 }
00545
00546 Sed_riv
00547 sed_river_destroy( Sed_riv s )
00548 {
00549 if ( s )
00550 {
00551 eh_free( s->name );
00552
00553 sed_river_hinge_destroy( s->hinge );
00554 sed_hydro_destroy ( s->data );
00555 sed_river_destroy ( s->l );
00556 sed_river_destroy ( s->r );
00557
00558 eh_free( s );
00559 }
00560 return NULL;
00561 }
00562
00563 Sed_riv**
00564 sed_river_leaves_helper( Sed_riv s , Sed_riv** leaf )
00565 {
00566 if ( !sed_river_has_children(s) )
00567 eh_strv_append( (gpointer)leaf , (gpointer)s );
00568 else
00569 {
00570 sed_river_leaves_helper( s->l , leaf );
00571 sed_river_leaves_helper( s->r , leaf );
00572 }
00573
00574 return leaf;
00575 }
00576
00594 Sed_riv*
00595 sed_river_leaves( Sed_riv s )
00596 {
00597 Sed_riv* leaf = NULL;
00598
00599 if ( s )
00600 {
00601 sed_river_leaves_helper( s , &leaf );
00602 }
00603
00604 return leaf;
00605 }
00606
00607 Sed_riv**
00608 sed_river_branches_helper( Sed_riv s , Sed_riv** leaf )
00609 {
00610
00611 if ( s )
00612 {
00613 sed_river_branches_helper( s->l , leaf );
00614 sed_river_branches_helper( s->r , leaf );
00615
00616 eh_strv_append( (gpointer)leaf , (gpointer)s );
00617 }
00618
00619 return leaf;
00620 }
00621
00638 Sed_riv*
00639 sed_river_branches( Sed_riv s )
00640 {
00641 Sed_riv* leaf = NULL;
00642
00643 if ( s )
00644 {
00645 sed_river_branches_helper( s , &leaf );
00646 }
00647
00648 return leaf;
00649 }
00650
00651 gint
00652 sed_river_fprint( FILE* fp , Sed_riv s )
00653 {
00654 gint n=0;
00655
00656 if ( s )
00657 {
00658 n += sed_hydro_fprint( fp , s->data );
00659 n += fprintf( fp , "Name : %s\n" , s->name?(s->name):"(null)" );
00660 n += fprintf( fp , "River mouth position : %d, %d\n" , s->x_ind , s->y_ind );
00661 n += fprintf( fp , "River hinge position : %d, %d\n" , sed_river_hinge(s).i , sed_river_hinge(s).j );
00662 n += fprintf( fp , "River angle (degs) : %f\n" , sed_river_angle( s )/S_RADS_PER_DEGREE );
00663 n += fprintf( fp , "River angle limits (degs) : %f, %f\n" , sed_river_min_angle(s)/S_RADS_PER_DEGREE ,
00664 sed_river_max_angle(s)/S_RADS_PER_DEGREE );
00665 }
00666
00667 return n;
00668 }
00669
00670 gint
00671 sed_river_fwrite( FILE* fp , Sed_riv s )
00672 {
00673 gint n=0;
00674
00675 if ( s )
00676 {
00677 eh_require_not_reached();
00678 }
00679
00680 return n;
00681 }
00682
00683 Sed_riv
00684 sed_river_fread( FILE* fp , Sed_riv d )
00685 {
00686 eh_require_not_reached();
00687 return NULL;
00688 }
00689
00690