/Users/huttone/Devel/sedflux-new/sedflux/trunk/ew/sedflux/run_bbl.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 EH_LOG_DOMAIN BBL_PROCESS_NAME_S
00022 
00023 #include <stdio.h>
00024 #include <math.h>
00025 #include <string.h>
00026 #include <glib.h>
00027 #include <utils/utils.h>
00028 #include <sed/sed_sedflux.h>
00029 #include "my_processes.h"
00030 
00031 #include "sedflux.h"
00032 
00033 double   add_sediment_from_external_source( Sed_cube     p      ,
00034                                             Eh_sequence* seq    ,
00035                                             double       start  ,
00036                                             double       finish );
00037 int      rain_sediment_3                  ( Sed_cube p    , int      algorithm , Sed_riv  r     );
00038 gboolean init_bbl_data                    ( Sed_process p , Sed_cube prof      , GError** error );
00039 
00040 Sed_process_info
00041 run_bbl( Sed_process p , Sed_cube prof )
00042 {
00043    Bbl_t*           data = sed_process_user_data(p);
00044    Sed_process_info info = SED_EMPTY_INFO;
00045    gint             n_rivers;
00046 
00047    if ( sed_process_run_count(p)==0 )
00048       init_bbl_data( p , prof , NULL );
00049 
00050    if ( data->src_seq )
00051    {
00052       info.mass_added =
00053          add_sediment_from_external_source( prof            ,
00054                                             data->src_seq   ,
00055                                             data->last_year ,
00056                                             sed_cube_age_in_years(prof) );
00057       data->last_year = sed_cube_age_in_years( prof );
00058    }
00059 
00060    n_rivers = sed_cube_n_rivers( prof );
00061 
00062    info.mass_lost = 0.;
00063    if ( n_rivers>0 )
00064    {
00065       Sed_riv* all = sed_cube_all_branches( prof );
00066       Sed_riv* r;
00067 
00068       if ( all )
00069       {
00070          for ( r=all ; *r ; r++ )
00071          {
00072             eh_debug( "Depositing sediment for river: %s" , sed_river_name_loc(*r) );
00073             rain_sediment_3( prof , data->algorithm , *r );
00074          }
00075 
00076          info.mass_lost += sed_cube_mass_in_suspension( prof );
00077 
00078          // remove any remaining suspended sediment from the model.
00079          for ( r=all ; *r ; r++ )
00080             sed_cell_grid_clear( sed_cube_in_suspension( prof , *r ) );
00081 
00082          eh_free( all );
00083       }
00084    }
00085 
00086    eh_message( "time : %f" , sed_cube_age_in_years( prof ) );
00087 
00088    return info;
00089 }
00090 
00091 #define BBL_ALGORITHM_NONE    (0)
00092 #define BBL_ALGORITHM_MUDS    (1)
00093 
00094 #define BBL_KEY_ALGORITHM     "algorithm"
00095 #define BBL_KEY_SOURCE_FILE   "external sediment source file"
00096 
00097 static gchar* bbl_req_labels[] =
00098 {
00099    BBL_KEY_ALGORITHM   ,
00100    BBL_KEY_SOURCE_FILE ,
00101    NULL
00102 };
00103 
00104 gboolean
00105 init_bbl( Sed_process p , Eh_symbol_table t , GError** error )
00106 {
00107    Bbl_t*   data    = sed_process_new_user_data( p , Bbl_t );
00108    GError*  tmp_err = NULL;
00109    gboolean is_ok   = TRUE;
00110 
00111    eh_return_val_if_fail( error==NULL || *error==NULL , FALSE );
00112    eh_require( t );
00113 
00114    data->src_seq   = NULL;
00115    data->last_year = 0.;
00116 
00117    if ( eh_symbol_table_require_labels( t , bbl_req_labels , &tmp_err ) )
00118    {
00119       gchar* src_file = eh_symbol_table_value ( t , BBL_KEY_SOURCE_FILE );
00120       gchar* key      = eh_symbol_table_lookup( t , BBL_KEY_ALGORITHM   );
00121 
00122       if ( g_ascii_strcasecmp( src_file , "NONE" )==0 )
00123       {
00124          eh_free( src_file );
00125          src_file = NULL;
00126       }
00127 
00128       data->src_file = src_file;
00129 
00130       if      ( g_ascii_strcasecmp( key , "MUDS" )==0 ) data->algorithm = BBL_ALGORITHM_MUDS;
00131       else if ( g_ascii_strcasecmp( key , "NONE" )==0 ) data->algorithm = BBL_ALGORITHM_NONE;
00132       else
00133          g_set_error( &tmp_err , SEDFLUX_ERROR , SEDFLUX_ERROR_BAD_ALGORITHM ,
00134                       "Invalid bbl algorithm (muds or none): %s" , key );
00135 
00136       if ( data->algorithm==BBL_ALGORITHM_MUDS && sed_mode_is_3d() )
00137       {
00138          eh_warning( "Sedflux3D requires bbl algorithm to be 'NONE'." );
00139          data->algorithm = BBL_ALGORITHM_NONE;
00140       }
00141    }
00142 
00143    if ( tmp_err )
00144    {
00145       g_propagate_error( error , tmp_err );
00146       is_ok = FALSE;
00147    }
00148 
00149    return is_ok;
00150 }
00151 
00152 gboolean
00153 init_bbl_data( Sed_process p , Sed_cube prof , GError** error )
00154 {
00155    gboolean is_ok = TRUE;
00156    Bbl_t*   data  = sed_process_user_data( p );
00157 
00158    if ( data )
00159    {
00160       GError* tmp_err = NULL;
00161       double* y       = sed_cube_y( prof , NULL );
00162 
00163       if ( data->src_file )
00164       {
00165          if ( sed_mode_is_3d() )
00166             data->src_seq  = sed_get_floor_sequence_3( data->src_file         ,
00167                                                        sed_cube_x_res( prof ) ,
00168                                                        sed_cube_y_res( prof ) , 
00169                                                        &tmp_err );
00170          else
00171             data->src_seq  = sed_get_floor_sequence_2( data->src_file ,
00172                                                        y              ,
00173                                                        sed_cube_n_y(prof) ,
00174                                                        &tmp_err );
00175       }
00176       else
00177          data->src_seq = NULL;
00178 
00179       data->last_year = sed_cube_age_in_years(prof);
00180 
00181       eh_free( y );
00182 
00183       if ( tmp_err )
00184       {
00185          g_propagate_error( error , tmp_err );
00186          is_ok = FALSE;
00187       }
00188    }
00189 
00190    return is_ok;
00191 }
00192 
00193 gboolean
00194 destroy_bbl( Sed_process p )
00195 {
00196    if ( p )
00197    {
00198       Bbl_t* data = sed_process_user_data( p );
00199 
00200       if ( data )
00201       {
00202          if ( data->src_seq )
00203          {
00204             gint i;
00205             for ( i=0 ; i<data->src_seq->len ; i++ )
00206                eh_grid_destroy( data->src_seq->data[i] , TRUE );
00207 
00208             eh_destroy_sequence( data->src_seq , FALSE );
00209          }
00210 
00211          eh_free( data );
00212       }
00213    }
00214    return TRUE;
00215 }
00216 
00217 double add_sediment_from_external_source( Sed_cube p       ,
00218                                           Eh_sequence* seq ,
00219                                           double start     ,
00220                                           double finish )
00221 {
00222    double mass_added = 0;
00223    Sed_cell deposit_cell;
00224    double time_step;
00225 
00226    eh_require( p   );
00227 
00228    eh_require( seq && seq->len>0 )
00229    {
00230       Eh_dbl_grid g;
00231       gssize i;
00232       for ( i=0 ; i<seq->len ; i++ )
00233       {
00234          g = seq->data[i];
00235 
00236          eh_require( sed_cube_n_x(p)==eh_grid_n_x(g) );
00237          eh_require( sed_cube_n_y(p)==eh_grid_n_y(g) );
00238       }
00239    }
00240 
00241    eh_require( start<=finish );
00242 
00243    time_step = finish-start;
00244 
00245    deposit_cell = sed_cell_new_env( );
00246    sed_cell_set_equal_fraction( deposit_cell );
00247 
00248    //---
00249    // Add sediment to the basin.  If there is only one record, assume that 
00250    // sedimentation is constant with time.  If there are multiple records
00251    // integrate the sedimentation over the time step.
00252    //
00253    // Note that the time step will be 0 at the beginning of an epoch, in
00254    // this case, don't do anything.
00255    //---
00256    if ( seq->len == 1 && time_step>1e-6 )
00257    {
00258       double **dzdt = eh_dbl_grid_data( seq->data[0] );
00259       double h;
00260       gssize i, j;
00261 
00262       for ( i=0 ; i<sed_cube_n_x(p) ; i++ )
00263          for ( j=0 ; j<sed_cube_n_y(p) ; j++ )
00264          {
00265             h = eh_min( dzdt[i][j]*time_step ,
00266                         sed_cube_water_depth(p,i,j) );
00267 
00268             if ( h>0 )
00269             {
00270                sed_cell_resize( deposit_cell , h );
00271 
00272                mass_added += sed_cell_mass(deposit_cell);
00273 
00274                sed_column_add_cell( sed_cube_col_ij(p,i,j) , deposit_cell );
00275             }
00276          }
00277    }
00278    else if ( time_step>1e-6 )
00279    {
00280       double **dzdt = eh_dbl_grid_data( seq->data[0] );
00281       gssize i, j, n;
00282       double h, total_time, lower_edge, upper_edge;
00283 
00284       for ( n=0,total_time=0 ; n<seq->len ; n++ )
00285       {
00286          lower_edge = seq->t[n];
00287          if ( n<seq->len-1 )
00288             upper_edge = seq->t[n+1];
00289          else
00290             upper_edge = G_MAXDOUBLE;
00291 
00292          if ( start >= upper_edge )
00293             time_step = -1;
00294          else if ( start >= lower_edge && finish <  upper_edge )
00295             time_step = finish - start;
00296          else if ( start < lower_edge && finish >= upper_edge )
00297             time_step = upper_edge - lower_edge;
00298          else if ( start >= lower_edge && finish >= upper_edge )
00299             time_step = upper_edge - start;
00300          else if ( start <  lower_edge && finish <  upper_edge )
00301             time_step = finish - lower_edge;
00302          else
00303             time_step = -1;
00304 
00305          if ( time_step > 0 )
00306          {
00307             total_time += time_step;
00308             dzdt        = eh_dbl_grid_data( seq->data[n] );
00309             for ( i=0 ; i<sed_cube_n_x(p) ; i++ )
00310                for ( j=0 ; j<sed_cube_n_y(p) ; j++ )
00311                {
00312                   h = eh_min( dzdt[i][j]*time_step ,
00313                               sed_cube_water_depth(p,i,j) );
00314 
00315                   if ( h>0 )
00316                   {
00317                      sed_cell_resize( deposit_cell , h );
00318 
00319                      mass_added += sed_cell_mass(deposit_cell);
00320 
00321                      sed_column_add_cell( sed_cube_col_ij(p,i,j) , deposit_cell );
00322                   }
00323 
00324                }
00325          }
00326       }
00327 
00328       if ( fabs( total_time - (finish-start) ) > 1e-5 )
00329       {
00330          eh_warning( "The current time interval is not completely contained "
00331                      "within the sequence." );
00332          eh_warning( "Start of this time interval: %f" , start );
00333          eh_warning( "End of this time interval: %f" , finish );
00334          eh_warning( "Total time: %f" , total_time );
00335       }
00336    }
00337 
00338    mass_added *= sed_cube_x_res(p)*sed_cube_y_res(p);
00339 
00340    sed_cell_destroy( deposit_cell );
00341 
00342    return mass_added;
00343 }
00344 

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