/Users/huttone/Devel/sedflux-new/sedflux/trunk/ew/bio/bio.c

Go to the documentation of this file.
00001 #include <glib.h>
00002 #include <utils/utils.h>
00003 #include "bio.h"
00004 
00005 G_GNUC_INTERNAL void diffuse_col( double* u , gint len , double dz , double k , double total_t );
00006 
00007 GQuark
00008 bio_error_quark( void )
00009 {
00010    return g_quark_from_static_string( "bio-error-quark" );
00011 }
00012 
00013 void
00014 bioturbate( double** col , gint n_grains , gint n_layers , double dz , double k , double total_t )
00015 {
00016    eh_require( n_grains>0 );
00017    eh_require( dz>0       );
00018    eh_require( k>0        );
00019 
00020    if ( col && n_layers>1 )
00021    {
00022       gint n;
00023 
00024       for ( n=0 ; n<n_grains ; n++ )
00025          diffuse_col( col[n] , n_layers , dz , k , total_t );
00026    }
00027 }
00028 
00029 void
00030 diffuse_col( double* f , gint len , double dz , double k , double total_t )
00031 {
00032    if ( len>2 )
00033    {
00034       {
00035          Eh_num_method method = EH_NUM_IMPLICIT;
00036          gint i, n;
00037          double*      f_new  = eh_dbl_array_dup( f , len );
00038          const double dt_opt = .9*.5*dz*dz/k;
00039 //         const double dt     = eh_min( dt_opt , total_t );
00040          const double dt     = total_t;
00041          const double c      = dt * k / (dz*dz);
00042          const gint   n_t    = total_t / dt;
00043          const double dt_rem = fmod( total_t , dt );
00044 
00045          for ( n=0 ; n<n_t ; n++ ) eh_dbl_array_diffuse( f , len , c                   , method );
00046          if  ( dt_rem > 0. )       eh_dbl_array_diffuse( f , len , c * ( dt_rem / dt ) , method );
00047 
00048          eh_free( f_new );
00049       }
00050    }
00051 
00052    return;
00053 }
00054 
00055 double**
00056 bio_diffuse_layers( double* t , gint n_layers , double dz , double k , double duration )
00057 {
00058    double** u_out = NULL;
00059 
00060    if ( n_layers>2 )
00061    {
00062       gint    i;
00063       double* u_copy;
00064 
00065       u_out = eh_new( double* , n_layers+1 );
00066 
00067       for ( i=0 ; i<n_layers ; i++ )
00068       {
00069          u_copy    = eh_new0( double , n_layers );
00070          u_copy[i] = t[i];
00071 
00072          diffuse_col( u_copy , n_layers , dz , k , duration );
00073 
00074          u_out[i] = u_copy;
00075       }
00076       u_out[n_layers] = NULL;
00077    }
00078 
00079    return u_out;
00080 }
00081 
00082 double**
00083 bio_conveyor_layers( double* t , gint n_layers , double dz , double r , double duration )
00084 {
00085    double** u_out = NULL;
00086 
00087    eh_require( dz       > 0 );
00088    eh_require( n_layers > 0 );
00089 
00090    if ( r > 0 && duration > 0 )
00091    {
00092       const double h  = eh_dbl_array_sum(t,n_layers);
00093       const double dh = r*duration;
00094 
00095       if ( dh >= h )
00096       {
00097          u_out    = eh_new( double* , 2        );
00098          u_out[0] = eh_dbl_array_dup( t , n_layers );
00099          u_out[1] = NULL;
00100       }
00101       else if ( dh > 0 )
00102       {
00103          double* u_avg = eh_new0( double , n_layers );
00104          gint    i, i_shift, j;
00105          gint    new_len;
00106          double  tot;
00107 
00108          for ( i=0,tot=t[0] ; tot<=dh && i<n_layers ; i++,tot+=t[i] ) u_avg[i] = t[i];
00109          u_avg[i] = t[i] - (tot-dh);
00110 
00111          i_shift  = i;
00112 
00113          eh_require( tot     >= dh       );
00114          eh_require( i_shift <  n_layers );
00115 
00116          new_len = n_layers-i_shift+1;
00117 
00118          u_out = eh_new( double* , new_len+1 );
00119 
00120          for ( i=0,j=i_shift ; i<new_len-1 ; i++,j++ )
00121          {
00122             u_out[i]    = eh_new0( double , n_layers );
00123             u_out[i][j] = t[j];
00124          }
00125          u_out[0][i_shift] = tot-dh;
00126 
00127          u_out[new_len-1] = u_avg;
00128          u_out[new_len]   = NULL;
00129       }
00130       else
00131       {
00132          gint i;
00133          u_out = eh_new( double* , n_layers+1 );
00134          for ( i=0 ; i<n_layers ; i++ )
00135          {
00136             u_out[i] = eh_new0( double , n_layers );
00137             u_out[i][i] = t[i];
00138          }
00139          u_out[n_layers] = NULL;
00140       }
00141    }
00142 
00143    return u_out;
00144 }
00145 
00146 void
00147 bio_conveyor( double* u , gint len , double r , double total_t , double** u_out , gint** i_out , gint* len_out )
00148 {
00149    eh_require( u );
00150 
00151    if ( u )
00152    {
00153       const double h     = eh_dbl_array_sum( u , len );
00154       const double dh    = fmod( r*total_t , h );
00155       gint*        i_in  = eh_new( gint   , len   );
00156       gint         i;
00157       gint         i_shift;
00158       double       z;
00159 
00160       *u_out   = eh_new( double , len+1 );
00161       *i_out   = eh_new( gint   , len+1 );
00162       *len_out = len+1;
00163 
00164       for ( i=0 ; i<len ; i++ ) i_in[i] = i;
00165 
00166       /* Find index to elevation dh */
00167       for ( i_shift=0 ; i_shift<len && z<dh ; z+=u[i_shift],i_shift++ );
00168 
00169       /* Shift the layers */
00170       g_memmove( *u_out               , u+i_shift    , sizeof(double)*(len-i_shift) );
00171       g_memmove( *u_out+(len-i_shift) , u            , sizeof(double)*(    i_shift) );
00172       g_memmove( i_out                , i_in+i_shift , sizeof(gint)  *(len-i_shift) );
00173       g_memmove( i_out+(len-i_shift)  , i_in         , sizeof(gint)  *(    i_shift) );
00174 
00175       /* Split the bottom cell.  Don't check if dh lies exactly at a layer boundary */
00176       (*u_out)[0]   = z - dh;
00177       (*u_out)[len] = u[i_shift] - (z-dh);
00178 
00179       eh_free( i_in );
00180    }
00181 
00182    return;
00183 }
00184 /*
00185 void
00186 bio_conveyor( double* u , gint len , double dz , double r , double total_t )
00187 {
00188    if ( u )
00189    {
00190       gint i, n;
00191       double*      u_new = eh_dbl_array_dup(u,len);
00192       const gint   top_i = len-1;
00193       const gint   n_t   = 100;
00194       const double c     = (r*total_t)*S_DAYS_PER_SECOND / ( dz*n_t );
00195 
00196       {
00197          const double dh  = r*total_t;
00198          const double h   = dz*len;
00199 
00200          dh = fmod( dh , h );
00201       }
00202 
00203       for ( n=0 ; n<n_t ; n++ )
00204       {
00205          for ( i=1 ; i<top_i ; i++ )
00206             u_new[i] = (1.-c) * u[i] + c * u[i-1];
00207          u_new[0] = (1.-c)*u[0] + c*u[top_i];
00208 
00209          eh_dbl_array_copy( u , u_new , len );
00210       }
00211 
00212       eh_free( u_new );
00213    }
00214 }
00215 */
00216 

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