예제 #1
0
int main()
{
  M_Env machEnv;
  realtype abstol, reltol, t, tout, ropt[OPT_SIZE];
  long int iopt[OPT_SIZE];
  N_Vector y;
  UserData data;
  CVBandPreData bpdata;
  void *cvode_mem;
  int ml, mu, iout, flag, jpre;

  /* Initialize serial machine environment */
  machEnv = M_EnvInit_Serial(NEQ);

  /* Allocate and initialize y, and set problem data and tolerances */ 

  y = N_VNew(NEQ, machEnv);
  data = (UserData) malloc(sizeof *data);
  InitUserData(data);
  SetInitialProfiles(y, data->dx, data->dz);
  abstol = ATOL; reltol = RTOL;

  /* Call CVodeMalloc to initialize CVODE: 
     NEQ     is the problem size = number of equations
     f       is the user's right hand side function in y'=f(t,y)
     T0      is the initial time
     y       is the initial dependent variable vector
     BDF     specifies the Backward Differentiation Formula
     NEWTON  specifies a Newton iteration
     SS      specifies scalar relative and absolute tolerances
     &reltol and &abstol are pointers to the scalar tolerances
     data    is the pointer to the user-defined block of coefficients
     FALSE   indicates there are no optional inputs in iopt and ropt
     iopt    and ropt arrays communicate optional integer and real input/output

     A pointer to CVODE problem memory is returned and stored in cvode_mem.  */

  cvode_mem = CVodeMalloc(NEQ, f, T0, y, BDF, NEWTON, SS, &reltol,
                          &abstol, data, NULL, FALSE, iopt, ropt, machEnv);
  if (cvode_mem == NULL) { printf("CVodeMalloc failed."); return(1); }

  /* Call CVBandPreAlloc to initialize band preconditioner */
  ml = mu = 2;
  bpdata = CVBandPreAlloc (NEQ, f, data, mu, ml, cvode_mem);

  /* Call CVSpgmr to specify the CVODE linear solver CVSPGMR with
     left preconditioning, modified Gram-Schmidt orthogonalization,
     default values for the maximum Krylov dimension maxl and the tolerance
     parameter delt, preconditioner setup and solve routines CVBandPrecond
     and CVBandPSolve, the pointer to the user-defined block data, and
     NULL for the user jtimes routine and Jacobian data pointer.             */

  flag = CVSpgmr(cvode_mem, LEFT, MODIFIED_GS, 0, 0.0, CVBandPrecond,
                  CVBandPSolve, bpdata, NULL, NULL);
  if (flag != SUCCESS) { printf("CVSpgmr failed."); return(1); }

  printf("2-species diurnal advection-diffusion problem, %d by %d mesh\n",
         MX, MZ);
  printf("SPGMR solver; band preconditioner; mu = %d, ml = %d\n\n",
         mu, ml);

  /* Loop over jpre (= LEFT, RIGHT), and solve the problem */

  for (jpre = LEFT; jpre <= RIGHT; jpre++) {

  /* On second run, re-initialize y, CVODE, CVBANDPRE, and CVSPGMR */

  if (jpre == RIGHT) {

    SetInitialProfiles(y, data->dx, data->dz);

    flag = CVReInit(cvode_mem, f, T0, y, BDF, NEWTON, SS, &reltol,
                    &abstol, data, NULL, FALSE, iopt, ropt, machEnv);
    if (flag != SUCCESS) { printf("CVReInit failed."); return(1); }

    flag = CVReInitBandPre(bpdata, NEQ, f, data, mu, ml);

    flag = CVReInitSpgmr(cvode_mem, jpre, MODIFIED_GS, 0, 0.0,
                         CVBandPrecond, CVBandPSolve, bpdata, NULL, NULL);
    if (flag != SUCCESS) { printf("CVReInitSpgmr failed."); return(1); }

    printf("\n\n-------------------------------------------------------");
    printf("------------\n");
  }

    printf("\n\nPreconditioner type is:  jpre = %s\n\n",
           (jpre == LEFT) ? "LEFT" : "RIGHT");

  /* In loop over output points, call CVode, print results, test for error */

  for (iout = 1, tout = TWOHR; iout <= NOUT; iout++, tout += TWOHR) {
    flag = CVode(cvode_mem, tout, y, &t, NORMAL);
    PrintOutput(iopt, ropt, y, t);
    if (flag != SUCCESS) {
      printf("CVode failed, flag = %d.\n", flag);
      break;
    }
  }

  /* Print final statistics */

  PrintFinalStats(iopt);

  } /* End of jpre loop */

  /* Free memory */  

  N_VFree(y);
  free(data);
  CVBandPreFree(bpdata);
  CVodeFree(cvode_mem);
  M_EnvFree_Serial(machEnv);

  return(0);
}
예제 #2
0
파일: ihm10.c 프로젝트: geoxuan/PIHM
/* Main Function */
int main(int argc, char *argv[])
{  
  char *filename = "shalehills";        /* Input file name prefix    */
  char *StateFile;                /* Output file name string   */
  char *FluxFile;
  char *ETISFile;  
  char *QFile;  
  
  Model_Data mData;               /* Model Data                */
  Control_Data cData;             /* Solver Control Data       */
  
  N_Vector CV_Y;                  /* State Variables Vector    */
  M_Env machEnv;                  /* Machine Environments      */
  
  realtype ropt[OPT_SIZE];        /* Optional real type and integer type  */
  long int iopt[OPT_SIZE];        /* vecter for Message Passing to solver */
  
  void *cvode_mem;                /* Model Data Pointer        */
  int flag;                       /* flag to test return value */
  
  FILE *res_state_file;           /* Output file for States    */
  FILE *res_flux_file;            /* Output file for Flux      */
  FILE *res_etis_file;            /* Output file for ET and IS */
  FILE *res_q_file;
  
  int N;                          /* Problem size              */
  int i;                          /* loop index                */
  realtype t;                     /* simulation time           */
  realtype NextPtr, StepSize;     /* stress period & step size */
  
  clock_t start, end_r, end_s;    /* system clock at points    */
  realtype cputime_r, cputime_s;  /* for duration in realtype  */
  
  /* allocate memory for model data structure */
  mData = (Model_Data)malloc(sizeof *mData);
  start = clock();
  
  /* get user specified file name in command line */
  if(argc >= 2)
  {
    filename = (char *)malloc(strlen(argv[1])*sizeof(char));
    strcpy(filename, argv[1]);
  }  
  
  printf("\nBelt up!  PIHM 1.0 is starting ... \n");
  
  /* read in 7 input files with "filename" as prefix */
  read_alloc(filename, mData, &cData); 
    
  /* problem size */
  N = 3*mData->NumEle + mData->NumRiv;
  
  /* initial machine environment variable */
  machEnv = M_EnvInit_Serial(N);
  
  /* initial state variable depending on machine*/
  CV_Y = N_VNew(N, machEnv);
  
  /* initialize mode data structure */
  initialize(filename, mData, &cData, CV_Y);
  
  if(cData.Debug == 1) {PrintModelData(mData);}  
  
  end_r = clock();
  cputime_r = (end_r - start)/(realtype)CLOCKS_PER_SEC;
  
  printf("\nSolving ODE system ... \n");
  
  /* initial control parameter for CVODE solver. Otherwise the default value by C could cause problems. */
  for(i=0; i<OPT_SIZE; i++)
  {
    ropt[i] = 0.0;
    iopt[i] = 0;
  }
  
  /* set user specified control parameter */
  ropt[H0] = cData.InitStep;  
  ropt[HMAX] = cData.MaxStep; 
  
  /* allocate memory for solver */
  cvode_mem = CVodeMalloc(N, f, cData.StartTime, CV_Y, BDF, NEWTON, SS, &cData.reltol, 
                          &cData.abstol, mData, NULL, TRUE, iopt, ropt, machEnv);
  if(cvode_mem == NULL) {printf("CVodeMalloc failed. \n"); return(1);}
  
  if(cData.Solver == 1)
  {
    /* using dense direct solver */
    flag = CVDense(cvode_mem, NULL, NULL);
    if(flag != SUCCESS) {printf("CVDense failed. \n"); return(1);}
  } 
  else if(cData.Solver == 2)
  {
    /* using iterative solver */
    flag = CVSpgmr(cvode_mem, NONE, cData.GSType, cData.MaxK, cData.delt, NULL, NULL,
                       mData, NULL, NULL);
    if (flag != SUCCESS) {printf("CVSpgmr failed."); return(1);}
  } 
  
  /*allocate and copy to get output file name */
  StateFile = (char *)malloc((strlen(filename)+4)*sizeof(char));
  strcpy(StateFile, filename);
  FluxFile  = (char *)malloc((strlen(filename)+5)*sizeof(char));
  strcpy(FluxFile, filename);
  ETISFile  = (char *)malloc((strlen(filename)+5)*sizeof(char));
  strcpy(ETISFile, filename);
  QFile = (char *)malloc((strlen(filename)+2)*sizeof(char));
  strcpy(QFile, filename);
  
  /* open output file */
  if (cData.res_out == 1) {res_state_file = fopen(strcat(StateFile, ".res"), "w");}
  if (cData.flux_out == 1) {res_flux_file = fopen(strcat(FluxFile, ".flux"), "w");}
  if (cData.etis_out == 1) {res_etis_file = fopen(strcat(ETISFile, ".etis"), "w");}
  if (cData.q_out == 1) {res_q_file = fopen(strcat(QFile, ".q"), "w");}
  
  /* print header of output file */
  if (cData.res_out == 1) {FPrintYheader(res_state_file, mData);}
  if (cData.etis_out == 1) {FPrintETISheader(res_etis_file, mData);}
  if (cData.q_out == 1) {FPrintETISheader(res_q_file, mData);}
  printf("\n");
  
  /* set start time */
  t = cData.StartTime;
  
  /* start solver in loops */
  for(i=0; i<cData.NumSteps; i++)
  {
    /* prompt information in non-verbose mode */
    if (cData.Verbose != 1)
    {
      printf("  Running: %-4.1f%% ... ", (100*(i+1)/((realtype) cData.NumSteps))); 
      fflush(stdout);
    }
    
    /* inner loops to next output points with ET step size control */
    while(t < cData.Tout[i+1])
    {
      if (t + cData.ETStep >= cData.Tout[i+1])
      {
        NextPtr = cData.Tout[i+1];
      }
      else
      {
        NextPtr = t + cData.ETStep;
      }
      StepSize = NextPtr - t; 
      
      /* calculate Interception Storage */
      calIS(t, StepSize, mData);
      /* solving ODE system */
      flag = CVode(cvode_mem, NextPtr, CV_Y, &t, NORMAL);  
      /* calculate ET and adjust states variables*/
      calET(t, StepSize, CV_Y, mData);
    }  
    
    if(cData.Verbose == 1) {PrintVerbose(i, t, iopt, ropt);}

    /* uncomment it if user need it verbose mode */  
    /* if(cData.Verbose == 1) {PrintY(mData, CV_Y, t);} */
    
    /* print out results to files at every output time */
    if (cData.res_out == 1) {FPrintY(mData, CV_Y, t, res_state_file);}
    if (cData.flux_out == 1) {FPrintFlux(mData, t, res_flux_file);}
    if (cData.etis_out == 1) {FPrintETIS(mData, t, res_etis_file);}
    if (cData.q_out == 1) {FPrintQ(mData, t, res_q_file);}
    
    if (cData.Verbose != 1) {printf("\r");}  
    
    if(flag != SUCCESS) {printf("CVode failed, flag = %d. \n", flag); return(flag);} 
    
    /* clear buffer */
    fflush(stdout);  
  }
  
  /* free memory */
  /*
  N_VFree(CV_Y);
  CVodeFree(cvode_mem);
  M_EnvFree_Serial(machEnv); 
  */
  
  /* capture time */
  end_s = clock();
  cputime_s = (end_s - end_r)/(realtype)CLOCKS_PER_SEC;
  
  /* print out simulation statistics */
  PrintFarewell(cData, iopt, ropt, cputime_r, cputime_s);
  if (cData.res_out == 1) {FPrintFarewell(cData, res_state_file, iopt, ropt, cputime_r, cputime_s);}
  
  /* close output files */
  if (cData.res_out == 1)  {fclose(res_state_file);}
  if (cData.flux_out == 1) {fclose(res_flux_file);}
  if (cData.etis_out == 1) {fclose(res_etis_file);}
  if (cData.q_out == 1)    {fclose(res_q_file);}
  
  free(mData);
  
  return 0;
}