00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdlib.h>
00022 #include <stdio.h>
00023 #include <math.h>
00024 #include <limits.h>
00025 #include <unistd.h>
00026 #include <string.h>
00027 #include "sakura.h"
00028 #include "sakura_local.h"
00029 #include <sed/sed_sedflux.h>
00030 #include <utils/utils.h>
00031
00032
00033 static gint _verbose = 0;
00034 static gboolean _reset_bathy = FALSE;
00035 static gboolean _version = FALSE;
00036 static gboolean _debug = FALSE;
00037 static gdouble _day = 1.;
00038 static gdouble _angle = 14.;
00039 static gchar* _in_file = NULL;
00040 static gchar* _out_file = NULL;
00041 static gchar* _bathy_file = NULL;
00042 static gchar* _flood_file = NULL;
00043 static gchar* _data_file = NULL;
00044 static gint* _data_id = NULL;
00045 static gint _data_int = 1;
00046
00047 gboolean parse_data_list( const gchar* name , const gchar* value , gpointer data , GError** error );
00048
00049 static GOptionEntry entries[] =
00050 {
00051 { "in-file" , 'i' , 0 , G_OPTION_ARG_FILENAME , &_in_file , "Initialization file" , "<file>" } ,
00052 { "out-file" , 'o' , 0 , G_OPTION_ARG_FILENAME , &_out_file , "Output file" , "<file>" } ,
00053 { "bathy-file" , 'b' , 0 , G_OPTION_ARG_FILENAME , &_bathy_file , "Bathymetry file" , "<file>" } ,
00054 { "flood-file" , 'f' , 0 , G_OPTION_ARG_FILENAME , &_flood_file , "Flood file" , "<file>" } ,
00055 { "data-file" , 'd' , 0 , G_OPTION_ARG_FILENAME , &_data_file , "Data file" , "<file>" } ,
00056 { "out-data" , 'D' , 0 , G_OPTION_ARG_CALLBACK , parse_data_list , "List of data to watch" , "[var1[,var2[...]]]" } ,
00057 { "out-int" , 'I' , 0 , G_OPTION_ARG_INT , &_data_int , "Data output interval (-)" , "INT" } ,
00058 { "angle" , 'a' , 0 , G_OPTION_ARG_DOUBLE , &_angle , "Spreading angle (deg)" , "DEG" } ,
00059 { "reset" , 0 , 0 , G_OPTION_ARG_NONE , &_reset_bathy , "Reset bathymetry with every flood" , NULL } ,
00060 { "verbose" , 'V' , 0 , G_OPTION_ARG_INT , &_verbose , "Verbosity level" , "n" } ,
00061 { "version" , 'v' , 0 , G_OPTION_ARG_NONE , &_version , "Version number" , NULL } ,
00062 { "debug" , 'b' , 0 , G_OPTION_ARG_NONE , &_debug , "Write debug messages", NULL } ,
00063 { NULL }
00064 };
00065
00066 static const gchar* _DATA_VAL_KEYS[] =
00067 {
00068 "velocity" , "height" , "concentration" , NULL
00069 };
00070
00071 gboolean
00072 parse_data_list( const gchar* name , const gchar* value , gpointer data , GError** error )
00073 {
00074 gboolean success = FALSE;
00075 gint* data_id = NULL;
00076
00077 eh_return_val_if_fail( error==NULL || *error==NULL , FALSE );
00078
00079 if ( name && value )
00080 {
00081 GError* tmp_err = NULL;
00082 gchar** data_list = g_strsplit( value , "," , 0 );
00083
00084 if ( !data_list )
00085 {
00086 g_set_error( &tmp_err ,
00087 G_OPTION_ERROR ,
00088 G_OPTION_ERROR_FAILED ,
00089 "Failed to parse comma-separated list of data values to monitor" );
00090 }
00091 else
00092 {
00093 gchar** key;
00094 gint id;
00095 gint i;
00096
00097
00098 data_id = eh_new( gint , g_strv_length( data_list )+1 );
00099
00100 for ( key=data_list,i=0 ; *key && !tmp_err ; key++,i++ )
00101 {
00102 id = eh_strv_find( _DATA_VAL_KEYS , *key );
00103 data_id[i] = id;
00104
00105 if ( id<0 )
00106 g_set_error( &tmp_err ,
00107 G_OPTION_ERROR ,
00108 G_OPTION_ERROR_FAILED ,
00109 "Invalid data key (%s)" , *key );
00110 }
00111 data_id[i] = -1;
00112 }
00113
00114 if ( tmp_err )
00115 {
00116 g_propagate_error( error , tmp_err );
00117 eh_free( data_id );
00118 data_id = NULL;
00119 success = FALSE;
00120 }
00121 else
00122 success = TRUE;
00123 }
00124
00125 _data_id = data_id;
00126
00127 return success;
00128 }
00129
00130 void
00131 sakura_run_flood( Sakura_bathy_st* b ,
00132 Sakura_flood_st* f ,
00133 Sakura_sediment_st* s ,
00134 Sakura_const_st* c ,
00135 double** deposit_in_m )
00136 {
00137
00138
00139
00140 {
00141 gint n, i;
00142 double** deposit = NULL;
00143 gint n_grains;
00144 gint len;
00145
00146 deposit = sakura_wrapper( b , f , s , c , &n_grains , &len );
00147
00148 eh_require( n_grains==s->n_grains );
00149 eh_require( len==b->len );
00150
00151
00152
00153 for ( n=0 ; n<s->n_grains ; n++ )
00154 for ( i=0 ; i<b->len ; i++ )
00155 deposit_in_m[n][i] = deposit[n][i];
00156
00157 eh_free_2( deposit );
00158 }
00159 }
00160
00161 gint
00162 main(int argc,char *argv[])
00163 {
00164 GError* error = NULL;
00165 gchar* program_name;
00166 gboolean mode_1d;
00167
00168 g_thread_init( NULL );
00169 eh_init_glib();
00170
00171 {
00172 GOptionContext* context = g_option_context_new( "Run hyperpycnal flow model." );
00173
00174 g_option_context_add_main_entries( context , entries , NULL );
00175
00176 if ( !g_option_context_parse( context , &argc , &argv , &error ) )
00177 eh_error( "Error parsing command line arguments: %s" , error->message );
00178 }
00179
00180 _day *= S_SECONDS_PER_DAY;
00181
00182 if ( _version )
00183 {
00184 eh_fprint_version_info( stdout , "sakura" , 0 , 9 , 0 );
00185 eh_exit(0);
00186 }
00187
00188 if ( _debug )
00189 g_setenv( "SAKURA_DEBUG" , "TRUE" , TRUE );
00190
00191 program_name = g_path_get_basename( argv[0] );
00192 if ( strcasecmp( program_name , "sakura")==0 )
00193 {
00194 _angle = 0.;
00195 mode_1d = TRUE;
00196 }
00197
00198 if ( _verbose )
00199 {
00200 if ( mode_1d ) eh_info( "Operating in 1D mode (ignoring width information)." );
00201 else eh_info( "Operating in 1.5D mode." );
00202
00203 eh_info( "Duration of flow (days) : %f" , _day*S_DAYS_PER_SECOND );
00204 eh_info( "Spreading angle (degrees) : %f" , _angle );
00205 }
00206
00207 if ( !error )
00208 {
00209 gint i;
00210 Sakura_param_st* param = NULL;
00211 Sakura_bathy_st* bathy_data = NULL;
00212 Sakura_bathy_st* bathy_data_0 = NULL;
00213 Sakura_flood_st** flood_data = NULL;
00214 Sakura_const_st* const_data = NULL;
00215 Sakura_sediment_st* sediment_data = NULL;
00216 Eh_dbl_grid deposit;
00217 Eh_dbl_grid total_deposit;
00218 const double spreading_angle = tan(_angle*G_PI/180.);
00219
00220 if ( ( param = sakura_scan_parameter_file( _in_file , &error ) )==NULL
00221 || ( flood_data = sakura_scan_flood_file ( _flood_file , param , &error ) )==NULL
00222 || ( bathy_data_0 = sakura_scan_bathy_file ( _bathy_file , param , &error ) )==NULL )
00223 eh_error( "%s" , error->message );
00224
00225 bathy_data = sakura_copy_bathy_data ( NULL , bathy_data_0 );
00226 const_data = sakura_set_constant_data ( param , bathy_data );
00227 const_data = sakura_set_constant_output_data( const_data , _data_file , _data_id , _data_int );
00228 sediment_data = sakura_set_sediment_data ( param );
00229
00230 deposit = eh_grid_new( double , sediment_data->n_grains , bathy_data->len );
00231 total_deposit = eh_grid_new( double , sediment_data->n_grains , bathy_data->len );
00232
00233 for ( i=0 ; flood_data[i] ; i++ )
00234 {
00235
00236
00237 sakura_set_width( bathy_data , flood_data[i]->width , spreading_angle );
00238
00239 sakura_run_flood( bathy_data , flood_data[i] , sediment_data , const_data , eh_dbl_grid_data(deposit) );
00240
00241 eh_dbl_grid_add( total_deposit , deposit );
00242
00243 if ( _data_file ) sakura_write_data ( _data_file , deposit );
00244 if ( _reset_bathy ) sakura_copy_bathy_data( bathy_data , bathy_data_0 );
00245 }
00246
00247 sakura_write_output( _out_file , bathy_data , eh_dbl_grid_data(total_deposit) , sediment_data->n_grains );
00248
00249 eh_grid_destroy( total_deposit , TRUE );
00250 eh_grid_destroy( deposit , TRUE );
00251 }
00252
00253 return EXIT_SUCCESS;
00254 }
00255
00256
00257