/Users/huttone/Devel/sedflux-new/sedflux/trunk/ew/plume/plumearray.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 /*
00022  * PlumeArray   Creates various arrays for PLUME
00023  *
00024  *      Author:         M.D. Morehead
00025  *      Original:       April 1998
00026  *
00027  *
00028  *      Define:
00029  *              Li   = Inertial distance, u/f
00030  *              zend = distance along the centerline at which the inventory
00031  *                      reaches pcrit for the smallest lambda
00032  *              yend = y position of the deformed plume when it reaches zend
00033  *              xend = x position of the deformed plume when it reaches zend
00034  *              (min) indicates in opposite direction of vo
00035  *              (max) indicates in the direction of vo
00036  *
00037  * Find optimal array size for the following cases
00038  *
00039  *      1) Fjord (fjrd) or non-deflected (strt) run,
00040  *              indicated by vo = 0
00041  *              xmin == 0
00042  *              xmax = 1.1*zend
00043  *              ymin, ymax  are user specified
00044  *      2) Ocean plume, with downwelling
00045  *              indicated by vo ~= 0, kwf = 1
00046  *              xmin == 0
00047  *              xmax = Li
00048  *              y(min) = -2*bo          
00049  *              y(max) = zend
00050  *      3) Ocean plume, with upwelling, strong vo
00051  *              indicated by vo ~= 0, kwf = 0, yend > 1.5*xend
00052  *              xmin == 0
00053  *              xmax = xend + Li
00054  *              y(min) = -4*bo
00055  *              y(max) = yend
00056  *      4) Ocean plume, with upwelling, weak vo
00057  *              indicated by vo ~= 0, kwf = 0, xend > 1.5*yend
00058  *              xmin == 0
00059  *              xmax = xend
00060  *              y(min) = -Li
00061  *              y(max) = yend
00062  *      5) Ocean plume, with upwelling, moderate vo
00063  *              indicated by vo ~= 0, kwf = 0, xend ~ yend
00064  *              xmin == 0
00065  *              xmax = xend
00066  *              y(min) = -li
00067  *              y(max) = yend
00068  *
00069  */
00070 #include "plumeinput.h"
00071 #include "plumevars.h"
00072 #include <stdlib.h>
00073 #include <utils/utils.h>
00074 
00075 //---
00076 // outputs:
00077 //    xmin
00078 //    xmax
00079 //    ymin
00080 //    ymax
00081 // inputs:
00082 //    river.Cs
00083 //    river.b0
00084 //    river.u0
00085 //    sedload.lambda
00086 //    n_grains
00087 //    fjrd
00088 //    strt
00089 //    ocean.v0
00090 //---
00091 
00092 //---
00093 // Start of PlumeArray
00094 //---
00095 int plumearray( Plume_grid *grid , Plume_enviro *env , Plume_options *opt )
00096 {
00097    static int reuse_count = 0;
00098    static int new_count = 0;
00099    int  ii, jj, kk, l1, endi;
00100    int x_size, y_size;
00101    double aa, AA, avo, mxcs, mnlm, Li, nv, tst, xend, yend, zend;
00102    double *dcl, *xcl, *ycl;
00103    int n_grains = env->n_grains;
00104    Plume_river *river = env->river;
00105    Plume_ocean *ocean = env->ocean;
00106    Plume_sediment *sedload = env->sed;
00107 
00108    grid->xmin   = 0;
00109 
00110    // find min's and max's
00111    mxcs = river->Cs[0];
00112    mnlm = sedload[0].lambda;
00113    for( ii=0; ii<n_grains; ii++ )
00114    {
00115       mxcs = mx( mxcs, river->Cs[ii]);
00116       mnlm = mn( mnlm, sedload[ii].lambda);
00117    }   
00118 
00119 //---
00120 // Find the along centerline distance to the cutoff concentration (zend)
00121 // use: I = Io sqrt(-lt)
00122 // where:
00123 //   I = pcrit*Io
00124 //   l = min(lambda)
00125 //   t = x/u
00126 //   u = albertson = uo*sqrt(bo/(sqrt(pi)*C1*x))
00127 //---
00128    zend = 1.2*pow((-(river->u0/mnlm)*sqrt(river->b0/(sqpi*C1))*log(pcrit) ),(2.0/3.0));
00129 
00130 //---
00131 // We don't need to track sediment if it leaves the model (travels a distance
00132 // greater than max_len).
00133 //---
00134    if ( zend > grid->max_len && grid->max_len != 0 )
00135       zend = grid->max_len;
00136 
00137    if ( !(opt->fjrd || opt->strt) )
00138       Li = river->u0/(2*omega*sin(env->lat*degTOr));
00139 
00140 //---
00141 // (1) Fjord run or straight centerline
00142 //---
00143    if ( opt->fjrd || opt->strt )
00144       grid->xmax = rnd(1.1*zend);
00145 
00146 //---
00147 // (2) Ocean plume, with downwelling
00148 //---
00149    else if( opt->kwf == 1 )
00150    {
00151       grid->xmax = rnd(Li);
00152       if( ocean->vo > 0 )
00153       {
00154          grid->ymin = floor(-2*river->b0);
00155          grid->ymax = ceil(zend);
00156       }
00157       else
00158       {
00159          grid->ymin = floor(-zend);
00160          grid->ymax = ceil(2*river->b0);
00161       }
00162    }
00163 
00164 //---
00165 // Upwelling Conditions
00166 //---
00167    else
00168    {
00169 
00170       // Deflected Jet centerline constants
00171       avo = fabs(ocean->vo);
00172       aa  = river->u0/avo;              // a = Wmo/Ue
00173       nv  = 0.37;                       // n = [ 0.375 0.380 0.370 0.385 ]
00174       AA  = 1.53 + 0.90*aa;
00175 
00176       // Allocate centerline arrays
00177       l1        = (int)rnd(1.1*zend/grid->dy);
00178       if( (xcl = (double *) calloc(l1,sizeof(double))) == NULL ||
00179           (ycl = (double *) calloc(l1,sizeof(double))) == NULL ||
00180           (dcl = (double *) calloc(l1,sizeof(double))) == NULL    )
00181       {
00182           fprintf(stderr," PlumeArray ERROR: memory allocation failed \n");
00183           fprintf(stderr,"                failed on xcl, ycl, dcl \n");
00184           return 1;
00185       }
00186 
00187       // Find the jet position and distance along the jet
00188       xcl[0] = ycl[0] = dcl[0] = 0.0;
00189       for ( jj = 1; jj<l1; jj++ )
00190       {
00191          ycl[jj] = grid->dy*(jj-1);
00192          xcl[jj] = river->b0*AA*pow((ycl[jj]/river->b0),nv);
00193          dcl[jj] = dcl[jj-1]
00194                  + sqrt(pow((ycl[jj]-ycl[jj-1]),2)+pow((xcl[jj]-xcl[jj-1]),2));
00195       }
00196 
00197       // find the x,y values of zend 
00198       // numerically minimize the quadratic equation z^2 - x^2 - y^2 = 0
00199       endi = 0;
00200       tst  = fabs(dcl[0]-zend);
00201       for( jj=1; jj<l1; jj++ )
00202       {
00203          if( fabs(dcl[jj]-zend) < tst )
00204          {
00205             endi = jj;
00206             tst = fabs(dcl[jj]-zend);
00207          }
00208       } 
00209       xend = xcl[endi]; yend = ycl[endi];
00210 
00211       // free up local allocated memory
00212       free(xcl);
00213       free(ycl);
00214       free(dcl);
00215     
00216       //---
00217       // (3) Ocean plume, with upwelling, strong vo
00218       // indicated by vo ~= 0, kwf = 0, yend > 1.5*xend
00219       //---
00220       if( yend > 1.5*xend )
00221       {
00222          grid->xmax = rnd(xend+Li);
00223          if( ocean->vo > 0 )
00224          {
00225             grid->ymin = rnd(-4*river->b0);
00226             grid->ymax = rnd(yend);
00227          }
00228          else
00229          {
00230             grid->ymin = rnd(-yend);
00231             grid->ymax = rnd(4*river->b0);
00232          }
00233       }
00234 
00235       //---
00236       // (4) Ocean plume, with upwelling, weak vo
00237       // indicated by vo ~= 0, kwf = 0, xend > 1.5*yend
00238       //---
00239       else if( xend > 1.5*yend )
00240       {
00241          grid->xmax = rnd(xend);
00242          if ( ocean->vo > 0 )
00243          {
00244             grid->ymin = rnd(-Li);
00245             grid->ymax = rnd(yend);
00246          }
00247           else
00248          {
00249             grid->ymin = rnd(-yend);
00250             grid->ymax = rnd(Li);
00251          }
00252       }
00253 
00254       //---
00255       // (5) Ocean plume, with upwelling, moderate vo
00256       // indicated by vo ~= 0, kwf = 0, xend ~ yend
00257       //---
00258       else
00259       {
00260          grid->xmax = xend;
00261          if ( ocean->vo > 0 )
00262          {
00263             grid->ymin = rnd(-Li);
00264             grid->ymax = rnd(yend);
00265          }
00266          else
00267          {
00268             grid->ymin = rnd(-yend);
00269             grid->ymax = rnd(Li);
00270          }
00271       } // end 3)
00272    } // end of Upwelling Conditons
00273 
00274    //---
00275    // Create nicely centered X/Y arrays
00276    // insure that yvals=0 at an integer index
00277    //---
00278    grid->ymin = rnd(floor(grid->ymin/(int)(grid->dy))*(int)(grid->dy));
00279    grid->lx = (int)(((grid->xmax-grid->xmin)/(int)(grid->dx))+2);
00280    grid->ly = (int)(((grid->ymax-grid->ymin)/(int)(grid->dy))+2);
00281    grid->lz = n_grains;
00282 /*
00283    if( (xval = (double *) calloc(grid->lx,sizeof(double))) == NULL ||
00284        (yval = (double *) calloc(grid->ly,sizeof(double))) == NULL )
00285    {
00286        fprintf(stderr," PlumeArray ERROR: memory allocation failed \n");
00287        fprintf(stderr,"                failed on xvals or yvals \n");
00288        eh_exit(1);
00289    }
00290    for( ii = 0 ; ii<grid->lx ; ii++ )
00291       xval[ii] = grid->xmin+ii*grid->dx;
00292    for( ii = 0 ; ii<grid->ly ; ii++ )
00293       yval[ii] = grid->ymin+ii*grid->dy;
00294 */
00295    // Recalculate array limits, sizes, and zero points
00296 //   grid->xmin = xval[0];
00297 //   grid->xmax = xval[grid->lx-1];
00298    grid->xmax = grid->xmin + (grid->lx-1)*grid->dx;
00299 //   grid->ymax = yval[grid->ly-1];
00300    grid->ymax = grid->ymin + (grid->ly-1)*grid->dy;
00301    grid->zx   = 0;
00302    grid->zy   = (int)((grid->ly - grid->ymax/(int)(grid->dy))-1);
00303    grid->lpc  = (int)(2.4*(grid->lx+grid->ly));
00304 
00305 // Increase lpc.  Sometimes it is not large enough to store the entrie grid.
00306    grid->lpc *= 10;
00307 
00308    if ( grid->lx>grid->x_len || grid->ly>grid->y_len || TRUE )
00309    {
00310 
00311 new_count++;
00312 
00313       if ( grid->x_len!=0 || grid->y_len!=0 )
00314       {
00315          eh_free( grid->xval );
00316          eh_free( grid->yval );
00317 
00318          free_d3tensor( grid->ccnc  );
00319          free_d3tensor( grid->ncnc  );
00320          free_d3tensor( grid->deps  );
00321          free_d3tensor( grid->dist  );
00322          free_dmatrix ( grid->ualb  );
00323          free_dmatrix ( grid->pcent );
00324       }
00325 
00326       if ( grid->lx>grid->x_len )
00327          grid->x_len = grid->lx;
00328       if ( grid->ly>grid->y_len )
00329          grid->y_len = grid->ly;
00330 
00331       grid->xval = eh_new( double , grid->lx );
00332       grid->yval = eh_new( double , grid->ly );
00333 
00334       for ( ii = 0 ; ii<grid->lx ; ii++ )
00335          grid->xval[ii] = grid->xmin+ii*grid->dx;
00336       for ( ii = 0 ; ii<grid->ly ; ii++ )
00337          grid->yval[ii] = grid->ymin+ii*grid->dy;
00338 
00339       y_size = grid->ly;
00340       if ( y_size<grid->y_len )
00341          y_size = grid->y_len;
00342       x_size = grid->lx;
00343       if ( x_size<grid->x_len )
00344          x_size = grid->x_len;
00345 
00346       // Create remaining arrays (i,j = cross-shore, along-shore)
00347       // ccnc  : Conservative Cs (kg/m^3)
00348       // ncnc  : Non-conservative Cs (kg/m^3)
00349       // deps  : Deposit thickness (kg/m^3)
00350       // dist  : Information relating to closest centerline point
00351       // ualb  : Albertson velocities (m/s)
00352       // pcent : Deflected centerline information
00353       grid->ccnc  = new_d3tensor(x_size,y_size,n_grains);
00354       grid->ncnc  = new_d3tensor(x_size,y_size,n_grains);
00355       grid->deps  = new_d3tensor(x_size,y_size,n_grains);
00356       grid->dist  = new_d3tensor(x_size,y_size,5);
00357       grid->ualb  = new_dmatrix(x_size,y_size);
00358       grid->pcent = new_dmatrix(grid->lpc,4);
00359 
00360       if( opt->o1 )
00361       {
00362          // sln  : Conservative tracer concentration
00363          grid->sln = new_dmatrix(x_size,y_size);
00364       }
00365    }
00366    else
00367    {
00368       reuse_count++;
00369    }
00370 
00371    for ( ii=0 ; ii<grid->x_len ; ii++ )
00372       for ( jj=0 ; jj<grid->y_len ; jj++ )
00373       {
00374          for ( kk=0 ; kk<n_grains ; kk++ )
00375          {
00376             grid->ccnc[ii][jj][kk] = 0.;
00377             grid->ncnc[ii][jj][kk] = 0.;
00378             grid->deps[ii][jj][kk] = 0.;
00379          }
00380          for ( kk=0 ; kk<5 ; kk++ )
00381             grid->dist[ii][jj][kk] = 0.;
00382          grid->ualb[ii][jj] = 0.;
00383       }
00384    for ( ii=0 ; ii<grid->lpc ; ii++ )
00385       for ( jj=0 ; jj<4 ; jj++ )
00386          grid->pcent[ii][jj] = 0.;
00387 
00388    return 0; 
00389  
00390 } // end of PlumeArray
00391 

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