/Users/huttone/Devel/sedflux-new/sedflux/trunk/ew/sed/sed_wave.c

Go to the documentation of this file.
00001 #include <glib.h>
00002 
00003 #include "utils/utils.h"
00004 
00005 #include "sed_sediment.h"
00006 #include "sed_wave.h"
00007 
00010 CLASS ( Sed_wave )
00011 {
00012    double h; 
00013    double k; 
00014    double w; 
00015 };
00016 
00019 CLASS ( Sed_ocean_storm )
00020 {
00021    Sed_wave w; 
00022    double val; 
00023    double dt;  
00024    gssize ind; 
00025 };
00026 
00027 Sed_wave sed_wave_new( double h , double k , double w )
00028 {
00029    Sed_wave new_wave = NULL;
00030 
00031    if ( h>=0 && k>=0 && w>=0 )
00032    {
00033       NEW_OBJECT( Sed_wave , new_wave );
00034 
00035       new_wave->h = h;
00036       new_wave->k = k;
00037       new_wave->w = w;
00038    }
00039 
00040    return new_wave;
00041 }
00042 
00043 Sed_wave sed_wave_copy( Sed_wave dest , Sed_wave src )
00044 {
00045    eh_require( src );
00046 
00047    if ( src )
00048    {
00049       if ( !dest )
00050          dest = sed_wave_new( src->h , src->k , src->w );
00051       else
00052       {
00053          dest->h = src->h;
00054          dest->w = src->w;
00055          dest->k = src->k;
00056       }
00057    }
00058    else
00059       dest = NULL;
00060 
00061    return dest;
00062 }
00063 
00064 Sed_wave sed_wave_dup( Sed_wave src )
00065 {
00066    return sed_wave_copy( NULL , src );
00067 }
00068 
00069 gboolean sed_wave_is_same( Sed_wave w_1 , Sed_wave w_2 )
00070 {
00071    gboolean same = FALSE;
00072 
00073    eh_require( w_1 );
00074    eh_require( w_2 );
00075 
00076    if ( w_1 && w_2 )
00077    {
00078       if ( w_1 != w_2 )
00079       {
00080          same =  fabs( w_1->h - w_2->h ) < 1e-12
00081               && fabs( w_1->w - w_2->w ) < 1e-12
00082               && fabs( w_1->k - w_2->k ) < 1e-12;
00083       }
00084       else
00085          same = TRUE;
00086    }
00087       
00088    return same;
00089 }
00090 
00091 Sed_wave sed_wave_destroy( Sed_wave w )
00092 {
00093    if ( w )
00094       eh_free( w );
00095    return NULL;
00096 }
00097 
00098 double sed_wave_height( Sed_wave w )
00099 {
00100    return w->h;
00101 }
00102 
00103 double sed_wave_number( Sed_wave w )
00104 {
00105    return w->k;
00106 }
00107 
00108 double sed_wave_length( Sed_wave w )
00109 {
00110    return 2*G_PI/w->k;
00111 }
00112 
00113 double sed_wave_frequency( Sed_wave w )
00114 {
00115    return w->w;
00116 }
00117 
00118 double sed_wave_period( Sed_wave w )
00119 {
00120    return 2*G_PI/w->w;
00121 }
00122 
00123 double sed_wave_phase_velocity( Sed_wave w )
00124 {
00125    return w->w/w->k;
00126 }
00127 
00128 gboolean sed_wave_is_bad( Sed_wave w )
00129 {
00130    return eh_isnan(   sed_wave_height(w)
00131                     * sed_wave_frequency(w)
00132                     * sed_wave_number(w) );
00133 }
00134 
00135 Sed_wave sed_gravity_wave_set_frequency( Sed_wave a , double w , double h)
00136 {
00137    eh_require( h>0 )
00138    {
00139       a->w = w;
00140       a->k = sed_dispersion_relation_wave_number( h , w );
00141    }
00142    return a;
00143 }
00144 
00145 Sed_wave sed_gravity_wave_set_number( Sed_wave w , double k , double h)
00146 {
00147    eh_require( h>0 )
00148    {
00149       w->k = k;
00150       w->w = sed_dispersion_relation_frequency( h , k );
00151    }
00152    return w;
00153 }
00154 
00155 Sed_wave sed_gravity_wave_set_height( Sed_wave w , Sed_wave w_infinity , double h )
00156 {
00157    double n = .5*( 1 + 2.*w->k*h/sinh(2*w->k*h) );
00158    double c          = sed_wave_phase_velocity( w );
00159    double c_infinity = sed_wave_phase_velocity( w_infinity );
00160 
00161    w->h = w_infinity->h*sqrt( 1./(2*n)*c_infinity/c );
00162 
00163    return w;
00164 }
00165 
00166 Sed_wave sed_gravity_wave_new( Sed_wave w_infinity , double h , Sed_wave new_wave )
00167 {
00168    if ( !new_wave )
00169       new_wave = sed_wave_new( 0 , 0 , 0 );
00170 
00171    // Set the frequency (and also the wavenumber from the dispersion
00172    // relation), and height of the new wave at the specified water depth.
00173    sed_gravity_wave_set_frequency( new_wave , w_infinity->w , h );
00174    sed_gravity_wave_set_height   ( new_wave , w_infinity    , h );
00175 
00176    return new_wave;
00177 }
00178 
00179 gboolean sed_wave_is_breaking( Sed_wave w , double h )
00180 {
00181    return w->h / sed_wave_length(w) >= 1./7.;
00182 }
00183 
00184 double sed_gravity_wave_deep_water_height( Sed_wave w )
00185 {
00186    double kh2;
00187    double h;
00188    double x = w->w*w->w/(sed_gravity()*w->k);
00189 
00190    if ( fabs(x-1.) < 1e-5 )
00191       return w->h;
00192    else
00193       h = atanh(x)/w->k;
00194 
00195    kh2 = 2*w->k*h;
00196 
00197    return w->h / sqrt( (cosh(kh2)+1)/(sinh(kh2)+kh2) );
00198 }
00199 
00200 double sed_gravity_wave_deep_water_wave_number( Sed_wave w )
00201 {
00202    return w->w*w->w/sed_gravity();
00203 }
00204 
00205 double sed_wave_break_depth( Sed_wave w )
00206 {
00207    void sed_wave_break_depth_helper( double k_times_h ,
00208                                      double *y        ,
00209                                      double *dydx     ,
00210                                      double *data );
00211    double k_times_h, k, h;
00212    double h_deep_water;
00213    double data[2];
00214 
00215    h_deep_water = sed_gravity_wave_deep_water_height( w );
00216 
00217    data[0] = h_deep_water;
00218    data[1] = w->w;
00219 
00220    k_times_h = rtsafe( &sed_wave_break_depth_helper ,
00221                        1e-5 ,
00222                        100 ,
00223                        .01 ,
00224                        data );
00225 //if ( eh_isnan( k_times_h ) )
00226 //   eh_warning( "Bad wave in sed_wave_break_depth" );
00227 
00228    k = pow( w->w , 2. ) / ( sed_gravity() * tanh(k_times_h) );
00229 
00230    h = k_times_h / k;
00231 
00232    return h;
00233 }
00234 
00235 void sed_wave_break_depth_helper( double k_times_h ,
00236                                   double *y        ,
00237                                   double *dydx     ,
00238                                   double *data )
00239 {
00240    double h   = data[0];
00241    double w   = data[1];
00242    double g   = sed_gravity();
00243    double kh  = k_times_h;
00244    double kh2 = 2*k_times_h;
00245 
00246    *y = (1./7.)*2.*G_PI*g*tanh( kh ) / ( h*w*w )
00247       - sqrt( (cosh(kh2) + 1.)/( sinh(kh2) + kh2 ) );
00248 
00249    *dydx = (1./7.)*2*G_PI*g/(h*w*w)*pow(1./cosh(kh),2.)
00250          -   .5/sqrt( (cosh(kh2)+1) / (sinh(kh2) + kh2 ) )
00251            * ( 2*(sinh(kh2)+kh2)*sinh(kh2) - (cosh(kh2)+1)*(2*cosh(kh2)+2))
00252            / pow(sinh(kh2)+kh2,2);
00253 
00254    return;
00255 }
00256 
00257 double sed_dispersion_relation_frequency( double water_depth , double wave_number )
00258 {
00259    double w = eh_nan();
00260 
00261    eh_require( water_depth>0 )
00262    {
00263       w = sqrt( sed_gravity()*wave_number*tanh(wave_number*water_depth) );
00264    }
00265 
00266    return w;
00267 }
00268 
00285 double sed_dispersion_relation_wave_number( double water_depth ,
00286                                             double frequency )
00287 {
00288    void sed_dispersion_relation_wave_number_helper( double k     ,
00289                                                     double *y    ,
00290                                                     double *dydx ,
00291                                                     double *data );
00292    double wave_number = eh_nan();
00293 
00294    eh_require( water_depth > 0 )
00295    {
00296       double data[2];
00297 
00298       data[0] = water_depth;
00299       data[1] = frequency;
00300 
00301       wave_number = rtsafe( &sed_dispersion_relation_wave_number_helper ,
00302                             0 ,
00303                             100 ,
00304                             .01 ,
00305                             data );
00306    }
00307 
00308    return wave_number;
00309 }
00310 
00311 void sed_dispersion_relation_wave_number_helper( double k     ,
00312                                                  double *y    ,
00313                                                  double *dydx ,
00314                                                  double *data )
00315 {
00316    double g = sed_gravity();
00317    double h = data[0]; // water depth
00318    double w = data[1]; // frequency
00319 
00320    *y    = g*k*tanh( k*h ) - w*w;
00321    *dydx = g*( k*h*pow(1./cosh(k*h),2.) + tanh(k*h) );
00322 }
00323 
00324 Sed_ocean_storm sed_ocean_storm_new( void )
00325 {
00326    Sed_ocean_storm s;
00327 
00328    NEW_OBJECT( Sed_ocean_storm , s );
00329 
00330    s->w   = sed_wave_new( 0 , 0 , 0 );
00331    s->val = 0;
00332    s->ind = 0;
00333    s->dt  = 0;
00334 
00335    return s;
00336 }
00337 
00338 Sed_ocean_storm sed_ocean_storm_destroy( Sed_ocean_storm s )
00339 {
00340    if ( s )
00341    {
00342       sed_wave_destroy( s->w );
00343       eh_free( s );
00344    }
00345    return NULL;
00346 }
00347 
00348 double sed_ocean_storm_duration( Sed_ocean_storm s )
00349 {
00350    return s->dt;
00351 }
00352 
00353 gssize sed_ocean_storm_index( Sed_ocean_storm s )
00354 {
00355    return s->ind;
00356 }
00357 
00358 double sed_ocean_storm_val( Sed_ocean_storm s )
00359 {
00360    return s->val;
00361 }
00362 
00363 double sed_ocean_storm_duration_in_seconds( Sed_ocean_storm s )
00364 {
00365    return s->dt*S_SECONDS_PER_DAY;
00366 }
00367 
00368 double sed_ocean_storm_wave_height( Sed_ocean_storm s )
00369 {
00370    return sed_wave_height(s->w);
00371 }
00372 
00373 double sed_ocean_storm_wave_number( Sed_ocean_storm s )
00374 {
00375    return sed_wave_number(s->w);
00376 }
00377 
00378 double sed_ocean_storm_wave_length( Sed_ocean_storm s )
00379 {
00380    return sed_wave_length(s->w);
00381 }
00382 
00383 double sed_ocean_storm_wave_freq( Sed_ocean_storm s )
00384 {
00385    return sed_wave_frequency(s->w);
00386 }
00387 
00388 double sed_ocean_storm_wave_period( Sed_ocean_storm s )
00389 {
00390    return sed_wave_period(s->w);
00391 }
00392 
00393 double sed_ocean_storm_phase_velocity( Sed_ocean_storm s )
00394 {
00395    return sed_wave_phase_velocity(s->w);
00396 }
00397 
00398 Sed_ocean_storm sed_ocean_storm_set_wave( Sed_ocean_storm s , Sed_wave w )
00399 {
00400    eh_require( w );
00401    if ( s )
00402       sed_wave_copy( s->w , w );
00403    return s;
00404 }
00405 
00406 Sed_ocean_storm sed_ocean_storm_set_index( Sed_ocean_storm s , gssize ind )
00407 {
00408    if ( s )
00409       s->ind = ind;
00410    return s;
00411 }
00412 
00413 Sed_ocean_storm sed_ocean_storm_set_duration( Sed_ocean_storm s , double dt_in_days )
00414 {
00415    if ( s )
00416       s->dt = dt_in_days;
00417    return s;
00418 }
00419 
00420 Sed_ocean_storm sed_ocean_storm_set_val( Sed_ocean_storm s , double val )
00421 {
00422    if ( s )
00423       s->val = val;
00424    return s;
00425 }
00426 
00427 gssize sed_ocean_storm_fprint( FILE* fp , Sed_ocean_storm s )
00428 {
00429    gssize n = 0;
00430 
00431    eh_require( fp );
00432    eh_require( s  );
00433 
00434    if ( s )
00435    {
00436       n += fprintf( fp , "Time index      : %d" , (gint)s->ind );
00437       n += fprintf( fp , "Value           : %f" , s->val );
00438       n += fprintf( fp , "Duration (days) : %f" , s->dt );
00439       n += fprintf( fp , "Wave height (m) : %f" , sed_wave_height( s->w ) );
00440       n += fprintf( fp , "Wave length (m) : %f" , sed_wave_length( s->w ) );
00441       n += fprintf( fp , "Wave period (m) : %f" , sed_wave_period( s->w ) );
00442    }
00443 
00444    return n;
00445 }
00446 

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