Yes. it is C++.
I attached the major routines for TSSolve.

Thanks
Xinya


-----Original Message-----
From: Barry Smith [mailto:[email protected]] 
Sent: Monday, June 29, 2015 11:27 AM
To: Li, Xinya
Cc: [email protected]
Subject: Re: [petsc-users] TSSolve problems


  Is your code C++?

                             count        time               percent time
---------------------------------------------------------------------
TSStep                     600    3.1174e+02    100
TSFunctionEval      2937    1.4288e+02     46
TSJacobianEval      1737    1.3074e+02    42
KSPSolve                1737    3.5144e+01    11

  Ok I pulled out the important time from the table.  46 percent of the time is 
in your function evaluation, 42 percent in the Jacobian evaluation and 11 
percent in the linear solve.

  The only way to improve the time significantly is by speeding up the function 
and Jacobian computations. What is happening in those routines, can you email 
them?

  Barry





> On Jun 29, 2015, at 11:57 AM, Li, Xinya <[email protected]> wrote:
> 
> Barry,
> 
> Here is the new output without debugging.
> 
> Thank you.
> 
> Xinya
> 
> ********************************************************************
> 
> 
> -----Original Message-----
> From: Barry Smith [mailto:[email protected]] 
> Sent: Friday, June 26, 2015 12:04 PM
> To: Li, Xinya
> Cc: [email protected]
> Subject: Re: [petsc-users] TSSolve problems
> 
> 
> ##########################################################
>      #                                                        #
>      #                          WARNING!!!                    #
>      #                                                        #
>      #   This code was compiled with a debugging option,      #
>      #   To get timing results run ./configure                #
>      #   using --with-debugging=no, the performance will      #
>      #   be generally two or three times faster.              #
>      #                                                        #
>      ##########################################################
> 
> First you need to configure PETSc again without all the debugging. So do, for 
> example,
> 
> export PETSC=arch-opt
> ./configure --with-cc=gcc --with-fc=gfortran --with-cxx=g++ 
> --with-scalar-type=complex --with-clanguage=C++ --with-cxx-dialect=C++11  
> --download-mpich --download-superlu_dist --download-mumps 
> --download-scalapack --download-parmetis --download-metis 
> --download-elemental make all test
> 
> then recompile and rerun your example again with -log_summary and send the 
> output.
> 
> Note that you should not pass --download-fblaslapack nor the fortran kernel 
> stuff.
> 
>  Barry
> 
> 
>> On Jun 26, 2015, at 12:16 PM, Li, Xinya <[email protected]> wrote:
>> 
>> Barry,
>> 
>> Thank you for your response.
>> 
>> Attached is the output. SNESSolve was taking most of the time. 
>> 
>> 
>> Xinya
>> 
>> 
>> 
>> -----Original Message-----
>> From: Barry Smith [mailto:[email protected]]
>> Sent: Thursday, June 25, 2015 5:47 PM
>> To: Li, Xinya
>> Cc: [email protected]
>> Subject: Re: [petsc-users] TSSolve problems
>> 
>> 
>> Run with -ts_view -log_summary and send the output. This will tell the 
>> current solvers and where the time is being spent.
>> 
>> Barry
>> 
>>> On Jun 25, 2015, at 6:37 PM, Li, Xinya <[email protected]> wrote:
>>> 
>>> Dear Sir,
>>> 
>>> I am using the ts solver to solve a set of ODE and DAE. The Jacobian matrix 
>>> is a 1152 *1152 sparse complex matrix.
>>> Each TSStep in TSSolve is taking nearly 1 second. Thus, I need  to improve 
>>> the speed of TSSolve.
>>> Which parts should be taking into account to accelerate TSSolve?
>>> Thank you very much.
>>> Regards
>>> __________________________________________________
>>> Xinya Li
>>> Scientist
>>> EED/Hydrology
>>> Pacific Northwest National Laboratory
>>> 902 Battelle Boulevard
>>> P.O. Box 999, MSIN K9-33
>>> Richland, WA  99352 USA
>>> Tel:  509-372-6248
>>> Fax: 509-372-6089
>>> [email protected]
>> 
>> <288g1081b_short.log>
> 
> <d288gen.log>

#include <iostream>
#include <fstream>
#include <string>

#include <petsc.h>
#include "simulation.h"
#include "vars.h"

int iteration=0;

// Collect all the values from the parallel Ybus into a sequential vector 
ybus[ngen*ngen] on each processor
static PetscErrorCode scatterYbus(Mat fy, PetscScalar *ybus, PetscInt ngen)
{
  PetscErrorCode ierr;
  PetscInt i, j;
  PetscInt rA, cA;
  ierr = MatGetSize(fy, &rA, &cA); CHKERRQ(ierr);
  Vec ACol[cA];
  PetscScalar *AColVal[cA];

  for (i = 0; i < cA; i++) {
    ierr = VecCreateMPI(PETSC_COMM_WORLD, PETSC_DECIDE, rA, &ACol[i]); 
CHKERRQ(ierr);
    ierr = MatGetColumnVector(fy, ACol[i], i); CHKERRQ(ierr);
    VecScatter ctx;
    Vec localACol;
    ierr = VecScatterCreateToAll(ACol[i], &ctx, &localACol); CHKERRQ(ierr);
    ierr = VecScatterBegin(ctx, ACol[i], localACol, INSERT_VALUES, 
SCATTER_FORWARD); CHKERRQ(ierr);
    ierr = VecScatterEnd(ctx, ACol[i], localACol, INSERT_VALUES, 
SCATTER_FORWARD); CHKERRQ(ierr);
    ierr = VecGetArray(localACol, &AColVal[i]); CHKERRQ(ierr);
    ierr = VecScatterDestroy(&ctx); CHKERRQ(ierr);
    ierr = VecRestoreArray(localACol, NULL); CHKERRQ(ierr);
  }
  for (i = 0; i < rA; i++) {
    for (j = 0; j < cA; j++) {
      ybus[i*ngen+j] = AColVal[i][j];
      //printf("%lf+%lfi\n", PetscRealPart( AColVal[i][j]), PetscImaginaryPart( 
AColVal[i][j]));
    }
  }
  //printf("\n");

  PetscFunctionReturn(0);
}

PetscErrorCode Simulation::IFunction(TS ts,PetscReal t,Vec X,Vec Xdot,Vec 
F,Userctx *ctx)
{
  PetscLogStagePush(ctx->fstage);
  PetscErrorCode ierr;
  PetscScalar *x, *xdot, *f;
  PetscInt i, j, k;
  PetscInt ngen = ctx->ngen;
  PetscScalar *ybus = ctx->ybus;
  PetscScalar *eqprime= ctx->eqprime;
  PetscScalar *pmech = ctx->pmech;
  PetscScalar *gen_d0 = ctx->gen_d0;
  PetscScalar *gen_h = ctx->gen_h;
  VecScatter vs = ctx->vs;

  //for (i = 0; i < ngen*ngen; i++)
    //printf("%lf+%lfi\n", PetscRealPart(ybus[i]), PetscImaginaryPart(ybus[i]));

  DM da;
  PetscInt xstart, xlen;

  int me;

  double t0, t1;

  PetscFunctionBeginUser;

  MPI_Comm_rank(PETSC_COMM_WORLD, &me);

  //printf("IFunction, me = %d:\n", me);

  ierr = TSGetDM(ts, &da); CHKERRQ(ierr);

  // Get pointers to vector data
  //ierr = DMDAVecGetArray(da, X, &x); CHKERRQ(ierr);
  //ierr = DMDAVecGetArray(da, Xdot, &xdot); CHKERRQ(ierr);
  t0 = MPI_Wtime();

  ierr = VecScatterBegin(ctx->vs, X, ctx->x, INSERT_VALUES, SCATTER_FORWARD); 
CHKERRQ(ierr);
  ierr = VecScatterEnd(ctx->vs, X, ctx->x, INSERT_VALUES, SCATTER_FORWARD); 
CHKERRQ(ierr);
  ierr = VecGetArray(ctx->x, &x); CHKERRQ(ierr);

  ierr = VecScatterBegin(ctx->vs, Xdot, ctx->xdot, INSERT_VALUES, 
SCATTER_FORWARD); CHKERRQ(ierr);
  ierr = VecScatterEnd(ctx->vs, Xdot, ctx->xdot, INSERT_VALUES, 
SCATTER_FORWARD); CHKERRQ(ierr);
  ierr = VecGetArray(ctx->xdot, &xdot); CHKERRQ(ierr);
  //t1 = MPI_Wtime();
  //if (me == 0) std::cout << "Scattering IFunction time: " << t1 - t0 << 
std::endl;

  ierr = DMDAVecGetArray(da, F, &f); CHKERRQ(ierr);
  //VecView(X, PETSC_VIEWER_STDOUT_WORLD);
  //VecView(Xdot, PETSC_VIEWER_STDOUT_WORLD);

  // Get local grid boundaries
  ierr = DMDAGetCorners(da, &xstart, NULL, NULL, &xlen, NULL, NULL); 
CHKERRQ(ierr);
  //printf("Function Called   ");
  //printf("IFunction:me, xstart, xstart+xlen=%d: [%d, %d]\n", me, xstart, 
xstart+xlen);

  //t0 = MPI_Wtime();

  // Set up DAE equations
  // Compute function over the locally owned part of the grid
  for (i = 0; i < ngen; i++) {
    if (2*i >= xstart && 2*i < xstart+xlen) {
      f[2*i] = xdot[2*i] - basrad * x[2*i+1];
      //std::cout << "IFunction:me,f[2*i]:" << me << ":[" << xstart << "," << 
xstart+xlen << "] " <<  "f[" << 2*i << "]=" << f[2*i] << std::endl;
    }
    if (2*i+1 >= xstart && 2*i+1 < xstart+xlen) {
      f[2*i+1] = xdot[2*i+1] - 0.5/gen_h[i]*(
                 pmech[i]-eqprime[i]*x[2*ngen+2*i+1]-gen_d0[i]*x[2*i+1]);
      //std::cout << "IFunction:me,f[2*i+1]:" << me << ":[" << xstart << "," << 
xstart+xlen << "] " <<  "f[" << 2*i+1 << "]=" << f[2*i+1] << std::endl;
      //std::cout <<"IFunction:x[2*ngen+2*i+1]:"<<x[2*ngen+2*i+1] << std::endl;
    }
  }
  for (i = 0; i < ngen; i++) {
    if (2*ngen+2*i >= xstart && 2*ngen+2*i < xstart+xlen) {
      f[2*ngen+2*i] = sin(x[2*i])*x[2*ngen+2*i] + cos(x[2*i])*x[2*ngen+2*i+1];
      for (k = 0; k < ngen; k++) {
        f[2*ngen+2*i] += 
-((cos(x[2*k])*eqprime[k])*PetscRealPart(ybus[k*ngen+i])
                         
-(sin(x[2*k])*eqprime[k])*PetscImaginaryPart(ybus[k*ngen+i]));
      }
    }
    if (2*ngen+2*i+1 >= xstart && 2*ngen+2*i+1 < xstart+xlen) {
      f[2*ngen+2*i+1] = -cos(x[2*i])*x[2*ngen+2*i] + 
sin(x[2*i])*x[2*ngen+2*i+1];
      for (k = 0; k < ngen; k++) {
        f[2*ngen+2*i+1] += 
-((cos(x[2*k])*eqprime[k])*PetscImaginaryPart(ybus[k*ngen+i])
                           
+(sin(x[2*k])*eqprime[k])*PetscRealPart(ybus[k*ngen+i]));
      }
    }
  }
  //VecView(F, PETSC_VIEWER_STDOUT_WORLD);

  //t1 = MPI_Wtime();
  //if (me == 0) std::cout << "Scattering IFunction time: " << t1 - t0 << 
std::endl;

  //for (i=0;i<4*ngen;i++) printf("me, xstart, xstart+xlen, 
PetscRealPart(f[i]), PetscImaginaryPart(f[i]):%d:[%d,%d] %lf+%lfi\n", me, 
xstart, xstart+xlen, PetscRealPart(f[i]), PetscImaginaryPart(f[i]));
  //for (i=0;i<4*ngen;i++) printf("me, xstart, xstart+xlen, 
PetscRealPart(pmech[i]), PetscImaginaryPart(pmech[i]):%d:[%d,%d] %lf+%lfi\n", 
me, xstart, xstart+xlen, PetscRealPart(pmech[i]), PetscImaginaryPart(pmech[i]));
  //printf("\n");

  ierr = VecRestoreArray(ctx->x, &x); CHKERRQ(ierr);
  ierr = VecRestoreArray(ctx->xdot, &xdot); CHKERRQ(ierr);
  ierr = DMDAVecRestoreArray(da, F, &f); CHKERRQ(ierr);

  PetscLogStagePop();
  PetscFunctionReturn(0);
}

//PetscErrorCode Simulation::IJacobian(TS ts, PetscReal t, Vec X, Vec Xdot, 
PetscReal a, Mat *A, Mat *B, MatStructure *flag, Userctx *ctx)
PetscErrorCode Simulation::IJacobian(TS ts, PetscReal t, Vec X, Vec Xdot, 
PetscReal a, Mat A, Mat B, Userctx *ctx) // version 3.5 change: all "*A" change 
to "A"
{
  PetscLogStage stage = ctx->jstage1;
  PetscLogStagePush(stage);

  VecScatter vs = ctx->vs;

  PetscErrorCode ierr;
  PetscInt ngen = ctx->ngen;
  PetscScalar *x;

  PetscInt i, j, icol;
  PetscScalar *ybus = ctx->ybus;
  PetscScalar *eqprime= ctx->eqprime;
  PetscScalar *pmech = ctx->pmech;
  PetscScalar *gen_d0 = ctx->gen_d0;
  PetscScalar *gen_h = ctx->gen_h;

  //for (i = 0; i < ngen*ngen; i++)
    //printf("%lf+%lfi\n", PetscRealPart(ybus[i]), PetscImaginaryPart(ybus[i]));

  // DM da;
  PetscInt xstart, xend , m, n;

  int me;
  double t0, t1, t2, t3, t4, t5, t6, t7;

  PetscFunctionBeginUser;

  //printf("   IJacobian:\n");

  // ierr = TSGetDM(ts, &da); CHKERRQ(ierr);

  // Get pointers to vector data
  //ierr = DMDAVecGetArray(da, X, &x); CHKERRQ(ierr);
  MPI_Comm_rank(PETSC_COMM_WORLD, &me);
  //t0 = MPI_Wtime();

  ierr = VecScatterBegin(ctx->vs, X, ctx->x, INSERT_VALUES, SCATTER_FORWARD); 
CHKERRQ(ierr);
  ierr = VecScatterEnd(ctx->vs, X, ctx->x, INSERT_VALUES, SCATTER_FORWARD); 
CHKERRQ(ierr);
  ierr = VecGetArray(ctx->x, &x); CHKERRQ(ierr);
  //t1 = MPI_Wtime();
  //if (me == 0) std::cout << "Scattering IJacobian time: " << t1 - t0 << 
std::endl;

  // Get local grid boundaries
  // ierr = DMDAGetCorners(da, &xstart, NULL, NULL, &xlen, NULL, NULL); 
CHKERRQ(ierr);


  ierr = MatGetOwnershipRange(A, &xstart, &xend); CHKERRQ(ierr);

  
////////////////////////////////////////////////////////////////////////////////////////
  if (iteration > 0) {
    ierr = MatRetrieveValues(A); CHKERRQ(ierr);
  }

  PetscScalar xVal, ybusVal;
  PetscScalar val[1];
  PetscInt ii;
  //printf("Jacobian Called  \n");
  t0 = MPI_Wtime();
  // Compute function over the locally owned part of the grid
  for (i = xstart; i < xend; i++) {
    //printf("IJacobian:i:%d\n", i);
    //if (xstart+xlen <= 2*ngen) { // the first two 2*ngen rows of Jacobain 
matrix
    if (i < 2*ngen) { // the first two 2*ngen rows of Jacobain matrix
    // only calculate the frist two 2*ngen in the first IJacobian iteration;
    // otherwise, just reuse the stored data calculated from the first iteration
      if (iteration == 0) {
        if (i % 2 == 0) { // row 0,2,4,...,2*ngen-2
          icol = i;
          val[0] = a;
          ierr = MatSetValues(A, 1, &i, 1, &icol, val, INSERT_VALUES); 
CHKERRQ(ierr);
          icol = i+1;
          val[0] = -basrad;
          ierr = MatSetValues(A, 1, &i, 1, &icol, val, INSERT_VALUES); 
CHKERRQ(ierr);
        } else { // row 1,3,5,...,2*ngen-1
          ii = (i-1)/2;
          icol = i;
          val[0] = a + gen_d0[ii]/(2.0*gen_h[ii]);
          ierr = MatSetValues(A, 1, &i, 1, &icol, val, INSERT_VALUES); 
CHKERRQ(ierr);
          icol = 2*ngen + i;
          val[0] = eqprime[ii]/(2.0*gen_h[ii]);
          ierr = MatSetValues(A, 1, &i, 1, &icol, val, INSERT_VALUES); 
CHKERRQ(ierr);
        }
      }
      t2 =  MPI_Wtime();
    } else { // the last two 2*ngen rows of Jacobian matrix
      if (i % 2 == 0) { // row 2*ngen,2*ngen+2,...,4*ngen-2
        ii = (i-2*ngen)/2; // ii=0,1,2...
        xVal = x[2*ii];
        for (j = 0; j < ngen; j++) {
          icol = j*2;
          ybusVal = ybus[j*ngen+ii];
          if (i == j*2+ngen*2) { // diaganol Jgx(ii)
            val[0] = x[i] * cos(xVal)
                   - x[i+1] * sin(xVal)
                   + PetscRealPart(ybusVal)*eqprime[ii]*sin(xVal)
                   + PetscImaginaryPart(ybusVal)*eqprime[ii]*cos(xVal);
          } else { // off-diaganol Jgx(ik)
            val[0] = PetscRealPart(ybusVal)*eqprime[j]*sin(x[2*j])
                   + PetscImaginaryPart(ybusVal)*eqprime[j]*cos(x[2*j]);
          }
          ierr = MatSetValues(A, 1, &i, 1, &icol, val, INSERT_VALUES); 
CHKERRQ(ierr);
        }
        icol = i;
        val[0] = sin(xVal);
        ierr = MatSetValues(A, 1, &i, 1, &icol, val, INSERT_VALUES); 
CHKERRQ(ierr);
        icol = i+1;
        val[0] = cos(xVal);
        ierr = MatSetValues(A, 1, &i, 1, &icol, val, INSERT_VALUES); 
CHKERRQ(ierr);

      } else { // row 2*ngen+1,2*ngen+3,...,4*ngen-1
        ii = (i-2*ngen-1)/2; // ii=0,1,2...
        xVal = x[2*ii];
        for (j = 0; j < ngen; j++) {
          icol = j*2;
          ybusVal = ybus[j*ngen+ii];
          if ((i-1) == j*2+ngen*2) { // diaganol Jgx(ii)
            val[0] = x[i-1] * sin(xVal)
                   + x[i] * cos(xVal)
                   + PetscImaginaryPart(ybusVal)*eqprime[ii]*sin(xVal)
                  - PetscRealPart(ybusVal)*eqprime[ii]*cos(xVal);
          } else {// off-diaganol Jgx(ik)
            val[0] = PetscImaginaryPart(ybusVal)*eqprime[j]*sin(x[2*j])
                   - PetscRealPart(ybusVal)*eqprime[j]*cos(x[2*j]);
          }
          ierr = MatSetValues(A, 1, &i, 1, &icol, val, INSERT_VALUES); 
CHKERRQ(ierr);
        }
        icol = i-1;
        val[0] = -cos(xVal);
        ierr = MatSetValues(A, 1, &i, 1, &icol, val, INSERT_VALUES); 
CHKERRQ(ierr);
        icol = i;
        val[0] = sin(xVal);
        ierr = MatSetValues(A, 1, &i, 1, &icol, val, INSERT_VALUES); 
CHKERRQ(ierr);
      }
    }
    t3 = MPI_Wtime();
  }

  t1 = MPI_Wtime();
 // if (me == 0) std::cout << "Scattering IJacobian time: " << t1 - t0 <<"," << 
t2 - t0<<"," << t3 - t2<<std::endl;


  /*ierr = MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
  ierr = MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
  MatView(A, PETSC_VIEWER_STDOUT_WORLD);
  exit(1);*/

  ierr = VecRestoreArray(ctx->x, &x); CHKERRQ(ierr);

  PetscLogStagePush(ctx->jstage2);

  ierr = MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
  ierr = MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
  //MatView(A, PETSC_VIEWER_STDOUT_WORLD);
  // *flag = SAME_NONZERO_PATTERN; // version 3.5 change

  PetscLogStagePop();

  if (iteration == 0) {
    ierr = MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); CHKERRQ(ierr);
    ierr = MatStoreValues(A); CHKERRQ(ierr);
  }

  iteration ++;
  //t1 = MPI_Wtime();
  //if (me == 0) std::cout << "Scattering IJacobian time: " << t1 - t0 << 
std::endl;

  PetscLogStagePop();
  PetscFunctionReturn(0);
}

PetscErrorCode Simulation::formInitialSolution(TS ts, Vec U, Userctx *ctx, 
PetscInt *t_step, PetscReal *t_width)
{
  PetscInt i;
  PetscScalar *psw1, *psw7;
  PetscScalar *pbus_a, *pbus_v, *pbus_pg, *pbus_qg;
  PetscScalar *pgen_mva, *pgen_d0, *pgen_h, *pgen_dtr;
  PetscScalar *theta = new PetscScalar[nbus];
  PetscErrorCode ierr;
  PetscInt flagF;
  PetscReal H_sum;
  PetscInt tst1;
  PetscScalar curr, phi, v, eprime;

  PetscScalar eterm, pelect, qelect, curq;
  PetscScalar mac_ang, mac_spd, dmac_ang, dmac_spd;
  PetscScalar cur_re, cur_im, psi_re, psi_im;
  PetscInt simu_k;

  DM da;
  PetscInt xstart, xlen, Mx;
  PetscScalar *u;
  PetscReal hx, x, r;

  PetscScalar *eqprime= ctx->eqprime;
  PetscScalar *pmech = ctx->pmech;

  PetscFunctionBeginUser;

  ierr = TSGetDM(ts, &da); CHKERRQ(ierr);

  // Get pointers to vector data
  ierr = DMDAVecGetArray(da, U, &u); CHKERRQ(ierr);

  // Get local grid boundaries
  ierr = DMDAGetCorners(da, &xstart, NULL, NULL, &xlen, NULL, NULL); 
CHKERRQ(ierr);

  simu_k = 0;

  ierr = VecGetArray(sw1, &psw1); CHKERRQ(ierr);
  ierr = VecGetArray(sw7, &psw7); CHKERRQ(ierr);

  ierr = VecGetArray(bus_a, &pbus_a); CHKERRQ(ierr);
  ierr = VecGetArray(bus_v, &pbus_v); CHKERRQ(ierr);
  ierr = VecGetArray(bus_pg, &pbus_pg); CHKERRQ(ierr);
  ierr = VecGetArray(bus_qg, &pbus_qg); CHKERRQ(ierr);

  ierr = VecGetArray(gen_mva, &pgen_mva); CHKERRQ(ierr);
  ierr = VecGetArray(gen_d0, &pgen_d0); CHKERRQ(ierr);
  ierr = VecGetArray(gen_h, &pgen_h); CHKERRQ(ierr);
  ierr = VecGetArray(gen_dtr, &pgen_dtr); CHKERRQ(ierr);

  for (i = 0; i < nswtch-1; i++) {
    t_step[i] = (PetscInt) PetscRealPart((psw1[i+1] - psw1[i]) / psw7[i]);
    t_width[i] = PetscRealPart((psw1[i+1] - psw1[i]) / (PetscScalar) t_step[i]);
    simu_k += t_step[i];
    //std::cout << i+1 << " " << t_step[i] << " " << t_width[i] << " " << 
simu_k << std::endl;
  }
  ierr = VecRestoreArray(sw1, &psw1); CHKERRQ(ierr);
  ierr = VecRestoreArray(sw1, &psw7); CHKERRQ(ierr);

  simu_k ++;
  //allocSimuData(); // Allocate memories for simulation related arrays

  for (i = 0; i < nbus; i++) {
    theta[i] = pbus_a[i] * M_PI / 180.0;
    //printf("theta[%d]: %f+%fi\n", i, PetscRealPart(theta[i]), 
PetscImaginaryPart(theta[i]));
  }

  // Calculate parameters
  flagF = 0;
  H_sum = 0.0;
  for (i = 0; i < ngen; i++) {
    pgen_mva[i] = basmva / pgen_mva[i];
    ctx->gen_d0[i] = pgen_d0[i] / pgen_mva[i];
    ctx->gen_h[i] = pgen_h[i] / pgen_mva[i];
    //std::cout << ctx->gen_d0[i] << ", " <<  ctx->gen_h[i] << std::endl;
    tst1 = gen_bus[i];
    eterm = pbus_v[tst1];
    pelect = pbus_pg[tst1];
    qelect = pbus_qg[tst1];
    curr = sqrt(pelect * pelect + qelect * qelect) / eterm * pgen_mva[i];
    phi = atan2(PetscRealPart(qelect), PetscRealPart(pelect));
    v = eterm * exp(PETSC_i * theta[tst1]);
    curr = curr * exp(PETSC_i * (theta[tst1] - phi));
    eprime = v + PETSC_i * pgen_dtr[i] * curr;
    mac_ang = atan2(PetscImaginaryPart(eprime), PetscRealPart(eprime));
    mac_spd = 0;
    eqprime[i] = abs(eprime);
    pmech[i] = pelect;
    //std::cout << std::endl <<  "eterm: " << eterm  << std::endl;
    //std::cout << "curr: " << curr  << std::endl;
    //std::cout << "phi: " << phi  << std::endl;
    //std::cout << "v: " << v  << std::endl;
    //std::cout << "eprime: " << eprime  << std::endl;
    //std::cout << "mac_ang: " << mac_ang  << std::endl;
    //std::cout << "mac_spd: " << mac_spd  << std::endl;
    if (i*2 >= xstart && i*2 < xstart+xlen)
      u[i*2] = mac_ang;
    //std::cout <<"formInitialSolution: i*2,u[i*2]:" << i*2 << ": " << u[i*2] 
<< std::endl;
    if (i*2+1 >= xstart && i*2+1 < xstart+xlen)
      u[i*2+1] = mac_spd;
    //std::cout << "formInitialSolution: i*2+1,u[i*2+1]:" <<i*2+1 << ": " << 
u[i*2+1] << std::endl;
    if (2*ngen+i*2 >= xstart && 2*ngen+i*2 < xstart+xlen)
      u[2*ngen+i*2] = sin(mac_ang)*PetscRealPart(curr)
                      - cos(mac_ang)*PetscImaginaryPart(curr);
    //std::cout << "formInitialSolution: 2*ngen+i*2,u[2*ngen+i*2]:" << 
2*ngen+i*2 << ": " << u[2*ngen+i*2] << std::endl;
    if (2*ngen+i*2+1 >= xstart && 2*ngen+i*2+1 < xstart+xlen)
      u[2*ngen+i*2+1] = cos(mac_ang)*PetscRealPart(curr)
                        + sin(mac_ang)*PetscImaginaryPart(curr);
    //std::cout << "formInitialSolution: 2*ngen+i*2+1,u[2*ngen+i*2+1]:"<< 
2*ngen+i*2+1 << ": " << u[2*ngen+i*2+1] << std::endl;
  }

  //for (i = 0; i < 4*ngen; i++)
  //  for (i = xstart; i < xstart+xlen; i++)
      //std::cout << "formInitialSolution: i, u[i]:"<< i << ": " << u[i] << 
std::endl;

  delete [] theta;

  ierr = VecRestoreArray(bus_a, &pbus_a); CHKERRQ(ierr);
  ierr = VecRestoreArray(bus_v, &pbus_v); CHKERRQ(ierr);
  ierr = VecRestoreArray(bus_pg, &pbus_pg); CHKERRQ(ierr);
  ierr = VecRestoreArray(bus_qg, &pbus_qg); CHKERRQ(ierr);

  ierr = VecRestoreArray(gen_mva, &pgen_mva); CHKERRQ(ierr);
  ierr = VecRestoreArray(gen_d0, &pgen_d0); CHKERRQ(ierr);
  ierr = VecRestoreArray(gen_h, &pgen_h); CHKERRQ(ierr);
  ierr = VecRestoreArray(gen_dtr, &pgen_dtr); CHKERRQ(ierr);

  // Set Userctx values: eqprime, pmech, gen_d0, gen_h

  // Restore vectors
  ierr = DMDAVecRestoreArray(da, U, &u); CHKERRQ(ierr);
  //VecView(U, PETSC_VIEWER_STDOUT_WORLD);

  PetscFunctionReturn(0);
}

PetscErrorCode Simulation::simu(Mat prefy11,Mat fy11,Mat posfy11)
{
  PetscErrorCode ierr;

  // Simulation related variables
  PetscInt i;
  PetscInt t_step[20];
  PetscReal t_width[20];

  // Petsc DAE related variables
  TS ts; // Nonlinear solver
  Vec x; // Solution, residual vectors
  Mat J; // Jacobian matrix
  PetscInt steps;
  PetscReal ftime;
  Userctx user;

  DM da;

  double t0, t1, tt0, tt1, tt2, tt3, tt4;

  PetscFunctionBegin;

  tt0 = MPI_Wtime(); //

  //---------------------------------------------------------------------
  // view prefy11, fy11, posfy11 values
  //---------------------------------------------------------------------
  //MatView(prefy11, PETSC_VIEWER_STDOUT_WORLD);
  //MatView(fy11, PETSC_VIEWER_STDOUT_WORLD);
  //MatView(posfy11, PETSC_VIEWER_STDOUT_WORLD);

  //---------------------------------------------------------------------
  // Start of Petsc DAE solver main driver
  //---------------------------------------------------------------------

  //---------------------------------------------------------------------
  // Create distributed array (DMDA) to manage parallel grid and vectors
  //---------------------------------------------------------------------
  ierr = DMDACreate1d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, 4*ngen, 1, 1, NULL, 
&da);
  CHKERRQ(ierr);

  //---------------------------------------------------------------------
  // Extract global vectors from DMDA;
  //---------------------------------------------------------------------
  ierr = DMCreateGlobalVector(da, &x); CHKERRQ(ierr);
  //VecView(x, PETSC_VIEWER_STDOUT_SELF);

  //---------------------------------------------------------------------
  // Initialize user application context
  //---------------------------------------------------------------------
  user.ngen = ngen;
  user.ybus = new PetscScalar[ngen*ngen];
  user.eqprime = new PetscScalar[ngen];
  user.pmech = new PetscScalar[ngen];
  user.gen_d0 = new PetscScalar[ngen];
  user.gen_h = new PetscScalar[ngen];

  PetscLogStageRegister("IFunction",&user.fstage);
  PetscLogStageRegister("IJacobian",&user.jstage1);
  PetscLogStageRegister("IJacobian assemble",&user.jstage2);

  ////////////////////////////////////////////////////////////////////////
  // 1. prefy11 DAE:
  ////////////////////////////////////////////////////////////////////////

  // Set Userctx values: corresponding Ybus (first with prefy11)
  // Collect all the values from the parallel Ybus into a sequential vector 
ybus[ngen*ngen] on each processor
  t0 = MPI_Wtime();
  scatterYbus(prefy11, user.ybus, ngen);
  t1 = MPI_Wtime();
  if (me == 0) std::cout << "Scattering prefy11 time: " << t1 - t0 << std::endl;

  //---------------------------------------------------------------------
  // Create timestepping solver context
  //---------------------------------------------------------------------
  //TSCreate(PETSC_COMM_WORLD,&ts);
  //TSSetProblemType(ts,TS_NONLINEAR);
  //TSSetType(ts,TSROSW);
  //TSSetType(ts,TSARKIMEX);
  t0 = MPI_Wtime();
  ierr = TSCreate(PETSC_COMM_WORLD, &ts); CHKERRQ(ierr);
  //ierr = TSSetType(ts, TSBEULER); CHKERRQ(ierr);
  ierr = TSSetType(ts, TSTHETA); CHKERRQ(ierr);
  //ierr = TSThetaSetTheta(ts, 1.0); CHKERRQ(ierr);
  ierr = TSThetaSetTheta(ts, 0.5); CHKERRQ(ierr);
  //ierr = TSSetType(ts, TSEULER); CHKERRQ(ierr);
  ierr = TSSetIFunction(ts, NULL, (TSIFunction) IFunction, &user); 
CHKERRQ(ierr);
  /*ierr = MatCreate(PETSC_COMM_WORLD, &J); CHKERRQ(ierr); // J: Jacobian matrix
  ierr = MatSetSizes(J, PETSC_DECIDE, PETSC_DECIDE, 4*ngen, 4*ngen); 
CHKERRQ(ierr);
  ierr = MatSetFromOptions(J); CHKERRQ(ierr);
  ierr = MatSetUp(J); CHKERRQ(ierr);*/

  ierr = MatCreate(PETSC_COMM_WORLD, &J); CHKERRQ(ierr); // J: Jacobian matrix
  ierr = MatSetType(J, MATMPIAIJ); CHKERRQ(ierr);
  ierr = MatSetSizes(J, PETSC_DECIDE, PETSC_DECIDE, 4*ngen, 4*ngen); 
CHKERRQ(ierr);
  ierr = MatSetFromOptions(J); CHKERRQ(ierr);


  /* PetscInt nnz[4*ngen];
  for (i = 0; i < 4*ngen; i++) {
     if (i < 2*ngen) {
        nnz[i] = 2;
     }else{
        nnz[i] = ngen+2;
     }
  }
  ierr = MatSeqAIJSetPreallocation(J,ngen+2,nnz);  CHKERRQ(ierr); */

  ierr = MatMPIAIJSetPreallocation(J,ngen+2,NULL,ngen+2,NULL);  CHKERRQ(ierr);

  //ierr = MatSetUp(J); CHKERRQ(ierr);

  //ierr = DMCreateMatrix(da, MATAIJ, &J); CHKERRQ(ierr);
  ierr = TSSetIJacobian(ts, J, J, (TSIJacobian) IJacobian, &user); 
CHKERRQ(ierr);

  // Use TSGetDM() to access. Setting here allows easy use of geometric 
multigrid.
  ierr = TSSetDM(ts, da); CHKERRQ(ierr);
  t1 = MPI_Wtime();
  if (me == 0) std::cout << "timestepping solver context time: " << t1 - t0 << 
std::endl;

  //---------------------------------------------------------------------
  // Set initial conditions
  //---------------------------------------------------------------------
  t0 = MPI_Wtime();
  ierr = formInitialSolution(ts, x, &user, t_step, t_width); CHKERRQ(ierr);
  ftime = t_step[0] * t_width[0];
  //printf("ftime = %lf\n", ftime);
  ierr = TSSetDuration(ts, PETSC_DEFAULT, ftime); CHKERRQ(ierr);
  ierr = TSSetSolution(ts, x); CHKERRQ(ierr);
  ierr = TSSetInitialTimeStep(ts, 0.0, t_width[0]); CHKERRQ(ierr);

  //---------------------------------------------------------------------
  // Use initial solution vector to set up vector scatter
  //---------------------------------------------------------------------
  ierr = VecScatterCreateToAll(x, &(user.vs), &(user.x)); CHKERRQ(ierr);
  ierr = VecDuplicate(user.x, &(user.xdot)); CHKERRQ(ierr);

  //---------------------------------------------------------------------
  // Set runtime options
  //---------------------------------------------------------------------
  ierr = TSSetFromOptions(ts);CHKERRQ(ierr);
  t1 = MPI_Wtime();
  if (me == 0) std::cout << "Set initial conditions time: " << t1 - t0 << 
std::endl;

  //---------------------------------------------------------------------
  // Solve nonlinear system
  //---------------------------------------------------------------------
  //ierr = VecView(x,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
  t0 = MPI_Wtime();
  ierr = TSSolve(ts,x);CHKERRQ(ierr);
  //  ierr = TSView(ts,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
  t1 = MPI_Wtime();
  if (me == 0) std::cout << "TSSolve time: " << t1 - t0 << std::endl;
  ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr);
  ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr);
  ierr = PetscPrintf(PETSC_COMM_WORLD,"%D steps, ftime 
%f\n",steps,ftime);CHKERRQ(ierr);
  // version 3.5 change: %G format is no longer supported, use %g and caste the 
argument to double,all change to %f
  //ierr = VecView(x,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
  t1 = MPI_Wtime();
  if (me == 0) std::cout << "Solve nonlinear system time: " << t1 - t0 << 
std::endl;


  tt2 = MPI_Wtime(); //
  if (me == 0) std::cout << "Total prefy11 time: " << tt2 - tt0 << std::endl;


  ////////////////////////////////////////////////////////////////////////
  // 2. fy11 DAE:
  ////////////////////////////////////////////////////////////////////////
  // Set Userctx values: corresponding Ybus (second with fy11)
  t0 = MPI_Wtime();
  scatterYbus(fy11, user.ybus, ngen);
  t1 = MPI_Wtime();
  if (me == 0) std::cout << "Scattering fy11 time: " << t1 - t0 << std::endl;
  ierr = TSCreate(PETSC_COMM_WORLD, &ts); CHKERRQ(ierr);
  //ierr = TSSetType(ts, TSBEULER); CHKERRQ(ierr);
  ierr = TSSetType(ts, TSTHETA); CHKERRQ(ierr);
  //ierr = TSThetaSetTheta(ts, 1.0); CHKERRQ(ierr);
  ierr = TSThetaSetTheta(ts, 0.5); CHKERRQ(ierr);
  //ierr = TSSetType(ts, TSEULER); CHKERRQ(ierr);
  ierr = TSSetIFunction(ts, NULL, (TSIFunction) IFunction, &user); 
CHKERRQ(ierr);
  ierr = TSSetIJacobian(ts, J, J, (TSIJacobian) IJacobian, &user); 
CHKERRQ(ierr);
  ierr = TSSetDM(ts, da); CHKERRQ(ierr);
  //ierr = formInitialSolution(ts, x, &user, t_step, t_width); CHKERRQ(ierr);
  ftime = t_step[1] * t_width[1];
  ierr = TSSetDuration(ts, PETSC_DEFAULT, ftime); CHKERRQ(ierr);
  ierr = TSSetInitialTimeStep(ts, 0.0, t_width[1]); CHKERRQ(ierr);
  ierr = TSSetFromOptions(ts);CHKERRQ(ierr);
  ierr = TSSolve(ts,x);CHKERRQ(ierr);
  //ierr = TSView(ts,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
  ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr);
  ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr);
  ierr = PetscPrintf(PETSC_COMM_WORLD,"%D steps, ftime 
%f\n",steps,ftime);CHKERRQ(ierr);
  //ierr = VecView(x,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);

  tt3 = MPI_Wtime(); //
  if (me == 0) std::cout << "Total fy11 time: " << tt3 - tt2 << std::endl;



  ////////////////////////////////////////////////////////////////////////
  // 2. posfy11 DAE:
  ////////////////////////////////////////////////////////////////////////
  // Set Userctx values: corresponding Ybus (third with posfy11)
  t0 = MPI_Wtime();
  scatterYbus(posfy11, user.ybus, ngen);
  t1 = MPI_Wtime();
  if (me == 0) std::cout << "Scattering posfy11 time: " << t1 - t0 << std::endl;
  ierr = TSCreate(PETSC_COMM_WORLD, &ts); CHKERRQ(ierr);
  //ierr = TSSetType(ts, TSBEULER); CHKERRQ(ierr);
  ierr = TSSetType(ts, TSTHETA); CHKERRQ(ierr);
  //ierr = TSThetaSetTheta(ts, 1.0); CHKERRQ(ierr);
  ierr = TSThetaSetTheta(ts, 0.5); CHKERRQ(ierr);
  //ierr = TSSetType(ts, TSEULER); CHKERRQ(ierr);
  ierr = TSSetIFunction(ts, NULL, (TSIFunction) IFunction, &user); 
CHKERRQ(ierr);
  ierr = TSSetIJacobian(ts, J, J, (TSIJacobian) IJacobian, &user); 
CHKERRQ(ierr);
  ierr = TSSetDM(ts, da); CHKERRQ(ierr);
  //ierr = formInitialSolution(ts, x, &user, t_step, t_width); CHKERRQ(ierr);
  ftime = t_step[2] * t_width[2];
  ierr = TSSetDuration(ts, PETSC_DEFAULT, ftime); CHKERRQ(ierr);
  ierr = TSSetInitialTimeStep(ts, 0.0, t_width[2]); CHKERRQ(ierr);
  ierr = TSSetFromOptions(ts);CHKERRQ(ierr);
  t0 = MPI_Wtime();
  ierr = TSSolve(ts,x);CHKERRQ(ierr);
  //  ierr = TSView(ts,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
  t1 = MPI_Wtime();
  if (me == 0) std::cout << "TSSolve posfy11 time: " << t1 - t0 << std::endl;
  ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr);
  ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr);
  ierr = PetscPrintf(PETSC_COMM_WORLD,"%D steps, ftime 
%f\n",steps,ftime);CHKERRQ(ierr);
  //ierr = VecView(x,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);

  tt4 = MPI_Wtime(); //
  if (me == 0) std::cout << "Total posfy11 time: " << tt4 - tt3 << std::endl;

  PetscViewer viewer;
  PetscViewerASCIIOpen(PETSC_COMM_WORLD, "u.dat", &viewer);
  PetscViewerSetFormat(viewer,PETSC_VIEWER_DEFAULT);
  VecView(x,viewer);
  PetscViewerDestroy(&viewer);

  //---------------------------------------------------------------------
  // Free work space.  All PETSc objects should be destroyed when they
  // are no longer needed.
  //---------------------------------------------------------------------
  ierr = VecScatterDestroy(&(user.vs));
  ierr = VecDestroy(&(user.x));
  ierr = VecDestroy(&(user.xdot));
  ierr = MatDestroy(&J); CHKERRQ(ierr);
  ierr = VecDestroy(&x); CHKERRQ(ierr);
  ierr = TSDestroy(&ts); CHKERRQ(ierr);
  ierr = DMDestroy(&da); CHKERRQ(ierr);

  delete [] user.ybus;
  delete [] user.eqprime;
  delete [] user.pmech;
  delete [] user.gen_d0;
  delete [] user.gen_h;

  tt1 = MPI_Wtime(); //
  if (me == 0) std::cout << "Total simu time: " << tt1 - tt0 << std::endl;

  PetscFunctionReturn(0);
}

Reply via email to