/Users/huttone/Devel/sedflux-new/sedflux/trunk/ew/sakura/sakura_utils.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 //LIST OF FUNCTIONS defined only for sakura
00022 
00023 #include <stdio.h>
00024 #include <math.h>
00025 #include "sakura.h"
00026 #include "sakura_local.h"
00027 
00028 /*
00029 double **dmatrix(int nrl, int nrh, int ncl, int nch)
00030 {
00031         int i;
00032         double **m;
00033 
00034         m=(double **) malloc((unsigned) (nrh-nrl+1)*sizeof(double*));
00035         if (!m) 
00036                 fprintf(stderr, "allocation failure 1 in dmatrix()\n");
00037         m -= nrl;
00038 
00039         for(i=nrl;i<=nrh;i++) {
00040                 m[i]=(double *) malloc((unsigned) (nch-ncl+1)*sizeof(double));
00041                 if (!m[i]) 
00042                         fprintf(stderr, "allocation failure 2 in dmatrix()\n");
00043                 m[i] -= ncl;
00044         }
00045         return m;
00046 }
00047 */
00048 
00049 /* ---bathyA--- *
00050   *  floor is flat in the box, then slope, and flat again to downstream end
00051   *  grid interval is constant dx
00052   */
00053 /*void bathyA(double *Xi, double *Zi, double *Si, double dx)
00054 {
00055         int i;
00056         Xi[0] = 0;
00057         Zi[0] = DEPTHATORIGIN;
00058         for (i =1; i < NNODES; i++){
00059                 Xi[i] = (double)( i * dx);
00060                 if (Xi[i] <= BOXLENGTH){
00061                         Zi[i] = DEPTHATORIGIN;
00062                         Si[i] = 0;
00063                 }
00064                 else if (Xi[i] <= BOXLENGTH + SLOPELENGTH){
00065                         Zi[i] = Zi[i-1] - dx * SLOPEGRADIENT;
00066                         Si[i] = SLOPEGRADIENT;
00067                 }
00068                 else {
00069                         Zi[i] = Zi[i-1];
00070                         Si[i] = 0;
00071                         }
00072         }
00073 }
00074 */
00075 /* ---bathyB--- *
00076   *  floor is flat in the box, then slope, and three ups and downs to downstream end
00077   *  grid interval is constant dx
00078   */
00079 /*
00080 void bathyB(double *Xi, double *Zi, double *Si, double dx)
00081 {
00082         int i;
00083         Xi[0] = 0;
00084         Zi[0] = DEPTHATORIGIN;
00085         for (i =1; i < NNODES; i++){
00086                 Xi[i] = (double)( i * dx);
00087                 if (Xi[i] <= BOXLENGTH){
00088                         Zi[i] = DEPTHATORIGIN;
00089                         Si[i] = 0;
00090                 }
00091                 else if (Xi[i] <= BOXLENGTH + SLOPELENGTH){
00092                         Zi[i] = Zi[i-1] - dx * SLOPEGRADIENT;
00093                         Si[i] = SLOPEGRADIENT;
00094                 }
00095                 else if (Xi[i] <= BOXLENGTH + SLOPELENGTH + HUMPLENGTH){
00096                         Zi[i] = Zi[i-1] + dx * (HUMPHEIGHT/HUMPLENGTH);
00097                         Si[i] = -HUMPHEIGHT/HUMPLENGTH;
00098                 }
00099                 else if (Xi[i] <= BOXLENGTH + SLOPELENGTH + 2 * HUMPLENGTH){
00100                         Zi[i] = Zi[i-1] - dx * (HUMPHEIGHT/HUMPLENGTH);
00101                         Si[i] = HUMPHEIGHT/HUMPLENGTH;
00102                 }
00103                 else if (Xi[i] <= BOXLENGTH + SLOPELENGTH + 3 * HUMPLENGTH){
00104                         Zi[i] = Zi[i-1] + dx * (HUMPHEIGHT/HUMPLENGTH);
00105                         Si[i] = -HUMPHEIGHT/HUMPLENGTH;
00106                 }
00107                 else if (Xi[i] <= BOXLENGTH + SLOPELENGTH + 4 * HUMPLENGTH){
00108                         Zi[i] = Zi[i-1] - dx * (HUMPHEIGHT/HUMPLENGTH);
00109                         Si[i] = HUMPHEIGHT/HUMPLENGTH;
00110                 }
00111                 else if (Xi[i] <= BOXLENGTH + SLOPELENGTH + 5 * HUMPLENGTH){
00112                         Zi[i] = Zi[i-1] + dx * (HUMPHEIGHT/HUMPLENGTH);
00113                         Si[i] = -HUMPHEIGHT/HUMPLENGTH;
00114                 }
00115                 else if (Xi[i] <= BOXLENGTH + SLOPELENGTH + 6 * HUMPLENGTH){
00116                         Zi[i] = Zi[i-1] - dx * (HUMPHEIGHT/HUMPLENGTH);
00117                         Si[i] = HUMPHEIGHT/HUMPLENGTH;
00118                 }
00119                 else {
00120                         Zi[i] = Zi[i-1];
00121                         Si[i] = 0;
00122                         }
00123         }
00124 }
00125 */
00126 /* ---bathyC--- *
00127   *  constant slope and then horizontal
00128   *  same with default inflow.bathy
00129   *  grid interval is constant dx
00130   */
00131 void bathyC(double *Xi, double *Zi, double *Si, double dx)
00132 {
00133         int i;
00134         Xi[0] = 0.0;
00135         Zi[0] = -3.0; /* river depth */
00136         for (i =1; i < 48; i++)
00137                         Xi[i] = (double)( i * 300.0);
00138         for (i =1; i < 25; i++){
00139                  if (Xi[i] <= 13200){
00140                         Zi[2*i -1] = Zi[2*i-2] - 300. * (13.12/300.0);
00141                         Si[2*i -1] = 13.12/300.0;
00142                         Zi[2*i] = Zi[2*i-1];
00143                         Si[2*i] = 0;
00144                 }
00145                 else {
00146                         Zi[i] = Zi[i-1];
00147                         Si[i] = 0;
00148                 }
00149         }
00150                 Xi[47] = 250000.0;
00151                 Zi[47] = Zi[47];
00152                 Si[47] = 0;
00153 }
00154 
00155 int interpolate2(double *x,double *y,int len,double *xNew,double *yNew,int lenNew, double dx)
00156 {
00157    int i,j;
00158         double m, b, x0;
00159         
00160         xNew[0]=x[0]; yNew[0] = y[0];
00161         for (j=1; j<lenNew; j++)
00162                         xNew[j] = dx + xNew[j-1];
00163 
00164    // initialize yNew with NaN's.
00165    for (j=0;j<lenNew;yNew[j]=0,j++);
00166 
00167    // set j to the first index inside of the given data.
00168    for (j=0;xNew[j]<x[0];j++);
00169 
00170    // interpolate linearly between points.
00171    for (i=0;i<len-1;i++)
00172    {
00173       m = (y[i+1]-y[i])/(x[i+1]-x[i]);
00174       b = y[i];
00175       x0 = x[i];
00176       while ( j<lenNew && xNew[j] <= x[i+1] )
00177       {
00178          yNew[j] = m*(xNew[j]-x0)+b;
00179          j++;
00180       }
00181    }
00182 
00183    return 0;
00184 }
00185 
00186 
00187 
00188 /* ---dudt--- *
00189   * returns (du/dt)
00190 */
00191 double
00192 dudt( double u     , double ul , double ur , double ull , double urr,
00193       double hl    , double hr , double hm ,
00194       double cl    , double cr , double cm ,
00195       double ustar , double s  , double Ew , double smallh , double dx, double Cd, double nu)
00196 {
00197         double dudx, du, ugrav, upress, ufric, uvisco, uright, uleft;
00198         double minmod2(double, double);
00199         double tvdleft(double, double, double, double, double, double);
00200         double tvdright(double, double, double, double, double, double);
00201         
00202 //      if (hm < HMIN )
00203 //                      fprintf(stderr, "error ...hm too small in dudt\n");
00204         if (cm < 0 )
00205                         fprintf(stderr, "error ...negative C in dudt; cm=%f\n",cm); 
00206                 
00207         uright = tvdright(u, u, ul, ur, ull, urr);
00208         uleft  = tvdleft (u, u, ul, ur, ull, urr);
00209         
00210         dudx = (uright - uleft)/dx;
00211         
00212         /* acceleration due to gravity on slope */
00213         ugrav = R * G * s * cm;
00214         
00215         /* acceleration due to pressure gradient */
00216         if (hm < HMIN) upress = R * G * (cm * (hr-hl) + 0.5 * hm * (cr-cl))/dx;
00217         else           upress = 0.5 * R * G / hm * ( cr * hr * hr - cl * hl * hl ) / dx;
00218                 
00219         /* acceleration due to friction; uStar determined from the energy equation*/
00220         if (hm < HMIN) ufric = 0;
00221         else           ufric= Cd * eh_sqr(u)/hm;
00222         
00223         uvisco = nu * (1 + 2.5 * cm) * (ur - 2 * u + ul)/(dx*dx);
00224 
00225         du = -u * dudx + ugrav - upress - ufric -uvisco;
00226 
00227         return du;
00228 }
00229 
00230 
00231 /* ---dfdt--- *
00232 * returns (d/dx)(u*f)
00233 * ext = Ew
00234 */
00235 double
00236 dfdt(double ul, double ur, double wl, double wr, double fl, double fr, double fll, double frr, double fm, double dx, double ext)
00237 {
00238         double fluxl, fluxr, dh, w;
00239         double minmod2(double, double);
00240         double tvdleft(double, double, double, double, double, double);
00241         double tvdright(double, double, double, double, double, double);
00242         
00243         fluxr = tvdright(ur, fm, fl, fr, fll, frr);
00244         fluxl = tvdleft(ul, fm, fl, fr, fll, frr);
00245         w = 0.5 * (wr + wl);    
00246         dh = (ul * wl * fluxl - ur * wr * fluxr)/dx/w + ext;
00247         return dh;
00248 }
00249 
00250 /* MINMOD */
00251 double minmod2(double x, double y)
00252 {
00253         double val;
00254         if (x * y < 0)
00255                         val = 0;
00256         else if (fabs(x) <= fabs(y))
00257                         val = x;
00258         else
00259                         val = y;
00260         return val;
00261 }
00262 
00263 /* TVD method to interpolate values at midpoint of the node */
00264 double tvdright(double u, double f, double fl, double fr, double fll, double frr){
00265         double ret;
00266         
00267         if (fabs(u) <= HMIN)
00268                         ret = 0.0;
00269         else if ( u > 0 && f - fl == 0 )
00270                         ret = f ;
00271         else if ( u > 0 && f <= HMIN)
00272                         ret = f ; 
00273         else if ( u > 0)
00274                         ret = f + 0.5 * (f - fl) * minmod2(1., (fr - f)/(f - fl));
00275         else if ( u < 0 && frr - fr ==0 )
00276                         ret = fr;
00277         else if ( u < 0 && fr <= HMIN)
00278                         ret = fr;
00279         else
00280                         ret = fr - 0.5 * (frr - fr) * minmod2(1., (fr - f)/(frr - fr));
00281         
00282         return ret;
00283         }
00284         
00285 double tvdleft(double u, double f, double fl, double fr, double fll, double frr){
00286         double ret;
00287         
00288         if (fabs(u) <= HMIN)
00289                         ret = 0.0;
00290         else if ( u > 0 && fl - fll == 0 )
00291                         ret = fl ;
00292         else if ( u > 0 && fl <= HMIN )
00293                         ret = fl ;
00294         else if ( u > 0)
00295                         ret = fl + 0.5 * (fl - fll) * minmod2(1., (f - fl)/(fl - fll));
00296         else if ( u < 0 && fr - f == 0 )
00297                         ret = f;
00298         else if ( u < 0 && f <= HMIN )
00299                         ret = f;
00300         else
00301                         ret = f - 0.5 * (fr - f) * minmod2(1., (f - fl)/(fr - f));
00302         
00303         return ret;
00304 }
00305 double tvd(double u, double fl, double fr, double fll, double frr){
00306         double ret;
00307         
00308         if ( u >= 0 && fl - fll == 0)
00309                         ret = fl;
00310         else if ( u >= 0)
00311                         ret = fl + 0.5 * (fl - fll) * minmod2(1., (fr - fl)/(fl - fll));
00312         else if ( u < 0 && frr - fr ==0)
00313                         ret = fr;
00314         else
00315                         ret = fr - 0.5 * (frr - fr) * minmod2(1., (fr - fl)/(frr - fr));
00316         
00317         return ret;
00318 }
00319 
00320 /* ---outputData--- *
00321   * print the results on outputfile 
00322 */
00323 
00324 void outputData(FILE *fp, int NNODES, double totTime, double *U, double *HH, double *CC, double *SED, double *Utemp, double *SEDRATE, double xhead, double uhead, int node)
00325 {
00326         int     i, day, hr, min;
00327         double sec;
00328         void getTime(double, int *, int *, int *, double *);
00329         
00330         /* output the time */
00331         getTime(totTime, &day, &hr, &min, &sec);
00332         fprintf(fp, "%2d:%2d:%2d:%4.1f\n", day, hr, min, sec);
00333         fprintf(stdout, "%2d:%2d:%2d:%4.2f\n", day, hr, min, sec);
00334         
00335         /* output the flow velocity, thickness, concentration, deposit mass and sedimentation rate at each node */
00336         for (i = 0; i < NNODES-1; i++) {
00337                 fprintf(fp, "%d\t%f\t%f\t%f\t%f\t%f\t%f\t\n", i, U[i], HH[i], CC[i], Utemp[i], SED[i], SEDRATE[i]);
00338         }
00339         
00340         /* ...and the last node of U and parameters at flow head */
00341         fprintf(fp, "%d\t%f\n", i, U[i]);
00342         fprintf(fp, "xhead = %f\tuhead = %f\n", xhead, uhead);
00343         fprintf(stdout, "xhead = %f\tuhead = %f\theadnode = %d\n\n", xhead, uhead, node);
00344                         
00345         /* output end-of-record indicator
00346         */
00347         fprintf(fp, "#\n");
00348         fflush(fp);
00349 }
00350 
00351 /* ---getTime---
00352   *     Gets the days, hours, minutes and seconds from a total number of seconds.
00353  */
00354 void getTime(double totTime, int *day, int *hr, int *min, double *sec)
00355 {
00356         *day    = (int)totTime/S_SECONDS_PER_DAY;
00357         *hr     = (int)(totTime - ((double)(*day) * DAY))/3600;
00358         *min    = (int)(totTime - ((double)(*day) * DAY) - ((double)(*hr) * 3600.0))/60;
00359         *sec    = totTime - ((double)(*day) * DAY) - ((double)(*hr) * 3600.0) - ((double)(*min) * 60);
00360 }
00361 
00362 
00363 

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