pihm/ihm10.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002  * File        : ihm10.c                                                       *
00003  * Function    : This is main entrance of IHM 1.0                              *
00004  * Programmer  : Yizhong Qu @ Pennsylvania State Univeristy                    *
00005  * Version     : May, 2004 (1.0)                                               * 
00006  *-----------------------------------------------------------------------------*
00007  *                                                                             *
00008  * IHM1.0 is an implementation of Yizhong Qu's PhD Thesis. It is an integrated *
00009  * finite volume hydrologic model. It simulates channel routing, overland flow *
00010  * and groundwater flow in full coupled scheme. It uses semi-discrete approach *
00011  * to discretize PDE into ODE, and solved it with SUNDIAL (LLNL) package.      *
00012  *                                                                             *
00013  * Reference                                                                   *
00014  *                                                                             *
00015  * 1.Yizhong Qu, An Integrated Hydrological Model Using Semi-Discrete Finite   *
00016  *               Volume Formulation, PhD Thesis, the Pennsylvanian State       *
00017  *               University, 2004                                              *
00018  * 2.Yizhong Qu, Christopher Duffy, Toward An Integrate Hydrological Model For *
00019  *               River Basins: A Semi-Discrete, Finite Volume Formulation      *
00020  *                                                                             *
00021  * This code is free for users with research purpose only, if appropriate      *
00022  * citation is refered. However, there is no warranty in any format for this   *
00023  * product.                                                                    *
00024  *                                                                             *
00025  * For questions or comments, please contact the authors of the reference.     *
00026  * One who want to use it for other consideration may also contact Dr.Duffy    *
00027  * at cxd11@psu.edu.                                                           *
00028  *                                                                             *      
00029  *******************************************************************************/
00030 
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <math.h>
00034 #include <string.h>
00035 #include <time.h>
00036 
00037 /* SUNDIAL Header Files */
00038 #include "sundials_types.h"   /* realtype, integertype, booleantype defination */
00039 #include "cvode.h"           /* CVODE header file                             */
00040 #include "cvode_spgmr.h"         /* CVSPGMR linear header file                    */
00041 #include "sundials_smalldense.h"      /* use generic DENSE linear solver for "small"   */
00042 #include "nvector_serial.h"  /* contains the definition of type N_Vector      */
00043 #include "sundials_math.h"    /* contains UnitRoundoff, RSqrt, SQR functions   */
00044 #include "cvode_dense.h"         /* CVDENSE header file                           */
00045 #include "sundials_dense.h"           /* generic dense solver header file              */
00046 
00047 /* IHM Header Files */
00048 #include "ihm.h"             /* Definations for all date Structure in IHM     */
00049 #include "calib.h"
00050 #include "et_is.h"
00051 #include "ihm10.h"
00052 
00053 #include "initialize.h"
00054 #include "read_alloc.h"
00055 #include "f.h"
00056 #include <QtGui/QProgressBar>
00057 #include "progress.h"
00058 
00059 /* Function to calculate right hand side of ODE systems */
00060 //void initialize(char *, Model_Data, Control_Data *, N_Vector);
00061 //void calET(realtype, realtype, N_Vector, Model_Data);
00062 //void calIS(realtype, realtype, Model_Data, N_Vector);
00063 //int f(realtype, N_Vector, N_Vector, void *);
00064 //void read_alloc(char *, Model_Data, Control_Data *);
00065 
00066 realtype CS_AreaOrPerem1(int rivOrder, realtype rivDepth, realtype rivCoeff, realtype a_pBool);
00067 realtype OverlandFlow1( int loci, int locj, int surfmode, realtype avg_y, realtype grad_y, realtype avg_sf, realtype alfa, realtype beta, realtype crossA, realtype avg_rough, int eletypeBool, realtype avg_perem);
00068 void printRiverFlux(Model_Data, N_Vector, FILE *res_flux_file);
00069 
00070 
00071 
00072 int satEle, ovrEle;
00073   
00074 /* Main Function */
00075 int ihm10(int argc, char *argv[], QProgressBar* bar)
00076 { 
00077   realtype Tsteps; 
00078   //char *filename = "sc";        /* Input file name prefix    */
00079   char *filename;
00080   char *StateFile;                /* Output file name string   */
00081   char *FluxFile;
00082   char *ETISFile;  
00083   char *QFile;  
00084   char c_char;  
00085   Model_Data mData;               /* Model Data                */
00086   Control_Data cData;             /* Solver Control Data       */
00087   
00088   N_Vector CV_Y;                  /* State Variables Vector    */
00089   
00090 /*  realtype ropt[OPT_SIZE]; */        /* Optional real type and integer type  */
00091 /*  long int iopt[OPT_SIZE];     */   /* vecter for Message Passing to solver */
00092   
00093   void *cvode_mem;                /* Model Data Pointer        */
00094   int flag;                       /* flag to test return value */
00095   
00096   FILE *res_state_file;           /* Output file for States    */
00097   FILE *res_flux_file;            /* Output file for Flux      */
00098   FILE *res_etis_file;            /* Output file for ET and IS */
00099   FILE *res_q_file;
00100   FILE *fpInit;
00101 
00102   FILE *headFile;
00103   FILE *overFile;
00104   FILE *baseFile; 
00105   FILE *timeFile;
00106 
00107 FILE *hFile;
00108 realtype *head;
00109 
00110 FILE *prepFile;
00111 realtype tempPrep=0.0;
00112 realtype tempNetPrep=0.0;
00113 realtype tempET0 = 0.0;
00114 realtype tempET1 = 0.0;
00115 realtype tempET2 = 0.0;
00116 realtype tempTF = 0.0;
00117 int tempI;
00118 
00119   int N;                          /* Problem size              */
00120   int i,j,k;                          /* loop index                */
00121   realtype t;                     /* simulation time           */
00122   realtype NextPtr, StepSize;     /* stress period & step size */
00123   
00124   clock_t start, end_r, end_s;    /* system clock at points    */
00125   realtype cputime_r, cputime_s;  /* for duration in realtype  */
00126 
00127   realtype totbase1=0,totbase2=0,totbase3,totbase4;
00128  
00129   int ctr3,ctr4; 
00130   realtype massSurf, massRiv, massSat, massUnSat,massP=0, massET1=0, massET2=0, massET3=0,NetMass,massQ=0,massIS,massSnow,massRecharge,massSurfC, massRivC, massSatC, tmpArea=0;
00131 
00132   FILE *fpMassBal;
00133   char *fpMassBalFile;
00134 
00135   char tmpFileName[100];
00136   setFileName(tmpFileName);
00137   filename = (char *)malloc(sizeof(char)*strlen(tmpFileName));
00138   strcpy(filename, tmpFileName);
00139 
00140   /* allocate memory for model data structure */
00141   mData = (Model_Data)malloc(sizeof *mData);
00142   start = clock();
00143         
00144   
00145   /* get user specified file name in command line */
00146   if(argc >= 2)
00147   {
00148     filename = (char *)malloc(strlen(argv[1])*sizeof(char));
00149     strcpy(filename, argv[1]);
00150   }  
00151 
00152   hFile = fopen("sc.h", "w");
00153   prepFile = fopen("sc.prep", "w");
00154 
00155   fpMassBalFile = (char *)malloc((strlen(tmpFileName)+5)*sizeof(char));
00156   strcpy(fpMassBalFile, tmpFileName);
00157   strcat(fpMassBalFile,".MB");
00158   fpMassBal=fopen(fpMassBalFile,"w");
00159   printf("\nBelt up!  PIHM 1.0 is starting ... \n");
00160   res_flux_file=fopen("sc.res1","w"); 
00161   /* read in 7 input files with "filename" as prefix */
00162   read_alloc(filename, mData, &cData); 
00163 
00164   headFile=fopen("sc.head","w");
00165   overFile=fopen("sc.over","w");
00166   baseFile=fopen("sc.base","w");
00167   timeFile=fopen("sc.time","w");
00168 
00169 if(mData->UnsatMode ==1)
00170         {    
00171   /* problem size */
00172   N = 2*mData->NumEle + mData->NumRiv;
00173         }
00174 if(mData->UnsatMode ==2)
00175         {    
00176   /* problem size */
00177   N = 3*mData->NumEle + mData->NumRiv;
00178   printf("\ndefinately here\n");
00179         }       
00180   
00181   /* initial state variable depending on machine*/
00182   CV_Y = N_VNew_Serial(N);
00183   
00184   /* initialize mode data structure */
00185   initialize(filename, mData, &cData, CV_Y);
00186   /*for (i=0; i<mData->NumEle; i++)
00187         printf("%lf\t%lf\t%lf\t%lf\n",mData->Ele[i].zmin, mData->Ele[i].zmax, NV_Ith_S(CV_Y, i+mData->NumEle), NV_Ith_S(CV_Y, i+2*mData->NumEle));
00188   getchar();*/
00189  
00190         head=(realtype *)malloc(mData->NumEle*sizeof(realtype));
00191 
00192   if(cData.Debug == 1) {PrintModelData(mData);}  
00193   
00194   end_r = clock();
00195   cputime_r = (end_r - start)/(realtype)CLOCKS_PER_SEC;
00196   
00197   printf("\nSolving ODE system ... \n");
00198   
00199   /* initial control parameter for CVODE solver. Otherwise the default value by C could cause problems. */
00200  /* for(i=0; i<OPT_SIZE; i++)
00201   {
00202     ropt[i] = 0.0;
00203     iopt[i] = 0;
00204   }
00205   */
00206  
00207   /* allocate memory for solver */
00208   cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON);
00209   if(cvode_mem == NULL) {printf("CVodeMalloc failed. \n"); return(1);}
00210   
00211   flag = CVodeSetFdata(cvode_mem, mData);
00212   flag = CVodeSetInitStep(cvode_mem,cData.InitStep);
00213   flag = CVodeSetStabLimDet(cvode_mem,TRUE);
00214   flag = CVodeSetMaxStep(cvode_mem,cData.MaxStep);
00215   flag = CVodeMalloc(cvode_mem, f, cData.StartTime, CV_Y, CV_SS, cData.reltol, &cData.abstol);
00216 
00217 
00218   flag = CVSpgmr(cvode_mem, PREC_NONE, 0);
00219   flag = CVSpilsSetGSType(cvode_mem, MODIFIED_GS);
00220 //CVSpilsSetGSType
00221 
00222 /* if(cData.Solver == 1)
00223   {
00224     /* using dense direct solver 
00225     flag = CVDense(cvode_mem, NULL, NULL);
00226     if(flag != SUCCESS) {printf("CVDense failed. \n"); return(1);} 
00227   } 
00228   else if(cData.Solver == 2)
00229   {
00230     /* using iterative solver 
00231     flag = CVSpgmr(cvode_mem, NONE, cData.GSType, cData.MaxK, cData.delt, NULL, NULL,
00232                        mData, NULL, NULL);
00233     if (flag != SUCCESS) {printf("CVSpgmr failed."); return(1);}
00234   } */
00235   
00236   /*allocate and copy to get output file name */
00237   StateFile = (char *)malloc((strlen(filename)+4)*sizeof(char));
00238   strcpy(StateFile, filename);
00239   FluxFile  = (char *)malloc((strlen(filename)+5)*sizeof(char));
00240   strcpy(FluxFile, filename);
00241   ETISFile  = (char *)malloc((strlen(filename)+5)*sizeof(char));
00242   strcpy(ETISFile, filename);
00243   QFile = (char *)malloc((strlen(filename)+2)*sizeof(char));
00244   strcpy(QFile, filename);
00245   
00246   /* open output file */
00247   if (cData.res_out == 1) {res_state_file = fopen(strcat(StateFile, ".res"), "w");}
00248   if (cData.flux_out == 1) {res_flux_file = fopen(strcat(FluxFile, ".flux"), "w");}
00249   if (cData.etis_out == 1) {res_etis_file = fopen(strcat(ETISFile, ".etis"), "w");}
00250   if (cData.q_out == 1) {res_q_file = fopen(strcat(QFile, ".q"), "w");}
00251   
00252   /* print header of output file */
00253   if (cData.res_out == 1) {FPrintYheader(res_state_file, mData);}
00254   if (cData.etis_out == 1) {FPrintETISheader(res_etis_file, mData);}
00255   if (cData.q_out == 1) {FPrintETISheader(res_q_file, mData);}
00256   printf("\n");
00257   
00258   /* set start time */
00259   t = cData.StartTime;
00260   
00261   /* start solver in loops */
00262   for(i=0; i<cData.NumSteps; i++)
00263   {
00264 /*    if (cData.Verbose != 1)
00265     {
00266       printf("  Running: %-4.1f%% ... ", (100*(i+1)/((realtype) cData.NumSteps))); 
00267       fflush(stdout);
00268     } */
00269 
00270     /* inner loops to next output points with ET step size control */
00271     while(t < cData.Tout[i+1])
00272     {
00273       if (t + cData.ETStep >= cData.Tout[i+1])
00274       {
00275         NextPtr = cData.Tout[i+1];
00276       }
00277       else
00278       {
00279         NextPtr = t + cData.ETStep;
00280       }
00281       StepSize = NextPtr - t; 
00282       
00283       /* calculate Interception Storage */
00284       calIS(t, StepSize, mData,CV_Y);
00285 
00286 /******************************************************************************************/
00287         //tempNetPrep = 0.0;
00288         //tempPrep    = 0.0;
00289         //tempET0     = 0.0;
00290         //tempTF      = 0.0;
00291         for(tempI=0; tempI<mData->NumEle; tempI++){
00292                 tempPrep += mData->ElePrep[tempI];
00293                 tempNetPrep += mData->EleNetPrep[tempI];
00294                 tempET0 += mData->EleET[tempI][0]*mData->Ele[tempI].VegFrac;
00295                 tempET1 += mData->EleET[tempI][1];
00296                 tempET2 += mData->EleET[tempI][2];
00297                 tempTF  += mData->EleTF[tempI]*mData->Ele[tempI].VegFrac;
00298         }
00299         fprintf(prepFile, "%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\n", t, tempPrep/mData->NumEle, tempNetPrep/mData->NumEle, tempET0/mData->NumEle, tempET1/mData->NumEle, tempET2/mData->NumEle,tempTF/mData->NumEle);//fflush(prepFile);
00300 /******************************************************************************************/
00301 
00302         Tsteps=t;
00303 printf("\n Tsteps = %f ",t);
00304       flag = CVode(cvode_mem, NextPtr, CV_Y, &t, CV_NORMAL);  
00305         setProgressBar(bar, 100*(i+1)/((realtype) cData.NumSteps));
00306 
00307 
00308    for(k=0; k<mData->NumPrep; k++){
00309         while(mData->TSD_Prep[k].iCounter < mData->TSD_Prep[k].length && t/(24.0*60.0) > mData->TSD_Prep[k].TS[mData->TSD_Prep[k].iCounter+1][0]){
00310                 mData->TSD_Prep[k].iCounter++;
00311         }
00312    }
00313    for(k=0; k<mData->NumTemp; k++){
00314         while(mData->TSD_Temp[k].iCounter < mData->TSD_Temp[k].length && t/(24.0*60.0) > mData->TSD_Temp[k].TS[mData->TSD_Temp[k].iCounter+1][0]){
00315                 mData->TSD_Temp[k].iCounter++;
00316         }
00317    }
00318    for(k=0; k<mData->NumHumidity; k++){
00319         while(mData->TSD_Humidity[k].iCounter < mData->TSD_Humidity[k].length && t/(24.0*60.0) > mData->TSD_Humidity[k].TS[mData->TSD_Humidity[k].iCounter+1][0]){
00320                 mData->TSD_Humidity[k].iCounter++;
00321         }
00322    }
00323    for(k=0; k<mData->NumWindVel; k++){
00324         while(mData->TSD_WindVel[k].iCounter < mData->TSD_WindVel[k].length && t/(24.0*60.0) > mData->TSD_WindVel[k].TS[mData->TSD_WindVel[k].iCounter+1][0]){
00325                 mData->TSD_WindVel[k].iCounter++;
00326         }
00327    }
00328    for(k=0; k<mData->NumRn; k++){
00329         while(mData->TSD_Rn[k].iCounter < mData->TSD_Rn[k].length && t/(24.0*60.0) > mData->TSD_Rn[k].TS[mData->TSD_Rn[k].iCounter+1][0]){
00330                 mData->TSD_Rn[k].iCounter++;
00331         }
00332    }
00333    for(k=0; k<mData->NumG; k++){
00334         while(mData->TSD_G[k].iCounter < mData->TSD_G[k].length && t/(24.0*60.0) > mData->TSD_G[k].TS[mData->TSD_G[k].iCounter+1][0]){
00335                 mData->TSD_G[k].iCounter++;
00336         }
00337    }
00338    for(k=0; k<mData->NumP; k++){
00339         while(mData->TSD_Pressure[k].iCounter < mData->TSD_Pressure[k].length && t/(24.0*60.0) > mData->TSD_Pressure[k].TS[mData->TSD_Pressure[k].iCounter+1][0]){
00340                 mData->TSD_Pressure[k].iCounter++;
00341         }
00342    }
00343    for(k=0; k<mData->NumLC; k++){
00344         while(mData->TSD_LAI[k].iCounter < mData->TSD_LAI[k].length && t/(24.0*60.0) > mData->TSD_LAI[k].TS[mData->TSD_LAI[k].iCounter+1][0]){
00345                 mData->TSD_LAI[k].iCounter++;
00346         }
00347    }
00348    for(k=0; k<mData->NumLC; k++){
00349         while(mData->TSD_DH[k].iCounter < mData->TSD_DH[k].length && t/(24.0*60.0) > mData->TSD_DH[k].TS[mData->TSD_DH[k].iCounter+1][0]){
00350                 mData->TSD_DH[k].iCounter++;
00351         }
00352    }
00353    for(k=0; k<mData->NumMeltF; k++){
00354         while(mData->TSD_MeltF[k].iCounter < mData->TSD_MeltF[k].length && t/(24.0*60.0) > mData->TSD_MeltF[k].TS[mData->TSD_MeltF[k].iCounter+1][0]){
00355                 mData->TSD_MeltF[k].iCounter++;
00356         }
00357    }
00358    for(k=0; k<mData->NumSource; k++){
00359         while(mData->TSD_Source[k].iCounter < mData->TSD_Source[k].length && t/(24.0*60.0) > mData->TSD_Source[k].TS[mData->TSD_Source[k].iCounter+1][0]){
00360                 mData->TSD_Source[k].iCounter++;
00361         }
00362    }
00363 
00364 
00365 
00366 
00367 
00368 
00369 /**********************************************MASS BALANCE*****************************************************/
00370 
00371         massSurf=0;
00372         massRiv=0;
00373         massSat=0;
00374         massUnSat=0;
00375         massIS=0;
00376         massRecharge=0;
00377         massSnow=0;
00378         tmpArea=0;
00379 
00380 /*      massNetP=0;
00381         massET=0; */
00382       for(j=0;j<N;j++)
00383       {
00384         if(j<mData->NumEle)
00385         {
00386                 head[j]=head[j]+(NV_Ith_S(CV_Y,j)>0.0?NV_Ith_S(CV_Y,j):0.0);
00387                 
00388                 massSurf=massSurf+((NV_Ith_S(CV_Y, j)<0?0:NV_Ith_S(CV_Y, j))-mData->Ele_IC[j].surf)*mData->Ele[j].area;
00389 /*              if(NV_Ith_S(CV_Y, j)>0)
00390                 {                printf("\n%d %e %e %e %e %e %e",j,mData->EleVic[j],mData->EleNetPrep[j],NV_Ith_S(CV_Y, j),NV_Ith_S(CV_Y, j+mData->NumEle),NV_Ith_S(CV_Y, j+2*mData->NumEle),mData->Ele[j].zmax-mData->Ele[j].zmin);
00391                 }
00392 */              massP=massP+mData->EleNetPrep[j]*mData->Ele[j].area;
00393 /*              massET=massET+(mData->EleET[j][1]+mData->EleET[j][0])*mData->Ele[j].area; */
00394                 massET1=massET1+(mData->EleET[j][0])*mData->Ele[j].area;
00395                 massET2=massET2+(mData->EleET[j][1])*mData->Ele[j].area;
00396                 massET3=massET3+(NV_Ith_S(CV_Y, j+2*mData->NumEle)<0?0:NV_Ith_S(CV_Y, j+2*mData->NumEle))*(mData->EleET[j][2])*mData->Ele[j].area/(mData->Ele[j].zmax-mData->Ele[j].zmin);               
00397                 massIS=massIS+mData->EleIS[j]*mData->Ele[j].area;
00398                 massSnow=massSnow+(mData->EleSnow[j]-mData->Ele_IC[j].snow)*mData->Ele[j].area;
00399                 massRecharge =massRecharge + mData->Recharge[j];
00400         
00401         }
00402         if(j>=3*mData->NumEle)
00403         {       
00404                 massRiv=massRiv+((NV_Ith_S(CV_Y, j)<0?0:NV_Ith_S(CV_Y, j))-mData->Riv_IC[j].value)*mData->Riv_Shape[mData->Riv[j-3*mData->NumEle].shape - 1].width*mData->Riv[j-3*mData->NumEle].Length;
00405         }
00406         if((j>=2*mData->NumEle)&&(j<3*mData->NumEle))
00407         {
00408 
00409                 massSat=massSat+((NV_Ith_S(CV_Y, j)<0?0:NV_Ith_S(CV_Y, j)))*mData->Ele[j-2*mData->NumEle].area*mData->Ele[j-2*mData->NumEle].Porosity;
00410 
00411         }
00412         if((j>=mData->NumEle)&&(j<2*mData->NumEle))
00413         {
00414                 massUnSat=massUnSat+((NV_Ith_S(CV_Y, j)<0?0:NV_Ith_S(CV_Y, j)))*mData->Ele[j-mData->NumEle].area*mData->Ele[j-mData->NumEle].Porosity;
00415 
00416         }
00417       }
00418       massQ=massQ+mData->Q;
00419       NetMass=-(massSurf+massSat+massUnSat+massRiv+massIS+massSnow)+massP-massET1-massET3-massQ;
00420 //      fprintf(fpMassBal,"\n %f %f %f %f %f %f %e %f %f %f %f %f %f",t,massSurf,massSat,massUnSat,massRiv,massIS,massRecharge,massP,massET1,massET2,massET3,massQ,NetMass);
00421 /*      fprintf(res_flux_file,"\n%f %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",t,mData->FluxRiv[1199][1],mData->FluxRiv[1199][0],mData->FluxRiv[1141][1],mData->FluxRiv[1141][0],mData->FluxRiv[1126][1],mData->FluxRiv[1126][0],mData->FluxRiv[1129][1],mData->FluxRiv[1129][0],mData->FluxRiv[1136][1],mData->FluxRiv[1136][0],mData->FluxRiv[1137][1],mData->FluxRiv[1137][0],mData->FluxRiv[1138][1],mData->FluxRiv[1138][0]);
00422   */
00423  //   fprintf(res_flux_file,"\n%f %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",t,mData->FluxRiv[1136][1],mData->FluxRiv[1136][0],mData->FluxRiv[1136][2],mData->FluxRiv[1136][3],NV_Ith_S(CV_Y,mData->Riv[1136].LeftEle-1),NV_Ith_S(CV_Y,mData->Riv[1136].RightEle-1),NV_Ith_S(CV_Y, 1136+3*mData->NumEle),NV_Ith_S(CV_Y,2*mData->NumEle+mData->Riv[1136].LeftEle-1),NV_Ith_S(CV_Y,2*mData->NumEle+mData->Riv[1136].RightEle-1),NV_Ith_S(CV_Y,1*mData->NumEle+mData->Riv[1136].LeftEle-1),NV_Ith_S(CV_Y,1*mData->NumEle+mData->Riv[1136].RightEle-1),mData->FluxRiv[1137][1],mData->FluxRiv[1137][0],mData->FluxRiv[1137][2],mData->FluxRiv[1137][3],NV_Ith_S(CV_Y,mData->Riv[1137].LeftEle-1),NV_Ith_S(CV_Y,mData->Riv[1137].RightEle-1),NV_Ith_S(CV_Y, 1137+3*mData->NumEle),NV_Ith_S(CV_Y,2*mData->NumEle+mData->Riv[1137].LeftEle-1),NV_Ith_S(CV_Y,2*mData->NumEle+mData->Riv[1137].RightEle-1),NV_Ith_S(CV_Y,1*mData->NumEle+mData->Riv[1137].LeftEle-1),NV_Ith_S(CV_Y,1*mData->NumEle+mData->Riv[1137].RightEle-1),mData->FluxRiv[1138][1],mData->FluxRiv[1138][0],mData->FluxRiv[1138][2],mData->FluxRiv[1138][3],NV_Ith_S(CV_Y,mData->Riv[1138].LeftEle-1),NV_Ith_S(CV_Y,mData->Riv[1138].RightEle-1),NV_Ith_S(CV_Y, 1138+3*mData->NumEle),NV_Ith_S(CV_Y,2*mData->NumEle+mData->Riv[1138].LeftEle-1),NV_Ith_S(CV_Y,2*mData->NumEle+mData->Riv[1138].RightEle-1),NV_Ith_S(CV_Y,1*mData->NumEle+mData->Riv[1138].LeftEle-1),NV_Ith_S(CV_Y,1*mData->NumEle+mData->Riv[1138].RightEle-1));
00424 // fprintf(res_flux_file,"\n%f",t);
00425 /*totbase2=0;
00426 totbase3=totbase4=0.0;
00427 ctr3=ctr4=0;
00428 for(k=0;k<mData->NumRiv;k++)
00429 {
00430   totbase2=totbase2+mData->FluxRiv[k][4]+mData->FluxRiv[k][5];
00431   totbase3=totbase3+NV_Ith_S(CV_Y,mData->Riv[k].LeftEle-1+2*mData->NumEle)/(mData->Ele[mData->Riv[k].LeftEle-1].zmax-mData->Ele[mData->Riv[k].LeftEle-1].zmin);
00432   totbase4=totbase4+NV_Ith_S(CV_Y,mData->Riv[k].RightEle-1+2*mData->NumEle)/(mData->Ele[mData->Riv[k].RightEle-1].zmax-mData->Ele[mData->Riv[k].RightEle-1].zmin);
00433   if(NV_Ith_S(CV_Y,mData->Riv[k].LeftEle-1)>0)
00434         {
00435         ctr3=ctr3+1;
00436         }
00437   if(NV_Ith_S(CV_Y,mData->Riv[k].RightEle-1)>0)
00438         {
00439         ctr4=ctr4+1;
00440         }
00441 // printf("\n%d\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf",k,NV_Ith_S(CV_Y,mData->Riv[k].LeftEle-1+2*mData->NumEle),mData->Ele[mData->Riv[k].LeftEle-1].zmax,mData->Ele[mData->Riv[k].LeftEle-1].zmin,NV_Ith_S(CV_Y,mData->Riv[k].RightEle-1+2*mData->NumEle),mData->Ele[mData->Riv[k].RightEle-1].zmax,mData->Ele[mData->Riv[k].RightEle-1].zmin);
00442 //fprintf(res_flux_file,"%f\t",mData->FluxRiv[k][1]);
00443 }*/
00444 //fprintf(res_flux_file,"\n");
00445 //fprintf(res_flux_file,"%lf %lf %lf %lf %lf %lf %lf %lf\n", mData->Riv[343].zmin,  mData->Riv[349].zmin, mData->Riv[350].zmin, mData->Riv[352].zmin, NV_Ith_S(CV_Y, 343+3*mData->NumEle), NV_Ith_S(CV_Y, 349+3*mData->NumEle), NV_Ith_S(CV_Y, 350+3*mData->NumEle), NV_Ith_S(CV_Y, 352+3*mData->NumEle));
00446 //fprintf(res_flux_file,"%lf %lf %lf %lf %lf %lf %lf %lf\n", mData->Riv[343].zmin,  mData->Riv[349].zmin, mData->Riv[350].zmin, mData->Riv[352].zmin, mData->FluxRiv[343][1], mData->FluxRiv[349][1], mData->FluxRiv[350][1], mData->FluxRiv[352][1]);
00447 //fprintf(res_flux_file,"%lf %lf %lf %lf\n", mData->FluxRiv[290][1], mData->FluxRiv[260][1], mData->FluxRiv[273][1], mData->FluxRiv[129][1]);
00448 printRiverFlux(mData, CV_Y, res_flux_file);
00449 for(k=0; k<mData->NumRiv;k++){
00450         //fprintf(res_flux_file,"%lf\t",mData->FluxRiv[k][1]);
00451         fprintf(headFile,"%lf\t",NV_Ith_S(CV_Y, k+3*mData->NumEle));
00452         fprintf(overFile,"%lf\t",mData->FluxRiv[k][2]+mData->FluxRiv[k][3]);
00453         fprintf(baseFile,"%lf\t",mData->FluxRiv[k][4]+mData->FluxRiv[k][5]);
00454 }
00455 satEle=0;
00456 ovrEle=0;
00457 for(k=0; k<mData->NumEle;k++)
00458 {
00459         if(NV_Ith_S(CV_Y, k+2*mData->NumEle)/(mData->Ele[k].zmax-mData->Ele[k].zmin)>0.99){
00460                 satEle++;
00461         }
00462         if(NV_Ith_S(CV_Y, k)>1E-4){
00463                 ovrEle++;
00464         }
00465 }
00466 
00467 
00468 //fprintf(res_flux_file,"\n"); //fflush(res_flux_file);
00469 fprintf(headFile,"\n"); //fflush(headFile);
00470 fprintf(overFile,"\n");
00471 fprintf(baseFile,"\n");
00472 //fprintf(timeFile,"%f\t%lf\n",t,(clock()-start)/(realtype)CLOCKS_PER_SEC/60.0);
00473 fprintf(timeFile,"%f\t%lf\t%d\t%d\n",t,(clock()-start)/(realtype)CLOCKS_PER_SEC/60.0,satEle,ovrEle);
00474 //fflush(timeFile);
00475 //getchar(); 
00476 totbase1=mData->FluxRiv[145][4]+mData->FluxRiv[145][5]+mData->FluxRiv[163][4]+mData->FluxRiv[163][5]+mData->FluxRiv[164][4]+mData->FluxRiv[164][5]+mData->FluxRiv[166][4]+mData->FluxRiv[166][5]+mData->FluxRiv[167][4]+mData->FluxRiv[167][5]+mData->FluxRiv[168][4]+mData->FluxRiv[168][5]+mData->FluxRiv[178][4]+mData->FluxRiv[178][5]+mData->FluxRiv[182][4]+mData->FluxRiv[182][5]+mData->FluxRiv[183][4]+mData->FluxRiv[183][5]+mData->FluxRiv[201][4]+mData->FluxRiv[201][5]+mData->FluxRiv[202][4]+mData->FluxRiv[202][5]+mData->FluxRiv[203][4]+mData->FluxRiv[203][5]+mData->FluxRiv[204][4]+mData->FluxRiv[204][5]+mData->FluxRiv[205][4]+mData->FluxRiv[205][5]+mData->FluxRiv[207][4]+mData->FluxRiv[207][5]+mData->FluxRiv[208][4]+mData->FluxRiv[208][5]+mData->FluxRiv[209][4]+mData->FluxRiv[209][5]+mData->FluxRiv[210][4]+mData->FluxRiv[210][5]+mData->FluxRiv[211][4]+mData->FluxRiv[211][5];
00477 //fprintf(res_flux_file,"\n%f\t%lf\t%lf",t,mData->FluxRiv[276][1],mData->FluxRiv[132][1]);
00478 
00479 //fprintf(res_flux_file,"\n%f\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%f",t,mData->FluxRiv[145][1],mData->FluxRiv[48][1],totbase1,totbase2,totbase3/mData->NumRiv,totbase4/mData->NumRiv,(float)(ctr3+ctr4)/mData->NumRiv);
00480 //fprintf(res_flux_file,"\n%f\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf",t,mData->FluxRiv[145][0],mData->FluxRiv[145][1],NV_Ith_S(CV_Y,2*mData->NumEle+mData->Riv[145].LeftEle-1),NV_Ith_S(CV_Y,2*mData->NumEle+mData->Riv[145].RightEle-1),NV_Ith_S(CV_Y,2*mData->NumEle+869),NV_Ith_S(CV_Y,2*mData->NumEle+772),mData->FluxRiv[48][0],mData->FluxRiv[48][1]);
00481 //fprintf(res_flux_file,"\n%f %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",t,mData->FluxRiv[208][0],mData->FluxRiv[208][1],mData->FluxRiv[208][2],mData->FluxRiv[208][3],mData->FluxRiv[208][4],mData->FluxRiv[208][5],mData->FluxRiv[145][0],mData->FluxRiv[145][1],mData->FluxRiv[145][2],mData->FluxRiv[145][3],mData->FluxRiv[145][4],mData->FluxRiv[145][5],NV_Ith_S(CV_Y,869+2*mData->NumEle));
00482 //      printf("\n%lf %lf %lf %lf ",mData->FluxRiv[1199][1],mData->FluxRiv[1109][1],mData->FluxRiv[1154][1],mData->FluxRiv[2036][1]);
00483 
00484 /**********************************************MASS BALANCE*****************************************************/    
00485     
00486     }  
00487 
00488 /*     if(cData.Verbose == 1) {PrintVerbose(i, t, iopt, ropt);} */
00489 
00490     /* uncomment it if user need it verbose mode */  
00491     /* if(cData.Verbose == 1) {PrintY(mData, CV_Y, t);} */
00492     
00493     /* print out results to files at every output time */
00494     if (cData.res_out == 1) {FPrintY(mData, CV_Y, t, res_state_file);}
00495     if (cData.flux_out == 1) {FPrintFlux(mData, t, res_flux_file);}
00496     if (cData.etis_out == 1) {FPrintETIS(mData, t, res_etis_file);}
00497   /*  if (cData.q_out == 1) {FPrintQ(mData, t, res_q_file);} */
00498     
00499 /*    if (cData.Verbose != 1) {printf("\r");}  
00500     
00501     if(flag != SUCCESS) {printf("CVode failed, flag = %d. \n", flag); return(flag);} 
00502   */  
00503     /* clear buffer */
00504    fflush(stdout);  
00505   }
00506 
00507 /**********************************/
00508 /*    Routine for .init File      */
00509 /**********************************/
00510 fpInit = fopen("rhode.init","w");
00511 fprintf(fpInit,"%lf\n",cData.Tout[i]);
00512 for(j=0; j<mData->NumEle; j++)
00513 {
00514         fprintf(fpInit,"%lf\t%lf\t%lf\t%lf\t%lf\n",mData->EleIS[j],mData->EleSnow[j],NV_Ith_S(CV_Y,j), NV_Ith_S(CV_Y,j+mData->NumEle), NV_Ith_S(CV_Y,j+2*mData->NumEle));
00515 }
00516 for(j=0; j<mData->NumRiv; j++)
00517 {
00518         fprintf(fpInit,"%lf\n",NV_Ith_S(CV_Y, j+3*mData->NumEle));
00519 }
00520 /**********************************/
00521 
00522 
00523 for(i=0; i<mData->NumEle; i++){
00524         fprintf(hFile, "%d %lf\n", i+1, head[i]);
00525 } 
00526 fflush(hFile);
00527 
00528 fflush(fpInit);
00529 fflush(headFile);
00530 fflush(timeFile);
00531 fflush(headFile);
00532 fflush(baseFile);
00533 fflush(overFile);
00534 
00535   /* free memory */
00536   /*
00537   N_VFree(CV_Y);
00538   CVodeFree(cvode_mem);
00539   M_EnvFree_Serial(machEnv); 
00540   */
00541   
00542   /* capture time */
00543   end_s = clock();
00544   cputime_s = (end_s - end_r)/(realtype)CLOCKS_PER_SEC;
00545   
00546   /* print out simulation statistics */
00547 /*  PrintFarewell(cData, iopt, ropt, cputime_r, cputime_s);
00548   if (cData.res_out == 1) {FPrintFarewell(cData, res_state_file, iopt, ropt, cputime_r, cputime_s);}
00549   */
00550   /* close output files */
00551   if (cData.res_out == 1)  {fclose(res_state_file);}
00552   if (cData.flux_out == 1) {fclose(res_flux_file);}
00553   if (cData.etis_out == 1) {fclose(res_etis_file);}
00554   if (cData.q_out == 1)    {fclose(res_q_file);}
00555   
00556   free(mData);
00557   
00558   return 0;
00559 }
00560 
00561 
00562 realtype CS_AreaOrPerem1(int rivOrder, realtype rivDepth, realtype rivCoeff, realtype a_pBool)
00563 {
00564         realtype rivArea, rivPerem, eq_Wid, EPSILON=0.05;
00565         switch(rivOrder)
00566         {
00567                 case 1:
00568                         rivArea = rivDepth*rivCoeff;
00569                         rivPerem= 2.0*rivDepth+rivCoeff;
00570                         eq_Wid=rivCoeff;
00571                         return (a_pBool==1?rivArea:(a_pBool==2?rivPerem:eq_Wid)); //returnVal1(rivArea, rivPerem, eq_Wid, a_pBool);
00572                 case 2:
00573                         rivArea = pow(rivDepth,2)/rivCoeff;
00574                         rivPerem = 2.0*rivDepth*pow(1+pow(rivCoeff,2),0.5)/rivCoeff;
00575                         eq_Wid=2.0*pow(rivDepth+EPSILON,1/(rivOrder-1))/pow(rivCoeff,1/(rivOrder-1));
00576                         return (a_pBool==1?rivArea:(a_pBool==2?rivPerem:eq_Wid)); //returnVal1(rivArea, rivPerem, eq_Wid, a_pBool);
00577                 case 3:
00578                         rivArea = 4*pow(rivDepth,1.5)/(3*pow(rivCoeff,0.5));
00579                         rivPerem =(pow(rivDepth*(1+4*rivCoeff*rivDepth)/rivCoeff,0.5))+(log(2*pow(rivCoeff*rivDepth,0.5)+pow(1+4*rivCoeff*rivDepth,0.5))/(2*rivCoeff));
00580                         eq_Wid=2.0*pow(rivDepth+EPSILON,1/(rivOrder-1))/pow(rivCoeff,1/(rivOrder-1));
00581                         return (a_pBool==1?rivArea:(a_pBool==2?rivPerem:eq_Wid)); //returnVal1(rivArea, rivPerem, eq_Wid, a_pBool);
00582                 case 4:
00583                         rivArea = 3*pow(rivDepth,4.0/3.0)/(2*pow(rivCoeff,1.0/3.0));
00584                         rivPerem = 2*((pow(rivDepth*(1+9*pow(rivCoeff,2.0/3.0)*rivDepth),0.5)/3)+(log(3*pow(rivCoeff,1.0/3.0)*pow(rivDepth,0.5)+pow(1+9*pow(rivCoeff,2.0/3.0)*rivDepth,0.5))/(9*pow(rivCoeff,1.0/3.0))));
00585                         eq_Wid=2.0*pow(rivDepth+EPSILON,1/(rivOrder-1))/pow(rivCoeff,1/(rivOrder-1));
00586                         return (a_pBool==1?rivArea:(a_pBool==2?rivPerem:eq_Wid)); //returnVal1(rivArea, rivPerem, eq_Wid, a_pBool);
00587                 default:
00588                         printf("\n Relevant Values entered are wrong");
00589                         printf("\n Depth: %lf\tCoeff: %lf\tOrder: %d\t");
00590                         return 0;
00591         }
00592 }
00593 
00594 realtype OverlandFlow1(int loci, int locj, int surfmode, realtype avg_y, realtype grad_y, realtype avg_sf, realtype alfa, realtype beta, realtype crossA, realtype avg_rough, int eletypeBool, realtype avg_perem) 
00595 {
00596         realtype flux;
00597         int locBool;
00598         float hydRadius;
00599         /* if surface gradient is not enough to overcome the friction */
00600     if(fabs(grad_y) <= avg_sf)
00601     {
00602          flux = 0;
00603     }
00604     else
00605     {
00606          if(grad_y > 0)
00607          {
00608               locBool=1;
00609          }
00610          else if(grad_y < 0)
00611          {
00612               locBool=-1;
00613          }
00614          switch(surfmode)
00615          {
00616                     case 1:
00617                       if(eletypeBool==1)
00618                       {
00619                        /* Kinematic Wave Approximation constitutive relationship: Manning Equation */
00620                            alfa = sqrt(locBool*grad_y)/avg_rough;
00621                            beta = pow(avg_y, 2.0/3.0);
00622                            flux = locBool*alfa*beta*crossA;
00623                            break;
00624                       }
00625                       else
00626                       {
00627                        /*alfa = sqrt(locBool*grad_y)/(avg_rough*pow((avg_perem>0?avg_perem:0), 2.0/3.0));
00628                            beta = 5.0/3.0;
00629                            *flux = locBool*alfa*pow(crossA, beta);
00630                        */
00631                        hydRadius = (avg_perem>0?crossA/avg_perem:0);
00632                                flux = locBool*sqrt(locBool*grad_y)*crossA*pow(hydRadius,2.0/3.0)/avg_rough;
00633                            break;
00634                       }
00635                     case 2:
00636                       if(eletypeBool==1)
00637                       {
00638                            /* Diffusion Wave Approximation constitutive relationship: Gottardi & Venutelli, 1993 */
00639                            alfa = pow(pow(avg_y, 1.0/3.0),2)/(1.0*avg_rough);
00640                            beta = alfa;
00641                            flux = locBool*crossA*beta*sqrt(locBool*grad_y);
00642                            break;
00643                       }
00644                       else
00645                       {
00646                        /*alfa = pow(pow(avg_y, 1.0/3.0),2)/(1.0*avg_rough);
00647                            beta = alfa;
00648                            flux = locBool*crossA*beta*sqrt(locBool*grad_y);
00649                        */
00650                                hydRadius = (avg_perem>0?crossA/avg_perem:0);
00651                                flux = locBool*sqrt(locBool*grad_y)*crossA*pow(hydRadius,2.0/3.0)/(1.0*avg_rough);
00652                                break;
00653                       }
00654                     default:
00655                       if(eletypeBool==1)
00656                       {
00657                        printf("Fatal Error: Surface Overland Mode Type Is Wrong!");
00658                       }
00659                       else
00660                       {
00661                            printf("Fatal Error: River Routing Mode Type Is Wrong!");
00662                       }
00663                       exit(1);
00664             }
00665         }
00666         return flux;
00667 }
00668 
00669 
00670 void  printRiverFlux(Model_Data mData, N_Vector CV_Y, FILE *res_flux_file)
00671 {
00672         int i;
00673         realtype TotalY_Riv, Perem, TotalY_Riv_down, Perem_down, Avg_Perem, Avg_Y_Riv, Avg_Rough, Distance, Dif_Y_Riv, Avg_Sf, CrossA, Alfa, Beta;
00674         realtype Flux;
00675         for(i=0; i<mData->NumRiv; i++)
00676         {
00677                 TotalY_Riv = NV_Ith_S(CV_Y, i + 3*mData->NumEle) + mData->Riv[i].zmin;
00678                 Perem = CS_AreaOrPerem1(mData->Riv_Shape[mData->Riv[i].shape - 1].interpOrd,NV_Ith_S(CV_Y, i + 3*mData->NumEle),mData->Riv_Shape[mData->Riv[i].shape - 1].coeff,2);
00679                 if(mData->Riv[i].down > 0)
00680                 {
00681                         TotalY_Riv_down = NV_Ith_S(CV_Y, mData->Riv[i].down - 1 + 3*mData->NumEle)  + mData->Riv[mData->Riv[i].down - 1].zmin;
00682                         Perem_down = CS_AreaOrPerem1(mData->Riv_Shape[mData->Riv[mData->Riv[i].down - 1].shape - 1].interpOrd,NV_Ith_S(CV_Y, mData->Riv[i].down - 1 + 3*mData->NumEle),mData->Riv_Shape[mData->Riv[mData->Riv[i].down - 1].shape - 1].coeff,2);
00683                         Avg_Perem = (Perem + Perem_down)/2.0;   
00684                         if(mData->Riv[mData->Riv[i].down - 1].zmin>mData->Riv[i].zmin)
00685                         {
00686                                 if(mData->Riv[mData->Riv[i].down - 1].zmin > TotalY_Riv)
00687                                 {
00688                                         Avg_Y_Riv=NV_Ith_S(CV_Y, mData->Riv[i].down - 1 + 3*mData->NumEle)/2;
00689                                 }
00690                                 else
00691                                 {
00692                                         Avg_Y_Riv=(TotalY_Riv-mData->Riv[mData->Riv[i].down - 1].zmin+NV_Ith_S(CV_Y, mData->Riv[i].down - 1 + 3*mData->NumEle))/2;
00693                                 }
00694                          }
00695                          else
00696                          {
00697                                 if(mData->Riv[i].zmin>TotalY_Riv_down)
00698                                 {
00699                                         Avg_Y_Riv=NV_Ith_S(CV_Y, i + 3*mData->NumEle)/2;
00700                                 }
00701                                 else
00702                                 {
00703                                         Avg_Y_Riv=(NV_Ith_S(CV_Y, i + 3*mData->NumEle)+TotalY_Riv_down-mData->Riv[i].zmin)/2;
00704                                 }
00705                          }
00706                          Avg_Rough = (mData->Riv_Mat[mData->Riv[i].material - 1].Rough + mData->Riv_Mat[mData->Riv[mData->Riv[i].down - 1].material-1].Rough)/2.0;
00707                          
00708                          Distance = (mData->Riv[i].Length+mData->Riv[mData->Riv[i].down - 1].Length)/2;
00709                 
00710                          Dif_Y_Riv = (TotalY_Riv - TotalY_Riv_down)/Distance;
00711                          Avg_Sf = (mData->Riv_Mat[mData->Riv[i].material - 1].Sf + mData->Riv_Mat[mData->Riv[mData->Riv[i].down - 1].material-1].Sf)/2.0;
00712                              /*CrossA = 0.5*(CS_AreaOrPerem1(mData->Riv_Shape[mData->Riv[i].shape - 1].interpOrd,DummyY[i + 3*MD->NumEle],MD->Riv_Shape[MD->Riv[i].shape - 1].coeff,1)+CS_AreaOrPerem(MD->Riv_Shape[MD->Riv[MD->Riv[i].down - 1].shape - 1].interpOrd,DummyY[MD->Riv[i].down - 1 + 3*MD->NumEle],MD->Riv_Shape[MD->Riv[MD->Riv[i].down - 1].shape - 1].coeff,1));
00713                              */
00714                          CrossA = CS_AreaOrPerem1(mData->Riv_Shape[mData->Riv[i].shape - 1].interpOrd,Avg_Y_Riv,mData->Riv_Shape[mData->Riv[i].shape - 1].coeff,1);
00715                          Flux = OverlandFlow1(i,1,mData->RivMode, Avg_Y_Riv,Dif_Y_Riv,Avg_Sf,Alfa,Beta,CrossA,Avg_Rough,0,Avg_Perem);
00716                          /* Correction is being done in flux terms which can be > 0 even when there is no source water level present */
00717                          if(NV_Ith_S(CV_Y, i + 3*mData->NumEle) <= 0 && Flux > 0)
00718                          {
00719                                 Flux = 0;
00720                          }
00721                          else if(NV_Ith_S(CV_Y, mData->Riv[i].down - 1 + 3*mData->NumEle) <= 0 && Flux < 0)
00722                          {
00723                                 Flux = 0;
00724                          }
00725 
00726                 }
00727                 else{
00728                         Flux = 0.0;
00729                 }
00730                 fprintf(res_flux_file, "%lf\t", Flux);
00731          }
00732          fprintf(res_flux_file, "\n");
00733 }
00734                 

Generated on Sun Aug 5 17:33:59 2007 for PIHMgis by  doxygen 1.5.2