/Users/huttone/Devel/sedflux-new/sedflux/trunk/ew/sedflux/run_turbidity_current.c

Go to the documentation of this file.
00001 //---
00002 //
00003 // This file is part of sedflux.
00004 //
00005 // sedflux is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation; either version 2 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // sedflux is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with sedflux; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 //
00019 //---
00020 
00021 #define SED_TURBIDITY_CURRENT_PROC_NAME "turbidity current"
00022 #define EH_LOG_DOMAIN SED_TURBIDITY_CURRENT_PROC_NAME
00023 
00024 #include <stdio.h>
00025 #include <math.h>
00026 #include <string.h>
00027 
00028 #include <utils/utils.h>
00029 #include <sed/sed_sedflux.h>
00030 #include <inflow.h>
00031 #include "my_processes.h"
00032 
00033 #define WITH_SAKURA
00034 #ifdef WITH_SAKURA
00035 #include "sakura.h"
00036 //#include "sakura_turbidity_current.h"
00037 #endif
00038 
00039 
00040 #ifndef VISCOSITY_OF_WATER
00041 # define VISCOSITY_OF_WATER 1.3e-6
00042 #endif
00043 #ifndef DENSITY_OF_WATER
00044 # define DENSITY_OF_WATER 1000.
00045 #endif
00046 #ifndef DENSITY_OF_SEA_WATER
00047 # define DENSITY_OF_SEA_WATER 1028.
00048 #endif
00049 #ifndef DENSITY_OF_SEDIMENT_GRAINS
00050 # define DENSITY_OF_SEDIMENT_GRAINS 2650.
00051 #endif
00052 
00053 #ifndef FLOW_CONCENTRATION 
00054 # define FLOW_CONCENTRATION 0.08
00055 #endif
00056 #ifndef FLOW_DURATION 
00057 # define FLOW_DURATION 7200.
00058 #endif
00059 
00060 #define TURBIDITY_CURRENT_GRID_SPACING          (100.0)
00061 #define TURBIDITY_CURRENT_TIME_INTERVAL         (3.0)
00062 #define TURBIDITY_CURRENT_INITIAL_VELOCITY      (1.0)
00063 #define TURBIDITY_CURRENT_VELOCITY_RANGE        (3.0)
00064 #define TURBIDITY_CURRENT_INITIAL_WIDTH         (1000.0)
00065 #define TURBIDITY_CURRENT_INITIAL_HEIGHT        (6.0)
00066 #define TURBIDITY_CURRENT_INITIAL_CONCENTRATION (0.01)
00067 #define TURBIDITY_CURRENT_CONCENTRATION_RANGE   (0.04)
00068 #define TURBIDITY_CURRENT_GRAIN_DENSITY         (2650.0)
00069 #define TURBIDITY_CURRENT_SPREADING_ANGLE       (14.0)
00070 #define TURBIDITY_CURRENT_NO_DEPOSIT_LENGTH     (0.)
00071 #define TURBIDITY_CURRENT_INITIAL_FLUID_DENSITY (DENSITY_OF_SEA_WATER)
00072 #define TURBIDITY_CURRENT_ALGORITHM_INFLOW      (0)
00073 #define TURBIDITY_CURRENT_ALGORITHM_SAKURA      (1)
00074 
00075 #define DAY_IN_SECONDS (86400.0)
00076 
00077 #define DEFAULT_SUPPLY_TIME (1000)
00078 #define DEFAULT_OUT_TIME    (30)
00079 #define DEFAULT_PHEBOTTOM   (0.2) 
00080 
00081 typedef struct
00082 {
00083    double  dx;
00084    double  x;
00085    double  erode_depth;
00086    double* phe;
00087 }
00088 Sed_phe_query_t;
00089 
00090 typedef struct
00091 {
00092    double dh;
00093    int    i;
00094 }
00095 Sed_remove_query_t;
00096 
00097 typedef struct
00098 {
00099    int     i;
00100    double  dh;
00101    double* phe;
00102    int     n_grains;
00103 }
00104 Sed_add_query_t;
00105 
00106 typedef struct
00107 {
00108    int    i;
00109    double depth;
00110 }
00111 Sed_depth_query_t;
00112 
00113 //void sed_get_phe   ( gpointer user_data , gpointer bathy_data );
00114 
00115 Sed_process_info
00116 run_turbidity_inflow( Sed_process proc , Sed_cube p )
00117 {
00118    Inflow_t*        data = sed_process_user_data(proc);
00119    Sed_process_info info = SED_EMPTY_INFO;
00120    Sed_cube         fail;
00121    Inflow_const_st  inflow_const;
00122    gssize           ind_start;
00123    Sed_cell         flow_cell;
00124    Sed_hydro        flow;
00125 
00126    //---
00127    // This module can only be run on a 1D profile.
00128    //---
00129    if ( sed_mode_is_3d() )
00130       return info;
00131 
00132    fail = sed_process_use( proc , FAILURE_PROFILE_DATA );
00133 
00134    eh_require( fail );
00135 
00136    // Transfer over the (inflow) turbidity current flow constants.
00137    inflow_const.e_a             = data->E_a;
00138    inflow_const.e_b             = data->E_b;
00139    inflow_const.sua             = data->sua;
00140    inflow_const.sub             = data->sub;
00141    inflow_const.c_drag          = data->C_d;
00142    inflow_const.tan_phi         = data->tan_phi;
00143    inflow_const.mu_water        = data->mu;
00144    inflow_const.rho_sea_water   = data->rhoSW;
00145    inflow_const.rho_river_water = data->rhoSW;
00146    inflow_const.channel_len     = data->channel_length;
00147    inflow_const.channel_width   = data->channel_width;
00148 
00149    // Start the flow at the end of the failure.
00150    ind_start    = (int)( sed_cube_col_y( fail,sed_cube_n_y(fail)-1 ) );
00151 
00152    // Average the failure into one cell.
00153    flow_cell = sed_cube_to_cell( fail , NULL );
00154 
00155    // initial flow conditions.
00156    flow = inflow_flood_from_cell( flow_cell , sed_cube_x_res(p)*sed_cube_y_res(p) );
00157 
00158    sed_inflow( p , flow , ind_start , TURBIDITY_CURRENT_GRID_SPACING , &inflow_const );
00159 
00160    sed_cell_destroy( flow_cell );
00161 
00162    return info;
00163 }
00164 
00165 Sed_process_info
00166 run_turbidity_sakura( Sed_process proc , Sed_cube p )
00167 {
00168    Inflow_t*        data = sed_process_user_data(proc);
00169    Sed_process_info info = SED_EMPTY_INFO;
00170    Sed_cube         fail;
00171    Sakura_const_st  sakura_const;
00172    gssize           ind_start;
00173    Sed_cell         flow_cell;
00174    Sed_hydro        flow;
00175 
00176    //---
00177    // This module can only be run on a 1D profile.
00178    //---
00179    if ( sed_mode_is_3d() )
00180       return info;
00181 
00182    fail = sed_process_use( proc , FAILURE_PROFILE_DATA );
00183    //fail = data->failure;
00184 
00185    // Transfer over the (inflow) turbidity current flow constants.
00186    sakura_const.e_a             = data->E_a;
00187    sakura_const.e_b             = data->E_b;
00188    sakura_const.sua             = data->sua;
00189    sakura_const.sub             = data->sub;
00190    sakura_const.c_drag          = data->C_d;
00191    sakura_const.tan_phi         = data->tan_phi;
00192    sakura_const.mu_water        = data->mu;
00193    sakura_const.rho_sea_water   = data->rhoSW;
00194    sakura_const.rho_river_water = data->rhoSW;
00195    sakura_const.channel_len     = data->channel_length;
00196    sakura_const.channel_width   = data->channel_width;
00197 
00198    // Start the flow at the end of the failure.
00199    ind_start    = (int)( sed_cube_col_y( fail,sed_cube_n_y(fail)-1 ) );
00200 
00201    // Average the failure into one cell.
00202    flow_cell = sed_cube_to_cell( fail , NULL );
00203 
00204    // initial flow conditions.
00205    flow = sakura_flood_from_cell( flow_cell , sed_cube_x_res(p)*sed_cube_y_res(p) );
00206 
00207    sed_sakura( p , flow , ind_start , TURBIDITY_CURRENT_GRID_SPACING , &sakura_const );
00208 
00209    sed_cell_destroy( flow_cell );
00210 
00211    return info;
00212 }
00213 
00214 Sed_process_info
00215 run_plume_hyper_inflow( Sed_process proc , Sed_cube p )
00216 {
00217    Inflow_t*        data = sed_process_user_data(proc);
00218    Sed_process_info info = SED_EMPTY_INFO;
00219 
00220    //---
00221    // This module can only be run on a 1D profile.
00222    //---
00223    if ( sed_mode_is_2d() )
00224    {
00225       Inflow_const_st  inflow_const;
00226       Sed_hydro        flow;
00227       Sed_riv          this_river;
00228       gint             ind_start;
00229 
00230       // Transfer over the (inflow) turbidity current flow constants.
00231       inflow_const.e_a             = data->E_a;
00232       inflow_const.e_b             = data->E_b;
00233       inflow_const.sua             = data->sua;
00234       inflow_const.sub             = data->sub;
00235       inflow_const.c_drag          = data->C_d;
00236       inflow_const.tan_phi         = data->tan_phi;
00237       inflow_const.mu_water        = data->mu;
00238       inflow_const.rho_sea_water   = data->rhoSW;
00239       inflow_const.rho_river_water = sed_rho_fresh_water();
00240       inflow_const.channel_len     = data->channel_length;
00241       inflow_const.channel_width   = data->channel_width;
00242       inflow_const.dep_start       = TURBIDITY_CURRENT_NO_DEPOSIT_LENGTH;
00243 
00244       // Start the flow at the river mouth
00245       ind_start  = sed_cube_river_mouth_1d( p );
00246 
00247       // initial flow conditions.
00248       this_river = sed_process_use( proc , PLUME_HYDRO_DATA );
00249       flow       = sed_river_hydro( this_river );
00250 
00251       eh_require( this_river                            );
00252       eh_require( flow                                  );
00253       eh_require( sed_cube_is_in_domain_id(p,ind_start) );
00254 
00255       info.mass_added = sed_hydro_suspended_load( flow );
00256 
00257       sed_inflow( p , flow , ind_start , TURBIDITY_CURRENT_GRID_SPACING , &inflow_const );
00258 
00259       flow = sed_hydro_destroy( flow );
00260    }
00261 
00262    return info;
00263 }
00264 
00265 Sed_process_info
00266 run_plume_hyper_sakura( Sed_process proc , Sed_cube p )
00267 {
00268    Inflow_t*        data = sed_process_user_data(proc);
00269    Sed_process_info info = SED_EMPTY_INFO;
00270 
00271    //---
00272    // This module can only be run on a 1D profile.
00273    //---
00274    if ( sed_mode_is_2d() )
00275    {
00276       Sakura_const_st  sakura_const;
00277       Sed_hydro        flow;
00278       Sed_riv          this_river;
00279       gint             ind_start;
00280 
00281       // Transfer over the (inflow) turbidity current flow constants.
00282       sakura_const.e_a             = data->E_a;
00283       sakura_const.e_b             = data->E_b;
00284       sakura_const.sua             = data->sua;
00285       sakura_const.sub             = data->sub;
00286       sakura_const.c_drag          = data->C_d;
00287       sakura_const.tan_phi         = data->tan_phi;
00288       sakura_const.mu_water        = data->mu;
00289       sakura_const.rho_sea_water   = data->rhoSW;
00290       sakura_const.rho_river_water = sed_rho_fresh_water();
00291       sakura_const.channel_len     = data->channel_length;
00292       sakura_const.channel_width   = data->channel_width;
00293       sakura_const.dep_start       = TURBIDITY_CURRENT_NO_DEPOSIT_LENGTH;
00294       sakura_const.dt              = TURBIDITY_CURRENT_TIME_INTERVAL;
00295 
00296       // Start the flow at the river mouth
00297       ind_start  = sed_cube_river_mouth_1d( p );
00298 
00299       // initial flow conditions.
00300       this_river = sed_process_use( proc , PLUME_HYDRO_DATA );
00301       flow       = sed_river_hydro( this_river );
00302 
00303       eh_require( this_river                            );
00304       eh_require( flow                                  );
00305       eh_require( sed_cube_is_in_domain_id(p,ind_start) );
00306 
00307       info.mass_added = sed_hydro_suspended_load( flow );
00308 
00309       sed_sakura( p , flow , ind_start , TURBIDITY_CURRENT_GRID_SPACING , &sakura_const );
00310 
00311       flow = sed_hydro_destroy( flow );
00312    }
00313 
00314    return info;
00315 }
00316 
00317 #undef HYPERPYCNAL
00318 #if defined( HYPERPYCNAL )
00319 Sed_process_info
00320 run_hyperpycnal( gpointer ptr , Sed_cube p )
00321 {
00322    Turbidity_t *data=(Turbidity_t*)ptr; 
00323    Sed_process_info info = SED_EMPTY_INFO;
00324    double get_equivalent_diameter( double real_diameter );
00325    Sed_cell flow, deposit_cell;
00326    double init_h, init_u, init_c, init_q, init_w;
00327    double *fraction, *bulk_density, *grain_size, *lambda, *grain_density;
00328    double rho_fluid, rho_flow;
00329    double flow_age, volume_of_sediment, day=DAY_IN_SECONDS, flow_duration;
00330    double *deposit_at_x, *slope;
00331    int i, ind, n_nodes, n, n_grains;
00332    int n_nodes0, start;
00333    long seed;
00334    pos_t *bathy, *bathy0;
00335    double *width, dx;
00336    double n_days;
00337    Sed_cube fail;
00338    gboolean ok;
00339    
00340    // specific to sakura
00341    double dt;
00342    double basin_len;
00343    double Dstar, Wstar, Rden;
00344    double *stv, *rey;
00345    double *phe_bot;
00346    double out_time;
00347 #ifdef WITH_SAKURA
00348    Sakura_t sakura_const;
00349 #endif
00350 
00351    // specific to inflow
00352    double x_dep;
00353    Inflow_t inflow_const;
00354 
00355    // Clean up process.
00356    if ( p == NULL )
00357    {
00358       if ( data->initialized )
00359       {
00360          eh_free_2( data->deposit );
00361          data->initialized = FALSE;
00362       }
00363       return SED_EMPTY_INFO;
00364    }
00365 
00366    // Initialize process.
00367    if ( !data->initialized )
00368    {
00369       int max_n_nodes = (sed_cube_n_y(p)+1)
00370                       * sed_cube_y_res(p)
00371                       / TURBIDITY_CURRENT_GRID_SPACING;
00372       gssize n_grains = sed_sediment_env_n_types();
00373       data->n_x = n_grains;
00374       data->n_y = max_n_nodes;
00375       data->deposit = eh_new_2( double , n_grains , max_n_nodes );
00376       data->initialized = TRUE;
00377    }
00378    
00379    //---
00380    // This module can only be run on a 1D profile.
00381    //---
00382    if ( sed_mode_is_3d() )
00383       return info;
00384 
00385    // Check which river are hyperpycnal.
00386    {
00387       gssize i, n;
00388 
00389       for ( i=0,n=0 ; i<n_rivers ; i++ )
00390       {
00391          if ( sed_hydro_is_hyperpycnal( sed_cube_river( prof , i ) ) )
00392          {
00393             river_no[n++] = i;
00394          }
00395       }
00396    }
00397 
00398    fail = data->failure;
00399 
00400    // Transfer over the (inflow) turbidity current flow constants.
00401    inflow_const.Ea            = data->E_a;
00402    inflow_const.Eb            = data->E_b;
00403    inflow_const.sua           = data->sua;
00404    inflow_const.sub           = data->sub;
00405    inflow_const.Cd            = data->C_d;
00406    inflow_const.tanPhi        = data->tan_phi;
00407    inflow_const.mu            = data->mu;
00408    inflow_const.rhoSW         = data->rhoSW;
00409    inflow_const.channelLength = data->channel_length;
00410    inflow_const.channelWidth  = data->channel_width;
00411 
00412    // Transfer over the (sakura) turbidity current flow constants.
00413 #ifdef WITH_SAKURA
00414    sakura_const.Ea            = data->E_a;
00415    sakura_const.Eb            = data->E_b;
00416    sakura_const.sua           = data->sua;
00417    sakura_const.sub           = data->sub;
00418    sakura_const.Cd            = data->C_d;
00419    sakura_const.tanPhi        = data->tan_phi;
00420    sakura_const.mu            = data->mu;
00421    sakura_const.rhoSW         = data->rhoSW;
00422    sakura_const.channelLength = data->channel_length;
00423    sakura_const.channelWidth  = data->channel_width;
00424    sakura_const.rhoRW         = DENSITY_OF_WATER;
00425 #endif
00426 
00427    dx       = TURBIDITY_CURRENT_GRID_SPACING;
00428    dt       = TURBIDITY_CURRENT_TIME_INTERVAL;
00429    n_grains = sed_sediment_env_n_types();
00430 
00431    // Start the flow at the river mouth.
00432    {
00433       start    = (int)( sed_cube_col_y( fail,sed_cube_n_y(fail)-1 ) );
00434       n_nodes0 = sed_cube_n_y(p) - start;
00435       n_nodes  = (int)((sed_cube_n_y(p)-(start+1))*sed_cube_y_res(p)/dx);
00436       basin_len = n_nodes * dx;
00437    }
00438 
00439    // Average the failure into one cell.
00440    {
00441       Sed_cell top  = sed_cell_new_env( );
00442 
00443       flow = sed_cell_new_env( );
00444       for ( i=0 ; i<sed_cube_n_y(fail) ; i++ )
00445       {
00446          sed_column_top( sed_cube_col(fail,i) , sed_cube_thickness(fail,0,i) , top );
00447          sed_cell_add( flow , top );
00448       }
00449       flow_age = sed_cell_age( flow );
00450 
00451       sed_cell_destroy( top );
00452    }
00453 
00454    // initial flow conditions.
00455    init_u = TURBIDITY_CURRENT_INITIAL_VELOCITY;
00456    init_h = TURBIDITY_CURRENT_INITIAL_HEIGHT;
00457    init_w = TURBIDITY_CURRENT_INITIAL_WIDTH;
00458    init_c = TURBIDITY_CURRENT_INITIAL_CONCENTRATION;
00459    init_q = init_u*init_h*init_w;
00460 
00461    fraction      = sed_cell_copy_fraction( NULL     , flow );
00462    bulk_density  = sed_sediment_property ( NULL     , &sed_type_rho_sat );
00463    lambda        = sed_sediment_property ( NULL     , &sed_type_lambda_in_per_seconds );
00464    grain_size    = sed_sediment_property ( NULL     , &sed_type_grain_size_in_meters );
00465    grain_density = eh_dbl_array_new_set  ( n_grains , TURBIDITY_CURRENT_GRAIN_DENSITY );
00466 
00467    for ( n=0 ; n<n_grains ; n++ )
00468       grain_size[n] = get_equivalent_diameter( grain_size[n] );
00469 
00470    rho_fluid = TURBIDITY_CURRENT_INITIAL_FLUID_DENSITY;
00471    rho_flow  = init_c*(TURBIDITY_CURRENT_GRAIN_DENSITY-rho_fluid)+rho_fluid;
00472    volume_of_sediment  = sed_cell_size_0( flow )
00473                        * sed_cube_y_res(p)
00474                        * sed_cube_x_res(p);
00475    volume_of_sediment *= sed_cell_density( flow )
00476                        / TURBIDITY_CURRENT_GRAIN_DENSITY;
00477 
00478    // the number of days the flow will last
00479    n_days = volume_of_sediment/( init_c*init_q )/day;
00480 
00481    // bathymetry.
00482    bathy  = createPosVec( n_nodes );
00483    bathy0 = createPosVec( n_nodes0 );
00484    width  = eh_new( double , n_nodes );
00485    for ( i=0 ; i<n_nodes0 ; i++ )
00486    {
00487       bathy0->x[i] = (i+start)*sed_cube_y_res(p);
00488       bathy0->y[i] = -sed_cube_water_depth(p,0,i+start);
00489    }
00490    bathy->x[0] = bathy0->x[0] + 0.5*dx;
00491    for ( i=1 ; i<bathy->size ; i++ )
00492       bathy->x[i] = bathy->x[i-1] + TURBIDITY_CURRENT_GRID_SPACING;
00493    interpolate( bathy0->x , bathy0->y , n_nodes0 ,
00494                 bathy->x  , bathy->y  , n_nodes );
00495 
00496 #ifdef WITH_SAKURA
00497    width[0] = sakura_const.channelWidth;
00498 #endif
00499    for ( i=1 ; i<n_nodes ; i++ )
00500    {
00501       if ( bathy->x[i]-bathy->x[0] < inflow_const.channelLength )
00502          width[i] = inflow_const.channelWidth;
00503       else
00504       {
00505          width[i] = width[i-1]
00506                   + tan( TURBIDITY_CURRENT_SPREADING_ANGLE*M_PI/180. )
00507                     * ( bathy->x[i]-bathy->x[i-1] );
00508          if ( width[i] > sed_cube_x_res(p) )
00509             width[i] = sed_cube_x_res(p);
00510       }
00511    }
00512 
00513    x_dep        = TURBIDITY_CURRENT_NO_DEPOSIT_LENGTH;
00514    deposit_at_x = eh_new( double , n_grains );
00515 
00516    // INITIALIZE settling velocity
00517 #ifdef WITH_SAKURA
00518    stv = eh_new0( double , n_grains );
00519    rey = eh_new0( double , n_grains );
00520    for ( i=0; i<n_grains ; i++ )
00521    {
00522         Rden  = grain_density[i] / sakura_const.rhoRW;
00523         Dstar = G * Rden * pow( grain_size[i], 3.0 )/ pow(sakura_const.mu,2.0);
00524         Wstar = - 3.76715 + (1.92944 * log10(Dstar)) - 0.09815 * pow(log10(Dstar), 2.0)
00525                 - 0.00575 * pow(log10(Dstar), 3.0) +0.00056 * pow(log10(Dstar), 4.0);
00526         Wstar = pow(10.0, Wstar);
00527         stv[i] = pow(Rden * G * sakura_const.mu * Wstar, 0.33333);
00528         rey[i] = sqrt(Rden * G * pow(grain_size[i], 3.0))/sakura_const.mu;
00529    } 
00530 #endif
00531 
00532    // set up the data for the get_phe function.
00533 //   get_phe_data.prof    = p;
00534 //   get_phe_data.dx      = dx;
00535    inflow_const.get_phe_data   = (gpointer)p;
00536    inflow_const.get_depth_data = (gpointer)p;
00537    inflow_const.remove_data    = (gpointer)p;
00538    inflow_const.add_data       = (gpointer)p;
00539    inflow_const.get_phe        = (Sed_query_func)&sed_get_phe;
00540    inflow_const.get_depth      = (Sed_query_func)&sed_get_depth;
00541    inflow_const.remove         = (Sed_query_func)&sed_remove;
00542    inflow_const.add            = (Sed_query_func)&sed_add;
00543 
00544    eh_message( "time                 : %f" , sed_cube_age_in_years(p) );
00545    eh_message( "flow_duration (days) : %f" , n_days                   );
00546    eh_message( "mass                 : %f" , sed_cube_mass(p)         );
00547 
00548    while ( volume_of_sediment > 0 )
00549    {
00550       // determine the initial flow parameters.
00551       init_h   = TURBIDITY_CURRENT_INITIAL_HEIGHT;
00552       init_w   = TURBIDITY_CURRENT_INITIAL_WIDTH;
00553       init_u   = TURBIDITY_CURRENT_INITIAL_VELOCITY
00554                + TURBIDITY_CURRENT_VELOCITY_RANGE*eh_ran2(&seed);
00555       init_c   = TURBIDITY_CURRENT_INITIAL_CONCENTRATION
00556                + TURBIDITY_CURRENT_CONCENTRATION_RANGE*eh_ran2(&seed);
00557       init_q   = init_u*init_h*init_w;
00558       rho_flow = init_c*(TURBIDITY_CURRENT_GRAIN_DENSITY-rho_fluid)+rho_fluid;
00559 
00560 #ifndef WITH_SAKURA
00561 data->algorithm = TURBIDITY_CURRENT_ALGORITHM_INFLOW;
00562 #endif
00563       if ( data->algorithm == TURBIDITY_CURRENT_ALGORITHM_INFLOW )
00564       {
00565          if ( volume_of_sediment < init_q*init_c*day )
00566             flow_duration = volume_of_sediment/init_q/init_c;
00567          else
00568             flow_duration = day;
00569          volume_of_sediment -= init_q*init_c*day;
00570       }
00571       else
00572          volume_of_sediment = 0;
00573 
00574       // Update the bathymetry.
00575       for (i=0;i<n_nodes0;i++)
00576          bathy0->y[i] = -sed_cube_water_depth(p,0,i+start);
00577       interpolate( bathy0->x , bathy0->y , n_nodes0 ,
00578                    bathy->x  , bathy->y  , n_nodes );
00579       slope = derivative( *bathy );
00580 
00581       // Run the flow.
00582 #ifdef WITH_SAKURA
00583       if ( data->algorithm == TURBIDITY_CURRENT_ALGORITHM_SAKURA )
00584          ok = sakura( dx            , dt            , basin_len     ,
00585                       n_nodes       , n_grains      , bathy->x      ,
00586                       bathy->y      , width         , &init_u       ,
00587                       &init_c       , lambda        , stv           ,
00588                       rey           , grain_density , init_h        ,
00589                       flow_duration , x_dep         , fraction      ,
00590                       phe_bot       , bulk_density  , out_time      ,
00591                       sakura_const  , data->deposit , NULL );
00592       else
00593 #endif
00594          ok = inflow( flow_duration , bathy->x  , slope        , width         ,
00595                       n_nodes       , dx        , x_dep        , init_w        ,
00596                       init_u        , init_h    , init_q       , fraction      ,
00597                       grain_size    , lambda    , bulk_density , grain_density ,
00598                       n_grains      , rho_fluid , rho_flow     , inflow_const  ,
00599                       data->deposit , NULL );
00600 
00601       if ( ok )
00602       {
00603          // Spread the deposit from just over the channel width to the entire
00604          // basin width.
00605          for ( n=0 ; n<n_grains ; n++ )
00606             for ( i=0 ; i<n_nodes ; i++ )
00607                data->deposit[n][i] *= width[i]
00608                                     / sed_cube_x_res(p)
00609                                     * TURBIDITY_CURRENT_GRID_SPACING
00610                                     / sed_cube_y_res(p);
00611 
00612          // Add the sediment to the profile.
00613          deposit_cell = sed_cell_new_env( );
00614          for ( i=0 ; i<n_nodes ; i++ )
00615          {
00616             for ( n=0 ; n<n_grains ; n++ )
00617                deposit_at_x[n] = data->deposit[n][i];
00618             ind = (int)(bathy->x[i]/sed_cube_y_res(p));
00619             if ( ind < sed_cube_n_y(p) )
00620             {
00621                sed_cell_clear( deposit_cell );
00622                sed_cell_set_age( deposit_cell , flow_age );
00623                sed_cell_set_facies( deposit_cell , S_FACIES_TURBIDITE );
00624                sed_cell_add_amount( deposit_cell , deposit_at_x );
00625                sed_column_add_cell( sed_cube_col(p,ind) , deposit_cell );
00626             }
00627          }
00628          sed_cell_destroy( deposit_cell );
00629       }
00630       else
00631       {
00632          // Pretend like nothing happened.  Put the failed sediment where
00633          // it began.
00634          sed_cube_add(p,fail);
00635       }
00636 
00637       eh_free( slope );
00638 
00639    }
00640 
00641    eh_free( stv           );
00642    eh_free( rey           );
00643    eh_free( deposit_at_x  );
00644    eh_free( fraction      );
00645    eh_free( bulk_density  );
00646    eh_free( grain_density );
00647    eh_free( grain_size    );
00648    eh_free( lambda        );
00649    eh_free( width         );
00650 
00651    sed_cell_destroy( flow );
00652    destroyPosVec( bathy0 );
00653    destroyPosVec( bathy  );
00654 
00655    return info;
00656 }
00657 #endif
00658 
00659 #define S_KEY_SUA            "sua"
00660 #define S_KEY_SUB            "sub"
00661 #define S_KEY_E_A            "entrainment constant, ea"
00662 #define S_KEY_E_B            "entrainment constant, eb"
00663 #define S_KEY_C_D            "drag coefficient"
00664 #define S_KEY_TAN_PHI        "internal friction angle"
00665 #define S_KEY_CHANNEL_WIDTH  "width of channel"
00666 #define S_KEY_CHANNEL_LENGTH "length of channel"
00667 
00668 static gchar* inflow_labels[] =
00669 {
00670    S_KEY_SUA            ,
00671    S_KEY_SUB            ,
00672    S_KEY_E_A            ,
00673    S_KEY_E_B            ,
00674    S_KEY_C_D            ,
00675    S_KEY_TAN_PHI        ,
00676    S_KEY_CHANNEL_WIDTH  ,
00677    S_KEY_CHANNEL_LENGTH ,
00678    NULL
00679 };
00680 
00681 gboolean
00682 init_inflow( Sed_process p , Eh_symbol_table tab , GError** error )
00683 {
00684    Inflow_t*    data    = sed_process_new_user_data( p , Inflow_t );
00685    GError*      tmp_err = NULL;
00686    gchar**      err_s   = NULL;
00687    gboolean     is_ok   = TRUE;
00688    //gchar*       key;
00689 
00690    eh_return_val_if_fail( error==NULL || *error==NULL , FALSE );
00691 
00692    eh_symbol_table_require_labels( tab , inflow_labels , &tmp_err );
00693 
00694    if ( !tmp_err )
00695    {
00696       data->sua            = eh_symbol_table_dbl_value( tab , S_KEY_SUA            );
00697       data->sub            = eh_symbol_table_dbl_value( tab , S_KEY_SUB            );
00698       data->E_a            = eh_symbol_table_dbl_value( tab , S_KEY_E_A            );
00699       data->E_b            = eh_symbol_table_dbl_value( tab , S_KEY_E_B            );
00700       data->C_d            = eh_symbol_table_dbl_value( tab , S_KEY_C_D            );
00701       data->tan_phi        = eh_symbol_table_dbl_value( tab , S_KEY_TAN_PHI        );
00702       data->channel_width  = eh_symbol_table_dbl_value( tab , S_KEY_CHANNEL_WIDTH  );
00703       data->channel_length = eh_symbol_table_dbl_value( tab , S_KEY_CHANNEL_LENGTH );
00704 /*
00705       key                  = eh_symbol_table_lookup( tab , S_KEY_ALGORITHM );
00706       if      ( g_ascii_strcasecmp( key , "INFLOW" ) == 0 ) data->algorithm = TURBIDITY_CURRENT_ALGORITHM_INFLOW;
00707       else if ( g_ascii_strcasecmp( key , "SAKURA" ) == 0 ) data->algorithm = TURBIDITY_CURRENT_ALGORITHM_SAKURA;
00708       else
00709          g_set_error( &tmp_err , SEDFLUX_ERROR , SEDFLUX_ERROR_BAD_PARAM ,
00710                       "Invalid turbidity current model (inflow or sakura): %s" , key );
00711 */
00712 
00713       data->tan_phi         = tan(data->tan_phi*S_RADS_PER_DEGREE);
00714       data->channel_length *= 1000.;
00715       data->mu              = 1.3e-6;
00716       data->rhoSW           = 1028.;
00717 
00718       eh_check_to_s( data->sua>=0            , "Bottom sediment shear strength positive"          , &err_s );
00719       eh_check_to_s( data->sub>=0            , "Bottom sediment shear strength gradient positive" , &err_s );
00720       eh_check_to_s( data->E_a>=0            , "Entrainment constant E_a positive"                , &err_s );
00721       eh_check_to_s( data->E_b>=0            , "Entrainment constant E_b positive"                , &err_s );
00722       eh_check_to_s( data->C_d>=0            , "Drag coefficient positive"                        , &err_s );
00723       eh_check_to_s( data->tan_phi>=0        , "Sediment friction angle positive"                 , &err_s );
00724       eh_check_to_s( data->channel_width>=0  , "Channel width positive"                           , &err_s );
00725       eh_check_to_s( data->channel_length>=0 , "Channel length positive"                          , &err_s );
00726 
00727       if ( !tmp_err && err_s )
00728          eh_set_error_strv( &tmp_err , SEDFLUX_ERROR , SEDFLUX_ERROR_BAD_PARAM , err_s );
00729 
00730    }
00731 
00732    if ( tmp_err )
00733    {
00734       g_propagate_error( error , tmp_err );
00735       is_ok = FALSE;
00736    }
00737 
00738    return is_ok;
00739 }
00740 
00741 gboolean
00742 destroy_inflow( Sed_process p )
00743 {
00744    if ( p )
00745    {
00746       Inflow_t* data = sed_process_user_data( p );
00747       
00748       if ( data ) eh_free( data );
00749    }
00750 
00751    return TRUE;
00752 }
00753 
00754 gboolean dump_turbidity_current_data( gpointer ptr , FILE *fp )
00755 {
00756    Inflow_t *data = (Inflow_t*)ptr;
00757 
00758    fwrite( data , sizeof(Inflow_t) , 1 , fp );
00759    sed_cube_write( fp , data->failure );
00760 
00761 //   for ( i=0 ; i<data->n_x ; i++ )
00762 //      fwrite( data->deposit[i] , sizeof(double) , data->n_y , fp );
00763 
00764    return TRUE;
00765 }
00766 
00767 gboolean load_turbidity_current_data( gpointer ptr , FILE *fp )
00768 {
00769    Inflow_t* data = (Inflow_t*)ptr;
00770 
00771    fread( data , sizeof(Inflow_t) , 1 , fp );
00772    data->failure = sed_cube_read( fp );
00773 
00774 //   data->deposit = eh_new( double* , data->n_x );
00775 //   for ( i=0 ; i<data->n_x ; i++ )
00776 //   {
00777 //      data->deposit[i] = eh_new( double , data->n_y );
00778 //      fread( data->deposit[i] , sizeof(double) , data->n_y , fp );
00779 //   }
00780 
00781    return TRUE;
00782 }
00783 
00784 /***********************************************************************
00785 *                                                                      *
00786 * Function :                                                           *
00787 *                                                                      *
00788 *  GETPHE                                                              *
00789 *                                                                      *
00790 ***********************************************************************/
00791 
00792 /***********************************************************************
00793 *                                                                      *
00794 * Description :                                                        *
00795 *                                                                      *
00796 *  Used by the turbidity current model to talk to the SEDFLUX model.   *
00797 *  This function removes sediment from our basin and returns the       *
00798 *  the amount that was eroded (in meters) and sets the fractions of    *
00799 *  each grain type that has been eroded.                               *
00800 *                                                                      *
00801 ***********************************************************************/
00802 
00803 /***********************************************************************
00804 *                                                                      *
00805 * Formal parameters :                                                  *
00806 *                                                                      *
00807 *  phe   - The fractions of each grain type that were removed.         *
00808 *  pos   - The position (in meters) within the basin that sediment is  *
00809 *          to be removed.                                              *
00810 *  depth - The depth (in meters) that is to be eroded.                 *
00811 *                                                                      *
00812 ***********************************************************************/
00813 
00814 /***********************************************************************
00815 *                                                                      *
00816 * Global Variables :                                                   *
00817 *                                                                      *
00818 *  prof_ - A pointer to the basin that sediment is to be eroded from.  *
00819 *  dx_   - The horizontal spacing of the sediment columns in our model *
00820 *          basin.                                                      *
00821 *                                                                      *
00822 ***********************************************************************/
00823 
00824 /***********************************************************************
00825 *                                                                      *
00826 * Local Variables :                                                    *
00827 *                                                                      *
00828 *  i       - Loop counter.                                             *
00829 *  n       - Loop counter.                                             *
00830 *  n_grains - The number of grains types in our basin.                  *
00831 *  avg     - A cell of sediment that contains the eroded sediment.     *
00832 *                                                                      *
00833 ***********************************************************************/
00834  
00835 #ifdef OLDWAY
00836 
00837 #include <string.h>
00838 #include "sed_sedflux.h"
00839 
00840 /* Sediment profile for inflow to remove sediment from.
00841 */
00842 extern Sed_cube prof_;
00843 
00844 /* Grid spacing used by inflow.
00845 */
00846 extern double dx_;
00847 
00848 double getPhe(double *phe,double pos,double depth)
00849 {
00850    Sed_cell avg;
00851    double volume;
00852    int i, n, n_grains;
00853    
00854    n_grains = sed_size(prof_->sed);
00855    avg = sed_create_cell(n_grains);
00856 
00857    if ( depth > 0 )
00858    {
00859       /* Determine which column of the profile to remove sediment from.
00860       */
00861       i = (int)(pos/sed_get_profile_spacing(prof_));
00862       if ( i<0 ) i=0;
00863       if ( i>prof_->size-1 ) i=prof_->size-1;
00864 
00865       /* The grid used by inflow will be smaller than that used by sedflux.
00866          As such we reduce the erosion depth but remove from the entire width
00867          of the cell in such a way that mass is conserved.
00868       */
00869       depth *= dx_/sed_get_profile_spacing(prof_);
00870 
00871       if ( depth > sed_get_column_thickness(prof_->col[i]) )
00872          depth = sed_get_column_thickness(prof_->col[i]);
00873    
00874       /* Remove different grain sizes equally.  We can change this so that sands 
00875          are more easily eroded than clays -- or whatever we want, really.
00876       */
00877       sed_extract_top_from_column(prof_->col[i],depth,avg);
00878 
00879 #ifdef ______NOTHING
00880       /* Remove 'depth' sediment from the column.
00881       */
00882       avg->thickness = -depth;
00883       avg->uncompacted_thickness = avg->thickness;
00884    
00885       /* Remove different grain sizes equally.  We can change this so that sands 
00886          are more easily eroded than clays -- or whatever we want, really.
00887       */
00888       for (n=0;n<n_grains;n++)
00889          avg->fraction[n] = 1.;
00890 
00891       /* Remove the sediment.
00892       */
00893       sedAddCell(prof_->col[i],avg);
00894 #endif
00895 
00896       for (n=0;n<n_grains;n++)
00897          phe[n] = avg->fraction[n];
00898 
00899       /* We want to return the amount of sediment that was removed.  That is,
00900          sediment - JUST SEDIMENT, DRY SEDIMENT - not sediment plus water.
00901       */
00902       for (n=0,volume=0.;n<n_grains;n++)
00903          volume += depth*phe[n]*sed_rho_sat(prof_->sed,n)/DENSITY_OF_SEDIMENT_GRAINS;
00904    }
00905    else
00906    {
00907       for (n=0;n<n_grains;n++)
00908          phe[n] = 0.;
00909       volume = 0.;
00910    }
00911 
00912    sed_destroy_cell(avg);
00913 
00914    /* This is how much was actually removed.
00915    */
00916    return volume;
00917 }
00918 
00919 #endif
00920 
00939 /*
00940 void sed_get_phe( gpointer data , gpointer p )
00941 {
00942    Sed_cube prof  = (Sed_cube)p;
00943    double dx      = EH_STRUCT_MEMBER( Sed_phe_query_t , data , dx          );
00944    double x       = EH_STRUCT_MEMBER( Sed_phe_query_t , data , x           );
00945    double depth   = EH_STRUCT_MEMBER( Sed_phe_query_t , data , erode_depth );
00946    double *phe    = EH_STRUCT_MEMBER( Sed_phe_query_t , data , phe         );
00947    Sed_cell avg;
00948    double volume;
00949    int i, n, n_grains;
00950    
00951    n_grains = sed_sediment_env_n_types();
00952    avg      = sed_cell_new_env( );
00953 
00954    if ( depth > 0 )
00955    {
00956       // Determine which column of the profile to remove sediment from.
00957       i = (int)(x/sed_cube_y_res(prof));
00958       if ( i<0 ) i=0;
00959       eh_lower_bound( i , 0 );
00960       eh_upper_bound( i , sed_cube_n_y(prof)-1 );
00961 
00962       // The grid used by inflow will be smaller than that used by sedflux.
00963       // As such, we reduce the erosion depth but remove from the entire width
00964       // of the cell in such a way that mass is conserved.
00965       depth *= dx/sed_cube_y_res( prof );
00966 
00967       eh_upper_bound( depth , sed_cube_thickness(prof,0,i) );
00968    
00969       // Remove different grain sizes equally.  We can change this so that
00970       // sands are more easily eroded than clays -- or whatever we want,
00971       // really.
00972       sed_column_extract_top( sed_cube_col(prof,i) , depth , avg );
00973 
00974       for ( n=0 ; n<n_grains ; n++ )
00975          phe[n] = sed_cell_nth_fraction( avg , n );
00976 
00977       // We want to return the amount of sediment that was removed.  That is,
00978       // sediment - JUST SEDIMENT, DRY SEDIMENT - not sediment plus water.
00979       for ( n=0 , volume=0. ; n<n_grains ; n++ )
00980          volume += depth
00981                  * phe[n]
00982                  * sed_type_rho_sat( sed_sediment_type( NULL , n ) )
00983                  / DENSITY_OF_SEDIMENT_GRAINS;
00984    }
00985    else
00986    {
00987       for ( n=0 ; n<n_grains ; n++ )
00988          phe[n] = 0.;
00989       volume = 0.;
00990    }
00991 
00992    sed_cell_destroy( avg );
00993 
00994    // save the volume that was actually eroded.
00995    EH_STRUCT_MEMBER( Sed_phe_query_t , data , erode_depth ) = volume;
00996 
00997    return;
00998 }
00999 
01000 void sed_remove( gpointer remove_query , gpointer data )
01001 {
01002    double remove = EH_STRUCT_MEMBER( Sed_remove_query_t , remove_query , dh );
01003    int    i      = EH_STRUCT_MEMBER( Sed_remove_query_t , remove_query , i  );
01004    Sed_cube prof = (Sed_cube)data;
01005    Sed_cell cell;
01006    
01007    cell = sed_column_top( sed_cube_col(prof,i) , remove , NULL );
01008    EH_STRUCT_MEMBER( Sed_remove_query_t , remove_query , dh ) = sed_cell_size( cell );
01009    sed_cell_destroy( cell );
01010 
01011    return;
01012 }
01013 
01014 void sed_add( gpointer add_query , gpointer data )
01015 {
01016    double add   = EH_STRUCT_MEMBER( Sed_add_query_t , add_query , dh       );
01017    double *phe  = EH_STRUCT_MEMBER( Sed_add_query_t , add_query , phe      );
01018    int    i     = EH_STRUCT_MEMBER( Sed_add_query_t , add_query , i        );
01019    int n_grains = EH_STRUCT_MEMBER( Sed_add_query_t , add_query , n_grains );
01020    Sed_cube prof = (Sed_cube)data;
01021    double *amount;
01022    int n;
01023 
01024    amount = eh_new( double , n_grains );
01025 
01026    for ( n=0 ; n<n_grains ; n++ )
01027       amount[n] = phe[n]*add;
01028 
01029    sed_column_add_vec( sed_cube_col(prof,i) , amount );
01030 
01031    eh_free( amount );
01032 
01033    return;
01034 }
01035 
01036 void sed_get_depth( gpointer depth_query , gpointer data )
01037 {
01038    int i   = EH_STRUCT_MEMBER( Sed_depth_query_t , depth_query , i );
01039    Sed_cube prof = (Sed_cube)data;
01040 
01041    EH_STRUCT_MEMBER( Sed_depth_query_t , depth_query , depth ) =
01042       sed_cube_water_depth( prof , 0 , i );
01043 
01044    return;
01045 }
01046 */

Generated on Fri Jan 4 18:04:16 2008 for sedflux by  doxygen 1.5.2