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 PLUME_PROCESS_NAME_S
00022
00023 #include <stdio.h>
00024 #include <string.h>
00025 #include <math.h>
00026
00027 #include <utils/utils.h>
00028 #include <sed/sed_sedflux.h>
00029 #include <plume_types.h>
00030 #include <plumeinput.h>
00031 #include "my_processes.h"
00032
00033 #define LEFT 0
00034 #define RIGHT 1
00035
00036 #undef DEBUG
00037
00038 gboolean plume3d( Plume_inputs *plume_const , Plume_river river ,
00039 int n_grains , Plume_sediment *sedload ,
00040 Eh_dbl_grid *deposit , Plume_data *data );
00041 gboolean compare_river(Plume_river *r1,Plume_river *r2,int n_grains);
00042 int copy_river(Plume_river *r1,Plume_river *r2,int n_grains);
00043
00044 gboolean init_plume_data ( Sed_process proc , Sed_cube prof , GError** error );
00045 gboolean init_plume_hypo_data( Sed_process proc , Sed_cube prof , GError** error );
00046
00047 GQuark
00048 plume_hydro_data_quark( void )
00049 {
00050 return g_quark_from_string( "plume-hydro-data-quark" );
00051 }
00052
00053 Sed_process_info
00054 run_plume( Sed_process proc , Sed_cube p )
00055 {
00056 Plume_t* data = sed_process_user_data(proc);
00057 Sed_process_info info = SED_EMPTY_INFO;
00058
00059 if ( sed_process_run_count(proc)==0 )
00060 init_plume_data( proc , p , NULL );
00061
00062 {
00063 Sed_process plume_hyper = data->plume_proc_hyper;
00064 Sed_process plume_hypo = data->plume_proc_hypo;
00065 Sed_riv* all_leaves;
00066 Sed_riv* r;
00067
00068 all_leaves = sed_cube_all_leaves( p );
00069
00070 if ( all_leaves )
00071 {
00072 for ( r=all_leaves ; *r ; r++ )
00073 {
00074 eh_debug( "The current time is %f years" , sed_cube_age_in_years( p ) );
00075 eh_debug( "Running plume for river %s" , sed_river_name_loc( *r ) );
00076 eh_debug( "River concentration is %f" , sed_river_concentration( *r ) );
00077
00078 if ( sed_river_is_hyperpycnal(*r) ) eh_debug( "Plume is hyperpycnal" );
00079 else eh_debug( "Plume is hypopycnal" );
00080
00081 info.mass_added = sed_river_suspended_load( *r );
00082
00083 sed_process_provide( plume_hyper , PLUME_HYDRO_DATA , *r );
00084 sed_process_provide( plume_hypo , PLUME_HYDRO_DATA , *r );
00085
00086 if ( plume_hyper && sed_river_is_hyperpycnal( *r ) )
00087 sed_process_run_now( plume_hyper , p );
00088 else if ( plume_hypo )
00089 sed_process_run_now( plume_hypo , p );
00090
00091 sed_process_withhold( plume_hyper , PLUME_HYDRO_DATA );
00092 sed_process_withhold( plume_hypo , PLUME_HYDRO_DATA );
00093 }
00094 }
00095 }
00096
00097 return info;
00098 }
00099
00100 Sed_process_info
00101 run_plume_hypo( Sed_process proc , Sed_cube prof )
00102 {
00103 Plume_hypo_t* data = sed_process_user_data(proc);
00104 Sed_process_info info = SED_EMPTY_INFO;
00105 Plume_sediment* sediment_data;
00106 gssize n_grains;
00107 gssize n_susp_grains;
00108
00109 if ( sed_process_run_count(proc)==0 )
00110 init_plume_hypo_data( proc , prof , NULL );
00111
00112 n_grains = sed_sediment_env_n_types();
00113 n_susp_grains = sed_sediment_env_n_types()-1;
00114
00115 {
00116 gssize i;
00117 double* lambda = sed_sediment_property( NULL , &sed_type_lambda_in_per_seconds );
00118 double* rho_sat = sed_sediment_property( NULL , &sed_type_rho_sat );
00119 double* grain_size = sed_sediment_property( NULL , &sed_type_grain_size );
00120 double* diff_coef = sed_sediment_property( NULL , &sed_type_diff_coef );
00121
00122 sediment_data = eh_new( Plume_sediment , n_susp_grains );
00123
00124 for ( i=0 ; i<n_susp_grains ; i++ )
00125 {
00126 sediment_data[i].lambda = lambda [i+1];
00127 sediment_data[i].rho = rho_sat [i+1];
00128 sediment_data[i].grainsize = grain_size[i+1];
00129 sediment_data[i].diff_coef = diff_coef [i+1];
00130 }
00131
00132 eh_free( lambda );
00133 eh_free( rho_sat );
00134 eh_free( grain_size );
00135 eh_free( diff_coef );
00136 }
00137
00138 info.mass_lost = 0.;
00139
00140 {
00141 gint i, j, n;
00142 Sed_hydro hydro_data;
00143 Sed_riv this_river;
00144 Plume_river river_data;
00145 Plume_inputs plume_const;
00146 Eh_dbl_grid* plume_deposit_grid = eh_new( Eh_dbl_grid , n_susp_grains );
00147 Sed_cell_grid in_suspension;
00148
00149 for ( n=0 ; n<n_susp_grains ; n++ )
00150 {
00151 eh_debug( "Creating grid for grain type %d" , n );
00152
00153 plume_deposit_grid[n] = eh_grid_new( double ,
00154 2*sed_cube_n_x(prof) ,
00155 2*sed_cube_n_y(prof) );
00156
00157 eh_debug( "Setting x values" );
00158
00159 if ( sed_mode_is_3d() )
00160 eh_grid_set_x_lin( plume_deposit_grid[n] ,
00161 - sed_cube_n_x(prof)*sed_cube_x_res( prof )
00162 + sed_cube_x_res( prof )*.5 ,
00163 sed_cube_x_res(prof) );
00164 else
00165 eh_grid_set_x_lin( plume_deposit_grid[n] ,
00166 -sed_cube_x_res(prof) ,
00167 sed_cube_x_res(prof) );
00168
00169 eh_debug( "Setting y values" );
00170 eh_grid_set_y_lin( plume_deposit_grid[n] ,
00171 - sed_cube_n_y(prof)*sed_cube_y_res( prof )
00172 + sed_cube_y_res( prof )*.5 ,
00173 sed_cube_y_res(prof) );
00174 }
00175
00176 this_river = sed_process_use( proc , PLUME_HYDRO_DATA );
00177 hydro_data = sed_river_hydro( this_river );
00178
00179
00180 river_data.Cs = sed_hydro_copy_concentration( NULL , hydro_data );
00181 river_data.Q = sed_hydro_water_flux( hydro_data );
00182 river_data.u0 = sed_hydro_velocity ( hydro_data );
00183 river_data.b0 = sed_hydro_width ( hydro_data );
00184 river_data.d0 = sed_hydro_depth ( hydro_data );
00185
00186 if ( eh_dbl_array_min( river_data.Cs , n_susp_grains ) < .001 )
00187 info.mass_lost += sed_hydro_suspended_load( hydro_data );
00188
00189
00190
00191
00192 river_data.rdirection = sed_cube_slope_dir( prof ,
00193 sed_river_hinge(this_river).i ,
00194 sed_river_hinge(this_river).j );
00195
00196 eh_note_block( "Setting river direction to zero" , TRUE )
00197 {
00198 river_data.rdirection = 0;
00199 }
00200
00201 river_data.rma = river_data.rdirection
00202 - sed_river_angle( this_river );
00203
00204 river_data.rdirection = sed_river_angle( this_river );
00205 river_data.rma = 0.;
00206
00207 if ( sed_mode_is_2d() )
00208 {
00209 river_data.rdirection = M_PI_2;
00210 river_data.rma = 0;
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220 eh_message( "shore normal : %f" , river_data.rdirection );
00221 eh_message( "river angle : %f" , river_data.rma );
00222
00223 plume_const.current_velocity = eh_input_val_eval(
00224 data->current_velocity ,
00225 sed_cube_age_in_years( prof ) );
00226 plume_const.ocean_concentration = data->ocean_concentration;
00227 plume_const.plume_width = data->plume_width;
00228 plume_const.ndx = data->ndx;
00229 plume_const.ndy = data->ndy;
00230
00231 if ( fabs( plume_const.current_velocity ) < .05
00232 && plume_const.current_velocity != 0 )
00233 plume_const.current_velocity = plume_const.current_velocity<0?-.05:.05;
00234
00235 if ( sed_mode_is_2d() )
00236 plume_const.current_velocity = 0.;
00237
00238 in_suspension = sed_cube_in_suspension( prof , this_river );
00239
00240
00241
00242 if ( compare_river( &river_data ,
00243 &data->last_river_data ,
00244 n_susp_grains ) )
00245 {
00246 sed_cell_grid_copy_data( data->deposit_grid , data->last_deposit_grid );
00247 }
00248 else if ( plume3d( &plume_const ,
00249 river_data ,
00250 n_susp_grains ,
00251 sediment_data ,
00252 plume_deposit_grid ,
00253 data->plume_data ) )
00254 {
00255 double* deposit_rate;
00256 double** plume_deposit;
00257 Sed_cell** deposit = sed_cell_grid_data( data->deposit_grid );
00258
00259 deposit_rate = eh_new( double , n_grains );
00260
00261 for ( i=0 ; i<eh_grid_n_x(data->deposit_grid) ; i++ )
00262 {
00263 for ( j=0 ; j<eh_grid_n_y(data->deposit_grid) ; j++ )
00264 {
00265 sed_cell_clear ( deposit[i][j] );
00266 sed_cell_set_facies( deposit[i][j] , S_FACIES_PLUME );
00267
00268 for ( n=0 ; n<n_susp_grains ; n++ )
00269 {
00270 plume_deposit = eh_dbl_grid_data(plume_deposit_grid[n]);
00271 deposit_rate[n+1] = plume_deposit[i][j]
00272 * sed_cube_time_step_in_days(prof);
00273 }
00274 deposit_rate[0] = 0.;
00275
00276 sed_cell_add_amount( deposit[i][j] , deposit_rate );
00277 }
00278 }
00279
00280 eh_free( deposit_rate );
00281 }
00282 else
00283 {
00284 g_warning( "Subroutine PLUME returned an error." );
00285 sed_cell_grid_clear( data->deposit_grid );
00286 }
00287
00288 eh_debug( "Save the current plume" );
00289 sed_cell_grid_copy_data( data->last_deposit_grid ,
00290 data->deposit_grid );
00291 copy_river( &data->last_river_data ,
00292 &river_data ,
00293 n_susp_grains );
00294
00295 info.mass_added = sed_hydro_suspended_load( hydro_data );
00296
00297
00298 eh_debug( "Calculate the input and output sediment" );
00299 {
00300 double init_mass = 0;
00301 double final_mass = 0;
00302 double input_mass;
00303
00304
00305 eh_debug( "Calculate the mass of sediment already in suspension." );
00306 init_mass = sed_cell_grid_mass( in_suspension )
00307 * sed_cube_x_res( prof )
00308 * sed_cube_y_res( prof );
00309
00310 eh_debug( "Calculate the mass of sediment input by the river." );
00311 input_mass = sed_hydro_suspended_flux( hydro_data )
00312 * sed_cube_time_step_in_seconds( prof );
00313
00314 eh_debug( "Add the plume sediment to the sediment in suspension" );
00315 eh_grid_reindex ( in_suspension , 0 , 0 );
00316 sed_cell_grid_add( in_suspension , data->deposit_grid );
00317 eh_grid_reindex ( in_suspension , -sed_cube_n_x(prof) , -sed_cube_n_y(prof) );
00318
00319 eh_debug( "Calculate the final mass of sediment in suspension." );
00320 final_mass = sed_cell_grid_mass( in_suspension )
00321 * sed_cube_x_res( prof )
00322 * sed_cube_y_res( prof );
00323
00324 eh_message( "time : %f" , sed_cube_age(prof) );
00325 eh_message( "sediment input (kg) : %g" , input_mass );
00326 eh_message( "sediment added (kg) : %g" , final_mass-init_mass );
00327 eh_message( "shore normal : %f" , river_data.rdirection );
00328 eh_message( "river angle : %f" , river_data.rma );
00329 eh_message( "current velocity (m/s): %f" , plume_const.current_velocity );
00330 eh_message( "river velocity (m/s) : %f" , sed_hydro_velocity( hydro_data ) );
00331 eh_message( "river width (m) : %f" , sed_hydro_width ( hydro_data ) );
00332 eh_message( "river depth (m) : %f" , sed_hydro_depth ( hydro_data ) );
00333 for ( i=0 ; i<n_susp_grains ; i++ )
00334 eh_message( "river conc %d (kg/m^3): %f" , i , sed_hydro_nth_concentration(hydro_data,i) );
00335 }
00336
00337 eh_debug( "Free temporary grids" );
00338 for ( n=0 ; n<n_susp_grains ; n++ )
00339 eh_grid_destroy( plume_deposit_grid[n] , TRUE );
00340 eh_free( plume_deposit_grid );
00341
00342 eh_free( river_data.Cs );
00343
00344 hydro_data = sed_hydro_destroy( hydro_data );
00345 }
00346
00347 eh_free( sediment_data );
00348
00349 return info;
00350 }
00351
00352 #define PLUME_KEY_HYPO_MODEL "Hypopycnal plume model"
00353 #define PLUME_KEY_HYPER_MODEL "Hyperpycnal plume model"
00354
00355 static gchar* plume_req_labels[] =
00356 {
00357 PLUME_KEY_HYPO_MODEL ,
00358 PLUME_KEY_HYPER_MODEL ,
00359 NULL
00360 };
00361
00362 gboolean
00363 init_plume( Sed_process p , Eh_symbol_table t , GError** error )
00364 {
00365 Plume_t* data = sed_process_new_user_data( p , Plume_t );
00366 GError* tmp_err = NULL;
00367
00368 data->plume_proc_hyper = NULL;
00369 data->plume_proc_hypo = NULL;
00370
00371 if ( eh_symbol_table_require_labels( t , plume_req_labels , &tmp_err ) )
00372 {
00373 data->hyper_name = eh_symbol_table_value ( t , PLUME_KEY_HYPER_MODEL );
00374 data->hypo_name = eh_symbol_table_value ( t , PLUME_KEY_HYPO_MODEL );
00375 }
00376
00377 if ( tmp_err ) g_propagate_error( error , tmp_err );
00378
00379 return TRUE;
00380 }
00381
00382 gboolean
00383 destroy_plume( Sed_process p )
00384 {
00385 if ( p )
00386 {
00387 Plume_t* data = sed_process_user_data( p );
00388
00389 if ( data )
00390 {
00391 eh_free( data->hypo_name );
00392 eh_free( data->hyper_name );
00393 eh_free( data );
00394 }
00395 }
00396
00397 return TRUE;
00398 }
00399
00400 gboolean
00401 init_plume_data( Sed_process proc , Sed_cube prof , GError** error )
00402 {
00403 Plume_t* data = sed_process_user_data( proc );
00404
00405 if ( data )
00406 {
00407 data->plume_proc_hypo = sed_process_child( proc , data->hypo_name );
00408 data->plume_proc_hyper = sed_process_child( proc , data->hyper_name );
00409 }
00410
00411 return TRUE;
00412 }
00413
00414 #define HYPO_KEY_CONCENTRATION "background ocean concentration"
00415 #define HYPO_KEY_CURRENT_VEL "velocity of coastal current"
00416 #define HYPO_KEY_WIDTH "maximum plume width"
00417 #define HYPO_KEY_X_SHORE_NODES "number of grid nodes in cross-shore"
00418 #define HYPO_KEY_RIVER_NODES "number of grid nodes in river mouth"
00419
00420 static gchar* hypo_3d_req_labels[] =
00421 {
00422 HYPO_KEY_CONCENTRATION ,
00423 HYPO_KEY_CURRENT_VEL ,
00424 HYPO_KEY_WIDTH ,
00425 HYPO_KEY_X_SHORE_NODES ,
00426 HYPO_KEY_RIVER_NODES ,
00427 NULL
00428 };
00429
00430 static gchar* hypo_2d_req_labels[] =
00431 {
00432 HYPO_KEY_CONCENTRATION ,
00433 HYPO_KEY_WIDTH ,
00434 HYPO_KEY_X_SHORE_NODES ,
00435 HYPO_KEY_RIVER_NODES ,
00436 NULL
00437 };
00438
00439 gboolean
00440 init_plume_hypo( Sed_process p , Eh_symbol_table tab , GError** error )
00441 {
00442 Plume_hypo_t* data = sed_process_new_user_data( p , Plume_hypo_t );
00443 GError* tmp_err = NULL;
00444 gchar** err_s = NULL;
00445 gboolean is_ok = TRUE;
00446
00447 eh_return_val_if_fail( error==NULL || *error==NULL , FALSE );
00448
00449 data->deposit_size = 0;
00450 data->deposit = NULL;
00451 data->last_deposit = NULL;
00452 data->plume_deposit = NULL;
00453 data->last_river_data.Cs = NULL;
00454 data->plume_data = NULL;
00455 data->deposit_grid = NULL;
00456 data->last_deposit_grid = NULL;
00457
00458 if ( sed_mode_is_3d() ) eh_symbol_table_require_labels( tab , hypo_3d_req_labels , &tmp_err );
00459 else eh_symbol_table_require_labels( tab , hypo_2d_req_labels , &tmp_err );
00460
00461 if ( !tmp_err )
00462 {
00463 if ( sed_mode_is_3d() )
00464 data->current_velocity = eh_symbol_table_input_value( tab , HYPO_KEY_CURRENT_VEL , &tmp_err);
00465 else
00466 data->current_velocity = eh_input_val_set( "0.0" , NULL );
00467
00468 data->ocean_concentration = eh_symbol_table_dbl_value( tab , HYPO_KEY_CONCENTRATION );
00469 data->plume_width = eh_symbol_table_dbl_value( tab , HYPO_KEY_WIDTH );
00470 data->ndx = eh_symbol_table_int_value( tab , HYPO_KEY_X_SHORE_NODES );
00471 data->ndy = eh_symbol_table_int_value( tab , HYPO_KEY_RIVER_NODES );
00472
00473 data->plume_width *= 1000.;
00474
00475 eh_check_to_s( data->ocean_concentration>=0. , "Ocean concentration positive" , &err_s );
00476 eh_check_to_s( data->plume_width>=0. , "Plume width positive" , &err_s );
00477 eh_check_to_s( data->ndx>0. , "Plume ndx positive integer" , &err_s );
00478 eh_check_to_s( data->ndy>0. , "Plume ndy positive integer" , &err_s );
00479
00480 if ( err_s ) eh_set_error_strv( &tmp_err , SEDFLUX_ERROR , SEDFLUX_ERROR_BAD_PARAM , err_s );
00481 }
00482
00483 if ( tmp_err )
00484 {
00485 g_propagate_error( error , tmp_err );
00486 is_ok = FALSE;
00487 }
00488
00489 return is_ok;
00490 }
00491
00492 gboolean
00493 init_plume_hypo_data( Sed_process proc , Sed_cube prof , GError** error )
00494 {
00495 Plume_hypo_t* data = sed_process_user_data( proc );
00496
00497 if ( data )
00498 {
00499 data->last_deposit_grid = sed_cell_grid_new( 2*sed_cube_n_x(prof) , 2*sed_cube_n_y(prof) );
00500 data->deposit_grid = sed_cell_grid_new( 2*sed_cube_n_x(prof) , 2*sed_cube_n_y(prof) );
00501
00502 sed_cell_grid_init( data->deposit_grid , sed_sediment_env_n_types() );
00503 sed_cell_grid_init( data->last_deposit_grid , sed_sediment_env_n_types() );
00504
00505 memset( &data->last_river_data , 0 , sizeof(Plume_river) );
00506 data->last_river_data.Cs = eh_new0( double , sed_sediment_env_n_types()-1 );
00507
00508 data->plume_data = eh_new( Plume_data , 1 );
00509 plume_data_init( data->plume_data );
00510 }
00511
00512 return TRUE;
00513 }
00514
00515 gboolean
00516 destroy_plume_hypo( Sed_process p )
00517 {
00518 if ( p )
00519 {
00520 Plume_hypo_t* data = sed_process_user_data( p );
00521
00522 if ( data )
00523 {
00524 sed_cell_grid_free( data->deposit_grid );
00525 sed_cell_grid_free( data->last_deposit_grid );
00526
00527 eh_grid_destroy( data->deposit_grid , TRUE );
00528 eh_grid_destroy( data->last_deposit_grid , TRUE );
00529
00530 eh_free( data->last_river_data.Cs );
00531 destroy_plume_data( data->plume_data );
00532
00533 eh_input_val_destroy( data->current_velocity );
00534 eh_free( data );
00535 }
00536 }
00537
00538 return TRUE;
00539 }
00540
00541 gboolean dump_plume_data( gpointer ptr , FILE *fp )
00542 {
00543 Plume_t *data=(Plume_t*)ptr;
00544
00545 fwrite( data , sizeof(Plume_t) , 1 , fp );
00546
00547
00548
00549
00550
00551
00552
00553
00554 return TRUE;
00555 }
00556
00557 gboolean compare_river( Plume_river *r1 , Plume_river *r2 , int n_grains )
00558 {
00559 int n;
00560 double load1=0., load2=0.;
00561
00562 for (n=0;n<n_grains;n++)
00563 {
00564 load1 += r1->Cs[n];
00565 load2 += r2->Cs[n];
00566 }
00567 load1 *= r1->Q;
00568 load2 *= r2->Q;
00569
00570 if ( fabs(load1-load2)/load1 < .1 )
00571 return TRUE;
00572
00573 for (n=0;n<n_grains;n++)
00574 if ( r1->Cs[n] != r2->Cs[n] )
00575 return FALSE;
00576
00577 if ( r1->Q == r2->Q &&
00578 r1->u0 == r2->u0 &&
00579 r1->b0 == r2->b0 &&
00580 r1->d0 == r2->d0 &&
00581 r1->rdirection == r2->rdirection &&
00582 r1->rma == r2->rma )
00583 return TRUE;
00584
00585 return FALSE;
00586 }
00587
00588 int copy_river(Plume_river *r1,Plume_river *r2,int n_grains)
00589 {
00590 memcpy(r1->Cs,r2->Cs,sizeof(double)*n_grains);
00591 r1->Q = r2->Q;
00592 r1->u0 = r2->u0;
00593 r1->b0 = r2->b0;
00594 r1->d0 = r2->d0;
00595 r1->rdirection = r2->rdirection;
00596 r1->rma = r2->rma;
00597 return 0;
00598 }
00599
00600