00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #define SED_ISOSTASY_PROC_NAME "isostasy"
00022 #define EH_LOG_DOMAIN SED_ISOSTASY_PROC_NAME
00023
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include <utils/utils.h>
00027 #include <sed/sed_sedflux.h>
00028 #include <subside.h>
00029 #include "my_processes.h"
00030
00031 #include "sedflux.h"
00032
00033 void subside_point_load ( Eh_dbl_grid g , double load , double h ,
00034 double E , int i_load , int j_load );
00035 void subside_half_plane_load ( Eh_dbl_grid g , double load , double h , double E );
00036 double get_flexure_parameter ( double h , double E , gssize n_dim );
00037 gboolean init_isostasy_data ( Sed_process proc , Sed_cube prof );
00038
00039 Sed_process_info
00040 run_isostasy( Sed_process proc , Sed_cube prof )
00041 {
00042 Isostasy_t* data = sed_process_user_data(proc);
00043 Sed_process_info info = SED_EMPTY_INFO;
00044 double full_n_x, full_n_y;
00045 gint small_n_x, small_n_y;
00046 double x_reduction, y_reduction;
00047 double C;
00048 double time, time_step;
00049 Eh_dbl_grid dw_iso;
00050 double total_dw = 0;
00051
00052 if ( sed_process_run_count(proc)==0 )
00053 init_isostasy_data( proc , prof );
00054
00055 if ( sed_mode_is_3d() )
00056 {
00057 x_reduction = .2;
00058 y_reduction = .2;
00059 }
00060 else
00061 {
00062 x_reduction = 1;
00063 y_reduction = .2;
00064 }
00065
00066 if ( sed_mode_is_3d() )
00067 C = sed_cube_x_res( prof )
00068 * sed_cube_y_res( prof )
00069 / x_reduction
00070 / y_reduction;
00071 else
00072 C = sed_cube_y_res( prof )
00073 / x_reduction
00074 / y_reduction;
00075
00076 eh_dbl_grid_scalar_mult( data->last_load , C );
00077
00078 full_n_x = sed_cube_n_x(prof);
00079 full_n_y = sed_cube_n_y(prof);
00080 small_n_x = ceil( full_n_x * x_reduction );
00081 small_n_y = ceil( full_n_y * y_reduction );
00082
00083
00084
00085
00086 time = sed_cube_age_in_years(prof);
00087 time_step = time - data->last_time;
00088 data->last_time = time;
00089
00090 dw_iso = eh_grid_new( double , full_n_x , full_n_y );
00091
00092
00093
00094
00095
00096 {
00097 gssize iter = 0;
00098 double last_dw;
00099 double this_half_load;
00100 Eh_dbl_grid this_dw_small;
00101 Eh_dbl_grid this_dw_full;
00102 Eh_dbl_grid last_load_small;
00103 Eh_dbl_grid last_load_full;
00104 Eh_dbl_grid this_load_small;
00105 Eh_dbl_grid this_load_full;
00106
00107
00108
00109
00110 eh_debug( "Create a grid to hold the calculated deflections" );
00111 {
00112 this_dw_small = eh_grid_new( double , small_n_x , small_n_y );
00113 eh_grid_set_x_lin( this_dw_small , 0 , sed_cube_x_res(prof)/x_reduction );
00114 eh_grid_set_y_lin( this_dw_small , 0 , sed_cube_y_res(prof)/y_reduction );
00115 }
00116
00117 last_load_full = eh_grid_dup( data->last_load );
00118
00119 eh_debug( "Subside the basin" );
00120 do
00121 {
00122 eh_debug( "Clear the deflection grid for each iteration" );
00123 eh_dbl_grid_scalar_mult( this_dw_small , 0. );
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 eh_debug( "Get the new load grid" );
00134 this_load_full = sed_cube_load_grid( prof , NULL );
00135 eh_dbl_grid_scalar_mult( this_load_full , C );
00136 this_half_load = sed_cube_water_pressure( prof , 0 , sed_cube_n_y(prof)-1 );
00137
00138
00139
00140
00141
00142 eh_debug( "Remesh the load grids" );
00143 last_load_small = eh_dbl_grid_remesh( last_load_full ,
00144 small_n_x ,
00145 small_n_y );
00146 this_load_small = eh_dbl_grid_remesh( this_load_full ,
00147 small_n_x ,
00148 small_n_y );
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 eh_debug( "Calculate deflections" );
00161 {
00162 Eh_dbl_grid v_0 = eh_grid_dup( this_load_small );
00163 double eet = data->eet;
00164 double y = data->youngs_modulus;
00165
00166 eh_dbl_grid_subtract( v_0 , last_load_small );
00167
00168 subside_grid_load( this_dw_small , v_0 , eet , y );
00169
00170 if ( sed_mode_is_2d() )
00171 {
00172 double half_load = this_half_load - data->last_half_load;
00173 subside_half_plane_load( this_dw_small , half_load , eet , y );
00174 }
00175
00176 eh_grid_destroy( v_0 , TRUE );
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 eh_debug( "Save the current load" );
00207 eh_grid_copy( last_load_full , this_load_full );
00208 data->last_half_load = this_half_load;
00209
00210
00211
00212
00213
00214 eh_debug( "Expand the grid to full resolution" );
00215 this_dw_full = eh_dbl_grid_expand( this_dw_small ,
00216 full_n_x ,
00217 full_n_y );
00218
00219
00220
00221
00222
00223 eh_debug( "Subside the basin" );
00224 {
00225 gssize i, len = sed_cube_size(prof);
00226
00227 for ( i=0 ; i<len ; i++ )
00228 sed_cube_adjust_base_height( prof , 0 , i , -eh_dbl_grid_val(this_dw_full,0,i) );
00229 }
00230
00231 eh_dbl_grid_add( dw_iso , this_dw_full );
00232
00233
00234
00235
00236 eh_grid_destroy( this_dw_full , TRUE );
00237 eh_grid_destroy( last_load_small , TRUE );
00238 eh_grid_destroy( this_load_small , TRUE );
00239 eh_grid_destroy( this_load_full , TRUE );
00240
00241 last_dw = total_dw;
00242 total_dw = eh_dbl_grid_sum( dw_iso );
00243 iter++;
00244 }
00245
00246 while ( fabs(total_dw)>0 && fabs((total_dw-last_dw)/total_dw )>.01 );
00247
00248 eh_grid_destroy( this_dw_small , TRUE );
00249 eh_grid_destroy( last_load_full , TRUE );
00250
00251 }
00252
00253
00254
00255
00256
00257
00258 {
00259 gssize i, j;
00260 double dt = time_step;
00261 double k = data->relaxation_time;
00262 double **last_dw_iso = eh_dbl_grid_data(data->last_dw_iso);
00263 double **this_dw_iso = eh_dbl_grid_data(dw_iso);
00264 double f = (k<1e-6)?0:exp(-dt/k);
00265
00266 for ( i=0 ; i<sed_cube_n_x(prof) ; i++ )
00267 for ( j=0 ; j<sed_cube_n_y(prof) ; j++ )
00268 {
00269 sed_cube_adjust_base_height( prof , i , j , this_dw_iso[i][j] );
00270 sed_cube_adjust_base_height( prof , i , j ,
00271 - (1.-f)
00272 * ( this_dw_iso[i][j]
00273 + last_dw_iso[i][j] ) );
00274
00275
00276
00277
00278 last_dw_iso[i][j] = f*(this_dw_iso[i][j]+last_dw_iso[i][j]);
00279 }
00280 }
00281
00282
00283
00284
00285 eh_grid_destroy( data->last_load , TRUE );
00286 data->last_load = sed_cube_load_grid( prof , NULL );
00287
00288 eh_grid_destroy( dw_iso , TRUE );
00289
00290 eh_message( "time : %f" , sed_cube_age_in_years(prof) );
00291 eh_message( "Youngs modulus : %f" , data->youngs_modulus );
00292 eh_message( "EET : %f" , data->eet );
00293 eh_message( "sea level : %f" , sed_cube_sea_level(prof) );
00294 eh_message( "total downward deflection : %f" , total_dw );
00295
00296 return info;
00297 }
00298
00299 #define ISOSTASY_KEY_EET "effective elastic thickness"
00300 #define ISOSTASY_KEY_YOUNGS_MODULUS "Youngs modulus"
00301 #define ISOSTASY_KEY_RELAXATION_TIME "relaxation time"
00302
00303 static gchar* isostasy_req_labels[] =
00304 {
00305 ISOSTASY_KEY_EET ,
00306 ISOSTASY_KEY_YOUNGS_MODULUS ,
00307 ISOSTASY_KEY_RELAXATION_TIME ,
00308 NULL
00309 };
00310
00311 gboolean
00312 init_isostasy( Sed_process p , Eh_symbol_table tab , GError** error )
00313 {
00314 Isostasy_t* data = sed_process_new_user_data( p , Isostasy_t );
00315 GError* tmp_err = NULL;
00316 gchar** err_s = NULL;
00317 gboolean is_ok = TRUE;
00318
00319 eh_return_val_if_fail( error==NULL || *error==NULL , FALSE );
00320
00321 data->last_dw_iso = NULL;
00322 data->last_load = NULL;
00323 data->last_half_load = 0.;
00324
00325 eh_symbol_table_require_labels( tab , isostasy_req_labels , &tmp_err );
00326
00327 if ( !tmp_err )
00328 {
00329 data->relaxation_time = eh_symbol_table_dbl_value( tab , ISOSTASY_KEY_RELAXATION_TIME );
00330 data->eet = eh_symbol_table_dbl_value( tab , ISOSTASY_KEY_EET );
00331 data->youngs_modulus = eh_symbol_table_dbl_value( tab , ISOSTASY_KEY_YOUNGS_MODULUS );
00332
00333 eh_check_to_s( data->relaxation_time>=0 , "Relaxation time positive" , &err_s );
00334 eh_check_to_s( data->eet>=0 , "Effective elastic thickness positive" , &err_s );
00335 eh_check_to_s( data->youngs_modulus>=0 , "Young's Modulus positive" , &err_s );
00336
00337 if ( !tmp_err && err_s )
00338 eh_set_error_strv( &tmp_err , SEDFLUX_ERROR , SEDFLUX_ERROR_BAD_PARAM , err_s );
00339
00340 }
00341
00342 if ( tmp_err )
00343 {
00344 g_propagate_error( error , tmp_err );
00345 is_ok = FALSE;
00346 }
00347
00348 return is_ok;
00349 }
00350
00351 gboolean
00352 init_isostasy_data( Sed_process proc , Sed_cube prof )
00353 {
00354 Isostasy_t* data = sed_process_user_data( proc );
00355
00356 if ( data )
00357 {
00358 data->last_dw_iso = eh_grid_new( double , sed_cube_n_x(prof) , sed_cube_n_y(prof) );
00359 data->last_load = sed_cube_load_grid( prof , NULL );
00360
00361 data->last_half_load = sed_cube_water_pressure( prof , 0 , sed_cube_n_y(prof)-1 );
00362 data->last_time = sed_cube_age_in_years(prof);
00363 }
00364
00365 return TRUE;
00366 }
00367
00368 gboolean
00369 destroy_isostasy( Sed_process p )
00370 {
00371 if ( p )
00372 {
00373 Isostasy_t* data = sed_process_user_data( p );
00374
00375 if ( data )
00376 {
00377 eh_grid_destroy( data->last_dw_iso , TRUE );
00378 eh_grid_destroy( data->last_load , TRUE );
00379
00380 eh_free( data );
00381 }
00382 }
00383
00384 return TRUE;
00385 }
00386
00387 gboolean dump_isostasy_data( gpointer ptr , FILE *fp )
00388 {
00389 Isostasy_t *data = (Isostasy_t*)ptr;
00390
00391 fwrite( data , sizeof(Isostasy_t) , 1 , fp );
00392
00393
00394
00395 return TRUE;
00396 }
00397
00398 gboolean load_isostasy_data( gpointer ptr , FILE *fp )
00399 {
00400 Isostasy_t *data = (Isostasy_t*)ptr;
00401
00402 fread( data , sizeof(Isostasy_t) , 1 , fp );
00403
00404
00405
00406
00407
00408
00409
00410 return TRUE;
00411 }