00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00067
00068 #include <stdio.h>
00069 #include <stdlib.h>
00070 #include <math.h>
00071 #include <string.h>
00072 #include <time.h>
00073
00074
00075
00076
00077 #include "sundials_types.h"
00078 #include "sundials_dense.h"
00079 #include "sundials_smalldense.h"
00080 #include "sundials_math.h"
00081 #include "cvode.h"
00082 #include "cvode_spgmr.h"
00083 #include "cvode_dense.h"
00084 #include "nvector_serial.h"
00085
00086
00087
00088
00089 #include "pihm.h"
00090
00091
00092
00093 void read_alloc(char *, Model_Data, Control_Data *);
00094 N_Vector N_VNew_Serial(int);
00095 void initialize(char *, Model_Data, Control_Data *, N_Vector);
00096
00097
00098 void* CVodeCreate(int , int);
00099 int CVodeSetFdata(void *, void *);
00100 int CVodeSetInitStep(void *, realtype);
00101 int CVodeSetStabLimDet(void *, booleantype);
00102 int CVodeSetMaxStep(void *, realtype);
00103 int CVodeMalloc(void *, CVRhsFn, realtype, N_Vector, int, realtype, void *);
00104 int CVSpgmr(void *, int, int);
00105 int CVSpilsSetGSType(void *, int);
00107 void calET_IS(realtype, realtype, Model_Data, N_Vector);
00108 int CVode(void *, realtype, n_Vector, realtype *, int);
00109 int f(realtype, N_Vector, N_Vector, void *);
00110
00111 void setTSDiCounter(Model_Data mData, realtype t);
00112 realtype Interpolation(TSD *Data, realtype t);
00113
00114 void FPrintInit(Model_Data);
00115 void FPrint(Model_Data, N_Vector, realtype);
00116 void FPrintInitFile(Model_Data, Control_Data, N_Vector, int);
00117 void FPrintCloseAll(void);
00118
00119
00120
00121
00122
00123
00124 int satEle, ovrEle;
00125
00126
00127 int main(int argc, char *argv[])
00128 {
00129 char *filename;
00130
00131 Model_Data mData;
00132 Control_Data cData;
00133 N_Vector CV_Y;
00134
00135 void *cvode_mem;
00136 int flag;
00137
00138 int N;
00139 int i,j,k;
00140 realtype t;
00141 realtype NextPtr, StepSize;
00142
00143 clock_t start, end_r, end_s;
00144 realtype cputime_r, cputime_s;
00145
00146
00147
00148 realtype loc1_bcEle, loc_Avg_Y_Surf, loc_Avg_Y_Sub, loc_Distance, loc_Dif_Y_Sub, loc_Avg_Ksat, loc_Grad_Y_Sub, Sub_Bdd, loc_Dif_Y_Surf, loc_Grad_Y_Surf, Surf_Bdd;
00149 int loc_i, loc_j;
00150
00151
00152 FILE *base2File, *over2File;
00153
00154 char tmpFileName[100];
00155 setFileName(tmpFileName);
00156 filename = (char *)malloc(sizeof(char)*strlen(tmpFileName));
00157 strcpy(filename, tmpFileName);
00158
00159 printf("\nBelt up! PIHM 2.0 is starting ... \n");
00160 start = clock();
00161
00162 mData = (Model_Data)malloc(sizeof *mData);
00163
00164
00165
00166
00167 base2File=fopen("sc.base2","w");
00168 over2File=fopen("sc.over2","w");
00169
00170
00171
00172 read_alloc(filename, mData, &cData);
00173
00174 if(mData->UnsatMode ==1)
00175 {
00176 N = 2*mData->NumEle + mData->NumRiv;
00177 }
00178 if(mData->UnsatMode ==2)
00179 {
00180 N = 3*mData->NumEle + mData->NumRiv;
00181 }
00182
00183 CV_Y = N_VNew_Serial(N);
00184
00185
00186 initialize(filename, mData, &cData, CV_Y);
00187
00188
00189 FPrintInit(mData);
00190
00191
00192 end_r = clock();
00193 cputime_r = (end_r - start)/(realtype)CLOCKS_PER_SEC;
00194
00195 printf("\nSolving ODE system ... \n");
00196
00197
00198
00199 cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON);
00200 if(cvode_mem == NULL) { printf("CVodeCreate failed. \n"); return(1); }
00201
00202
00203 flag = CVodeSetFdata(cvode_mem, mData);
00204 flag = CVodeSetInitStep(cvode_mem,cData.InitStep);
00205 flag = CVodeSetStabLimDet(cvode_mem,TRUE);
00206 flag = CVodeSetMaxStep(cvode_mem,cData.MaxStep);
00207 flag = CVodeMalloc(cvode_mem, f, cData.StartTime, CV_Y, CV_SS, cData.reltol, &cData.abstol);
00208
00209
00210 flag = CVSpgmr(cvode_mem, PREC_NONE, 0);
00211 flag = CVSpilsSetGSType(cvode_mem, MODIFIED_GS);
00212
00213
00214
00215
00216
00217
00218 t = cData.StartTime;
00219
00220
00221 for(i=0; i<cData.NumSteps; i++)
00222 {
00223
00224
00225
00226
00227
00228
00229
00230 while(t < cData.Tout[i+1])
00231 {
00232 if (t + cData.ETStep >= cData.Tout[i+1])
00233 {
00234 NextPtr = cData.Tout[i+1];
00235 }
00236 else
00237 {
00238 NextPtr = t + cData.ETStep;
00239 }
00240 StepSize = NextPtr - t;
00241
00242 calET_IS(t, StepSize, mData, CV_Y);
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263 Tsteps=t;
00264 printf("\n Tsteps = %f ",t);
00265
00266 flag = CVode(cvode_mem, NextPtr, CV_Y, &t, CV_NORMAL);
00267
00268 setTSDiCounter(mData, t);
00269 FPrint(mData, CV_Y, t);
00270
00271
00272
00273
00274
00275 for(loc_i=0; loc_i<mData->NumEle; loc_i++){
00276 for(loc_j=0; loc_j<3; loc_j++){
00277 if(mData->Ele[loc_i].BC > 0){
00278 loc1_bcEle = Interpolation(&mData->TSD_EleBC[(mData->Ele[loc_i].BC)-1], t);
00279 if( loc1_bcEle < mData->Ele[loc_i].zmin ){
00280 loc_Avg_Y_Surf = NV_Ith_S(CV_Y, loc_i)/2;
00281 loc_Avg_Y_Sub = NV_Ith_S(CV_Y, loc_i+2*mData->NumEle);
00282 }
00283 else if(loc1_bcEle < mData->Ele[loc_i].zmax){
00284 loc_Avg_Y_Surf = NV_Ith_S(CV_Y, loc_i)/2;
00285 loc_Avg_Y_Sub = (loc1_bcEle - mData->Ele[loc_i].zmin + NV_Ith_S(CV_Y, loc_i+2*mData->NumEle))/2.0;
00286 }
00287 else{
00288 loc_Avg_Y_Surf = (NV_Ith_S(CV_Y, loc_i) + loc1_bcEle - mData->Ele[loc_i].zmax)/2;
00289 loc_Avg_Y_Sub = mData->Ele[loc_i].zmax - mData->Ele[loc_i].zmin;
00290 }
00291 loc_Distance = sqrt(pow(mData->Ele[loc_i].edge[0]*mData->Ele[loc_i].edge[1]*mData->Ele[loc_i].edge[2]/(4*mData->Ele[loc_i].area), 2) - pow(mData->Ele[loc_i].edge[loc_j]/2, 2));
00292
00293 loc_Dif_Y_Sub = NV_Ith_S(CV_Y, loc_i+2*mData->NumEle) + mData->Ele[loc_i].zmin - loc1_bcEle;
00294 loc_Avg_Ksat = mData->Ele[loc_i].Ksat;
00295 loc_Grad_Y_Sub = loc_Dif_Y_Sub/loc_Distance;
00296 Sub_Bdd = loc_Avg_Ksat * loc_Grad_Y_Sub * loc_Avg_Y_Sub * mData->Ele[loc_i].edge[loc_j];
00297
00298
00299 loc_Dif_Y_Surf = NV_Ith_S(CV_Y, loc_i) + mData->Ele[loc_i].zmax - loc1_bcEle;
00300 loc_Grad_Y_Surf = loc_Dif_Y_Surf / loc_Distance;
00301
00302
00303 Surf_Bdd = sqrt(NV_Ith_S(CV_Y, loc_i)/loc_Distance)*pow(NV_Ith_S(CV_Y, loc_i),2.0/3.0)*(NV_Ith_S(CV_Y, loc_i)/2)*mData->Ele[loc_i].edge[loc_j]/mData->Ele[loc_i].Rough;
00304
00305 fprintf(base2File, "%lf\t", Sub_Bdd);
00306 fprintf(over2File, "%lf\t", Surf_Bdd);
00307 }
00308 }
00309 }
00310 fprintf(base2File, "\n");
00311 fprintf(over2File, "\n");
00312
00313
00314
00315
00316
00317
00318
00319 satEle=0;
00320 ovrEle=0;
00321 for(k=0; k<mData->NumEle;k++)
00322 {
00323 if(NV_Ith_S(CV_Y, k+2*mData->NumEle)/(mData->Ele[k].zmax-mData->Ele[k].zmin)>0.99){
00324 satEle++;
00325 }
00326 if(NV_Ith_S(CV_Y, k)>1E-4){
00327 ovrEle++;
00328 }
00329 }
00330
00331
00332
00333
00334
00335
00336
00337 }
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351 fflush(stdout);
00352 }
00353
00354 FPrintInitFile(mData, cData, CV_Y, i);
00355 FPrintCloseAll();
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365 end_s = clock();
00366 cputime_s = (end_s - end_r)/(realtype)CLOCKS_PER_SEC;
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378 free(mData);
00379
00380 return 0;
00381 }
00382
00383
00384
00385
00386
00387
00388
00389
00390 void setTSDiCounter(Model_Data mData, realtype t)
00392
00395 {
00396
00397 int k;
00398
00399 for(k=0; k<mData->NumPrep; k++)
00400 {
00401 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]){
00402 mData->TSD_Prep[k].iCounter++;
00403 }
00404 }
00405 for(k=0; k<mData->NumTemp; k++){
00406 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]){
00407 mData->TSD_Temp[k].iCounter++;
00408 }
00409 }
00410 for(k=0; k<mData->NumHumidity; k++){
00411 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]){
00412 mData->TSD_Humidity[k].iCounter++;
00413 }
00414 }
00415 for(k=0; k<mData->NumWindVel; k++){
00416 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]){
00417 mData->TSD_WindVel[k].iCounter++;
00418 }
00419 }
00420 for(k=0; k<mData->NumRn; k++){
00421 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]){
00422 mData->TSD_Rn[k].iCounter++;
00423 }
00424 }
00425 for(k=0; k<mData->NumG; k++){
00426 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]){
00427 mData->TSD_G[k].iCounter++;
00428 }
00429 }
00430 for(k=0; k<mData->NumP; k++){
00431 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]){
00432 mData->TSD_Pressure[k].iCounter++;
00433 }
00434 }
00435 for(k=0; k<mData->NumLC; k++){
00436 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]){
00437 mData->TSD_LAI[k].iCounter++;
00438 }
00439 }
00440 for(k=0; k<mData->NumLC; k++){
00441 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]){
00442 mData->TSD_DH[k].iCounter++;
00443 }
00444 }
00445 for(k=0; k<mData->NumMeltF; k++){
00446 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]){
00447 mData->TSD_MeltF[k].iCounter++;
00448 }
00449 }
00450 for(k=0; k<mData->NumSource; k++){
00451 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]){
00452 mData->TSD_Source[k].iCounter++;
00453 }
00454 }
00455
00456 for(k=0; k<mData->Num1BC+mData->Num2BC; k++){
00457 while(mData->TSD_EleBC[k].iCounter < mData->TSD_EleBC[k].length && t/(24.0*60.0) > mData->TSD_EleBC[k].TS[mData->TSD_EleBC[k].iCounter+1][0]){
00458 mData->TSD_EleBC[k].iCounter++;
00459 }
00460 }
00461
00462 }