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