Пример #1
0
 virtual TimeStepperStatus step(Real *ftime) {
   PetscErrorCode ierr;
   TSConvergedReason reason;
   ierr = TSStep(_ts);
   CHKERRABORT(libMesh::COMM_WORLD,ierr);
   ierr = TSGetConvergedReason(_ts,&reason);
   CHKERRABORT(libMesh::COMM_WORLD,ierr);
   ierr = TSGetTime(_ts,ftime);
   CHKERRABORT(libMesh::COMM_WORLD,ierr);
   return (TimeStepperStatus)reason;
 }
Пример #2
0
int main(int argc,char **argv)
{
  TS                ts;         /* time integrator */
  SNES              snes;       /* nonlinear solver */
  SNESLineSearch    linesearch; /* line search */
  Vec               X;          /* solution, residual vectors */
  Mat               J;          /* Jacobian matrix */
  PetscInt          steps,maxsteps,mx;
  PetscErrorCode    ierr;
  DM                da;
  PetscReal         ftime,dt;
  struct _User      user;       /* user-defined work context */
  TSConvergedReason reason;

  PetscInitialize(&argc,&argv,(char*)0,help);

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Create distributed array (DMDA) to manage parallel grid and vectors
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = DMDACreate1d(PETSC_COMM_WORLD,DMDA_BOUNDARY_NONE,-11,2,2,NULL,&da);CHKERRQ(ierr);

  /*  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Extract global vectors from DMDA;
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = DMCreateGlobalVector(da,&X);CHKERRQ(ierr);

  /* Initialize user application context */
  ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Advection-reaction options","");
  {
    user.a[0] = 1;           ierr = PetscOptionsReal("-a0","Advection rate 0","",user.a[0],&user.a[0],NULL);CHKERRQ(ierr);
    user.a[1] = 0;           ierr = PetscOptionsReal("-a1","Advection rate 1","",user.a[1],&user.a[1],NULL);CHKERRQ(ierr);
    user.k[0] = 1e6;         ierr = PetscOptionsReal("-k0","Reaction rate 0","",user.k[0],&user.k[0],NULL);CHKERRQ(ierr);
    user.k[1] = 2*user.k[0]; ierr = PetscOptionsReal("-k1","Reaction rate 1","",user.k[1],&user.k[1],NULL);CHKERRQ(ierr);
    user.s[0] = 0;           ierr = PetscOptionsReal("-s0","Source 0","",user.s[0],&user.s[0],NULL);CHKERRQ(ierr);
    user.s[1] = 1;           ierr = PetscOptionsReal("-s1","Source 1","",user.s[1],&user.s[1],NULL);CHKERRQ(ierr);
  }
  ierr = PetscOptionsEnd();CHKERRQ(ierr);

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Create timestepping solver context
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr);
  ierr = TSSetDM(ts,da);CHKERRQ(ierr);
  ierr = TSSetType(ts,TSARKIMEX);CHKERRQ(ierr);
  ierr = TSSetRHSFunction(ts,NULL,FormRHSFunction,&user);CHKERRQ(ierr);
  ierr = TSSetIFunction(ts,NULL,FormIFunction,&user);CHKERRQ(ierr);
  ierr = DMCreateMatrix(da,MATAIJ,&J);CHKERRQ(ierr);
  ierr = TSSetIJacobian(ts,J,J,FormIJacobian,&user);CHKERRQ(ierr);

  /* A line search in the nonlinear solve can fail due to ill-conditioning unless an absolute tolerance is set. Since
   * this problem is linear, we deactivate the line search. For a linear problem, it is usually recommended to also use
   * SNESSetType(snes,SNESKSPONLY). */
  ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
  ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr);
  ierr = SNESLineSearchSetType(linesearch,SNESLINESEARCHBASIC);CHKERRQ(ierr);

  ftime    = 1.0;
  maxsteps = 10000;
  ierr     = TSSetDuration(ts,maxsteps,ftime);CHKERRQ(ierr);

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Set initial conditions
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = FormInitialSolution(ts,X,&user);CHKERRQ(ierr);
  ierr = TSSetSolution(ts,X);CHKERRQ(ierr);
  ierr = VecGetSize(X,&mx);CHKERRQ(ierr);
  dt   = .1 * PetscMax(user.a[0],user.a[1]) / mx; /* Advective CFL, I don't know why it needs so much safety factor. */
  ierr = TSSetInitialTimeStep(ts,0.0,dt);CHKERRQ(ierr);

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Set runtime options
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = TSSetFromOptions(ts);CHKERRQ(ierr);

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Solve nonlinear system
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = TSSolve(ts,X);CHKERRQ(ierr);
  ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr);
  ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr);
  ierr = TSGetConvergedReason(ts,&reason);CHKERRQ(ierr);
  ierr = PetscPrintf(PETSC_COMM_WORLD,"%s at time %G after %D steps\n",TSConvergedReasons[reason],ftime,steps);CHKERRQ(ierr);

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Free work space.
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = MatDestroy(&J);CHKERRQ(ierr);
  ierr = VecDestroy(&X);CHKERRQ(ierr);
  ierr = TSDestroy(&ts);CHKERRQ(ierr);
  ierr = DMDestroy(&da);CHKERRQ(ierr);
  ierr = PetscFinalize();
  return 0;
}
Пример #3
0
int main(int argc, char **argv)
{
  MPI_Comm          comm;
  PetscMPIInt       rank;
  PetscErrorCode    ierr;
  User              user;
  PetscLogDouble       v1, v2;
  PetscInt          nplot = 0;
  char              filename1[2048], fileName[2048];
  PetscBool         set = PETSC_FALSE;
  PetscInt          steps_output;

  ierr = PetscInitialize(&argc, &argv, (char*) 0, help);CHKERRQ(ierr);
  comm = PETSC_COMM_WORLD;
  ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
  ierr = PetscNew(&user);CHKERRQ(ierr);
  ierr = PetscNew(&user->algebra);CHKERRQ(ierr);
  ierr = PetscNew(&user->model);CHKERRQ(ierr);
  ierr = PetscNew(&user->model->physics);CHKERRQ(ierr);

  Algebra   algebra = user->algebra;

  ierr = LoadOptions(comm, user);CHKERRQ(ierr);
  ierr = PetscTime(&v1);CHKERRQ(ierr);
  ierr = CreateMesh(comm, user);CHKERRQ(ierr);
  ierr = PetscTime(&v2);CHKERRQ(ierr);
  ierr = PetscPrintf(PETSC_COMM_WORLD,
		       "Read and Distribute mesh takes %f sec \n", v2 - v1);CHKERRQ(ierr);
  ierr = SetUpLocalSpace(user);CHKERRQ(ierr); //Set up the dofs of each element
  ierr = ConstructGeometryFVM(&user->facegeom, &user->cellgeom, user);CHKERRQ(ierr);

  ierr = LimiterSetup(user);CHKERRQ(ierr);

  if(user->output_solution){
  // the output file options
    ierr = PetscOptionsBegin(PETSC_COMM_WORLD,0,"Options for output solution",0);CHKERRQ(ierr);
    ierr = PetscOptionsString("-solutionfile", "solution file", "AeroSim.c", filename1,filename1, 2048, &set);CHKERRQ(ierr);
    if(!set){SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,"please use option -solutionfile to specify solution file name \n");}
    ierr = PetscOptionsInt("-steps_output", "the number of time steps between two outputs", "", steps_output, &steps_output, &set);CHKERRQ(ierr);
    if(!set){ steps_output = 1;}
    ierr = PetscOptionsEnd();CHKERRQ(ierr);
  }

  if (user->TimeIntegralMethod == EXPLICITMETHOD) {
    if(user->myownexplicitmethod){
      ierr = PetscPrintf(PETSC_COMM_WORLD,"Using the fully explicit method based on my own routing\n");CHKERRQ(ierr);
      user->current_time = user->initial_time;
      user->current_step = 1;
      ierr = DMCreateGlobalVector(user->dm, &algebra->solution);CHKERRQ(ierr);
      ierr = PetscObjectSetName((PetscObject) algebra->solution, "solution");CHKERRQ(ierr);
      ierr = SetInitialCondition(user->dm, algebra->solution, user);CHKERRQ(ierr);
      ierr = VecDuplicate(algebra->solution, &algebra->fn);CHKERRQ(ierr);
      ierr = VecDuplicate(algebra->solution, &algebra->oldsolution);CHKERRQ(ierr);
      if(user->Explicit_RK2){
        ierr = PetscPrintf(PETSC_COMM_WORLD,"Use the second order Runge Kutta method \n");CHKERRQ(ierr);
      }else{
        ierr = PetscPrintf(PETSC_COMM_WORLD,"Use the first order forward Euler method \n");CHKERRQ(ierr);
      }
      nplot = 0; //the plot step
      while(user->current_time < (user->final_time - 0.05 * user->dt)){
        user->current_time = user->current_time + user->dt;

        ierr = FormTimeStepFunction(user, algebra, algebra->solution, algebra->fn);CHKERRQ(ierr);
        PetscReal fnnorm;
        ierr = VecNorm(algebra->fn,NORM_INFINITY,&fnnorm);CHKERRQ(ierr);
        if(0){
          PetscViewer    viewer;
          ierr = OutputVTK(user->dm, "function.vtk", &viewer);CHKERRQ(ierr);
          ierr = VecView(algebra->fn, viewer);CHKERRQ(ierr);
          ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
          ierr = PetscPrintf(PETSC_COMM_WORLD,"Step %D at time %g with founction norm = %g \n",
                                user->current_step, user->current_time, fnnorm);CHKERRQ(ierr);
          //break;
        }
        if(user->Explicit_RK2){
          ierr = VecCopy(algebra->solution, algebra->oldsolution);CHKERRQ(ierr);//U^n
          ierr = VecAXPY(algebra->solution, user->dt, algebra->fn);CHKERRQ(ierr);//U^{(1)}
          ierr = FormTimeStepFunction(user, algebra, algebra->solution, algebra->fn);CHKERRQ(ierr);//f(U^{(1)})
          ierr = VecAXPY(algebra->solution, 1.0, algebra->oldsolution);CHKERRQ(ierr);//U^n + U^{(1)}
          ierr = VecAXPY(algebra->solution, user->dt, algebra->fn);CHKERRQ(ierr);// + dt*f(U^{(1)})
          ierr = VecScale(algebra->solution, 0.5);CHKERRQ(ierr);
        }else{
          ierr = VecCopy(algebra->solution, algebra->oldsolution);CHKERRQ(ierr);
          ierr = VecAXPY(algebra->solution, user->dt, algebra->fn);CHKERRQ(ierr);
        }

        {// Monitor the solution and function norms
          PetscReal         norm;
          PetscLogDouble    space =0;
          PetscInt          size;

          ierr = VecNorm(algebra->solution,NORM_INFINITY,&norm);CHKERRQ(ierr);
          ierr = VecGetSize(algebra->solution, &size);CHKERRQ(ierr);
          norm = norm/size;
          if (norm>1.e5) {
            SETERRQ2(PETSC_COMM_WORLD, PETSC_ERR_LIB,
            "The norm of the solution is: %f (current time: %f). The explicit method is going to DIVERGE!!!", norm, user->current_time);
          }
          if (user->current_step%10==0) {
            ierr = PetscPrintf(PETSC_COMM_WORLD,"Step %D at time %g with solution norm = %g and founction norm = %g \n",
                                user->current_step, user->current_time, norm, fnnorm);CHKERRQ(ierr);
          }
          ierr =  PetscMallocGetCurrentUsage(&space);CHKERRQ(ierr);
//          if (user->current_step%10==0) {
//            ierr =  PetscPrintf(PETSC_COMM_WORLD,"Current space PetscMalloc()ed %g M\n",
//                                 space/(1024*1024));CHKERRQ(ierr);
//          }
        }

        { // Monitor the difference of two steps' solution
          PetscReal         norm;
          ierr = VecAXPY(algebra->oldsolution, -1, algebra->solution);CHKERRQ(ierr);
          ierr = VecNorm(algebra->oldsolution,NORM_INFINITY,&norm);CHKERRQ(ierr);
          if (user->current_step%10==0) {
            ierr = PetscPrintf(PETSC_COMM_WORLD,"Step %D at time %g with ||u_k-u_{k-1}|| = %g \n",
                              user->current_step, user->current_time, norm);CHKERRQ(ierr);
          }
          if((norm<1.e-6)||(user->current_step > user->max_time_its)) break;
        }

        // output the solution
        if (user->output_solution && (user->current_step%steps_output==0)){
          PetscViewer    viewer;

          // update file name for the current time step
          ierr = PetscSNPrintf(fileName, sizeof(fileName),"%s_%d.vtk",filename1, nplot);CHKERRQ(ierr);
          ierr = PetscPrintf(PETSC_COMM_WORLD,"Outputing solution %s (current time %f)\n", fileName, user->current_time);CHKERRQ(ierr);
          ierr = OutputVTK(user->dm, fileName, &viewer);CHKERRQ(ierr);
          ierr = VecView(algebra->solution, viewer);CHKERRQ(ierr);
          ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
          nplot++;
        }

        user->current_step++;

      }
      ierr = VecDestroy(&algebra->fn);CHKERRQ(ierr);
    }else{
      PetscReal         ftime;
      TS                ts;
      TSConvergedReason reason;
      PetscInt          nsteps;

      ierr = PetscPrintf(PETSC_COMM_WORLD,"Using the fully explicit method based on the PETSC TS routing\n");CHKERRQ(ierr);
      ierr = DMCreateGlobalVector(user->dm, &algebra->solution);CHKERRQ(ierr);
      ierr = PetscObjectSetName((PetscObject) algebra->solution, "solution");CHKERRQ(ierr);
      ierr = SetInitialCondition(user->dm, algebra->solution, user);CHKERRQ(ierr);
      ierr = TSCreate(comm, &ts);CHKERRQ(ierr);
      ierr = TSSetType(ts, TSEULER);CHKERRQ(ierr);
      ierr = TSSetDM(ts, user->dm);CHKERRQ(ierr);
      ierr = TSMonitorSet(ts,TSMonitorFunctionError,&user,NULL);CHKERRQ(ierr);
      ierr = TSSetRHSFunction(ts, NULL, MyRHSFunction, user);CHKERRQ(ierr);
      ierr = TSSetDuration(ts, 1000, user->final_time);CHKERRQ(ierr);
      ierr = TSSetInitialTimeStep(ts, user->initial_time, user->dt);CHKERRQ(ierr);
      ierr = TSSetFromOptions(ts);CHKERRQ(ierr);
      ierr = TSSolve(ts, algebra->solution);CHKERRQ(ierr);
      ierr = TSGetSolveTime(ts, &ftime);CHKERRQ(ierr);
      ierr = TSGetTimeStepNumber(ts, &nsteps);CHKERRQ(ierr);
      ierr = TSGetConvergedReason(ts, &reason);CHKERRQ(ierr);
      ierr = PetscPrintf(PETSC_COMM_WORLD,"%s at time %g after %D steps\n",TSConvergedReasons[reason],ftime,nsteps);CHKERRQ(ierr);
      ierr = TSDestroy(&ts);CHKERRQ(ierr);
    }

    if(user->benchmark_couette) {
      ierr = DMCreateGlobalVector(user->dm, &algebra->exactsolution);CHKERRQ(ierr);
      ierr = ComputeExactSolution(user->dm, user->final_time, algebra->exactsolution, user);CHKERRQ(ierr);
    }

    if (user->output_solution){
      PetscViewer    viewer;
      ierr = OutputVTK(user->dm, "solution.vtk", &viewer);CHKERRQ(ierr);
      ierr = VecView(algebra->solution, viewer);CHKERRQ(ierr);
      ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
    }

    if(user->benchmark_couette) {
      PetscViewer    viewer;
      PetscReal      norm;

      ierr = OutputVTK(user->dm, "exact_solution.vtk", &viewer);CHKERRQ(ierr);
      ierr = VecView(algebra->exactsolution, viewer);CHKERRQ(ierr);
      ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);

      ierr = VecAXPY(algebra->exactsolution, -1, algebra->solution);CHKERRQ(ierr);
      ierr = VecNorm(algebra->exactsolution,NORM_INFINITY,&norm);CHKERRQ(ierr);
      ierr = PetscPrintf(PETSC_COMM_WORLD,"Final time at %f, Error: ||u_k-u|| = %g \n", user->final_time, norm);CHKERRQ(ierr);

      ierr = OutputVTK(user->dm, "Error.vtk", &viewer);CHKERRQ(ierr);
      ierr = VecView(algebra->exactsolution, viewer);CHKERRQ(ierr);
      ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
    }

    ierr = VecDestroy(&algebra->solution);CHKERRQ(ierr);
    ierr = VecDestroy(&algebra->oldsolution);CHKERRQ(ierr);
    ierr = DMDestroy(&user->dm);CHKERRQ(ierr);
  } else if (user->TimeIntegralMethod == IMPLICITMETHOD) {
    ierr = PetscPrintf(PETSC_COMM_WORLD,"Using the fully implicit method\n");CHKERRQ(ierr);
    ierr =  SNESCreate(comm,&user->snes);CHKERRQ(ierr);
    ierr =  SNESSetDM(user->snes,user->dm);CHKERRQ(ierr);

    ierr = DMCreateGlobalVector(user->dm, &algebra->solution);CHKERRQ(ierr);
    ierr = VecDuplicate(algebra->solution, &algebra->oldsolution);CHKERRQ(ierr);
    ierr = VecDuplicate(algebra->solution, &algebra->f);CHKERRQ(ierr);
    ierr = VecDuplicate(algebra->solution, &algebra->fn);CHKERRQ(ierr);
    ierr = VecDuplicate(algebra->solution, &algebra->oldfn);CHKERRQ(ierr);

    ierr = PetscObjectSetName((PetscObject) algebra->solution, "solution");CHKERRQ(ierr);
    ierr = SetInitialCondition(user->dm, algebra->solution, user);CHKERRQ(ierr);

    ierr = DMSetMatType(user->dm, MATAIJ);CHKERRQ(ierr);
//    ierr = DMCreateMatrix(user->dm, &algebra->A);CHKERRQ(ierr);
    ierr = DMCreateMatrix(user->dm, &algebra->J);CHKERRQ(ierr);
    if (user->JdiffP) {
     /*Set up the preconditioner matrix*/
     ierr = DMCreateMatrix(user->dm, &algebra->P);CHKERRQ(ierr);
    }else{
     algebra->P = algebra->J;
    }

    ierr = MatSetOption(algebra->J, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE);CHKERRQ(ierr);

    /*set nonlinear function */
    ierr =  SNESSetFunction(user->snes, algebra->f, FormFunction, (void*)user);CHKERRQ(ierr);
    /* compute Jacobian */
    ierr =  SNESSetJacobian(user->snes, algebra->J, algebra->P, FormJacobian, (void*)user);CHKERRQ(ierr);

    ierr = SNESSetFromOptions(user->snes);CHKERRQ(ierr);

    /* do the solve */
    if (user->timestep == TIMESTEP_STEADY_STATE) {
      ierr = SolveSteadyState(user);CHKERRQ(ierr);
    } else {
      ierr = SolveTimeDependent(user);CHKERRQ(ierr);
    }

    if (user->output_solution){
      PetscViewer    viewer;
      ierr = OutputVTK(user->dm, "solution.vtk", &viewer);CHKERRQ(ierr);
      ierr = VecView(algebra->solution, viewer);CHKERRQ(ierr);
      ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
    }

    if(user->benchmark_couette) {
      PetscViewer    viewer;
      PetscReal      norm;

      ierr = OutputVTK(user->dm, "exact_solution.vtk", &viewer);CHKERRQ(ierr);
      ierr = VecView(algebra->exactsolution, viewer);CHKERRQ(ierr);
      ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);

      ierr = VecAXPY(algebra->exactsolution, -1, algebra->solution);CHKERRQ(ierr);
      ierr = VecNorm(algebra->exactsolution,NORM_INFINITY,&norm);CHKERRQ(ierr);
      ierr = PetscPrintf(PETSC_COMM_WORLD,"Error: ||u_k-u|| = %g \n", norm);CHKERRQ(ierr);

      ierr = OutputVTK(user->dm, "Error.vtk", &viewer);CHKERRQ(ierr);
      ierr = VecView(algebra->exactsolution, viewer);CHKERRQ(ierr);
      ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
    }

    ierr = VecDestroy(&algebra->solution);CHKERRQ(ierr);
    ierr = VecDestroy(&algebra->f);CHKERRQ(ierr);
    ierr = VecDestroy(&algebra->oldsolution);CHKERRQ(ierr);
    ierr = VecDestroy(&algebra->fn);CHKERRQ(ierr);
    ierr = VecDestroy(&algebra->oldfn);CHKERRQ(ierr);

    ierr = SNESDestroy(&user->snes);CHKERRQ(ierr);
    ierr = DMDestroy(&user->dm);CHKERRQ(ierr);

  } else {
    SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"WRONG option for the time integral method. Using the option '-time_integral_method 0 or 1'");
  }

  ierr = VecDestroy(&user->cellgeom);CHKERRQ(ierr);
  ierr = VecDestroy(&user->facegeom);CHKERRQ(ierr);
  ierr = DMDestroy(&user->dmGrad);CHKERRQ(ierr);

  ierr = PetscFunctionListDestroy(&LimitList);CHKERRQ(ierr);
  ierr = PetscFree(user->model->physics);CHKERRQ(ierr);
  ierr = PetscFree(user->algebra);CHKERRQ(ierr);
  ierr = PetscFree(user->model);CHKERRQ(ierr);
  ierr = PetscFree(user);CHKERRQ(ierr);

  {
    PetscLogDouble    space =0;
    ierr =  PetscMallocGetCurrentUsage(&space);CHKERRQ(ierr);
    ierr =  PetscPrintf(PETSC_COMM_WORLD,"Unfreed space at the End %g M\n", space/(1024*1024));CHKERRQ(ierr);
  }

  ierr = PetscFinalize();
  return(0);
}
Пример #4
0
int main(int argc,char **argv)
{
  TS                ts;         /* time integrator */
  TSAdapt           adapt;
  Vec               X;          /* solution vector */
  Mat               J;          /* Jacobian matrix */
  PetscInt          steps,maxsteps,ncells,xs,xm,i;
  PetscErrorCode    ierr;
  PetscReal         ftime,dt;
  char              chemfile[PETSC_MAX_PATH_LEN] = "chem.inp",thermofile[PETSC_MAX_PATH_LEN] = "therm.dat";
  struct _User      user;
  TSConvergedReason reason;
  PetscBool         showsolutions = PETSC_FALSE;
  char              **snames,*names;
  Vec               lambda;     /* used with TSAdjoint for sensitivities */

  ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr;
  ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Chemistry solver options","");CHKERRQ(ierr);
  ierr = PetscOptionsString("-chem","CHEMKIN input file","",chemfile,chemfile,sizeof(chemfile),NULL);CHKERRQ(ierr);
  ierr = PetscOptionsString("-thermo","NASA thermo input file","",thermofile,thermofile,sizeof(thermofile),NULL);CHKERRQ(ierr);
  user.pressure = 1.01325e5;    /* Pascal */
  ierr = PetscOptionsReal("-pressure","Pressure of reaction [Pa]","",user.pressure,&user.pressure,NULL);CHKERRQ(ierr);
  user.Tini   = 1550;
  ierr = PetscOptionsReal("-Tini","Initial temperature [K]","",user.Tini,&user.Tini,NULL);CHKERRQ(ierr);
  user.diffus = 100;
  ierr = PetscOptionsReal("-diffus","Diffusion constant","",user.diffus,&user.diffus,NULL);CHKERRQ(ierr);
  ierr = PetscOptionsBool("-draw_solution","Plot the solution for each cell","",showsolutions,&showsolutions,NULL);CHKERRQ(ierr);
  user.diffusion = PETSC_TRUE;
  ierr = PetscOptionsBool("-diffusion","Have diffusion","",user.diffusion,&user.diffusion,NULL);CHKERRQ(ierr);
  user.reactions = PETSC_TRUE;
  ierr = PetscOptionsBool("-reactions","Have reactions","",user.reactions,&user.reactions,NULL);CHKERRQ(ierr);
  ierr = PetscOptionsEnd();CHKERRQ(ierr);

  ierr = TC_initChem(chemfile, thermofile, 0, 1.0);TCCHKERRQ(ierr);
  user.Nspec = TC_getNspec();
  user.Nreac = TC_getNreac();

  ierr    = DMDACreate1d(PETSC_COMM_WORLD,DM_BOUNDARY_PERIODIC,-1,user.Nspec+1,1,NULL,&user.dm);CHKERRQ(ierr);
  ierr    = DMDAGetInfo(user.dm,NULL,&ncells,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);CHKERRQ(ierr);
  user.dx = 1.0/ncells;  /* Set the coordinates of the cell centers; note final ghost cell is at x coordinate 1.0 */
  ierr    = DMDASetUniformCoordinates(user.dm,0.0,1.0,0.0,1.0,0.0,1.0);CHKERRQ(ierr);

  /* set the names of each field in the DMDA based on the species name */
  ierr = PetscMalloc1((user.Nspec+1)*LENGTHOFSPECNAME,&names);CHKERRQ(ierr);
  ierr = PetscStrcpy(names,"Temp");CHKERRQ(ierr);
  TC_getSnames(user.Nspec,names+LENGTHOFSPECNAME);CHKERRQ(ierr);
  ierr = PetscMalloc1((user.Nspec+2),&snames);CHKERRQ(ierr);
  for (i=0; i<user.Nspec+1; i++) snames[i] = names+i*LENGTHOFSPECNAME;
  snames[user.Nspec+1] = NULL;
  ierr = DMDASetFieldNames(user.dm,(const char * const *)snames);CHKERRQ(ierr);
  ierr = PetscFree(snames);CHKERRQ(ierr);
  ierr = PetscFree(names);CHKERRQ(ierr);


  ierr = DMCreateMatrix(user.dm,&J);CHKERRQ(ierr);
  ierr = DMCreateGlobalVector(user.dm,&X);CHKERRQ(ierr);

  ierr = PetscMalloc3(user.Nspec+1,&user.tchemwork,PetscSqr(user.Nspec+1),&user.Jdense,user.Nspec+1,&user.rows);CHKERRQ(ierr);

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Create timestepping solver context
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr);
  ierr = TSSetDM(ts,user.dm);CHKERRQ(ierr);
  ierr = TSSetType(ts,TSARKIMEX);CHKERRQ(ierr);
  ierr = TSARKIMEXSetFullyImplicit(ts,PETSC_TRUE);CHKERRQ(ierr);
  ierr = TSARKIMEXSetType(ts,TSARKIMEX4);CHKERRQ(ierr);
  ierr = TSSetRHSFunction(ts,NULL,FormRHSFunction,&user);CHKERRQ(ierr);
  ierr = TSSetRHSJacobian(ts,J,J,FormRHSJacobian,&user);CHKERRQ(ierr);

  ftime    = 1.0;
  maxsteps = 10000;
  ierr     = TSSetDuration(ts,maxsteps,ftime);CHKERRQ(ierr);
  ierr     = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);CHKERRQ(ierr);

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Set initial conditions
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = FormInitialSolution(ts,X,&user);CHKERRQ(ierr);
  ierr = TSSetSolution(ts,X);CHKERRQ(ierr);
  dt   = 1e-10;                 /* Initial time step */
  ierr = TSSetInitialTimeStep(ts,0.0,dt);CHKERRQ(ierr);
  ierr = TSGetAdapt(ts,&adapt);CHKERRQ(ierr);
  ierr = TSAdaptSetStepLimits(adapt,1e-12,1e-4);CHKERRQ(ierr); /* Also available with -ts_adapt_dt_min/-ts_adapt_dt_max */
  ierr = TSSetMaxSNESFailures(ts,-1);CHKERRQ(ierr);            /* Retry step an unlimited number of times */


  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Pass information to graphical monitoring routine
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  if (showsolutions) {
    ierr = DMDAGetCorners(user.dm,&xs,NULL,NULL,&xm,NULL,NULL);CHKERRQ(ierr);
    for (i=xs;i<xs+xm;i++) {
      ierr = MonitorCell(ts,&user,i);CHKERRQ(ierr);
    }
  }

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Set runtime options
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = TSSetFromOptions(ts);CHKERRQ(ierr);

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Set final conditions for sensitivities
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = DMCreateGlobalVector(user.dm,&lambda);CHKERRQ(ierr);
  ierr = TSSetCostGradients(ts,1,&lambda,NULL);CHKERRQ(ierr);
  ierr = VecSetValue(lambda,0,1.0,INSERT_VALUES);CHKERRQ(ierr);
  ierr = VecAssemblyBegin(lambda);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(lambda);CHKERRQ(ierr);

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Solve ODE
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = TSSolve(ts,X);CHKERRQ(ierr);
  ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr);
  ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr);
  ierr = TSGetConvergedReason(ts,&reason);CHKERRQ(ierr);
  ierr = PetscPrintf(PETSC_COMM_WORLD,"%s at time %g after %D steps\n",TSConvergedReasons[reason],(double)ftime,steps);CHKERRQ(ierr);

  {
    Vec                max;
    const char * const *names;
    PetscInt           i;
    const PetscReal    *bmax;

    ierr = TSMonitorEnvelopeGetBounds(ts,&max,NULL);CHKERRQ(ierr);
    if (max) {
      ierr = TSMonitorLGGetVariableNames(ts,&names);CHKERRQ(ierr);
      if (names) {
        ierr = VecGetArrayRead(max,&bmax);CHKERRQ(ierr);
        ierr = PetscPrintf(PETSC_COMM_SELF,"Species - maximum mass fraction\n");CHKERRQ(ierr);
        for (i=1; i<user.Nspec; i++) {
          if (bmax[i] > .01) {ierr = PetscPrintf(PETSC_COMM_SELF,"%s %g\n",names[i],bmax[i]);CHKERRQ(ierr);}
        }
        ierr = VecRestoreArrayRead(max,&bmax);CHKERRQ(ierr);
      }
    }
  }

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Free work space.
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  TC_reset();
  ierr = DMDestroy(&user.dm);CHKERRQ(ierr);
  ierr = MatDestroy(&J);CHKERRQ(ierr);
  ierr = VecDestroy(&X);CHKERRQ(ierr);
  ierr = VecDestroy(&lambda);CHKERRQ(ierr);
  ierr = TSDestroy(&ts);CHKERRQ(ierr);
  ierr = PetscFree3(user.tchemwork,user.Jdense,user.rows);CHKERRQ(ierr);
  ierr = PetscFinalize();
  return ierr;
}
Пример #5
0
int main(int argc, char **argv)
{
  MPI_Comm          comm;
  PetscMPIInt       rank;
  PetscErrorCode    ierr;
  User              user;
  PetscLogDouble       v1, v2;
  PetscInt          nplot = 0;
  char              fileName[2048];


  ierr = PetscInitialize(&argc, &argv, (char*) 0, help);CHKERRQ(ierr);
  comm = PETSC_COMM_WORLD;
  ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
  ierr = PetscNew(&user);CHKERRQ(ierr);
  ierr = PetscNew(&user->algebra);CHKERRQ(ierr);
  ierr = PetscNew(&user->model);CHKERRQ(ierr);
  ierr = PetscNew(&user->model->physics);CHKERRQ(ierr);

  Algebra   algebra = user->algebra;

  ierr = LoadOptions(comm, user);CHKERRQ(ierr);
  ierr = PetscTime(&v1);CHKERRQ(ierr);
  ierr = CreateMesh(comm, user);CHKERRQ(ierr);
  ierr = PetscTime(&v2);CHKERRQ(ierr);
  ierr = PetscPrintf(PETSC_COMM_WORLD,
		       "Read and Distribute mesh takes %f sec \n", v2 - v1);CHKERRQ(ierr);
  ierr = SetUpLocalSpace(user);CHKERRQ(ierr); //Set up the dofs of each element
  ierr = ConstructGeometryFVM(&user->facegeom, &user->cellgeom, user);CHKERRQ(ierr);

  ierr = LimiterSetup(user);CHKERRQ(ierr);

  if (user->TimeIntegralMethod == EXPLICITMETHOD) { // explicit method
    if(user->myownexplicitmethod){// Using the fully explicit method based on my own routing
      ierr = PetscPrintf(PETSC_COMM_WORLD,"Using the fully explicit method based on my own routing\n");CHKERRQ(ierr);
      user->current_time = user->initial_time;
      user->current_step = 1;
      ierr = DMCreateGlobalVector(user->dm, &algebra->solution);CHKERRQ(ierr);
      ierr = PetscObjectSetName((PetscObject) algebra->solution, "solution");CHKERRQ(ierr);
      ierr = VecSet(algebra->solution, 0);CHKERRQ(ierr);
      ierr = SetInitialCondition(user->dm, algebra->solution, user);CHKERRQ(ierr);
      if(1){
        PetscViewer    viewer;
        ierr = OutputVTK(user->dm, "intialcondition.vtk", &viewer);CHKERRQ(ierr);
        ierr = VecView(algebra->solution, viewer);CHKERRQ(ierr);
        ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
        ierr = PetscPrintf(PETSC_COMM_WORLD,"Outputing the initial condition intialcondition.vtk!!! \n");CHKERRQ(ierr);
      }
      ierr = VecDuplicate(algebra->solution, &algebra->fn);CHKERRQ(ierr);
      ierr = VecDuplicate(algebra->solution, &algebra->oldsolution);CHKERRQ(ierr);
      if(user->Explicit_RK2||user->Explicit_RK4){
        ierr = PetscPrintf(PETSC_COMM_WORLD,"Use the second order Runge Kutta method \n");CHKERRQ(ierr);
      }else{
        ierr = PetscPrintf(PETSC_COMM_WORLD,"Use the first order forward Euler method \n");CHKERRQ(ierr);
      }
      nplot = 0; //the plot step
      while(user->current_time < (user->final_time - 0.05 * user->dt)){

        user->current_time = user->current_time + user->dt;
        ierr = FormTimeStepFunction(user, algebra, algebra->solution, algebra->fn);CHKERRQ(ierr);
        if(0){
            PetscViewer    viewer;
            ierr = OutputVTK(user->dm, "function.vtk", &viewer);CHKERRQ(ierr);
            ierr = VecView(algebra->fn, viewer);CHKERRQ(ierr);
            ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
          }

        if(user->Explicit_RK2){
        /*
          U^n_1   = U^n + 0.5*dt*f(U^n)
          U^{n+1} = U^n + dt*f(U^n_1)
        */
          ierr = VecCopy(algebra->solution, algebra->oldsolution);CHKERRQ(ierr);
          //note that algebra->oldsolution and algebra->solution are both U^n
          ierr = VecAXPY(algebra->solution, 0.5*user->dt, algebra->fn);CHKERRQ(ierr);
          //U^n_1 = U^n + 0.5*dt*f(U^n), now algebra->solution is U^n_1, and algebra->fn is f(U^n)

          ierr = FormTimeStepFunction(user, algebra, algebra->solution, algebra->fn);CHKERRQ(ierr);
          //algebra->fn is f(U^n_1)

          // reset the algebra->solution to U^n
          ierr = VecCopy(algebra->oldsolution, algebra->solution);CHKERRQ(ierr);
          ierr = VecAXPY(algebra->solution, user->dt, algebra->fn);CHKERRQ(ierr);
          // now algebra->solution is U^{n+1} = U^n + dt*f(U^n_1)
        }else if(user->Explicit_RK4){
        /* refer to https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods
          k_1     = f(U^n)
          U^n_1   = U^n + 0.5*dt*k_1
          k_2     = f(U^n_1)
          U^n_2   = U^n + 0.5*dt*k_2
          k_3     = f(U^n_2)
          U^n_3   = U^n + 0.5*dt*k_3
          k_4     = f(U^n_3)

          U^{n+1} = U^n + dt/6*(k_1 + 2*k_2 + 2*k_3 + k_4)
        */
          Vec  VecTemp; // store the U^n_1
          Vec  k1, k2, k3, k4;

          ierr = VecDuplicate(algebra->solution, &k1);CHKERRQ(ierr);
          ierr = VecDuplicate(algebra->solution, &k2);CHKERRQ(ierr);
          ierr = VecDuplicate(algebra->solution, &k3);CHKERRQ(ierr);
          ierr = VecDuplicate(algebra->solution, &k4);CHKERRQ(ierr);
          ierr = VecCopy(algebra->solution, algebra->oldsolution);CHKERRQ(ierr);

          ierr = VecCopy(algebra->fn, k1);CHKERRQ(ierr);
          //note that algebra->oldsolution and algebra->solution are both U^n
          ierr = VecAXPY(algebra->solution, 0.5*user->dt, k1);CHKERRQ(ierr);
          //U^n_1 = U^n + 0.5*dt*k1, now algebra->solution is U^n_1, and algebra->fn is f(U^n)

          ierr = FormTimeStepFunction(user, algebra, algebra->solution, algebra->fn);CHKERRQ(ierr);
          //algebra->fn is f(U^n_1)
          ierr = VecCopy(algebra->fn, k2);CHKERRQ(ierr);
          // reset the algebra->solution to U^n
          ierr = VecCopy(algebra->oldsolution, algebra->solution);CHKERRQ(ierr);
          ierr = VecAXPY(algebra->solution, 0.5*user->dt, k2);CHKERRQ(ierr);
          //U^n_2 = U^n + 0.5*dt*k2, now algebra->solution is U^n_2, and algebra->fn is f(U^n_1)

          ierr = FormTimeStepFunction(user, algebra, algebra->solution, algebra->fn);CHKERRQ(ierr);
          //algebra->fn is f(U^n_2)
          ierr = VecCopy(algebra->fn, k3);CHKERRQ(ierr);
          // reset the algebra->solution to U^n
          ierr = VecCopy(algebra->oldsolution, algebra->solution);CHKERRQ(ierr);
          ierr = VecAXPY(algebra->solution, 0.5*user->dt, k3);CHKERRQ(ierr);
          //U^n_3 = U^n + 0.5*dt*k3, now algebra->solution is U^n_3, and algebra->fn is f(U^n_2)

          ierr = FormTimeStepFunction(user, algebra, algebra->solution, algebra->fn);CHKERRQ(ierr);
          //algebra->fn is f(U^n_3)
          ierr = VecCopy(algebra->fn, k4);CHKERRQ(ierr);

          //U^{n+1} = U^n + dt/6*(k_1 + 2*k_2 + 2*k_3 + k_4)
          PetscReal temp;
          temp = user->dt/6;
          // reset the algebra->solution to U^n
          ierr = VecCopy(algebra->oldsolution, algebra->solution);CHKERRQ(ierr);
          ierr = VecAXPY(algebra->solution, temp, k1);CHKERRQ(ierr);
          // now algebra->solution is U^n + dt/6*k_1
          ierr = VecAXPY(algebra->solution, 2*temp, k2);CHKERRQ(ierr);
          // now algebra->solution is U^n + dt/6*k_1 + 2*dt/6*k_2
          ierr = VecAXPY(algebra->solution, 2*temp, k3);CHKERRQ(ierr);
          // now algebra->solution is U^n + dt/6*k_1 + 2*dt/6*k_2 + 2*dt/6*k_3
          ierr = VecAXPY(algebra->solution, temp, k4);CHKERRQ(ierr);
          // now algebra->solution is U^n + dt/6*k_1 + 2*dt/6*k_2 + 2*dt/6*k_3 + dt/6*k_4

          ierr = VecDestroy(&k1);CHKERRQ(ierr);
          ierr = VecDestroy(&k2);CHKERRQ(ierr);
          ierr = VecDestroy(&k3);CHKERRQ(ierr);
          ierr = VecDestroy(&k4);CHKERRQ(ierr);
        }else{
          ierr = VecCopy(algebra->solution, algebra->oldsolution);CHKERRQ(ierr);
          ierr = VecAXPY(algebra->solution, user->dt, algebra->fn);CHKERRQ(ierr);
        }

        {// Monitor the solution and function norms
          PetscReal         norm;
          PetscLogDouble    space =0;
          PetscInt          size;

          PetscReal fnnorm;
          ierr = VecNorm(algebra->fn,NORM_2,&fnnorm);CHKERRQ(ierr);
          //ierr = VecView(algebra->fn, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);

          ierr = VecNorm(algebra->solution,NORM_2,&norm);CHKERRQ(ierr);
          ierr = VecGetSize(algebra->solution, &size);CHKERRQ(ierr);
          norm   = norm/size;
          fnnorm = fnnorm/size;
          if (norm>1.e5) {
            SETERRQ2(PETSC_COMM_WORLD, PETSC_ERR_LIB,
            "The norm of the solution is: %f (current time: %f). The explicit method is going to DIVERGE!!!", norm, user->current_time);
          }
          if (user->current_step%10==0) {
            ierr = PetscPrintf(PETSC_COMM_WORLD,"Step %D at time %g with solution norm = %g and founction norm = %g \n",
                                user->current_step, user->current_time, norm, fnnorm);CHKERRQ(ierr);
          }
//          ierr =  PetscMallocGetCurrentUsage(&space);CHKERRQ(ierr);
//          if (user->current_step%10==0) {
//            ierr =  PetscPrintf(PETSC_COMM_WORLD,"Current space PetscMalloc()ed %g M\n",
//                                 space/(1024*1024));CHKERRQ(ierr);
//          }
        }

        { // Monitor the difference of two steps' solution
          PetscReal         norm;
          ierr = VecAXPY(algebra->oldsolution, -1, algebra->solution);CHKERRQ(ierr);
          ierr = VecNorm(algebra->oldsolution,NORM_2,&norm);CHKERRQ(ierr);
          if (user->current_step%10==0) {
            ierr = PetscPrintf(PETSC_COMM_WORLD,"Step %D at time %g with ||u_k-u_{k-1}|| = %g \n",
                              user->current_step, user->current_time, norm);CHKERRQ(ierr);
          }
          if((norm<1.e-6)||(user->current_step > user->max_time_its)){
            if(norm<1.e-6) ierr = PetscPrintf(PETSC_COMM_WORLD,"\n Convergence with ||u_k-u_{k-1}|| = %g < 1.e-6\n\n", norm);CHKERRQ(ierr);
            if(user->current_step > user->max_time_its) ierr = PetscPrintf(PETSC_COMM_WORLD,"\n Convergence with reaching the max time its\n\n");CHKERRQ(ierr);
            break;
          }
        }

        // output the solution
        if (user->output_solution && (user->current_step%user->steps_output==0)){
          PetscViewer    viewer;
          Vec            solution_unscaled; // Note the the algebra->solution is scaled by the density, so this is for the unscaled solution

          nplot = user->current_step/user->steps_output;
          // update file name for the current time step
          ierr = VecDuplicate(algebra->solution, &solution_unscaled);CHKERRQ(ierr);

          ierr = ReformatSolution(algebra->solution, solution_unscaled, user);CHKERRQ(ierr);

          ierr = PetscSNPrintf(fileName, sizeof(fileName),"%s_%d.vtk",user->solutionfile, nplot);CHKERRQ(ierr);
          ierr = PetscPrintf(PETSC_COMM_WORLD,"Outputing solution %s (current time %f)\n", fileName, user->current_time);CHKERRQ(ierr);
          ierr = OutputVTK(user->dm, fileName, &viewer);CHKERRQ(ierr);
          ierr = VecView(solution_unscaled, viewer);CHKERRQ(ierr);
          ierr = VecDestroy(&solution_unscaled);CHKERRQ(ierr);
          ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
        }

        user->current_step++;

      }

      ierr = VecDestroy(&algebra->fn);CHKERRQ(ierr);
    }else{ // Using the fully explicit method based on the PETSC TS routing
      PetscReal         ftime;
      TS                ts;
      TSConvergedReason reason;
      PetscInt          nsteps;
      //PetscReal         minRadius;

      //ierr = DMPlexTSGetGeometry(user->dm, NULL, NULL, &minRadius);CHKERRQ(ierr);
      //user->dt  = 0.9*4 * minRadius / 1.0;

      ierr = PetscPrintf(PETSC_COMM_WORLD,"Using the fully explicit method based on the PETSC TS routing\n");CHKERRQ(ierr);
      ierr = DMCreateGlobalVector(user->dm, &algebra->solution);CHKERRQ(ierr);
      ierr = PetscObjectSetName((PetscObject) algebra->solution, "solution");CHKERRQ(ierr);
      ierr = VecSet(algebra->solution, 0.0);CHKERRQ(ierr);
      ierr = SetInitialCondition(user->dm, algebra->solution, user);CHKERRQ(ierr);
      ierr = TSCreate(comm, &ts);CHKERRQ(ierr);
      ierr = TSSetType(ts, TSEULER);CHKERRQ(ierr);
      ierr = TSSetDM(ts, user->dm);CHKERRQ(ierr);
      ierr = TSMonitorSet(ts,TSMonitorFunctionError,(void*)user,NULL);CHKERRQ(ierr);
      ierr = TSSetRHSFunction(ts, NULL, MyRHSFunction, user);CHKERRQ(ierr);
      ierr = TSSetDuration(ts, 1000, user->final_time);CHKERRQ(ierr);
      ierr = TSSetInitialTimeStep(ts, user->initial_time, user->dt);CHKERRQ(ierr);
      ierr = TSSetFromOptions(ts);CHKERRQ(ierr);
      ierr = TSSolve(ts, algebra->solution);CHKERRQ(ierr);
      ierr = TSGetSolveTime(ts, &ftime);CHKERRQ(ierr);
      ierr = TSGetTimeStepNumber(ts, &nsteps);CHKERRQ(ierr);
      ierr = TSGetConvergedReason(ts, &reason);CHKERRQ(ierr);
      ierr = PetscPrintf(PETSC_COMM_WORLD,"%s at time %g after %D steps\n",TSConvergedReasons[reason],ftime,nsteps);CHKERRQ(ierr);
      ierr = TSDestroy(&ts);CHKERRQ(ierr);

    }

    if(user->benchmark_couette) {
      ierr = DMCreateGlobalVector(user->dm, &algebra->exactsolution);CHKERRQ(ierr);
      ierr = ComputeExactSolution(user->dm, user->current_time, algebra->exactsolution, user);CHKERRQ(ierr);
    }

    if(user->benchmark_couette) {
      PetscViewer    viewer;
      PetscReal      norm;

      ierr = OutputVTK(user->dm, "exact_solution.vtk", &viewer);CHKERRQ(ierr);
      ierr = VecView(algebra->exactsolution, viewer);CHKERRQ(ierr);
      ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);

      ierr = VecAXPY(algebra->exactsolution, -1, algebra->solution);CHKERRQ(ierr);
      ierr = VecNorm(algebra->exactsolution,NORM_INFINITY,&norm);CHKERRQ(ierr);
      ierr = PetscPrintf(PETSC_COMM_WORLD,"Final time at %f, Error: ||u_k-u|| = %g \n", user->current_time, norm);CHKERRQ(ierr);

      ierr = OutputVTK(user->dm, "Error.vtk", &viewer);CHKERRQ(ierr);
      ierr = VecView(algebra->exactsolution, viewer);CHKERRQ(ierr);
      ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
    }

    ierr = VecDestroy(&algebra->solution);CHKERRQ(ierr);
    if(user->myownexplicitmethod){ierr = VecDestroy(&algebra->oldsolution);CHKERRQ(ierr);}
    ierr = VecDestroy(&algebra->exactsolution);CHKERRQ(ierr);
    ierr = DMDestroy(&user->dm);CHKERRQ(ierr);
  } else if (user->TimeIntegralMethod == IMPLICITMETHOD) { // Using the fully implicit method
    ierr = PetscPrintf(PETSC_COMM_WORLD,"Using the fully implicit method\n");CHKERRQ(ierr);
    ierr =  SNESCreate(comm,&user->snes);CHKERRQ(ierr);
    ierr =  SNESSetDM(user->snes,user->dm);CHKERRQ(ierr);

    ierr = DMCreateGlobalVector(user->dm, &algebra->solution);CHKERRQ(ierr);
    ierr = VecDuplicate(algebra->solution, &algebra->oldsolution);CHKERRQ(ierr);
    ierr = VecDuplicate(algebra->solution, &algebra->f);CHKERRQ(ierr);
    ierr = VecDuplicate(algebra->solution, &algebra->fn);CHKERRQ(ierr);
    ierr = VecDuplicate(algebra->solution, &algebra->oldfn);CHKERRQ(ierr);

    ierr = PetscObjectSetName((PetscObject) algebra->solution, "solution");CHKERRQ(ierr);
    ierr = SetInitialCondition(user->dm, algebra->solution, user);CHKERRQ(ierr);

    ierr = DMSetMatType(user->dm, MATAIJ);CHKERRQ(ierr);
//    ierr = DMCreateMatrix(user->dm, &algebra->A);CHKERRQ(ierr);
    ierr = DMCreateMatrix(user->dm, &algebra->J);CHKERRQ(ierr);
    if (user->JdiffP) {
     /*Set up the preconditioner matrix*/
     ierr = DMCreateMatrix(user->dm, &algebra->P);CHKERRQ(ierr);
    }else{
     algebra->P = algebra->J;
    }

    ierr = MatSetOption(algebra->J, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE);CHKERRQ(ierr);

    /*set nonlinear function */
    ierr =  SNESSetFunction(user->snes, algebra->f, FormFunction, (void*)user);CHKERRQ(ierr);
    /* compute Jacobian */
    ierr =  SNESSetJacobian(user->snes, algebra->J, algebra->P, FormJacobian, (void*)user);CHKERRQ(ierr);

    ierr = SNESSetFromOptions(user->snes);CHKERRQ(ierr);

    /* do the solve */
    if (user->timestep == TIMESTEP_STEADY_STATE) {
      ierr = SolveSteadyState(user);CHKERRQ(ierr);
    } else {
      ierr = SolveTimeDependent(user);CHKERRQ(ierr);
    }

    if (user->output_solution){
      PetscViewer    viewer;
      Vec            solution_unscaled; // Note the the algebra->solution is scaled by the density, so this is for the unscaled solution

      ierr = VecDuplicate(algebra->solution, &solution_unscaled);CHKERRQ(ierr);
      ierr = ReformatSolution(algebra->solution, solution_unscaled, user);CHKERRQ(ierr);
      ierr = OutputVTK(user->dm, "solution.vtk", &viewer);CHKERRQ(ierr);
      ierr = VecView(solution_unscaled, viewer);CHKERRQ(ierr);
      ierr = VecDestroy(&solution_unscaled);CHKERRQ(ierr);
      ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
    }

    if(user->benchmark_couette) {
      PetscViewer    viewer;
      PetscReal      norm;

      ierr = OutputVTK(user->dm, "exact_solution.vtk", &viewer);CHKERRQ(ierr);
      ierr = VecView(algebra->exactsolution, viewer);CHKERRQ(ierr);
      ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);

      ierr = VecAXPY(algebra->exactsolution, -1, algebra->solution);CHKERRQ(ierr);
      ierr = VecNorm(algebra->exactsolution,NORM_INFINITY,&norm);CHKERRQ(ierr);
      ierr = PetscPrintf(PETSC_COMM_WORLD,"Error: ||u_k-u|| = %g \n", norm);CHKERRQ(ierr);

      ierr = OutputVTK(user->dm, "Error.vtk", &viewer);CHKERRQ(ierr);
      ierr = VecView(algebra->exactsolution, viewer);CHKERRQ(ierr);
      ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
    }

    ierr = VecDestroy(&algebra->solution);CHKERRQ(ierr);
    ierr = VecDestroy(&algebra->f);CHKERRQ(ierr);
    ierr = VecDestroy(&algebra->oldsolution);CHKERRQ(ierr);
    ierr = VecDestroy(&algebra->fn);CHKERRQ(ierr);
    ierr = VecDestroy(&algebra->oldfn);CHKERRQ(ierr);

    ierr = SNESDestroy(&user->snes);CHKERRQ(ierr);
    ierr = DMDestroy(&user->dm);CHKERRQ(ierr);

  } else {
    SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"WRONG option for the time integral method. Using the option '-time_integral_method 0 or 1'");
  }

  ierr = VecDestroy(&user->cellgeom);CHKERRQ(ierr);
  ierr = VecDestroy(&user->facegeom);CHKERRQ(ierr);
  ierr = DMDestroy(&user->dmGrad);CHKERRQ(ierr);

  ierr = PetscFunctionListDestroy(&LimitList);CHKERRQ(ierr);
  ierr = PetscFree(user->model->physics);CHKERRQ(ierr);
  ierr = PetscFree(user->algebra);CHKERRQ(ierr);
  ierr = PetscFree(user->model);CHKERRQ(ierr);
  ierr = PetscFree(user);CHKERRQ(ierr);

  {
    PetscLogDouble    space =0;
    ierr =  PetscMallocGetCurrentUsage(&space);CHKERRQ(ierr);
    ierr =  PetscPrintf(PETSC_COMM_WORLD,"Unfreed space at the End %g M\n", space/(1024*1024));CHKERRQ(ierr);
  }

  ierr = PetscFinalize();
  return(0);
}
Пример #6
0
int main(int argc,char **argv)
{
  TS                ts;         /* nonlinear solver */
  Vec               X;          /* solution, residual vectors */
  Mat               J;          /* Jacobian matrix */
  PetscInt          steps,maxsteps,mx;
  PetscErrorCode    ierr;
  DM                da;
  PetscReal         ftime,hx,dt;
  struct _User      user;       /* user-defined work context */
  TSConvergedReason reason;

  PetscInitialize(&argc,&argv,(char*)0,help);

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Create distributed array (DMDA) to manage parallel grid and vectors
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = DMDACreate1d(PETSC_COMM_WORLD,DMDA_BOUNDARY_NONE,-11,2,2,NULL,&da);CHKERRQ(ierr);

  /*  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Extract global vectors from DMDA;
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = DMCreateGlobalVector(da,&X);CHKERRQ(ierr);

  /* Initialize user application context */
  ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Advection-reaction options","");
  {
    user.A      = 1;
    user.B      = 3;
    user.alpha  = 0.02;
    user.uleft  = 1;
    user.uright = 1;
    user.vleft  = 3;
    user.vright = 3;
    ierr        = PetscOptionsReal("-A","Reaction rate","",user.A,&user.A,NULL);CHKERRQ(ierr);
    ierr        = PetscOptionsReal("-B","Reaction rate","",user.B,&user.B,NULL);CHKERRQ(ierr);
    ierr        = PetscOptionsReal("-alpha","Diffusion coefficient","",user.alpha,&user.alpha,NULL);CHKERRQ(ierr);
    ierr        = PetscOptionsReal("-uleft","Dirichlet boundary condition","",user.uleft,&user.uleft,NULL);CHKERRQ(ierr);
    ierr        = PetscOptionsReal("-uright","Dirichlet boundary condition","",user.uright,&user.uright,NULL);CHKERRQ(ierr);
    ierr        = PetscOptionsReal("-vleft","Dirichlet boundary condition","",user.vleft,&user.vleft,NULL);CHKERRQ(ierr);
    ierr        = PetscOptionsReal("-vright","Dirichlet boundary condition","",user.vright,&user.vright,NULL);CHKERRQ(ierr);
  }
  ierr = PetscOptionsEnd();CHKERRQ(ierr);

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Create timestepping solver context
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr);
  ierr = TSSetDM(ts,da);CHKERRQ(ierr);
  ierr = TSSetType(ts,TSARKIMEX);CHKERRQ(ierr);
  ierr = TSSetRHSFunction(ts,NULL,FormRHSFunction,&user);CHKERRQ(ierr);
  ierr = TSSetIFunction(ts,NULL,FormIFunction,&user);CHKERRQ(ierr);
  ierr = DMCreateMatrix(da,MATAIJ,&J);CHKERRQ(ierr);
  ierr = TSSetIJacobian(ts,J,J,FormIJacobian,&user);CHKERRQ(ierr);

  ftime    = 10.0;
  maxsteps = 10000;
  ierr     = TSSetDuration(ts,maxsteps,ftime);CHKERRQ(ierr);

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Set initial conditions
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = FormInitialSolution(ts,X,&user);CHKERRQ(ierr);
  ierr = TSSetSolution(ts,X);CHKERRQ(ierr);
  ierr = VecGetSize(X,&mx);CHKERRQ(ierr);
  hx = 1.0/(PetscReal)(mx/2-1);
  dt = 0.4 * PetscSqr(hx) / user.alpha; /* Diffusive stability limit */
  ierr = TSSetInitialTimeStep(ts,0.0,dt);CHKERRQ(ierr);

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Set runtime options
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = TSSetFromOptions(ts);CHKERRQ(ierr);

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Solve nonlinear system
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = TSSolve(ts,X);CHKERRQ(ierr);
  ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr);
  ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr);
  ierr = TSGetConvergedReason(ts,&reason);CHKERRQ(ierr);
  ierr = PetscPrintf(PETSC_COMM_WORLD,"%s at time %G after %D steps\n",TSConvergedReasons[reason],ftime,steps);CHKERRQ(ierr);

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Free work space.
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = MatDestroy(&J);CHKERRQ(ierr);
  ierr = VecDestroy(&X);CHKERRQ(ierr);
  ierr = TSDestroy(&ts);CHKERRQ(ierr);
  ierr = DMDestroy(&da);CHKERRQ(ierr);
  ierr = PetscFinalize();
  return 0;
}
Пример #7
0
int main(int argc, char **argv)
{
  DM                dm;
  TS                ts;
  Vec               X;
  Mat               J;
  PetscInt          steps, maxsteps, mx;
  PetscReal         ftime, hx, dt;
  TSConvergedReason reason;
  struct _User      user;
  PetscErrorCode    ierr;

  ierr = PetscInitialize(&argc, &argv, NULL,help);if (ierr) return ierr;
  ierr = DMDACreate1d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, -11, 3, 1, NULL, &dm);CHKERRQ(ierr);
  ierr = DMSetFromOptions(dm);CHKERRQ(ierr);
  ierr = DMSetUp(dm);CHKERRQ(ierr);
  ierr = DMDASetUniformCoordinates(dm, 0.0, 20.0, 0.0, 0.0, 0.0, 0.0);CHKERRQ(ierr);
  ierr = DMCreateGlobalVector(dm, &X);CHKERRQ(ierr);

  ierr = PetscOptionsBegin(PETSC_COMM_WORLD, NULL, "Dynamic Friction Options", "");
  {
    user.epsilon    = 0.1;
    user.gamma      = 0.5;
    user.gammaTilde = 0.5;
    user.xi         = 0.5;
    user.c          = 0.5;
    ierr = PetscOptionsReal("-epsilon", "Inverse of seismic ratio", "", user.epsilon, &user.epsilon, NULL);CHKERRQ(ierr);
    ierr = PetscOptionsReal("-gamma", "Wave frequency for interblock coupling", "", user.gamma, &user.gamma, NULL);CHKERRQ(ierr);
    ierr = PetscOptionsReal("-gamma_tilde", "Wave frequency for plate coupling", "", user.gammaTilde, &user.gammaTilde, NULL);CHKERRQ(ierr);
    ierr = PetscOptionsReal("-xi", "Interblock spring constant", "", user.xi, &user.xi, NULL);CHKERRQ(ierr);
    ierr = PetscOptionsReal("-c", "Wavespeed", "", user.c, &user.c, NULL);CHKERRQ(ierr);
  }
  ierr = PetscOptionsEnd();CHKERRQ(ierr);

  ierr = TSCreate(PETSC_COMM_WORLD, &ts);CHKERRQ(ierr);
  ierr = TSSetDM(ts, dm);CHKERRQ(ierr);
  ierr = TSSetRHSFunction(ts, NULL, FormRHSFunction, &user);CHKERRQ(ierr);
  ierr = TSSetIFunction(ts, NULL, FormIFunction, &user);CHKERRQ(ierr);
  ierr = DMSetMatType(dm, MATAIJ);CHKERRQ(ierr);
  ierr = DMCreateMatrix(dm, &J);CHKERRQ(ierr);
  ierr = TSSetIJacobian(ts, J, J, FormIJacobian, &user);CHKERRQ(ierr);

  ftime    = 800.0;
  maxsteps = 10000;
  ierr = TSSetDuration(ts, maxsteps, ftime);CHKERRQ(ierr);
  ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);CHKERRQ(ierr);
  ierr = FormInitialSolution(ts, X, &user);CHKERRQ(ierr);
  ierr = TSSetSolution(ts, X);CHKERRQ(ierr);
  ierr = VecGetSize(X, &mx);CHKERRQ(ierr);
  hx   = 20.0/(PetscReal)(mx-1);
  dt   = 0.4 * PetscSqr(hx) / PetscSqr(user.c); /* Diffusive stability limit */
  ierr = TSSetInitialTimeStep(ts, 0.0, dt);CHKERRQ(ierr);
  ierr = TSSetFromOptions(ts);CHKERRQ(ierr);

  ierr = TSSolve(ts, X);CHKERRQ(ierr);
  ierr = TSGetSolveTime(ts, &ftime);CHKERRQ(ierr);
  ierr = TSGetTimeStepNumber(ts, &steps);CHKERRQ(ierr);
  ierr = TSGetConvergedReason(ts, &reason);CHKERRQ(ierr);
  ierr = PetscPrintf(PETSC_COMM_WORLD, "%s at time %g after %D steps\n", TSConvergedReasons[reason], (double)ftime, steps);CHKERRQ(ierr);

  ierr = MatDestroy(&J);CHKERRQ(ierr);
  ierr = VecDestroy(&X);CHKERRQ(ierr);
  ierr = TSDestroy(&ts);CHKERRQ(ierr);
  ierr = DMDestroy(&dm);CHKERRQ(ierr);
  ierr = PetscFinalize();
  return ierr;
}
Пример #8
0
Файл: tsf.c Проект: Kun-Qu/petsc
void PETSC_STDCALL  tsgetconvergedreason_(TS ts,TSConvergedReason *reason, int *__ierr ){
*__ierr = TSGetConvergedReason(
	(TS)PetscToPointer((ts) ),reason);
}
Пример #9
0
/* ------------------------------------------------------- */
int main(int argc,char ** argv)
{
  PetscErrorCode    ierr;
  Wash              wash;
  Junction          junctions,junction;
  Pipe              pipe,pipes;
  PetscInt          numEdges,numVertices,KeyPipe,KeyJunction;
  int               *edgelist = NULL;
  PetscInt          i,e,v,eStart,eEnd,vStart,vEnd,pipeOffset,key,frombType,tobType;
  PetscInt          vfrom,vto,vkey,fromOffset,toOffset,type,varoffset,pipeoffset;
  PetscInt          from_nedge_in,from_nedge_out,to_nedge_in;
  const PetscInt    *cone; 
  DM                networkdm;
  PetscMPIInt       size,rank;
  PetscReal         ftime = 2500.0;
  Vec               X;
  TS                ts;
  PetscInt          maxsteps=-1,steps;
  TSConvergedReason reason;
  PetscBool         viewpipes;
  PetscInt          pipesCase;
  DMNetworkMonitor  monitor;
  DMNetworkComponentGenericDataType *nwarr;

  ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr;
  ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
  ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);

  /* Create and setup network */
  /*--------------------------*/
  ierr = DMNetworkCreate(PETSC_COMM_WORLD,&networkdm);CHKERRQ(ierr);
  if (size == 1) {
    ierr = DMNetworkMonitorCreate(networkdm,&monitor);CHKERRQ(ierr); 
  }
  /* Register the components in the network */
  ierr = DMNetworkRegisterComponent(networkdm,"junctionstruct",sizeof(struct _p_Junction),&KeyJunction);CHKERRQ(ierr);
  ierr = DMNetworkRegisterComponent(networkdm,"pipestruct",sizeof(struct _p_Pipe),&KeyPipe);CHKERRQ(ierr);

  /* Set global number of pipes, edges, and vertices */
  pipesCase = 2;
  ierr = PetscOptionsGetInt(NULL,NULL, "-case", &pipesCase, NULL);CHKERRQ(ierr);

  ierr = WashNetworkCreate(PETSC_COMM_WORLD,pipesCase,&wash,&edgelist);CHKERRQ(ierr);
  numEdges    = wash->nedge;
  numVertices = wash->nvertex;
  junctions    = wash->junction;
  pipes       = wash->pipe;

  /* Set number of vertices and edges */
  ierr = DMNetworkSetSizes(networkdm,numVertices,numEdges,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
  /* Add edge connectivity */
  ierr = DMNetworkSetEdgeList(networkdm,edgelist);CHKERRQ(ierr); 
  /* Set up the network layout */
  ierr = DMNetworkLayoutSetUp(networkdm);CHKERRQ(ierr);

  /* Add EDGEDATA component to all edges -- currently networkdm is a sequential network */
  ierr = DMNetworkGetEdgeRange(networkdm,&eStart,&eEnd);CHKERRQ(ierr);
  ierr = DMNetworkGetVertexRange(networkdm,&vStart,&vEnd);CHKERRQ(ierr);
  
  for (e = eStart; e < eEnd; e++) {
    /* Add Pipe component to all edges -- create pipe here */
    ierr = DMNetworkAddComponent(networkdm,e,KeyPipe,&pipes[e-eStart]);CHKERRQ(ierr);
    
    /* Add number of variables to each edge */
    ierr = DMNetworkAddNumVariables(networkdm,e,2*pipes[e-eStart].nnodes);CHKERRQ(ierr);

    if (size == 1) { /* Add monitor -- show Q_{pipes[e-eStart].id}? */
      ierr = DMNetworkMonitorAdd(monitor, "Pipe Q", e, pipes[e-eStart].nnodes, 0, 2, -0.8, 0.8, PETSC_TRUE);CHKERRQ(ierr);
      ierr = DMNetworkMonitorAdd(monitor, "Pipe H", e, pipes[e-eStart].nnodes, 1, 2, -400.0, 800.0, PETSC_TRUE);CHKERRQ(ierr);
    }
  }

  /* Add Junction component to all vertices */
  for (v = vStart; v < vEnd; v++) {
    ierr = DMNetworkAddComponent(networkdm,v,KeyJunction,&junctions[v-vStart]);CHKERRQ(ierr);

    /* Add number of variables to vertex */
    ierr = DMNetworkAddNumVariables(networkdm,v,2);CHKERRQ(ierr);
  }

  /* Set up DM for use */
  ierr = DMSetUp(networkdm);CHKERRQ(ierr);
  ierr = WashNetworkCleanUp(wash,edgelist);CHKERRQ(ierr);

  /* Network partitioning and distribution of data */
  if (size > 1) { 
    DM distnetworkdm;
    ierr = DMNetworkDistribute(networkdm,0,&distnetworkdm);CHKERRQ(ierr);
    ierr = DMDestroy(&networkdm);CHKERRQ(ierr);
    networkdm = distnetworkdm;
  }
  
  /* PipeSetUp -- each process only sets its own pipes */
  /*---------------------------------------------------*/
  ierr = DMNetworkGetComponentDataArray(networkdm,&nwarr);CHKERRQ(ierr); 

  ierr = DMNetworkGetEdgeRange(networkdm,&eStart,&eEnd);CHKERRQ(ierr);
  for (e=eStart; e<eEnd; e++) { /* each edge has only one component, pipe */
    ierr = DMNetworkGetComponentTypeOffset(networkdm,e,0,&type,&pipeoffset);CHKERRQ(ierr);
    ierr = DMNetworkGetVariableOffset(networkdm,e,&varoffset);CHKERRQ(ierr);
    pipe = (Pipe)(nwarr + pipeoffset);

    /* Setup conntected vertices */
    ierr = DMNetworkGetConnectedNodes(networkdm,e,&cone);CHKERRQ(ierr); 
    vfrom = cone[0]; /* local ordering */
    vto   = cone[1];

    /* vfrom */
    ierr = DMNetworkGetComponentTypeOffset(networkdm,vfrom,0,&vkey,&fromOffset);CHKERRQ(ierr); 
    junction = (Junction)(nwarr+fromOffset);
    from_nedge_in  = junction->nedges_in;
    from_nedge_out = junction->nedges_out;
       
    /* vto */
    ierr = DMNetworkGetComponentTypeOffset(networkdm,vto,0,&vkey,&toOffset);CHKERRQ(ierr);  
    junction    = (Junction)(nwarr+toOffset);
    to_nedge_in = junction->nedges_in;
        
    pipe->comm = PETSC_COMM_SELF; /* must be set here, otherwise crashes in my mac??? */
    wash->nnodes_loc += pipe->nnodes; /* local total num of nodes, will be used by PipesView() */
    ierr = PipeSetParameters(pipe,
                             600.0,          /* length */
                             pipe->nnodes,   /* nnodes -- rm from PipeSetParameters */
                             0.5,            /* diameter */
                             1200.0,         /* a */
                             0.018);CHKERRQ(ierr);    /* friction */

    /* set boundary conditions for this pipe */
    if (from_nedge_in <= 1 && from_nedge_out > 0) {
      frombType = 0;
    } else {
      frombType = 1;
    }

    if (to_nedge_in == 1) {
      tobType = 0;
    } else {
      tobType = 1;
    }

    if (frombType == 0) {
      pipe->boundary.Q0 = PIPE_CHARACTERISTIC; /* will be obtained from characteristic */
      pipe->boundary.H0 = wash->H0;
    } else {
      pipe->boundary.Q0 = wash->Q0;
      pipe->boundary.H0 = PIPE_CHARACTERISTIC; /* will be obtained from characteristic */
    }
    if (tobType == 0) {
      pipe->boundary.QL = wash->QL;
      pipe->boundary.HL = PIPE_CHARACTERISTIC; /* will be obtained from characteristic */
    } else {
      pipe->boundary.QL = PIPE_CHARACTERISTIC; /* will be obtained from characteristic */
      pipe->boundary.HL = wash->HL; 
    }
      
    ierr = PipeSetUp(pipe);CHKERRQ(ierr);  
  }
  
  /* create vectors */
  ierr = DMCreateGlobalVector(networkdm,&X);CHKERRQ(ierr);
  ierr = DMCreateLocalVector(networkdm,&wash->localX);CHKERRQ(ierr); 
  ierr = DMCreateLocalVector(networkdm,&wash->localXdot);CHKERRQ(ierr); 

  /* Setup solver                                           */
  /*--------------------------------------------------------*/
  ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr);

  ierr = TSSetDM(ts,(DM)networkdm);CHKERRQ(ierr);
  ierr = TSSetIFunction(ts,NULL,WASHIFunction,wash);CHKERRQ(ierr);
  
  ierr = TSSetDuration(ts,maxsteps,ftime);CHKERRQ(ierr);
  ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);CHKERRQ(ierr);
  ierr = TSSetInitialTimeStep(ts,0.0,0.1);CHKERRQ(ierr);
  ierr = TSSetType(ts,TSBEULER);CHKERRQ(ierr);
  if (size == 1) {
    ierr = TSMonitorSet(ts, TSDMNetworkMonitor, monitor, NULL);CHKERRQ(ierr);
  }
  ierr = TSSetFromOptions(ts);CHKERRQ(ierr);

  ierr = WASHSetInitialSolution(networkdm,X,wash);CHKERRQ(ierr);

  ierr = TSSolve(ts,X);CHKERRQ(ierr);

  ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr);
  ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr);
  ierr = TSGetConvergedReason(ts,&reason);CHKERRQ(ierr);
  ierr = PetscPrintf(PETSC_COMM_WORLD,"%s at time %g after %D steps\n",TSConvergedReasons[reason],(double)ftime,steps);CHKERRQ(ierr);
  /* ierr = VecView(X,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); */
  
  /* View solution q and h */
  /* --------------------- */
  viewpipes = PETSC_FALSE;
  ierr = PetscOptionsGetBool(NULL,NULL, "-pipe_view", &viewpipes,NULL);CHKERRQ(ierr);
  if (viewpipes) {
    ierr = PipesView(X,networkdm,wash);CHKERRQ(ierr);
  }

  /* Free spaces */
  /* ----------- */
  ierr = TSDestroy(&ts);CHKERRQ(ierr);
  ierr = VecDestroy(&X);CHKERRQ(ierr);
  ierr = VecDestroy(&wash->localX);CHKERRQ(ierr);
  ierr = VecDestroy(&wash->localXdot);CHKERRQ(ierr);
  
  /* Destroy objects from each pipe that are created in PipeSetUp() */
  ierr = DMNetworkGetEdgeRange(networkdm,&eStart, &eEnd);CHKERRQ(ierr);
  for (i = eStart; i < eEnd; i++) {
    ierr = DMNetworkGetComponentTypeOffset(networkdm,i,0,&key,&pipeOffset);CHKERRQ(ierr); 
    pipe = (Pipe)(nwarr+pipeOffset);
    ierr = DMDestroy(&(pipe->da));CHKERRQ(ierr); 
    ierr = VecDestroy(&pipe->x);CHKERRQ(ierr);
  }
  if (size == 1) {
    ierr = DMNetworkMonitorDestroy(&monitor);CHKERRQ(ierr);
  }
  ierr = DMDestroy(&networkdm);CHKERRQ(ierr);
  ierr = PetscFree(wash);CHKERRQ(ierr);
  ierr = PetscFinalize();
  return ierr;
}