/Users/huttone/Devel/sedflux-new/sedflux/trunk/ew/sedflux/run_isostasy.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 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    // Save the current time, and the time since the last subsidence
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    // First we calculate the total deflection to equilibrium.  Keep updating
00094    // the sed_cube but save the deflection so we can add it back later.
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       // Create a grid to hold the calculated deflections.
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          // Calculate the loads due to each column in a sed_cube.  This is the
00127          // total load, which includes all of the sediment and water in each
00128          // column.
00129          //
00130          // Multiply by a constant that takes into account the width and length
00131          // of each column.
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          // Remesh the old and new load grids, to a coarser mesh.  We do this to
00140          // improve run-time for 2D simulations.
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          // Calculate the isostatic subsidence for the newly added sediment.
00152          // All of the grids used in this step are reduced from the original
00153          // size.  Unfortunately, this method is order n^3 and so we do the
00154          // calculations on a small grid to save time.  The result is then
00155          // interpolated to a full size grid.
00156          //
00157          // Skip the subsidence if there is no load change.  However, the load
00158          // can now be less than zero.
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          eh_debug( "Calculate the isostatic subsidence" );
00180          {
00181             gssize i, j;
00182             double v_0;
00183             double eet = data->eet;
00184             double y   = data->youngs_modulus;
00185    
00186             for ( i=0 ; i<small_n_x ; i++ )
00187                for ( j=0 ; j<small_n_y ; j++ )
00188                {
00189                   v_0 = eh_dbl_grid_val(this_load_small,i,j)
00190                       - eh_dbl_grid_val(last_load_small,i,j);
00191                   if ( fabs(v_0) > 1e-3 )
00192                      subside_point_load( this_dw_small , v_0 , eet , y , i , j );
00193                }
00194 
00195             if ( !is_sedflux_3d() )
00196             {
00197                v_0 = this_half_load - data->last_half_load;
00198                subside_half_plane_load( this_dw_small , v_0 , eet , y );
00199             }
00200 
00201          }
00202 */
00203          //---
00204          // Save the current load.
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          // Expand the deflection grid back to full resolution so that the
00212          // sed_cube can be deflected.
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          // Subside the sed_cube.
00221          // Save the total defelction.
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          // Free the grids.
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 //      while ( iter<50 );
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 // After we know the total deflection, add it back to the sed_cube.  Now we
00255 // again deflect the sed_cube but this time we add the relaxation-time
00256 // term.
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             // Save the distance from isostatic equilibrium.
00277             //---
00278             last_dw_iso[i][j] = f*(this_dw_iso[i][j]+last_dw_iso[i][j]);
00279          }
00280    }
00281 
00282    //---
00283    // Save the current load.
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 //   fwrite( data->old_thickness , sizeof(double) , data->len , fp );
00393 //   fwrite( data->old_height    , sizeof(double) , data->len , fp );
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 //   data->old_thickness = eh_new( double , data->len );
00405 //   data->old_height    = eh_new( double , data->len );
00406 
00407 //   fread( data->old_thickness , sizeof(double) , data->len , fp );
00408 //   fread( data->old_height    , sizeof(double) , data->len , fp );
00409 
00410    return TRUE;
00411 }

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