00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #define SED_AVULSION_PROC_NAME "avulsion"
00022 #define EH_LOG_DOMAIN SED_AVULSION_PROC_NAME
00023
00024 #include <stdio.h>
00025 #include <math.h>
00026 #include <utils/utils.h>
00027 #include <sed/sed_sedflux.h>
00028 #include <avulsion.h>
00029 #include "my_processes.h"
00030
00031 #include "sedflux.h"
00032
00033 gboolean init_avulsion_data( Sed_process p , Sed_cube prof );
00034
00035 Sed_process_info
00036 run_avulsion( Sed_process p , Sed_cube prof )
00037 {
00038 Avulsion_t* data = sed_process_user_data(p);
00039 Sed_process_info info = SED_EMPTY_INFO;
00040 Sed_riv this_river;
00041
00042 if ( sed_process_run_count(p)==0 )
00043 init_avulsion_data( p , prof );
00044
00045 this_river = sed_cube_river_by_name( prof , data->river_name );
00046
00047 if ( this_river )
00048 {
00049 double time = sed_cube_age_in_years( prof );
00050 double fraction = eh_input_val_eval( data->f_remain , time );
00051 double std_dev = eh_input_val_eval( data->std_dev , time )*S_RADS_PER_DEGREE;
00052 double min_angle = eh_input_val_eval( data->min_angle , time )*S_RADS_PER_DEGREE;
00053 double max_angle = eh_input_val_eval( data->max_angle , time )*S_RADS_PER_DEGREE;
00054 double f = 10e6;
00055
00056 if ( data->branching_is_on )
00057 {
00058 double area = sed_cube_area_above( prof , sed_cube_sea_level(prof) );
00059 gint n_branches = sed_cube_n_branches( prof );
00060
00061 while ( area/n_branches > f )
00062 {
00063 sed_cube_split_river( prof , sed_river_name_loc(this_river) );
00064
00065 sed_river_impart_avulsion_data( this_river );
00066
00067 n_branches += 2;
00068 }
00069 }
00070
00071 eh_require( sed_river_avulsion_data( this_river ) );
00072
00073 sed_river_avulsion_data( this_river )->std_dev = std_dev;
00074 sed_river_avulsion_data( this_river )->rand = data->rand;
00075
00076 eh_require( max_angle>min_angle );
00077 eh_require( fraction>=0. );
00078 eh_require( fraction<=1. );
00079 eh_require( !eh_isnan(fraction) );
00080
00081 if ( data->reset_angle )
00082 {
00083 data->reset_angle = FALSE;
00084 sed_river_set_angle( this_river , .5*(max_angle+min_angle) );
00085 }
00086
00087 sed_river_set_angle_limit( this_river , min_angle , max_angle );
00088 sed_river_set_hinge ( this_river , data->hinge_i , data->hinge_j );
00089
00090 sed_cube_avulse_river( prof , this_river );
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 if ( sed_mode_is_2d() )
00112 sed_river_adjust_mass( this_river , fraction );
00113 }
00114 else
00115 eh_require_not_reached();
00116
00117 return info;
00118 }
00119
00123
00124 #define AVULSION_KEY_STDDEV "standard deviation"
00126 #define AVULSION_KEY_MIN_ANGLE "minimum angle"
00128 #define AVULSION_KEY_MAX_ANGLE "maximum angle"
00130 #define AVULSION_KEY_RIVER_NAME "river name"
00132 #define AVULSION_KEY_HINGE_POINT "hinge point"
00135 #define AVULSION_KEY_FRACTION "fraction of sediment remaining in plane"
00137 #define AVULSION_KEY_BRANCHING "river can branch?"
00139 #define AVULSION_KEY_SEED "seed for random number generator"
00140
00141
00142 static gchar* avulsion_req_labels[] =
00143 {
00144 AVULSION_KEY_STDDEV ,
00145 AVULSION_KEY_MIN_ANGLE ,
00146 AVULSION_KEY_MAX_ANGLE ,
00147 AVULSION_KEY_RIVER_NAME ,
00148 AVULSION_KEY_FRACTION ,
00149 AVULSION_KEY_BRANCHING ,
00150 AVULSION_KEY_SEED ,
00151 NULL
00152 };
00153 static gchar* avulsion_3d_req_labels[] =
00154 {
00155 AVULSION_KEY_HINGE_POINT ,
00156 NULL
00157 };
00158
00159 gboolean
00160 init_avulsion( Sed_process p , Eh_symbol_table tab , GError** error )
00161 {
00162 Avulsion_t* data = sed_process_new_user_data( p , Avulsion_t );
00163 GError* tmp_err = NULL;
00164 gboolean is_ok = TRUE;
00165
00166 eh_return_val_if_fail( error==NULL || *error==NULL , FALSE );
00167
00168 data->rand = NULL;
00169
00170 if ( eh_symbol_table_require_labels( tab , avulsion_req_labels , &tmp_err ) )
00171 {
00172 if ( !tmp_err ) data->std_dev = eh_symbol_table_input_value( tab , AVULSION_KEY_STDDEV , &tmp_err );
00173 if ( !tmp_err ) data->f_remain = eh_symbol_table_input_value( tab , AVULSION_KEY_FRACTION , &tmp_err );
00174 if ( !tmp_err ) data->min_angle = eh_symbol_table_input_value( tab , AVULSION_KEY_MIN_ANGLE , &tmp_err );
00175 if ( !tmp_err ) data->max_angle = eh_symbol_table_input_value( tab , AVULSION_KEY_MAX_ANGLE , &tmp_err );
00176
00177 data->branching_is_on = eh_symbol_table_bool_value( tab , AVULSION_KEY_BRANCHING );
00178 data->rand_seed = eh_symbol_table_int_value ( tab , AVULSION_KEY_SEED );
00179 data->river_name = eh_symbol_table_value ( tab , AVULSION_KEY_RIVER_NAME );
00180
00181 data->reset_angle = TRUE;
00182
00183 data->hinge_i = 0;
00184 data->hinge_j = 0;
00185
00186 if ( sed_mode_is_3d()
00187 && eh_symbol_table_require_labels( tab , avulsion_3d_req_labels , &tmp_err ) )
00188 {
00189 gchar** err_s = NULL;
00190 gchar** hinge = g_strsplit( eh_symbol_table_lookup( tab , AVULSION_KEY_HINGE_POINT ) , "," , -1 );
00191
00192 eh_check_to_s( hinge[0] && hinge[1] , "Need i and j index for hinge point" , &err_s );
00193
00194 if ( hinge[0] && hinge[1] )
00195 {
00196 data->hinge_i = strtoul( hinge[0] , NULL , 10 );
00197 data->hinge_j = strtoul( hinge[1] , NULL , 10 );
00198 }
00199
00200 g_strfreev( hinge );
00201
00202 eh_check_to_s( data->hinge_i>=0 , "Hinge index positive integer" , &err_s );
00203 eh_check_to_s( data->hinge_j>=0 , "Hinge index positive integer" , &err_s );
00204
00205 if ( !tmp_err && err_s )
00206 eh_set_error_strv( &tmp_err , SEDFLUX_ERROR , SEDFLUX_ERROR_BAD_PARAM , err_s );
00207 }
00208 }
00209
00210 if ( tmp_err )
00211 {
00212 g_propagate_error( error , tmp_err );
00213 is_ok = FALSE;
00214 }
00215
00216 return is_ok;
00217 }
00218
00219 gboolean
00220 init_avulsion_data( Sed_process p , Sed_cube prof )
00221 {
00222 Avulsion_t* data = sed_process_user_data( p );
00223
00224 if ( data )
00225 {
00226 Sed_riv r = sed_cube_river_by_name( prof , data->river_name );
00227
00228 sed_river_set_avulsion_data( r , avulsion_new(NULL,0.) );
00229
00230 if ( data->rand_seed>0 ) data->rand = g_rand_new_with_seed( data->rand_seed );
00231 else data->rand = g_rand_new();
00232
00233 data->reset_angle = TRUE;
00234 }
00235
00236 return TRUE;
00237 }
00238
00239 gboolean
00240 destroy_avulsion( Sed_process p )
00241 {
00242 if ( p )
00243 {
00244 Avulsion_t* data = sed_process_user_data( p );
00245
00246 if ( data )
00247 {
00248 if ( data->rand ) g_rand_free( data->rand );
00249
00250 eh_input_val_destroy( data->min_angle );
00251 eh_input_val_destroy( data->max_angle );
00252 eh_input_val_destroy( data->std_dev );
00253 eh_input_val_destroy( data->f_remain );
00254 eh_free ( data->river_name );
00255 eh_free ( data );
00256 }
00257 }
00258
00259 return TRUE;
00260 }
00261