/Users/huttone/Devel/sedflux-new/sedflux/trunk/ew/sed/sed_column.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 //#include "sed_sedflux.h"
00022 
00023 #include <glib.h>
00024 #include <stdio.h>
00025 
00026 #include "utils/utils.h"
00027 
00028 #include "sed_column.h"
00029 
00030 CLASS( Sed_column )
00031 {
00032    Sed_cell* cell;    
00033    double z;          
00034    double t;          
00035    gssize len;        
00036    gssize size;       
00037    double dz;         
00038    double x;          
00039    double y;          
00040    double age;        
00041    double sl;         
00042 };
00043 
00044 //@Include: sed_column.h
00045 
00055 Sed_column
00056 sed_column_new( gssize n_bins )
00057 {
00058    Sed_column s = NULL;
00059    
00060    if ( n_bins>0 )
00061    {
00062       NEW_OBJECT( Sed_column , s );
00063    
00064       // use resize to allocate memory for the column in blocks.
00065       s->size = 0;
00066       s->cell = NULL;
00067       sed_column_resize( s , n_bins );
00068 
00069       s->len = 0;
00070       s->dz  = 1.;
00071       s->t   = 0.;
00072       s->z   = 0.;
00073       s->x   = 0.;
00074       s->y   = 0.;
00075       s->age = 0.;
00076       s->sl  = 0.;
00077    }
00078       
00079    return s;
00080 }
00081 
00082 Sed_column sed_column_new_filled( double t , Sed_size_class size )
00083 {
00084    Sed_column c  = sed_column_new( 1 );
00085    Sed_cell cell = sed_cell_new_classed( NULL , t , size );
00086 
00087    sed_column_add_cell( c , cell );
00088 
00089    sed_cell_destroy( cell );
00090 
00091    return c;
00092 }
00093 
00100 Sed_column
00101 sed_column_destroy( Sed_column s )
00102 {
00103    if ( s )
00104    {
00105       gssize i;
00106    
00107       for ( i=0;i<s->size;i++)
00108          sed_cell_destroy(s->cell[i]);
00109       eh_free(s->cell);
00110 
00111       eh_free(s);
00112    }
00113    
00114    return NULL;
00115 }
00116 
00121 Sed_column
00122 sed_column_clear( Sed_column s )
00123 {
00124    if ( s )
00125    {
00126       gssize i;
00127 
00128       for ( i=0 ; i<s->len ; i++ )
00129          sed_cell_clear( s->cell[i] );
00130       s->len = 0;
00131       s->t   = 0.;
00132    }
00133    return s;
00134 }
00135 
00150 Sed_column
00151 sed_column_copy( Sed_column dest , const Sed_column src )
00152 {
00153    eh_require( src );
00154 
00155    if ( src )
00156    {
00157       gssize i;
00158 
00159       if ( !dest )
00160          dest = sed_column_new( src->size );
00161    
00162       sed_column_resize( dest , src->size );
00163 
00164       dest->z   = src->z;
00165       dest->t   = src->t;
00166       dest->len = src->len;
00167       dest->dz  = src->dz;
00168       dest->x   = src->x;
00169       dest->y   = src->y;
00170       dest->age = src->age;
00171       dest->sl  = src->sl;
00172 
00173       for ( i=0 ; i<src->size ; i++ )
00174          sed_cell_copy( dest->cell[i] , src->cell[i] );
00175    }
00176    else
00177       dest = NULL;
00178    
00179    return dest;
00180 }
00181 
00182 gboolean
00183 sed_column_is_same( const Sed_column c_1 , const Sed_column c_2 )
00184 {
00185    gboolean same = TRUE;
00186 
00187    if ( c_1!=c_2 )
00188    {
00189       if ( sed_column_is_same_data(c_1,c_2) )
00190       {
00191          gssize i;
00192          gssize len = sed_column_len( c_1 );
00193          for ( i=0 ; same && i<len ; i++ )
00194             same = sed_cell_is_same( c_1->cell[i] , c_2->cell[i] );
00195       }
00196       else
00197          same = FALSE;
00198    }
00199 
00200    return same;
00201 }
00202 
00203 gboolean
00204 sed_column_is_same_data( const Sed_column c_1 , const Sed_column c_2 )
00205 {
00206    gboolean same = TRUE;
00207 
00208    if ( c_1!=c_2 )
00209    {
00210       same =  eh_compare_dbl( c_1->z   , c_2->z   , 1e-12 )
00211            && eh_compare_dbl( c_1->t   , c_2->t   , 1e-12 )
00212            && eh_compare_dbl( c_1->dz  , c_2->dz  , 1e-12 )
00213            && eh_compare_dbl( c_1->x   , c_2->x   , 1e-12 )
00214            && eh_compare_dbl( c_1->y   , c_2->y   , 1e-12 )
00215            && eh_compare_dbl( c_1->age , c_2->age , 1e-12 ) 
00216            && eh_compare_dbl( c_1->sl  , c_2->sl  , 1e-12 ) 
00217            && c_1->len == c_2->len;
00218    }
00219 
00220    return same;
00221 }
00222 
00223 Sed_column sed_column_copy_data( Sed_column dest , const Sed_column src )
00224 {
00225    eh_require( src )
00226    {
00227       dest->z    = src->z;
00228       dest->t    = src->t;
00229       dest->len  = src->len;
00230       dest->size = src->size;
00231       dest->dz   = src->dz;
00232       dest->x    = src->x;
00233       dest->y    = src->y;
00234       dest->age  = src->age;
00235       dest->sl   = src->sl;
00236    }
00237 
00238    return dest;
00239 }
00240 
00241 Sed_column sed_column_copy_public_data( Sed_column dest , const Sed_column src )
00242 {
00243    eh_require( src )
00244    {
00245       dest->z    = src->z;
00246       dest->dz   = src->dz;
00247       dest->x    = src->x;
00248       dest->y    = src->y;
00249       dest->age  = src->age;
00250       dest->sl   = src->sl;
00251    }
00252 
00253    return dest;
00254 }
00255 
00266 Sed_column sed_column_dup( const Sed_column src )
00267 {
00268    return sed_column_copy( NULL , src );
00269 }
00270 
00282 double*
00283 sed_column_cell_fraction( const Sed_column col , gssize i )
00284 {
00285    return sed_cell_fraction_ptr( col->cell[i] );
00286 }
00287 
00294 double sed_column_base_height( const Sed_column col)
00295 {
00296    eh_return_val_if_fail( col , 0 );
00297    return col->z;
00298 }
00299 
00311 double sed_column_position( const Sed_column col )
00312 {
00313    return col->x;
00314 }
00315 
00328 double sed_column_x_position( const Sed_column col )
00329 {
00330    return col->x;
00331 }
00332 
00345 double sed_column_y_position( const Sed_column col )
00346 {
00347    return col->y;
00348 }
00349 
00350 double sed_column_age( const Sed_column col )
00351 {
00352    return col->age;
00353 }
00354 
00355 double sed_column_sea_level( const Sed_column col )
00356 {
00357    return col->sl;
00358 }
00359 
00374 Sed_column sed_column_set_position( Sed_column col , double x )
00375 {
00376    col->x = x;
00377    return col;
00378 }
00379 
00393 Sed_column sed_column_set_x_position( Sed_column col , double x )
00394 {
00395    col->x = x;
00396    return col;
00397 }
00398 
00412 Sed_column sed_column_set_y_position( Sed_column col , double y )
00413 {
00414    col->y = y;
00415    return col;
00416 }
00417 
00418 Sed_column sed_column_set_age( Sed_column c , double age )
00419 {
00420    c->age = age;
00421    return c;
00422 }
00423 
00424 Sed_column sed_column_set_sea_level( Sed_column c , double sl )
00425 {
00426    c->sl = sl;
00427    return c;
00428 }
00429 
00430 Sed_column sed_column_set_base_height( Sed_column c , double z )
00431 {
00432    c->z = z;
00433    return c;
00434 }
00435 
00436 Sed_column sed_column_adjust_base_height( Sed_column c , double dz )
00437 {
00438    c->z += dz;
00439    return c;
00440 }
00441 
00453 double sed_column_cell_height( const Sed_column col )
00454 {
00455    return col->dz;
00456 }
00457 
00458 double sed_column_z_res( const Sed_column col )
00459 {
00460    return col->dz;
00461 }
00462 
00463 Sed_column sed_column_set_z_res( Sed_column col , double new_dz )
00464 {
00465    col->dz = new_dz;
00466    return col;
00467 }
00468 
00469 
00476 double
00477 sed_column_top_height( const Sed_column col )
00478 {
00479    eh_return_val_if_fail( col , 0 );
00480    return col->z + sed_column_thickness(col);
00481 }
00482 
00492 gboolean sed_column_is_below( Sed_column col , double z )
00493 {
00494    return sed_column_top_height( col ) < z;
00495 }
00496 
00506 gboolean sed_column_is_above( Sed_column col , double z )
00507 {
00508    return sed_column_top_height( col ) > z;
00509 }
00510 
00517 double sed_column_mass(const Sed_column s)
00518 {
00519    double sum = 0;
00520 
00521    eh_require( s );
00522    {
00523       gssize i;
00524       gssize n_bins = sed_column_len(s);
00525 
00526       for ( i=0 ; i<n_bins ; i++ )
00527          sum += sed_cell_mass( s->cell[i] );
00528    }
00529 
00530    return sum;
00531 }
00532 
00533 double
00534 sed_column_sediment_mass(const Sed_column s)
00535 {
00536    double sum = 0;
00537 
00538    eh_require( s );
00539    {
00540       gssize i;
00541       gssize n_bins = sed_column_len(s);
00542 
00543       for ( i=0 ; i<n_bins ; i++ )
00544          sum += sed_cell_sediment_mass( s->cell[i] );
00545    }
00546 
00547    return sum;
00548 }
00549 
00569 double *sed_column_total_load( const Sed_column s    ,
00570                                gssize start          ,
00571                                gssize n_bins         ,
00572                                double overlying_load ,
00573                                double *load )
00574 {
00575 
00576    eh_require( s );
00577 
00578    if ( s )
00579    {
00580       gssize i;
00581       gssize col_len = s->len;
00582       double load0 = 0;
00583 
00584       eh_lower_bound( start , 0 );
00585 
00586       if ( n_bins <= 0 || start+n_bins>col_len )
00587          n_bins = col_len - start;
00588 
00589       // calculate the load above the top cell.  the load on cell includes the
00590       // weight of itself.
00591       if ( !load )
00592          load = eh_new0( double , n_bins );
00593 
00594       for ( i=col_len-1 ; i>=start+n_bins-1 ; i-- )
00595          load0 += sed_cell_sediment_load( s->cell[i] );
00596 
00597       load0 += overlying_load;
00598 
00599       // calculate the overlying load on each of the cells.
00600       load[n_bins-1]=load0;
00601       for ( i=n_bins-2 ; i>=0 ; i-- )
00602          load[i] = load[i+1] + sed_cell_sediment_load( s->cell[i+start] );
00603    }
00604    else
00605       load = NULL;
00606 
00607    return load;
00608 }
00609 
00610 double* sed_column_load( const Sed_column s ,
00611                          gssize start       ,
00612                          gssize n_bins      ,
00613                          double* load )
00614 {
00615    return sed_column_total_load( s , start , n_bins , 0. , load );
00616 }
00617 
00618 double* sed_column_load_with_water( const Sed_column s ,
00619                                     gssize start       ,
00620                                     gssize n_bins      ,
00621                                     double* load )
00622 {
00623    double water_load = sed_column_water_pressure( s );
00624 
00625    return sed_column_total_load( s , start , n_bins , water_load , load );
00626 }
00627 
00628 double sed_column_water_pressure( const Sed_column s )
00629 {
00630    double p = 0;
00631 
00632    if ( sed_column_water_depth(s)>0 )
00633       p = sed_column_water_depth(s)*sed_rho_sea_water()*sed_gravity();
00634 
00635    return p;
00636 }
00637 
00661 double* sed_column_total_property( Sed_property f ,
00662                                    Sed_column c   ,
00663                                    gssize start   ,
00664                                    gssize n_bins  ,
00665                                    double* val )
00666 {
00667    eh_require( c );
00668 
00669    if ( c )
00670    {
00671       gssize i;
00672       gssize low_i;
00673       double val0 = 0.;
00674       gssize col_len = c->len;
00675 
00676       if ( n_bins <= 0 || start+n_bins>col_len )
00677          n_bins = col_len-start;
00678 
00679       low_i = start+n_bins-1;
00680 
00681       if ( !val )
00682          val = eh_new0( double , n_bins );
00683 
00684       for ( i=col_len-1 ; i>=low_i ; i-- )
00685          val0 += sed_property_measure( f , c->cell[i] );
00686 
00687       val[n_bins-1] = val0;
00688       for ( i=n_bins-2 ; i>=0 ; i-- )
00689          val[i] = val[i+1] + sed_property_measure( f , c->cell[i] );
00690    }
00691    else
00692       val = NULL;
00693 
00694    return val;
00695 }
00696 
00723 double* sed_column_avg_property_with_load( Sed_property f ,
00724                                            Sed_column c   ,
00725                                            gssize start   ,
00726                                            gssize n_bins  ,
00727                                            double* val )
00728 {
00729    eh_require( c );
00730 
00731    if ( c )
00732    {
00733       gssize i;
00734       double *t, *load;
00735       gssize col_len = c->len;
00736 
00737       if ( n_bins <= 0 || start+n_bins>col_len )
00738          n_bins = col_len-start;
00739 
00740       if ( !val )
00741          val = eh_new( double , n_bins );
00742       t = eh_new( double , n_bins );
00743 
00744       load = sed_column_load( c , start , n_bins , NULL );
00745 
00746       t[n_bins-1] = sed_cell_size( c->cell[n_bins-1] );
00747       for ( i=n_bins-2 ; i>=0 ; i-- )
00748          t[i] = t[i+1] + sed_cell_size( c->cell[i] );
00749 
00750       val[n_bins-1] = sed_property_measure( f , c->cell[n_bins-1] , load[n_bins-1] ); // this used to be load[i] (now load[n_bins-1])
00751       for ( i=n_bins-2 ; i>=0 ; i-- )
00752          val[i] = ( val[i+1]*t[i+1] + sed_property_measure( f , c->cell[i] , load[i] )*(t[i]-t[i+1]) ) / t[i];
00753 
00754       eh_free( t    );
00755       eh_free( load );
00756    }
00757    else
00758       val = NULL;
00759 
00760    return val;
00761 }
00762 
00789 double* sed_column_avg_property( Sed_property f , 
00790                                  Sed_column c   ,
00791                                  gssize start   ,
00792                                  gssize n_bins  ,
00793                                  double* val )
00794 {
00795    eh_require( c );
00796 
00797    if ( c )
00798    {
00799       gssize i;
00800       double *t;
00801       gssize col_len = c->len;
00802 
00803       if ( n_bins <= 0 || start+n_bins>col_len )
00804          n_bins = col_len-start;
00805 
00806       if ( !val )
00807          val = eh_new( double , n_bins );
00808       t = eh_new( double , n_bins );
00809 
00810       t[n_bins-1] = sed_cell_size( c->cell[n_bins-1] );
00811       for ( i=n_bins-2 ; i>=0 ; i-- )
00812          t[i] = t[i+1] + sed_cell_size( c->cell[i] );
00813 
00814       val[n_bins-1] = sed_property_measure( f , c->cell[n_bins-1] );
00815       for ( i=n_bins-2 ; i>=0 ; i-- )
00816          val[i] = (   val[i+1]*t[i+1] 
00817                     + sed_property_measure( f , c->cell[i] )
00818                     * (t[i]-t[i+1]) ) 
00819                   / t[i];
00820 
00821       eh_free( t );
00822    }
00823    else
00824       val = NULL;
00825 
00826    return val;
00827 }
00828 
00852 double* sed_column_at_property( Sed_property f ,
00853                                 Sed_column c   ,
00854                                 gssize start   ,
00855                                 gssize n_bins  ,
00856                                 double* val )
00857 {
00858    eh_require( c );
00859 
00860    if ( c )
00861    {
00862       gssize i;
00863       gssize col_len = c->len;
00864 
00865       if ( n_bins <= 0 || start+n_bins>col_len )
00866          n_bins = col_len-start;
00867 
00868       if ( !val )
00869          val = eh_new( double , n_bins );
00870 
00871       for ( i=n_bins-1 ; i>=0 ; i-- )
00872          val[i] = sed_property_measure( f , c->cell[i] );
00873    }
00874    else
00875       val = NULL;
00876 
00877    return val;
00878 }
00879 
00887 double sed_column_load_at( const Sed_column s , gssize n )
00888 {
00889    double load_0 = 0;
00890 
00891    eh_require( s );
00892    eh_require( n>=0 );
00893 
00894    if ( s )
00895    {
00896       gssize i, col_len = s->len;
00897 
00898       eh_lower_bound( n , 0 );
00899       for ( i=col_len-1 ; i>=n; i--)
00900          load_0 += sed_cell_load( s->cell[i] );
00901    }
00902 
00903    return load_0;
00904 }
00905 
00921 double sed_column_property_0( Sed_property f, const Sed_column c )
00922 {
00923    double val = 0;
00924 
00925    eh_require( c );
00926 
00927    if ( c )
00928    {
00929       gssize i;
00930       gssize len = sed_column_len( c );
00931 
00932       for ( i=0 ; i<len ; i++ )
00933       {
00934          val += sed_property_measure( f , c->cell[i] )
00935               * sed_cell_size( c->cell[i] );
00936       }
00937 
00938       val /= sed_column_thickness(c);
00939    }
00940 
00941    return val;
00942 }
00943 
00959 double sed_column_property( Sed_property f ,
00960                             const Sed_column s )
00961 {
00962    double val = 0;
00963 
00964    eh_require( s )
00965 
00966    if ( s )
00967    {
00968       gssize i;
00969       gssize len = sed_column_len( s );
00970       double* load = eh_new( double , len );
00971 
00972       if ( sed_property_n_args(f)==2 )
00973       {
00974 
00975          if (    sed_property_is_named( f , "consolidation" )
00976               || sed_property_is_named( f , "consolidation rate" ) )
00977          {
00978             double extra_arg = sed_column_age( s );
00979 
00980             for ( i=0 ; i<len ; i++ )
00981             {
00982                val += sed_property_measure( f , s->cell[i] , extra_arg )
00983                     * sed_cell_size(s->cell[i]);
00984             }
00985          }
00986          else
00987          {
00988             double* extra_arg = sed_column_load( s , 0 , sed_column_len(s) , NULL );
00989 
00990             for ( i=0 ; i<len ; i++ )
00991             {
00992                val += sed_property_measure( f , s->cell[i] , extra_arg[i] )
00993                     * sed_cell_size(s->cell[i]);
00994             }
00995          }
00996       }
00997       else
00998       {
00999          for ( i=0 ; i<len ; i++ )
01000          {
01001             val += sed_property_measure( f , s->cell[i] )
01002                  * sed_cell_size(s->cell[i]);
01003          }
01004       }
01005 
01006       val /= sed_column_thickness(s);
01007 
01008       eh_free( load );
01009    }
01010 
01011    return val;
01012 }
01013 
01028 Sed_column
01029 sed_column_resize_cell( Sed_column s , gssize i , double new_t )
01030 {
01031    eh_require( s );
01032 
01033    if ( s && sed_column_is_get_index(s,i) )
01034    {
01035       double old_t = sed_cell_size(s->cell[i]);
01036 
01037       eh_lower_bound( new_t , 0 );
01038 
01039       sed_cell_resize( s->cell[i] , new_t );
01040       sed_column_set_thickness( s , sed_column_thickness(s) + new_t-old_t );
01041    }
01042 
01043    return s;
01044 }
01045 
01061 Sed_column sed_column_compact_cell( Sed_column s , gssize i , double new_t )
01062 {
01063    eh_require( s )
01064 
01065    if ( s && sed_column_is_get_index(s,i) )
01066    {
01067       double old_t = sed_cell_size( s->cell[i] );
01068       sed_cell_compact( s->cell[i] , new_t );
01069       sed_column_set_thickness( s , sed_column_thickness(s) + new_t - old_t );
01070    }
01071 
01072    return s;
01073 }
01074 
01090 double sed_column_add_cell_real( Sed_column col ,
01091                                  Sed_cell cell  ,
01092                                  gboolean update_pressure )
01093 {
01094    double amount_to_add = 0;
01095 
01096    eh_require( col  );
01097    eh_require( cell );
01098 
01099    if ( col && cell && !sed_cell_is_empty(cell) )
01100    {
01101       Sed_cell copy = sed_cell_dup( cell );
01102       Sed_cell top_cell;
01103       double free_space, left_to_add;
01104       double cell_load;
01105 
01106       amount_to_add = sed_cell_size( cell );
01107       left_to_add   = sed_cell_size( cell );
01108 
01109       if ( update_pressure )
01110       {
01111          gssize i;
01112          gssize len = sed_column_len( col );
01113 
01114          cell_load = sed_cell_load( cell );
01115 
01116          for ( i=0 ; i<len ; i++ )
01117             sed_cell_set_pressure( col->cell[i] ,
01118                                    sed_cell_pressure( col->cell[i] )
01119                                    + cell_load );
01120       }
01121 
01122       if ( sed_column_is_empty(col) )
01123       {
01124          top_cell = sed_column_nth_cell(col,0);
01125          sed_column_resize( col , 1 );
01126          col->len++;
01127       }
01128       else
01129          top_cell = sed_column_top_cell(col);
01130 
01131       while ( left_to_add > 0 )
01132       {
01133          // Determine how much sediment we need to fill up the next cell.
01134          free_space = sed_column_z_res( col ) - sed_cell_size( top_cell );
01135          if ( free_space <= 1e-12 )
01136          {
01137             // Add another cell.
01138             sed_column_resize( col , col->len+1 );
01139             col->len++;
01140          }
01141          else
01142          {
01143             if ( free_space >= left_to_add )
01144                free_space = left_to_add;
01145             sed_cell_resize(cell,free_space);
01146             sed_cell_add( top_cell , cell );
01147             sed_column_set_thickness(col,sed_column_thickness(col)+free_space);
01148 
01149             left_to_add -= free_space;
01150 
01151             if ( update_pressure )
01152             {
01153                sed_cell_resize( cell , left_to_add );
01154                cell_load = sed_cell_load( cell );
01155                sed_cell_set_pressure( top_cell ,
01156                                       cell_load
01157                                       + sed_column_water_pressure( col ) );
01158             }
01159          }
01160 
01161          top_cell = sed_column_top_cell(col);
01162       }
01163       sed_cell_copy( cell , copy );
01164       sed_cell_destroy( copy );
01165    }
01166 
01167    return amount_to_add;
01168 }
01169 
01184 double sed_column_add_cell( Sed_column col , Sed_cell cell  )
01185 {
01186    return sed_column_add_cell_real( col , cell , FALSE );
01187 }
01188 
01203 double sed_column_add_cell_avg_pressure( Sed_column col , Sed_cell cell  )
01204 {
01205    return sed_column_add_cell_real( col , cell , FALSE );
01206 }
01207 
01219 double sed_column_add_vec( Sed_column c , const double* t )
01220 {
01221    double rtn = 0;
01222 
01223    eh_require( c );
01224    eh_require( t );
01225 
01226    if ( c && t )
01227    {
01228       Sed_cell cell = sed_cell_new( sed_sediment_env_n_types() );
01229 
01230       sed_cell_add_amount( cell , t );
01231       rtn = sed_column_add_cell( c , cell );
01232 
01233       sed_cell_destroy( cell );
01234    }
01235    return rtn;
01236 }
01237 
01244 Sed_cell
01245 sed_column_top_cell( const Sed_column col )
01246 {
01247    Sed_cell top = NULL;
01248 
01249    if ( !sed_column_is_empty(col) )
01250       top = col->cell[col->len-1];
01251 
01252    return top;
01253 }
01254 
01265 Sed_cell
01266 sed_column_nth_cell( const Sed_column col , gssize n )
01267 {
01268    Sed_cell cell = NULL;
01269 
01270    eh_return_val_if_fail( col , NULL );
01271 
01272    if ( sed_column_is_set_index(col,n) )
01273       cell = col->cell[n];
01274 
01275    return cell;
01276 }
01277 
01289 Sed_column
01290 sed_column_resize( Sed_column col , gssize n )
01291 {
01292    eh_require( col );
01293 
01294    {
01295       gssize i;
01296 
01297       if ( n > col->size )
01298       {
01299          // Add bins in blocks of S_ADDBINS
01300          gssize add_bins = ((n-col->size)/S_ADDBINS+1)*S_ADDBINS;
01301          gssize new_size = col->size + add_bins;
01302 
01303          if ( col->cell ) col->cell = eh_renew( Sed_cell , col->cell , col->size+add_bins );
01304          else             col->cell = eh_new  ( Sed_cell             , col->size+add_bins );
01305 
01306          for ( i=col->size ; i<new_size ; i++ )
01307             col->cell[i] = sed_cell_new_env();
01308          col->size += add_bins;
01309       }
01310       else
01311       {
01312          for ( i=n ; i<col->size ; i++ )
01313             sed_cell_clear( col->cell[i] );
01314       }
01315    }
01316 
01317    return col;
01318 }
01319 
01335 Sed_cell
01336 sed_column_extract_top_cell( Sed_column col ,
01337                              double f       ,
01338                              Sed_cell dest )
01339 {
01340    eh_require( col );
01341    eh_require( f<=1 );
01342    eh_require( f>=0 );
01343 
01344    eh_clamp( f , 0 , 1 );
01345 
01346    if ( col && !sed_column_is_empty(col) )
01347    {
01348       Sed_cell top_cell = sed_column_top_cell(col);
01349 
01350       dest = sed_cell_copy( dest , top_cell );
01351 
01352       sed_cell_resize( dest , sed_cell_size(dest)*f );
01353       sed_column_remove_top_cell( col , f );
01354    }
01355    else
01356       dest = NULL;
01357 
01358    return dest;
01359 }
01360 
01371 Sed_column
01372 sed_column_remove_top_cell( Sed_column col , double f )
01373 {
01374    eh_require( col );
01375    eh_require( f<=1 );
01376    eh_require( f>=0 );
01377 
01378    eh_clamp( f , 0 , 1 );
01379 
01380    if ( col && !sed_column_is_empty(col) )
01381    {
01382       Sed_cell top_cell = sed_column_top_cell(col);
01383       sed_column_set_thickness( col ,
01384                                   sed_column_thickness(col)
01385                                 - f*sed_cell_size(top_cell) );
01386       sed_cell_resize( top_cell , sed_cell_size(top_cell)*(1.-f) );
01387 
01388       if ( sed_cell_size(top_cell) < 1e-12 )
01389       {
01390          sed_cell_clear( top_cell );
01391          (col->len)--;
01392          if ( col->len<0 )
01393             eh_require_not_reached();
01394       }
01395    }
01396 
01397    return col;
01398 }
01399 
01415 Sed_cell
01416 sed_column_extract_top( Sed_column col ,
01417                         double     t   ,
01418                         Sed_cell   dest )
01419 {
01420    return sed_column_extract_top_fill( col , t , NULL , dest );
01421 }
01422 
01423 Sed_cell sed_column_extract_top_fill( Sed_column col ,
01424                                       double t       ,
01425                                       Sed_cell fill  ,
01426                                       Sed_cell dest )
01427 {
01428    eh_require( col );
01429 
01430    if ( !dest )
01431       dest = sed_cell_new( sed_sediment_env_n_types() );
01432    else
01433       sed_cell_clear( dest );
01434 
01435    if ( fill )
01436       sed_cell_resize( fill , G_MINDOUBLE );
01437 
01438    if ( t>0 )
01439    {
01440       double left_to_remove, available_sediment;
01441       double f;
01442       Sed_cell cell_temp, top_cell;
01443       gboolean more_to_remove = FALSE;
01444    
01445       cell_temp = sed_cell_new_env();
01446       left_to_remove = t;
01447 
01448       if ( left_to_remove>0 )
01449          more_to_remove = TRUE;
01450 
01451       while ( !sed_column_is_empty(col) && more_to_remove )
01452       {
01453          top_cell = sed_column_top_cell(col);
01454          available_sediment = sed_cell_size( top_cell );
01455          if ( available_sediment > left_to_remove )
01456          {
01457             f = left_to_remove/available_sediment;
01458             more_to_remove = FALSE;
01459          }
01460          else 
01461             f = 1.0;
01462          sed_column_extract_top_cell( col , f , cell_temp );
01463          sed_cell_add( dest , cell_temp );
01464          left_to_remove -= sed_cell_size( cell_temp );
01465       }
01466 
01467       if ( fill && fabs( sed_cell_size(dest) - t ) > 1e-12 )
01468       {
01469          double dh = t - sed_cell_size(dest);
01470 
01471          if ( dh > 0 )
01472          {
01473             eh_require( col->t < 1e-12 );
01474 
01475             if ( !(col->t < 1e-12) )
01476             {
01477                eh_watch_dbl( col->t );
01478                eh_watch_dbl( t );
01479                eh_watch_dbl( sed_cell_size(dest) );
01480             }
01481 
01482             sed_cell_resize( fill , dh );
01483             sed_column_adjust_base_height( col , -dh );
01484             col->z -= dh;
01485             sed_cell_add( dest , fill );
01486          }
01487       }
01488 
01489       sed_cell_destroy( cell_temp );
01490    }
01491 
01492    return dest;
01493 }
01494 
01505 Sed_column
01506 sed_column_remove_top( Sed_column col , double t )
01507 {
01508    eh_require( col );
01509 
01510    if ( col && t>0 && !sed_column_is_empty(col) )
01511    {
01512       Sed_cell top_cell;
01513       double left_to_remove, available_sediment;
01514       double f;
01515       gboolean more_to_remove = FALSE;
01516    
01517       left_to_remove = t;
01518 
01519       if ( left_to_remove>0 )
01520          more_to_remove = TRUE;
01521 
01522       while ( !sed_column_is_empty(col) && more_to_remove )
01523       {
01524          top_cell = sed_column_top_cell(col);
01525          available_sediment = sed_cell_size( top_cell );
01526          if ( available_sediment >= left_to_remove )
01527          {
01528             f = left_to_remove/available_sediment;
01529             more_to_remove = FALSE;
01530          }
01531          else 
01532             f = 1.0;
01533          sed_column_remove_top_cell(col,f);
01534          left_to_remove -= f*available_sediment;
01535       }
01536    }
01537 
01538    return col;
01539 }
01540 
01541 Sed_column sed_column_remove_top_erode( Sed_column col , double t )
01542 {
01543    eh_require( col );
01544 
01545    if ( col )
01546    {
01547       double erode = t - sed_column_thickness(col);
01548 
01549       sed_column_remove_top( col , t );
01550 
01551       if ( erode>0 )
01552       {
01553          col->z -= erode;
01554       }
01555    }
01556 
01557    return col;
01558 }
01559 
01560 Sed_cell sed_column_separate_top( Sed_column col  ,
01561                                   double t        ,
01562                                   double f[]      ,
01563                                   Sed_cell rem_cell )
01564 {
01565    Sed_cell lag_cell = sed_cell_new( sed_sediment_env_n_types() );
01566 
01567    sed_column_extract_top    ( col      , t        , lag_cell );
01568    sed_cell_separate_fraction( lag_cell , f        , rem_cell );
01569    sed_column_add_cell       ( col      , lag_cell            );
01570    sed_cell_destroy          ( lag_cell                       );
01571 
01572    return rem_cell;
01573 }
01574 
01575 Sed_cell sed_column_separate_top_amounts( Sed_column col ,
01576                                           double total_t ,
01577                                           double t[]     ,
01578                                           Sed_cell rem_cell )
01579 {
01580    Sed_cell lag_cell = sed_cell_new( sed_sediment_env_n_types() );
01581 
01582    sed_column_extract_top  ( col      , total_t  , lag_cell );
01583    sed_cell_separate_amount( lag_cell , t        , rem_cell );
01584    sed_column_add_cell     ( col      , lag_cell            );
01585    sed_cell_destroy        ( lag_cell );
01586 
01587    return rem_cell;
01588 }
01589 
01590 Sed_cell sed_column_separate_top_amounts_fill( Sed_column col ,
01591                                                double total_t ,
01592                                                double t[]     ,
01593                                                Sed_cell fill  ,
01594                                                Sed_cell rem_cell )
01595 {
01596    Sed_cell lag_cell;
01597 //   double m_0 = sed_column_mass(col);
01598 //   double t_0 = sed_column_thickness(col);
01599 //   gssize len_0 = col->len;
01600 //   double m_1, t_1;
01601 
01602    lag_cell = sed_cell_new_env( );
01603    sed_column_extract_top_fill( col , total_t , fill , lag_cell );
01604    sed_cell_separate_amount( lag_cell , t , rem_cell );
01605    sed_column_add_cell( col , lag_cell );
01606    sed_cell_destroy( lag_cell );
01607 /*
01608    m_1 = sed_column_mass(col);
01609 //   if ( fill && fabs(m_1+sed_cell_mass(rem_cell)-(m_0+sed_cell_mass(fill)) )/m_0 > 1e-5 )
01610    if ( fabs(m_1+sed_cell_mass(rem_cell)-m_0 )/m_0 > 1e-5 )
01611 {
01612    t_1 = sed_column_thickness(col);
01613 eh_watch_int( len_0 );
01614 eh_watch_int( col->len );
01615 eh_watch_dbl( t_0 );
01616 eh_watch_dbl( t_1 );
01617 eh_watch_dbl( m_0 );
01618 eh_watch_dbl( m_1 );
01619 eh_watch_dbl( sed_cell_mass(rem_cell) );
01620 //eh_watch_dbl( sed_cell_mass(fill) );
01621 eh_watch_dbl( total_t );
01622 eh_dbl_array_fprint( stderr , t , sed_sediment_env_n_types() );
01623       exit(0);
01624 }
01625 */
01626    return rem_cell;
01627 }
01628 
01645 Sed_cell sed_column_top( const Sed_column col ,
01646                          double t             ,
01647                          Sed_cell dest )
01648 {
01649    eh_return_val_if_fail( col , NULL );
01650 
01651    if ( !dest )
01652       dest = sed_cell_new( sed_sediment_env_n_types() );
01653    sed_cell_clear( dest );
01654 
01655    if ( !sed_column_is_empty(col) )
01656    {
01657       Sed_cell next_cell;
01658       double left_to_get, available_sediment;
01659       int next_ind;
01660 
01661       left_to_get = t;
01662 
01663       next_ind = sed_column_len( col )-1;
01664       while ( left_to_get > 1e-12 && next_ind >= 0 )
01665       {
01666          next_cell = sed_column_nth_cell( col , next_ind );
01667          available_sediment = sed_cell_size( next_cell );
01668 
01669          if ( available_sediment > left_to_get )
01670          {
01671             sed_cell_resize( next_cell , left_to_get        );
01672             sed_cell_add   ( dest      , next_cell          );
01673             sed_cell_resize( next_cell , available_sediment );
01674 
01675             left_to_get = 0.;
01676          }
01677          else
01678          {
01679             sed_cell_add( dest , next_cell );
01680             left_to_get -= available_sediment;
01681          }
01682          next_ind--;
01683       }
01684    }
01685 
01686    return dest;
01687 }
01688 
01702 double sed_column_top_property_0( Sed_property property ,
01703                                 const Sed_column s    ,
01704                                 double top )
01705 {
01706    double val = 0;
01707 
01708    eh_require( s );
01709 
01710    if ( s )
01711    {
01712       Sed_cell avg;
01713 
01714       avg = sed_cell_new( sed_sediment_env_n_types() );
01715 
01716       avg = sed_column_top( s , top , avg );
01717       val = sed_property_measure( property , avg );
01718 
01719       sed_cell_destroy( avg );
01720    }
01721 
01722    return val;
01723 }
01724 
01739 double sed_column_top_property( Sed_property property , const Sed_column s , double top )
01740 {
01741    double val;
01742 
01743    eh_return_val_if_fail( s        , 0 );
01744    eh_return_val_if_fail( property , 0 );
01745 
01746    {
01747       Sed_cell avg = sed_column_top( s , top , NULL );
01748 
01749       if ( sed_property_n_args(property)==2 )
01750       {
01751          double extra_arg;
01752          if (    sed_property_is_named( property , "consolidation" )
01753               || sed_property_is_named( property , "consolidation rate" ) )
01754             extra_arg = sed_column_age( s );
01755          else
01756             extra_arg = sed_cell_load( avg );
01757          val  = sed_property_measure( property , avg , extra_arg );
01758       }
01759       else
01760          val  = sed_property_measure( property , avg );
01761 
01762 
01763       sed_cell_destroy( avg );
01764    }
01765 
01766    return val;
01767 }
01768 
01779 double sed_column_top_rho( const Sed_column s , double top )
01780 {
01781    double rho = 0.;
01782 
01783    eh_return_val_if_fail( s , 0. );
01784 
01785    {
01786       Sed_cell avg;
01787 
01788       avg = sed_cell_new( sed_sediment_env_n_types() );
01789 
01790       avg = sed_column_top(s,top,avg);
01791       rho = sed_cell_density( avg );
01792 
01793       sed_cell_destroy(avg);
01794    }
01795 
01796    return rho;
01797 }
01798 
01809 double sed_column_top_age( const Sed_column s , double top )
01810 {
01811    double age = 0;
01812 
01813    eh_require( s );
01814 
01815    if ( s )
01816    {
01817       Sed_cell avg;
01818 
01819       avg = sed_cell_new( sed_sediment_env_n_types() );
01820       sed_column_top(s,top,avg);
01821       age = sed_cell_age(avg);
01822       sed_cell_destroy(avg);
01823    }
01824 
01825    return age;
01826 }
01827 
01839 gssize
01840 sed_column_top_nbins( Sed_column s , double z )
01841 {
01842    gssize n_bins = 0;
01843 
01844    eh_require( s );
01845 
01846    if ( s && !sed_column_is_empty(s) )
01847    {
01848       double t = z - sed_column_base_height( s );
01849 
01850       if ( t>0 )
01851       {
01852          gssize ind_bot = sed_column_index_thickness( s , t );
01853          gssize ind_top = s->len;
01854          n_bins = ind_top - ind_bot;
01855       }
01856       else
01857          n_bins = s->len;
01858    }
01859 
01860    return n_bins;
01861 }
01862 
01870 gssize sed_column_index_at( const Sed_column s , double z )
01871 {
01872    eh_return_val_if_fail( s , -1 );
01873 
01874    return sed_column_index_thickness( s , z - sed_column_base_height(s) );
01875 }
01876 
01884 gssize sed_column_write( FILE* fp , const Sed_column s )
01885 {
01886    return sed_column_write_to_byte_order( fp , s , G_BYTE_ORDER );
01887 }
01888 
01889 gssize sed_column_write_to_byte_order( FILE* fp , const Sed_column s , gint order )
01890 {
01891    gssize n = 0;
01892 
01893    if ( s && fp )
01894    {
01895       if ( order == G_BYTE_ORDER )
01896       {
01897          gssize i;
01898          gint32 len  = s->len;
01899          gint32 size = s->size;
01900 
01901          n += fwrite( &(s->z)    , sizeof(double) , 1 , fp );
01902          n += fwrite( &(s->t)    , sizeof(double) , 1 , fp );
01903          n += fwrite( &(len)     , sizeof(gint32) , 1 , fp );
01904          n += fwrite( &(size)    , sizeof(gint32) , 1 , fp );
01905          n += fwrite( &(s->dz)   , sizeof(double) , 1 , fp );
01906          n += fwrite( &(s->x)    , sizeof(double) , 1 , fp );
01907          n += fwrite( &(s->y)    , sizeof(double) , 1 , fp );
01908          n += fwrite( &(s->age)  , sizeof(double) , 1 , fp );
01909          n += fwrite( &(s->sl)   , sizeof(double) , 1 , fp );
01910 
01911          for ( i=0 ; i<s->size ; i++ )
01912             n += sed_cell_write( fp , s->cell[i] );
01913       }
01914       else
01915       {
01916          gssize i;
01917          gint32 len  = s->len;
01918          gint32 size = s->size;
01919 
01920          n += eh_fwrite_dbl_swap  ( &(s->z)    , sizeof(double) , 1 , fp );
01921          n += eh_fwrite_dbl_swap  ( &(s->t)    , sizeof(double) , 1 , fp );
01922          n += eh_fwrite_int32_swap( &(len)     , sizeof(gint32) , 1 , fp );
01923          n += eh_fwrite_int32_swap( &(size)    , sizeof(gint32) , 1 , fp );
01924          n += eh_fwrite_dbl_swap  ( &(s->dz)   , sizeof(double) , 1 , fp );
01925          n += eh_fwrite_dbl_swap  ( &(s->x)    , sizeof(double) , 1 , fp );
01926          n += eh_fwrite_dbl_swap  ( &(s->y)    , sizeof(double) , 1 , fp );
01927          n += eh_fwrite_dbl_swap  ( &(s->age)  , sizeof(double) , 1 , fp );
01928          n += eh_fwrite_dbl_swap  ( &(s->sl)   , sizeof(double) , 1 , fp );
01929 
01930          for ( i=0 ; i<s->size ; i++ )
01931             n += sed_cell_write_to_byte_order( fp , s->cell[i] , order );
01932       }
01933    }
01934 
01935    return n;
01936 }
01937 
01944 Sed_column sed_column_read( FILE* fp )
01945 {
01946    Sed_column s = NULL;
01947 
01948    eh_require( fp );
01949 
01950    if ( fp )
01951    {
01952       gssize i;
01953       gint32 len;
01954       gint32 size;
01955 
01956       NEW_OBJECT( Sed_column , s );
01957 
01958       fread( &(s->z)    , sizeof(double) , 1 , fp );
01959       fread( &(s->t)    , sizeof(double) , 1 , fp );
01960       fread( &(len)     , sizeof(gint32) , 1 , fp );
01961       fread( &(size)    , sizeof(gint32) , 1 , fp );
01962       fread( &(s->dz)   , sizeof(double) , 1 , fp );
01963       fread( &(s->x)    , sizeof(double) , 1 , fp );
01964       fread( &(s->y)    , sizeof(double) , 1 , fp );
01965       fread( &(s->age)  , sizeof(double) , 1 , fp );
01966       fread( &(s->sl)   , sizeof(double) , 1 , fp );
01967 
01968       s->len  = len;
01969       s->size = size;
01970 
01971       s->cell = eh_new( Sed_cell , s->size );
01972       for ( i=0 ; i<s->size ; i++ )
01973          s->cell[i] = sed_cell_read( fp );
01974    }
01975 
01976    return s;
01977 }
01978 
01993 Sed_column
01994 sed_column_height_copy( const Sed_column src ,
01995                         double z             ,
01996                         Sed_column dest )
01997 {
01998    eh_return_val_if_fail( src , NULL );
01999 
02000    {
02001       gssize bins_to_extract, start;
02002       double t       = z - sed_column_base_height(src);
02003 
02004       start = sed_column_index_thickness( src , t );
02005       bins_to_extract = sed_column_len(src) - start;
02006 
02007       if ( !dest )
02008          dest = sed_column_new( 1 );
02009       sed_column_copy_public_data( dest , src );
02010 
02011       sed_column_set_base_height( dest , z );
02012 
02013       if ( bins_to_extract > 0 )
02014       {
02015          gssize i;
02016          double dh;
02017 
02018          dh = sed_column_thickness_index( src , start )
02019             - ( z - sed_column_base_height(src) );
02020 
02021          if ( dh>0 )
02022          {
02023             sed_column_stack_cell( dest , src->cell[start] );
02024             sed_cell_resize( dest->cell[0] , dh );
02025          }
02026 
02027          // Add the cells to be extracted.
02028          for ( i=1 ; i<bins_to_extract ; i++ )
02029             sed_column_stack_cell( dest , src->cell[start+i] );
02030 
02031       }
02032    }
02033 
02034    return dest;
02035 }
02036 
02046 Sed_column sed_column_chomp( Sed_column col , double bottom )
02047 {
02048    eh_return_val_if_fail( col , NULL );
02049 
02050    if ( bottom > sed_column_base_height(col) )
02051    {
02052       Sed_column new_col = sed_column_height_copy( col , bottom , NULL );
02053       sed_column_copy( col , new_col );
02054       sed_column_destroy( new_col );
02055    }
02056 
02057    return col;
02058 }
02059 
02069 Sed_column
02070 sed_column_chop( Sed_column col , double top )
02071 {
02072    eh_return_val_if_fail( col , NULL );
02073 
02074    if ( top < sed_column_top_height(col) )
02075    {
02076       double top_t = sed_column_top_height( col ) - top;
02077 
02078       sed_column_remove_top( col , top_t );
02079 
02080       if ( top < sed_column_base_height( col ) )
02081          sed_column_set_base_height( col , top );
02082    }
02083 
02084    return col;
02085 }
02086 
02099 Sed_column sed_column_strip( Sed_column col , double bottom , double top )
02100 {
02101    return sed_column_chop( sed_column_chomp( col , bottom ) , top );
02102 }
02103 
02114 double sed_column_water_depth( const Sed_column col )
02115 {
02116    return sed_column_sea_level(col) - sed_column_top_height(col);
02117 }
02118 
02125 int sed_get_column_size(const Sed_column col)
02126 {
02127    return col->len;
02128 }
02129 
02130 gssize sed_column_len( const Sed_column col )
02131 {
02132    eh_return_val_if_fail( col , 0 );
02133    return col->len;
02134 }
02135 
02136 gboolean
02137 sed_column_is_empty( const Sed_column col )
02138 {
02139    eh_return_val_if_fail( col , TRUE );
02140    return col->len==0;
02141 }
02142 
02145 gboolean sed_column_is_valid_index( const Sed_column c , gssize n )
02146 {
02147    eh_return_val_if_fail( c , FALSE );
02148    return n>=0 && n<c->size;
02149 }
02150 
02153 gboolean sed_column_is_get_index( const Sed_column c , gssize n )
02154 {
02155    eh_return_val_if_fail( c , FALSE );
02156    return n>=0 && n<c->len;
02157 }
02158 
02161 gboolean sed_column_is_set_index( const Sed_column c , gssize n )
02162 {
02163    eh_return_val_if_fail( c , FALSE );
02164    return n>=0 && n<=c->len;
02165 }
02166 
02173 gssize
02174 sed_column_top_index( const Sed_column col )
02175 {
02176    eh_return_val_if_fail( col , -1 );
02177    return col->len-1;
02178 }
02179 
02186 double
02187 sed_column_thickness( const Sed_column col)
02188 {
02189    eh_return_val_if_fail( col , 0 );
02190    return col->t;
02191 }
02192 
02200 Sed_column sed_column_set_thickness( Sed_column col , double new_t )
02201 {
02202    col->t = new_t;
02203    return col;
02204 }
02205 
02206 gboolean sed_column_size_is( const Sed_column col , double t )
02207 
02208 {
02209    return eh_compare_dbl( col->t , t , 1e-12 );
02210 }
02211 
02212 gboolean sed_column_mass_is( const Sed_column c , double m )
02213 {
02214    return eh_compare_dbl( sed_column_mass(c) , m , 1e-12 );
02215 }
02216 
02217 gboolean sed_column_sediment_mass_is( const Sed_column c , double m )
02218 {
02219    return eh_compare_dbl( sed_column_sediment_mass(c) , m , 1e-12 );
02220 }
02221 
02222 gboolean sed_column_base_height_is( const Sed_column c , double z )
02223 {
02224    return eh_compare_dbl( sed_column_base_height(c) , z , 1e-12 );
02225 }
02226 
02227 gboolean sed_column_top_height_is( const Sed_column c , double z )
02228 {
02229    return eh_compare_dbl( sed_column_top_height(c) , z , 1e-12 );
02230 }
02231 
02240 double sed_column_thickness_index( const Sed_column col , gssize ind )
02241 {
02242    double t=0;
02243 
02244    eh_return_val_if_fail( col , 0 );
02245 
02246    {
02247       gssize i;
02248       gssize top_ind = ind+1;
02249 
02250       eh_clamp( top_ind , 0 , sed_column_len(col) );
02251 
02252       for ( i=0 ; i<top_ind ; i++ )
02253          t += sed_cell_size( col->cell[i] );
02254    }
02255 
02256    return t;
02257 }
02258 
02267 double sed_column_depth_age( const Sed_column col , double age )
02268 {
02269    double d = 0;
02270 
02271    eh_require( col );
02272 
02273    if ( col )
02274    {
02275       gssize i;
02276       for ( i=col->len-1 ; i>=0 && sed_cell_age(col->cell[i])>age ; i--)
02277          d += sed_cell_size( col->cell[i] );
02278    }
02279    
02280    return d;
02281 }
02282 
02291 gssize sed_column_index_thickness( const Sed_column col , double t )
02292 {
02293    gssize i = -1;
02294 
02295    eh_return_val_if_fail( col , -1 );
02296 
02297    if ( t>sed_column_thickness(col)*.5 )
02298       i = sed_column_index_depth( col , sed_column_thickness(col)-t );
02299    else
02300    {
02301       double total_t = 0;
02302 
02303       eh_lower_bound( t , 0 );
02304 
02305       for ( i=0 ; total_t<t && i<col->len ; i++)
02306          total_t += sed_cell_size( col->cell[i] );
02307 
02308       i -= 1;
02309    }
02310 
02311    return i;
02312 }
02313 
02321 gssize
02322 sed_column_index_depth( const Sed_column col , double d )
02323 {
02324    gssize i;
02325 
02326    eh_return_val_if_fail( col , -1 );
02327 
02328    if ( d>=sed_column_thickness(col)*.5 )
02329       i = sed_column_index_thickness( col , sed_column_thickness(col)-d );
02330    else
02331    {
02332       double total_d = 0;
02333 
02334       eh_lower_bound( d , 0 );
02335 
02336       for ( i=col->len-1 ; total_d<=d && i>=0 ; i--)
02337          total_d += sed_cell_size( col->cell[i] );
02338 
02339       i += 1;
02340    }
02341 
02342    return i;
02343 }
02344 
02355 Sed_cell sed_cell_add_column( Sed_cell dest , const Sed_column src )
02356 {
02357    eh_return_val_if_fail(src,NULL);
02358 
02359    {
02360       gssize i;
02361 
02362       if ( !dest )
02363          dest = sed_cell_new( sed_sediment_env_n_types() );
02364 
02365       for ( i=0 ; i<src->len ; i++ )
02366          sed_cell_add( dest , src->cell[i] );
02367    }
02368 
02369    return dest;
02370 }
02371 
02383 Sed_column
02384 sed_column_add( Sed_column dest , const Sed_column src )
02385 {
02386    eh_return_val_if_fail( src , NULL );
02387 
02388    if ( src )
02389    {
02390       gssize i;
02391       if ( !dest )
02392          dest = sed_column_new( src->size );
02393       for ( i=0 ; i<src->len ; i++ )
02394          sed_column_add_cell( dest , src->cell[i] );
02395    }
02396 
02397    return dest;
02398 }
02399 
02400 Sed_column
02401 sed_column_append( Sed_column dest , const Sed_column src )
02402 {
02403    eh_require( src );
02404 
02405    if ( src )
02406    {
02407       gssize i;
02408       for ( i=0 ; i<src->len ; i++ )
02409          sed_column_stack_cell( dest , src->cell[i] );
02410    }
02411    else
02412       dest = NULL;
02413 
02414    return dest;
02415 }
02416 
02417 Sed_column sed_column_remove( Sed_column s1 , const Sed_column s2 )
02418 {
02419    eh_return_val_if_fail( s1 , NULL );
02420    eh_return_val_if_fail( s2 , NULL );
02421 
02422    {
02423       double d = sed_column_top_height(s1) - sed_column_base_height( s2 );
02424 
02425       if ( d > 0 )
02426       {
02427          sed_column_remove_top( s1 , d );
02428          if ( sed_column_is_empty(s1) )
02429             sed_column_set_base_height(s1,sed_column_base_height(s2));
02430       }
02431    }
02432 
02433    return s1;
02434 }
02435 
02442 Sed_column sed_column_rebin( Sed_column col )
02443 {
02444    eh_require( col );
02445 
02446    if ( col )
02447    {
02448       gssize i;
02449       Sed_column col_temp;
02450 
02451       // Create a temporary sediment column that is a copy of the old one.
02452       col_temp = sed_column_new( col->size );
02453       sed_column_copy( col_temp , col );
02454 
02455       // Remove all of the sediment from the old one.
02456       sed_column_clear( col );
02457    
02458       // Add each cell from the temporary sediment column back to the
02459       // new one so that the cells will be rebinned with the proper cell
02460       // heights.
02461       for ( i=0 ; i<sed_column_len(col_temp) ; i++ )
02462          sed_column_add_cell_avg_pressure( col , col_temp->cell[i] ); 
02463    
02464       // Destroy the temporary sediment column.
02465       sed_column_destroy( col_temp );
02466    }
02467 
02468    return col;
02469 }
02470 
02471 Sed_cell
02472 sed_column_extract_top_cell_loc( Sed_column col )
02473 {
02474    Sed_cell c = NULL;
02475 
02476    eh_require( col );
02477 
02478    if ( col && !sed_column_is_empty(col) )
02479    {
02480       gint n = sed_column_len(col)-1;
02481 
02482       c = col->cell[n];
02483 
02484       sed_column_set_thickness( col , sed_column_thickness(col) - sed_cell_size(c) );
02485 
02486       col->len -= 1;
02487       if ( col->len<0 )
02488          eh_require_not_reached();
02489    }
02490 
02491    return c;
02492 }
02493 
02494 Sed_cell*
02495 sed_column_extract_cells_above( Sed_column col , double z )
02496 {
02497    Sed_cell* cell_arr = NULL;
02498 
02499    eh_require( col  );
02500 
02501    if ( col && !sed_column_is_empty(col) )
02502    {
02503       gint n_bins = sed_column_top_nbins( col , z );
02504 
02505       if ( n_bins>0 )
02506       {
02507          double dz_bot;
02508          double dz_back;
02509 
02510          cell_arr = sed_column_extract_top_n_cells( col , n_bins );
02511 
02512          eh_require( cell_arr && cell_arr[0] );
02513 
02514          dz_back = z - sed_column_top_height(col);
02515          dz_bot  = sed_cell_size( cell_arr[0] ) - dz_back;
02516 
02517          if ( dz_back>1e-12 )
02518          {
02519 //eh_require( sed_cell_is_valid(cell_arr[0]) );
02520             sed_cell_resize    ( cell_arr[0] , dz_back     );
02521 //eh_require( sed_cell_is_valid(cell_arr[0]) );
02522             sed_column_add_cell( col         , cell_arr[0] );
02523 
02524             if ( dz_bot>1e-12 )
02525 {
02526                sed_cell_resize( cell_arr[0] , dz_bot );
02527 //eh_require( sed_cell_is_valid(cell_arr[0]) );
02528 }
02529             else
02530             {
02531                Sed_cell* c;
02532                sed_cell_destroy( cell_arr[0] );
02533                for ( c=cell_arr ; *c ; c++ ) *c = *(c+1);
02534 //eh_require( sed_cell_is_valid(cell_arr[0]) );
02535             }
02536          }
02537 /*
02538          {
02539                Sed_cell* c;
02540                for ( c=cell_arr ; *c ; c++ )
02541                   if ( !sed_cell_is_valid(*c) || sed_cell_is_empty(*c) || sed_cell_is_clear(*c) )
02542                   {
02543                      sed_cell_fprint( stderr , *c );
02544                      eh_watch_int( n_bins );
02545                      eh_watch_int( g_strv_length( cell_arr ) );
02546                      eh_watch_dbl( dz_back );
02547                      eh_watch_dbl( dz_bot );
02548                      eh_watch_int( c-cell_arr );
02549 sed_cell_array_fprint( stderr , cell_arr );
02550                   }
02551          }
02552 */
02553       }
02554    }
02555 
02556    return cell_arr;
02557 }
02558 
02559 Sed_cell*
02560 sed_column_extract_top_n_cells( Sed_column col , gint n_cells )
02561 {
02562    Sed_cell* cell_arr = NULL;
02563 
02564    eh_require( col  );
02565    eh_require( n_cells>=0 );
02566 
02567    if ( col )
02568    {
02569       eh_clamp( n_cells , 0 , sed_column_len(col) );
02570 
02571       if ( n_cells>0 )
02572       {
02573          gint   n_0 = sed_column_len(col) - n_cells;
02574          double dz  = 0;
02575          gint i, n;
02576 
02577          cell_arr          = eh_new( Sed_cell , n_cells+1 );
02578          cell_arr[n_cells] = NULL;
02579 
02580          for ( i=0,n=n_0 ; i<n_cells ; i++,n++ )
02581          {
02582             dz           += sed_cell_size( col->cell[n] );
02583             cell_arr[i]   = col->cell[n];
02584             col->cell[n]  = sed_cell_new_env();
02585          }
02586 
02587          sed_column_set_thickness( col , sed_column_thickness(col) - dz );
02588          col->len -= n_cells;
02589 
02590          eh_require( col->len>=0 );
02591       }
02592    }
02593 
02594    return cell_arr;
02595 }
02596 
02597 Sed_column
02598 sed_column_stack_cells( Sed_column dest , Sed_cell* src )
02599 {
02600    eh_require( src );
02601 
02602    if ( src )
02603    {
02604       Sed_cell* c;
02605       for ( c=src ; *c ; c++ )
02606       {
02607          sed_column_stack_cell( dest , *c );
02608 if ( sed_cell_is_clear( *c ) )
02609 {
02610    eh_watch_int( c-src );
02611    sed_cell_array_fprint( stderr , src );
02612 }
02613       }
02614    }
02615    else
02616       dest = NULL;
02617 
02618    return dest;
02619 }
02620 
02621 Sed_column
02622 sed_column_stack_cells_loc( Sed_column dest , Sed_cell* src )
02623 {
02624    eh_require( src );
02625 
02626    if ( src )
02627    {
02628       Sed_cell* c;
02629       for ( c=src ; *c ; c++ )
02630 {
02631 if ( !sed_cell_is_valid(*c) || sed_cell_is_empty(*c) || sed_cell_is_clear(*c) )
02632    eh_watch_int( c-src );
02633          sed_column_stack_cell_loc( dest , *c );
02634 }
02635    }
02636    else
02637       dest = NULL;
02638 
02639    return dest;
02640 }
02641 
02642 double
02643 sed_column_stack_cell_real( Sed_column col , Sed_cell cell , gboolean update_pressure )
02644 {
02645    double amount_to_add = 0;
02646 
02647    eh_require( col  );
02648    eh_require( cell );
02649 
02650    if ( col && cell )
02651    {
02652       amount_to_add = sed_cell_size( cell );
02653 
02654       sed_column_resize( col , col->len + 1 );
02655       sed_cell_copy( col->cell[col->len] , cell );
02656       col->len += 1;
02657 
02658       sed_column_set_thickness( col , sed_column_thickness(col)+sed_cell_size(cell) );
02659 
02660       if ( update_pressure )
02661       {
02662          gssize i;
02663          gssize len = sed_column_len( col );
02664          double cell_load = sed_cell_load( cell );
02665 
02666          for ( i=0 ; i<len ; i++ )
02667             sed_cell_set_pressure( col->cell[i] ,
02668                                    sed_cell_pressure( col->cell[i] )
02669                                    + cell_load );
02670       }
02671 
02672    }
02673 
02674    return amount_to_add;
02675 }
02676 
02677 double
02678 sed_column_stack_cell_loc_real( Sed_column col , Sed_cell cell , gboolean update_pressure )
02679 {
02680    double amount_to_add = 0;
02681 
02682    eh_require( col  );
02683    eh_require( cell );
02684 
02685    if ( col && cell )
02686    {
02687 /*
02688 if ( !sed_cell_is_valid(cell) || sed_cell_is_empty(cell) || sed_cell_is_clear(cell) )
02689 {
02690    sed_cell_fprint( stderr , cell );
02691    eh_watch_ptr( cell );
02692 eh_exit(0);
02693 }
02694 */
02695       amount_to_add = sed_cell_size( cell );
02696 
02697       sed_column_resize( col , col->len + 1 );
02698 
02699       sed_cell_destroy( col->cell[col->len] );
02700 
02701       col->cell[col->len] = cell;
02702       col->len += 1;
02703 
02704       sed_column_set_thickness( col , sed_column_thickness(col)+sed_cell_size(cell) );
02705 
02706       if ( update_pressure )
02707       {
02708          gssize i;
02709          gssize len = sed_column_len( col );
02710          double cell_load = sed_cell_load( cell );
02711 
02712          for ( i=0 ; i<len ; i++ )
02713             sed_cell_set_pressure( col->cell[i] ,
02714                                    sed_cell_pressure( col->cell[i] )
02715                                    + cell_load );
02716       }
02717 
02718       eh_require( sed_cell_is_valid(col->cell[col->len-1]) );
02719    }
02720 
02721    return amount_to_add;
02722 }
02723 
02724 double
02725 sed_column_stack_cell( Sed_column col , Sed_cell cell )
02726 {
02727    return sed_column_stack_cell_real( col , cell , FALSE );
02728 }
02729 
02730 double
02731 sed_column_stack_cell_loc( Sed_column col , Sed_cell cell )
02732 {
02733    return sed_column_stack_cell_loc_real( col , cell , FALSE );
02734 }
02735 

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