00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdio.h>
00022 #include <fcntl.h>
00023 #include <stdlib.h>
00024 #include <string.h>
00025
00026 #define SED_SUBSIDENCE_PROC_NAME "subsidence"
00027 #define EH_LOG_DOMAIN SED_SUBSIDENCE_PROC_NAME
00028
00029 #include <utils/utils.h>
00030 #include <sed/sed_sedflux.h>
00031 #include "my_processes.h"
00032
00033 typedef struct
00034 {
00035 double time;
00036 double *rate;
00037 }
00038 Subsidence_record_t;
00039
00040
00041 int get_tectonics(GArray *rate_array, double year, double *rate_resample, int len);
00042
00043 gboolean init_subsidence_data( Sed_process proc , Sed_cube prof , GError** error );
00044
00045 Sed_process_info
00046 run_subsidence( Sed_process proc , Sed_cube prof )
00047 {
00048 Subsidence_t* data = sed_process_user_data(proc);
00049 Sed_process_info info = SED_EMPTY_INFO;
00050 gsize i, j, n;
00051 double year;
00052 double start_year, end_year;
00053 double upper_edge, lower_edge;
00054 double time_step, total_time=0., total_subsidence=0.;
00055
00056 if ( sed_process_run_count(proc)==0 )
00057 init_subsidence_data( proc , prof , NULL );
00058
00059 start_year = data->last_year;
00060 end_year = sed_cube_age_in_years( prof );
00061 year = sed_cube_age_in_years( prof );
00062 time_step = year - data->last_year;
00063 data->last_year = year;
00064
00065 eh_message( "subsidence time step (years): %f" , time_step );
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 if ( data->subsidence_seq->len == 1 && time_step>1e-6 )
00076 {
00077 double** sub_grid = eh_dbl_grid_data(data->subsidence_seq->data[0]);
00078 for ( i=0 ; i<sed_cube_n_x(prof) ; i++ )
00079 for ( j=0 ; j<sed_cube_n_y(prof) ; j++ )
00080 sed_cube_adjust_base_height( prof , i , j , sub_grid[i][j]*time_step );
00081 }
00082 else if ( time_step>1e-6 )
00083 {
00084 for ( n=0,total_time=0 ; n<data->subsidence_seq->len ; n++ )
00085 {
00086 lower_edge = data->subsidence_seq->t[n];
00087 if ( n<data->subsidence_seq->len-1 )
00088 upper_edge = data->subsidence_seq->t[n+1];
00089 else
00090 upper_edge = G_MAXDOUBLE;
00091
00092 if ( start_year >= upper_edge )
00093 time_step = -1;
00094 else if ( start_year >= lower_edge && end_year < upper_edge )
00095 time_step = end_year - start_year;
00096 else if ( start_year < lower_edge && end_year >= upper_edge )
00097 time_step = upper_edge - lower_edge;
00098 else if ( start_year >= lower_edge && end_year >= upper_edge )
00099 time_step = upper_edge - start_year;
00100 else if ( start_year < lower_edge && end_year < upper_edge )
00101 time_step = end_year - lower_edge;
00102 else
00103 time_step = -1;
00104
00105 if ( time_step > 0 )
00106 {
00107 double dz;
00108 double** sub_grid_l = eh_dbl_grid_data(data->subsidence_seq->data[n] );
00109 double** sub_grid_h = eh_dbl_grid_data(data->subsidence_seq->data[n+1]);
00110
00111 total_time += time_step;
00112 for ( i=0 ; i<sed_cube_n_x(prof) ; i++ )
00113 for ( j=0 ; j<sed_cube_n_y(prof) ; j++ )
00114 {
00115 dz = ( (sub_grid_h[i][j] - sub_grid_l[i][j] )
00116 / (upper_edge - lower_edge ) )
00117 * (start_year - lower_edge)
00118 + sub_grid_l[i][j];
00119 sed_cube_adjust_base_height( prof , i , j , dz*time_step );
00120 total_subsidence += dz*time_step;
00121 }
00122 }
00123 }
00124
00125 if ( fabs( total_time - (end_year-start_year) ) > 1e-5 )
00126 {
00127 eh_warning( "The current time interval is not completely contained "
00128 " within the subsidence curve." );
00129 eh_warning( "Start of this time interval: %f" , start_year );
00130 eh_warning( "End of this time interval: %f" , end_year );
00131 eh_warning( "Total time: %f" , total_time );
00132 }
00133 }
00134
00135 eh_message( "Time: %f" , sed_cube_age( prof ) );
00136 eh_message( "Total subsidence (m): %f" , total_subsidence );
00137
00138 return info;
00139 }
00140
00141 #define SUBSIDENCE_KEY_FILENAME "subsidence file"
00142
00143 static gchar* subsidence_req_labels[] =
00144 {
00145 SUBSIDENCE_KEY_FILENAME ,
00146 NULL
00147 };
00148
00149 gboolean
00150 init_subsidence( Sed_process p , Eh_symbol_table tab , GError** error )
00151 {
00152 Subsidence_t* data = sed_process_new_user_data( p , Subsidence_t );
00153 GError* tmp_err = NULL;
00154 gboolean is_ok = TRUE;
00155
00156 eh_return_val_if_fail( error==NULL || *error==NULL , FALSE );
00157
00158 data->last_year = 0.;
00159 data->subsidence_seq = NULL;
00160
00161 eh_symbol_table_require_labels( tab , subsidence_req_labels , &tmp_err );
00162
00163 if ( !tmp_err )
00164 {
00165 data->filename = eh_symbol_table_value( tab , SUBSIDENCE_KEY_FILENAME );
00166
00167 eh_touch_file( data->filename , O_RDONLY , &tmp_err );
00168 }
00169
00170 if ( tmp_err )
00171 {
00172 g_propagate_error( error , tmp_err );
00173 is_ok = FALSE;
00174 }
00175
00176 return is_ok;
00177 }
00178
00179 gboolean
00180 init_subsidence_data( Sed_process proc , Sed_cube prof , GError** error )
00181 {
00182 gboolean is_ok = TRUE;
00183 Subsidence_t* data = sed_process_user_data( proc );
00184
00185 if ( data )
00186 {
00187 GError* tmp_err = NULL;
00188 double* y = sed_cube_y( prof , NULL );
00189
00190 data->last_year = sed_cube_age_in_years(prof);
00191
00192 if ( sed_mode_is_3d() )
00193 data->subsidence_seq = sed_get_floor_sequence_3(
00194 data->filename ,
00195 sed_cube_x_res( prof ) ,
00196 sed_cube_y_res( prof ) ,
00197 &tmp_err );
00198 else
00199 data->subsidence_seq = sed_get_floor_sequence_2(
00200 data->filename ,
00201 y ,
00202 sed_cube_n_y(prof) ,
00203 &tmp_err );
00204
00205 eh_free( y );
00206
00207 if ( tmp_err )
00208 {
00209 g_propagate_error( error , tmp_err );
00210 is_ok = FALSE;
00211 }
00212 }
00213
00214 return is_ok;
00215 }
00216
00217 gboolean
00218 destroy_subsidence( Sed_process p )
00219 {
00220 if ( p )
00221 {
00222 Subsidence_t* data = sed_process_user_data( p );
00223
00224 if ( data )
00225 {
00226 gint i;
00227
00228 if ( data->subsidence_seq )
00229 {
00230 for ( i=0 ; i<data->subsidence_seq->len ; i++ )
00231 eh_grid_destroy( data->subsidence_seq->data[i] , TRUE );
00232 eh_destroy_sequence( data->subsidence_seq , FALSE );
00233 }
00234
00235 eh_free( data->filename );
00236 eh_free( data );
00237 }
00238 }
00239
00240 return TRUE;
00241 }
00242
00243 gboolean dump_subsidence_data( gpointer ptr , FILE *fp )
00244 {
00245 Subsidence_t *data = (Subsidence_t*)ptr;
00246 guint len;
00247
00248 len = strlen( data->filename )+1;
00249 fwrite( &len , sizeof(guint) , 1 , fp );
00250 fwrite( data->filename , sizeof(char) , len , fp );
00251
00252 fwrite( &(data->last_year) , sizeof(double) , 1 , fp );
00253
00254 len = data->tectonic_curve->len;
00255 fwrite( &len , sizeof(guint) , 1 , fp );
00256 fwrite( data->tectonic_curve->data , sizeof(double) , len , fp );
00257
00258 return TRUE;
00259 }
00260
00261 gboolean load_subsidence_data( gpointer ptr , FILE *fp )
00262 {
00263 Subsidence_t *data = (Subsidence_t*)ptr;
00264 guint len;
00265 double *tectonic_data;
00266
00267 fread( &len , sizeof(guint) , 1 , fp );
00268 fread( data->filename , sizeof(char) , len , fp );
00269
00270 fread( &(data->last_year) , sizeof(double) , 1 , fp );
00271
00272 fread( &len , sizeof(guint) , 1 , fp );
00273 tectonic_data = eh_new( double , len );
00274 fread( tectonic_data , sizeof(double) , len , fp );
00275
00276 data->tectonic_curve = g_array_new( FALSE , FALSE , sizeof(double) );
00277 g_array_append_vals( data->tectonic_curve , tectonic_data , len );
00278
00279 return TRUE;
00280 }
00281
00282 int get_tectonics(GArray *rate_array, double year, double *rate_resample, int len)
00283 {
00284 int i, j;
00285 Subsidence_record_t r1, r2;
00286 double time[2], rate[2], *rate1, *rate2;
00287
00288
00289 for ( i=0 ;
00290 i<rate_array->len
00291 && g_array_index(rate_array,Subsidence_record_t,i).time <= year ;
00292 i++ );
00293
00294
00295
00296 if ( i >= rate_array->len )
00297 {
00298 g_warning( "current time is outside of bounds in subsidence file" );
00299 g_warning( "using the rates from the last subsidence record" );
00300 i = rate_array->len-1;
00301 year = g_array_index( rate_array , Subsidence_record_t , i ).time;
00302 }
00303 if ( i == 0 )
00304 {
00305 g_warning( "current time is outside of bounds in subsidence file" );
00306 g_warning( "using the rates from the first subsidence record" );
00307 i = 1;
00308 year = g_array_index( rate_array , Subsidence_record_t , 0 ).time;
00309 }
00310
00311 r1 = g_array_index( rate_array , Subsidence_record_t , i-1 );
00312 r2 = g_array_index( rate_array , Subsidence_record_t , i );
00313
00314 rate1 = r1.rate;
00315 rate2 = r2.rate;
00316
00317 time[0] = r1.time;
00318 time[1] = r2.time;
00319
00320 for ( j=0 ; j<len ; j++ )
00321 {
00322 rate[0] = rate1[j];
00323 rate[1] = rate2[j];
00324
00325 interpolate( time , rate , 2 , &year , &rate_resample[j] , 1 );
00326 }
00327
00328 return 0;
00329
00330 }
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378