/Users/huttone/Devel/sedflux-new/sedflux/trunk/ew/avulsion/avulsion.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 <math.h>
00022 #include <glib.h>
00023 #include "utils/utils.h"
00024 #include "avulsion.h"
00025 
00026 GQuark
00027 avulsion_data_struct_quark( void )
00028 {
00029    return g_quark_from_static_string( "avulsion-data-struct-quark" );
00030 }
00031 
00032 Avulsion_st*
00033 avulsion_new( GRand* rand , double std_dev )
00034 {
00035    Avulsion_st* data = eh_new( Avulsion_st , 1 );
00036 
00037    data->rand    = rand;
00038    data->std_dev = std_dev;
00039 
00040    return data;
00041 }
00042 
00043 Avulsion_st*
00044 avulsion_dup( Avulsion_st* s )
00045 {
00046    Avulsion_st* d = NULL;
00047 
00048    if ( s )
00049    {
00050       d = avulsion_new( g_rand_copy(s->rand) , s->std_dev );
00051    }
00052 
00053    return d;
00054 }
00055 
00056 Avulsion_st*
00057 avulsion_destroy( Avulsion_st* data )
00058 {
00059    if ( data )
00060    {
00061       g_rand_free( data->rand );
00062       data->std_dev = 0;
00063       data->rand    = NULL;
00064       eh_free( data );
00065    }
00066    return NULL;
00067 }
00068 
00069 double
00070 get_std_dev_func( double angle , double std_dev )
00071 {
00072    return std_dev*(1. - .25*exp(-pow(angle-.0*G_PI,2.)) );
00073 }
00074 
00075 double
00076 avulsion( GRand* rand , double last_angle , double std_dev )
00077 {
00078    double new_angle;
00079 //   double d_angle = eh_rand_normal( rand , 0. , std_dev );
00080    double d_angle = eh_rand_normal( rand , 0. , get_std_dev_func(last_angle,std_dev) );
00081 
00082    new_angle = last_angle+d_angle;
00083 
00084    if      ( new_angle>G_PI )
00085       new_angle = 2.*G_PI - new_angle;
00086    else if ( new_angle<-G_PI )
00087       new_angle = -2.*G_PI - new_angle;
00088 
00089    new_angle = eh_reduce_angle( new_angle );
00090 
00091    return new_angle;
00092 }
00093 
00094 double
00095 avulsion_scale_angle_down( double angle , double min_angle , double max_angle )
00096 {
00097    return   angle*(max_angle-min_angle)/(2.*G_PI) + .5*(min_angle+max_angle);
00098 }
00099 
00100 double
00101 avulsion_scale_angle_up( double angle , double min_angle , double max_angle )
00102 {
00103    return (angle - .5*(min_angle+max_angle))*(2.*G_PI)/(max_angle-min_angle);
00104 }
00105 
00106 double
00107 avulsion_scale_std_dev_up( double std_dev , double min_angle , double max_angle )
00108 {
00109    return std_dev*2.*G_PI/( max_angle-min_angle );
00110 }
00111 
00112 Sed_riv
00113 sed_river_set_avulsion_data( Sed_riv r , Avulsion_st* data )
00114 {
00115    g_dataset_id_set_data_full( r , AVULSION_DATA , data , (GDestroyNotify)avulsion_destroy );
00116    return r;
00117 }
00118 
00119 Sed_riv
00120 sed_river_impart_avulsion_data( Sed_riv r )
00121 {
00122    Avulsion_st* parent_data = sed_river_avulsion_data(r);
00123    Avulsion_st* left_data   = avulsion_dup( parent_data );
00124    Avulsion_st* right_data  = avulsion_dup( parent_data );
00125 
00126    left_data->std_dev  *=.5;
00127    right_data->std_dev *=2.;
00128 
00129    sed_river_set_avulsion_data( sed_river_left (r) , left_data  );
00130    sed_river_set_avulsion_data( sed_river_right(r) , right_data );
00131 
00132    return r;
00133 }
00134 
00135 Sed_riv
00136 sed_river_unset_avulsion_data( Sed_riv r )
00137 {
00138    g_dataset_id_remove_data( r , AVULSION_DATA );
00139    return r;
00140 }
00141 
00142 Avulsion_st*
00143 sed_river_avulsion_data( Sed_riv r )
00144 {
00145    return g_dataset_id_get_data( r , AVULSION_DATA );
00146 }
00147 
00148 Sed_riv
00149 sed_river_avulse( Sed_riv r )
00150 {
00151    eh_require( r );
00152 
00153    if ( r )
00154    {
00155       double       angle;
00156       double       last_angle = sed_river_angle        ( r );
00157       Avulsion_st* data       = sed_river_avulsion_data( r );
00158 
00159       eh_require( data );
00160 
00161       if ( data && data->std_dev>0 )
00162       {
00163          GRand* rand       = data->rand;
00164          double std_dev    = data->std_dev;
00165          double min_angle  = sed_river_min_angle(r);
00166          double max_angle  = sed_river_max_angle(r);
00167 
00168          std_dev    = avulsion_scale_std_dev_up( std_dev    , min_angle  , max_angle );
00169          last_angle = avulsion_scale_angle_up  ( last_angle , min_angle  , max_angle );
00170          angle      = avulsion                 ( rand       , last_angle , std_dev   );
00171          angle      = avulsion_scale_angle_down( angle      , min_angle  , max_angle );
00172 
00173          sed_river_set_angle( r , angle );
00174       }
00175    }
00176 
00177    return r;
00178 }
00179 
00194 Sed_cube
00195 sed_cube_avulse_river( Sed_cube c , Sed_riv r )
00196 {
00197 
00198    if ( c )
00199    {
00200       Sed_riv* branch = sed_river_branches( r );
00201       Sed_riv* this_branch;
00202 
00203       for ( this_branch=branch ; *this_branch ; this_branch++ )
00204       {
00205          sed_river_avulse( *this_branch );
00206          sed_cube_find_river_mouth( c , *this_branch );
00207       }
00208 
00209       eh_free( branch );
00210    }
00211 
00212    return c;
00213 }
00214 
00215 void
00216 sed_cube_avulse_river_helper( Sed_riv r , Sed_cube c )
00217 {
00218    sed_cube_avulse_river( c , r );
00219 }
00220 
00221 Sed_cube
00222 sed_cube_avulse_all_rivers( Sed_cube c )
00223 {
00224    return sed_cube_foreach_river( c , (GFunc)&sed_cube_avulse_river_helper , c );
00225 }
00226 
00227 

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