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
00172
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
00226
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];
00318 double w = data[1];
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