Beispiel #1
0
int main (int argc, char* argv[])
{
  //Do it by Forward Euler
  std::ofstream output("eulerSolution.dat");
  assert(output.is_open());
 
  ForwardEulerSolver solver(&myFunc, 0.05, 0.0, 1.0, 2.0);
  solver.SolveEquation(output);

  output.close();

  //Do it by R-K 4
  std::ofstream output2("rkSolution.dat");
  assert(output2.is_open());
  
  RungeKuttaFour solver2(&myFunc, 0.05, 0.0, 1.0, 2.0);
  solver2.SolveEquation(output2);
  
  output2.close();
}
Beispiel #2
0
void gridpack::dynamic_simulation_r::DSAppModule::solve(
    gridpack::dynamic_simulation_r::DSBranch::Event fault)
{
  gridpack::utility::CoarseTimer *timer =
    gridpack::utility::CoarseTimer::instance();
  int t_total = timer->createCategory("Dynamic Simulation: Total Application");
#if 0
  timer->start(t_total);
  int t_matset = timer->createCategory("Dynamic Simulation: Matrix Setup");
  timer->start(t_matset);
  p_factory->setMode(YBUS);
  gridpack::mapper::FullMatrixMap<DSNetwork> ybusMap(p_network);
  boost::shared_ptr<gridpack::math::Matrix> orgYbus = ybusMap.mapToMatrix();
  ///p_branchIO.header("\n=== orginal ybus: ============\n");
  ///orgYbus->print();

  // Form constant impedance load admittance yl for all buses and add it to 
  // system Y matrix: ybus = ybus + yl
  p_factory->setMode(YL);
  boost::shared_ptr<gridpack::math::Matrix> ybus = ybusMap.mapToMatrix();
  ///p_branchIO.header("\n=== ybus after added yl: ============\n");
  ///ybus->print();
 
  // Construct permutation matrix perm by checking for multiple generators at a bus
  p_factory->setMode(PERM);
  gridpack::mapper::FullMatrixMap<DSNetwork> permMap(p_network);
  boost::shared_ptr<gridpack::math::Matrix> perm = permMap.mapToMatrix();
  timer->stop(t_matset);
  ///p_busIO->header("\n=== perm: ============\n");
  ///perm->print(); 

  // Form a transposed matrix of perm
  int t_trans = timer->createCategory("Dynamic Simulation: Matrix Transpose");
  timer->start(t_trans);
   boost::shared_ptr<gridpack::math::Matrix> permTrans(transpose(*perm));
  timer->stop(t_trans);
  ///p_busIO->header("\n=== permTrans: ============\n");
  ///permTrans->print();

  // Construct matrix Y_a using extracted xd and ra from gen data, 
  // and construct its diagonal matrix diagY_a
  timer->start(t_matset);
  p_factory->setMode(YA);
  gridpack::mapper::FullMatrixMap<DSNetwork> yaMap(p_network);
  boost::shared_ptr<gridpack::math::Matrix> diagY_a = yaMap.mapToMatrix();
  ///p_busIO->header("\n=== diagY_a: ============\n");
  ///diagY_a->print(); 
  // Convert diagY_a from sparse matrix to dense matrix Y_a so that SuperLU_DIST can solve
  gridpack::math::MatrixStorageType denseType = gridpack::math::Dense;
  boost::shared_ptr<gridpack::math::Matrix> Y_a(gridpack::math::storageType(*diagY_a, denseType));
  timer->stop(t_matset);

  // Construct matrix Ymod: Ymod = diagY_a * permTrans
  int t_matmul = timer->createCategory("Dynamic Simulation: Matrix Multiply");
  timer->start(t_matmul);
  boost::shared_ptr<gridpack::math::Matrix> Ymod(multiply(*diagY_a, *permTrans));
  timer->stop(t_matmul);
  ///p_busIO->header("\n=== Ymod: ============\n");
  ///Ymod->print(); 
 
  // Form matrix Y_b: Y_b(1:ngen, jg) = -Ymod, where jg represents the 
  // corresponding index sets of buses that the generators are connected to. 
  // Then construct Y_b's transposed matrix Y_c: Y_c = Y_b'
  // This two steps can be done by using a P matrix to get Y_c directly.
  timer->start(t_matset);
  p_factory->setMode(PMatrix);
  gridpack::mapper::FullMatrixMap<DSNetwork> pMap(p_network);
  boost::shared_ptr<gridpack::math::Matrix> P = pMap.mapToMatrix();
  ///p_busIO->header("\n=== P: ============\n");
  ///P->print();
  p_factory->setMode(YC);
  gridpack::mapper::FullMatrixMap<DSNetwork> cMap(p_network);
  boost::shared_ptr<gridpack::math::Matrix> Y_c = cMap.mapToMatrix();
  Y_c->scale(-1.0);
  ///p_busIO->header("\n=== Y_c: ============\n");
  ///Y_c->print();
  p_factory->setMode(YB);
  gridpack::mapper::FullMatrixMap<DSNetwork> bMap(p_network);
  boost::shared_ptr<gridpack::math::Matrix> Y_b = bMap.mapToMatrix();
  timer->stop(t_matset);
  ///p_busIO->header("\n=== Y_b: ============\n");
  ///Y_b->print();
  
  Y_c->scale(-1.0); // scale Y_c by -1.0 for linear solving
  // Convert Y_c from sparse matrix to dense matrix Y_cDense so that SuperLU_DIST can solve
  //gridpack::math::Matrix::StorageType denseType = gridpack::math::Matrix::Dense;
  timer->start(t_matset);
  boost::shared_ptr<gridpack::math::Matrix> Y_cDense(gridpack::math::storageType(*Y_c, denseType));
   
  // Form matrix permYmod
  p_factory->setMode(permYMOD);
  gridpack::mapper::FullMatrixMap<DSNetwork> pymMap(p_network);
  boost::shared_ptr<gridpack::math::Matrix>  permYmod= pymMap.mapToMatrix();
  ///p_busIO->header("\n=== permYmod: ============\n");
  ///permYmod->print();

  // Update ybus: ybus = ybus+permYmod (different dimension) => prefy11ybus
  p_factory->setMode(updateYbus);

  boost::shared_ptr<gridpack::math::Vector> vPermYmod(diagonal(*permYmod));
  ///p_busIO->header("\n=== vPermYmod: ============\n");
  ///vPermYmod->print();
  gridpack::mapper::BusVectorMap<DSNetwork> permYmodMap(p_network);
  permYmodMap.mapToBus(vPermYmod);

  boost::shared_ptr<gridpack::math::Matrix> prefy11ybus = ybusMap.mapToMatrix();
  timer->stop(t_matset);
  ///p_branchIO.header("\n=== prefy11ybus: ============\n");
  ///prefy11ybus->print();

  // Solve linear equations of ybus * X = Y_c
  //gridpack::math::LinearSolver solver1(*prefy11ybus);
  //solver1.configure(cursor);
  int t_solve = timer->createCategory("Dynamic Simulation: Solve Linear Equation");
  timer->start(t_solve);
  gridpack::math::LinearMatrixSolver solver1(*prefy11ybus);
  boost::shared_ptr<gridpack::math::Matrix> prefy11X(solver1.solve(*Y_cDense));
  timer->stop(t_solve);
  ///p_branchIO.header("\n=== prefy11X: ============\n");
  ///prefy11X->print(); 
  
  //-----------------------------------------------------------------------
  // Compute prefy11
  //-----------------------------------------------------------------------
  // Form reduced admittance matrix prefy11: prefy11 = Y_b * X
  timer->start(t_matmul);
  boost::shared_ptr<gridpack::math::Matrix> prefy11(multiply(*Y_b, *prefy11X)); 
  timer->stop(t_matmul);
  // Update prefy11: prefy11 = Y_a + prefy11
  prefy11->add(*Y_a);
  ///p_branchIO.header("\n=== Reduced Ybus: prefy11: ============\n");
  ///prefy11->print();

  //-----------------------------------------------------------------------
  // Compute fy11
  // Update ybus values at fault stage
  //-----------------------------------------------------------------------
  // Read the switch info from faults Event from input.xml
  int sw2_2 = fault.from_idx - 1;
  int sw3_2 = fault.to_idx - 1;

  boost::shared_ptr<gridpack::math::Matrix> fy11ybus(prefy11ybus->clone());
  ///p_branchIO.header("\n=== fy11ybus(original): ============\n");
  ///fy11ybus->print();
  gridpack::ComplexType x(0.0, -1e7);
#if 0
  fy11ybus->setElement(sw2_2, sw2_2, -x);
  fy11ybus->ready();
#else
  timer->start(t_matset);
  p_factory->setEvent(fault);
  p_factory->setMode(onFY);
  ybusMap.overwriteMatrix(fy11ybus);
  timer->stop(t_matset);
#endif
  ///p_branchIO.header("\n=== fy11ybus: ============\n");
  ///fy11ybus->print();

  // Solve linear equations of fy11ybus * X = Y_c
  timer->start(t_solve);
  gridpack::math::LinearMatrixSolver solver2(*fy11ybus);
  boost::shared_ptr<gridpack::math::Matrix> fy11X(solver2.solve(*Y_cDense)); 
  timer->stop(t_solve);
  ///p_branchIO.header("\n=== fy11X: ============\n");
  ///fy11X->print();
  
  // Form reduced admittance matrix fy11: fy11 = Y_b * X
  timer->start(t_matmul);
  boost::shared_ptr<gridpack::math::Matrix> fy11(multiply(*Y_b, *fy11X)); 
  timer->stop(t_matmul);
  // Update fy11: fy11 = Y_a + fy11
  fy11->add(*Y_a);
  ///p_branchIO.header("\n=== Reduced Ybus: fy11: ============\n");
  ///fy11->print();

  //-----------------------------------------------------------------------
  // Compute posfy11
  // Update ybus values at clear fault stage
  //-----------------------------------------------------------------------
  // Get the updating factor for posfy11 stage ybus
#if 0
  gridpack::ComplexType myValue = p_factory->setFactor(sw2_2, sw3_2);
#endif
  timer->start(t_matset);
  boost::shared_ptr<gridpack::math::Matrix> posfy11ybus(prefy11ybus->clone());
  timer->stop(t_matset);
  ///p_branchIO.header("\n=== posfy11ybus (original): ============\n");
  ///posfy11ybus->print();
#if 0
  gridpack::ComplexType big(0.0, 1e7);
  gridpack::ComplexType x11 = big - myValue;
  posfy11ybus->addElement(sw2_2, sw2_2, x+x11);

  gridpack::ComplexType x12 = myValue;
  posfy11ybus->addElement(sw2_2, sw3_2, x12);

  gridpack::ComplexType x21 = myValue;
  posfy11ybus->addElement(sw3_2, sw2_2, x21);

  gridpack::ComplexType x22 = -myValue; 
  posfy11ybus->addElement(sw3_2, sw3_2, x22);
  
  posfy11ybus->ready(); 
#else
  timer->start(t_matset);
  p_factory->setMode(posFY);
  ybusMap.incrementMatrix(posfy11ybus);
  timer->stop(t_matset);
#endif
  ///p_branchIO.header("\n=== posfy11ybus: ============\n");
  ///posfy11ybus->print();
    
  // Solve linear equations of posfy11ybus * X = Y_c
  timer->start(t_solve);
  gridpack::math::LinearMatrixSolver solver3(*posfy11ybus);
  boost::shared_ptr<gridpack::math::Matrix> posfy11X(solver3.solve(*Y_cDense)); 
  timer->stop(t_solve);
  ///p_branchIO.header("\n=== posfy11X: ============\n");
  ///posfy11X->print();
  
  // Form reduced admittance matrix posfy11: posfy11 = Y_b * X
  timer->start(t_matmul);
  boost::shared_ptr<gridpack::math::Matrix> posfy11(multiply(*Y_b, *posfy11X)); 
  timer->stop(t_matmul);
  // Update posfy11: posfy11 = Y_a + posfy11
  posfy11->add(*Y_a);
  ///p_branchIO.header("\n=== Reduced Ybus: posfy11: ============\n");
  ///posfy11->print();

  //-----------------------------------------------------------------------
  // Integration implementation (Modified Euler Method)
  //-----------------------------------------------------------------------
 
  // Map to create vector pelect  
  int t_vecset = timer->createCategory("Dynamic Simulation: Setup Vector");
  timer->start(t_vecset);
  p_factory->setMode(init_pelect);
  gridpack::mapper::BusVectorMap<DSNetwork> XMap1(p_network);
  boost::shared_ptr<gridpack::math::Vector> pelect = XMap1.mapToVector();
  ///p_busIO->header("\n=== pelect: ===\n");
  ///pelect->print();

  // Map to create vector eprime_s0 
  p_factory->setMode(init_eprime);
  gridpack::mapper::BusVectorMap<DSNetwork> XMap2(p_network);
  boost::shared_ptr<gridpack::math::Vector> eprime_s0 = XMap2.mapToVector();
  ///p_busIO->header("\n=== eprime: ===\n");
  ///eprime_s0->print();

  // Map to create vector mac_ang_s0
  p_factory->setMode(init_mac_ang);
  gridpack::mapper::BusVectorMap<DSNetwork> XMap3(p_network);
  boost::shared_ptr<gridpack::math::Vector> mac_ang_s0 = XMap3.mapToVector();
  ///p_busIO->header("\n=== mac_ang_s0: ===\n");
  ///mac_ang_s0->print();

  // Map to create vector mac_spd_s0
  p_factory->setMode(init_mac_spd);
  gridpack::mapper::BusVectorMap<DSNetwork> XMap4(p_network);
  boost::shared_ptr<gridpack::math::Vector> mac_spd_s0 = XMap4.mapToVector();
  ///p_busIO->header("\n=== mac_spd_s0: ===\n");
  ///mac_spd_s0->print();

  // Map to create vector eqprime
  p_factory->setMode(init_eqprime);
  gridpack::mapper::BusVectorMap<DSNetwork> XMap5(p_network);
  boost::shared_ptr<gridpack::math::Vector> eqprime = XMap5.mapToVector();
  ///p_busIO->header("\n=== eqprime: ===\n");
  ///eqprime->print();

  // Map to create vector pmech  
  p_factory->setMode(init_pmech);
  gridpack::mapper::BusVectorMap<DSNetwork> XMap6(p_network);
  boost::shared_ptr<gridpack::math::Vector> pmech = XMap6.mapToVector();
  ///p_busIO->header("\n=== pmech: ===\n");
  ///pmech->print();

  // Map to create vector mva
  p_factory->setMode(init_mva);
  gridpack::mapper::BusVectorMap<DSNetwork> XMap7(p_network);
  boost::shared_ptr<gridpack::math::Vector> mva = XMap7.mapToVector();
  ///p_busIO->header("\n=== mva: ===\n");
  ///mva->print();

  // Map to create vector d0
  p_factory->setMode(init_d0);
  gridpack::mapper::BusVectorMap<DSNetwork> XMap8(p_network);
  boost::shared_ptr<gridpack::math::Vector> d0 = XMap8.mapToVector();
  ///p_busIO->header("\n=== d0: ===\n");
  ///d0->print();

  // Map to create vector h
  p_factory->setMode(init_h);
  gridpack::mapper::BusVectorMap<DSNetwork> XMap9(p_network);
  boost::shared_ptr<gridpack::math::Vector> h = XMap9.mapToVector();
  ///p_busIO->header("\n=== h: ===\n");
  ///h->print();

  ///p_busIO->header("\n============Start of Simulation:=====================\n");

  // Declare vector mac_ang_s1, mac_spd_s1
  boost::shared_ptr<gridpack::math::Vector> mac_ang_s1(mac_ang_s0->clone()); 
  boost::shared_ptr<gridpack::math::Vector> mac_spd_s1(mac_spd_s0->clone()); 
 
  // Declare vector eprime_s1
  boost::shared_ptr<gridpack::math::Vector> eprime_s1(mac_ang_s0->clone());
 
  // Declare vector dmac_ang_s0, dmac_spd_s0, dmac_ang_s1, dmac_spd_s1
  boost::shared_ptr<gridpack::math::Vector> dmac_ang_s0(mac_ang_s0->clone()); 
  boost::shared_ptr<gridpack::math::Vector> dmac_ang_s1(mac_ang_s0->clone()); 
  boost::shared_ptr<gridpack::math::Vector> dmac_spd_s0(mac_spd_s0->clone()); 
  boost::shared_ptr<gridpack::math::Vector> dmac_spd_s1(mac_spd_s0->clone()); 

  // Declare vector curr
  boost::shared_ptr<gridpack::math::Vector> curr(mac_ang_s0->clone());
  timer->stop(t_vecset);

  timer->start(t_trans);
  boost::shared_ptr<gridpack::math::Matrix> trans_prefy11(transpose(*prefy11));
  boost::shared_ptr<gridpack::math::Matrix> trans_fy11(transpose(*fy11));
  boost::shared_ptr<gridpack::math::Matrix> trans_posfy11(transpose(*posfy11));
  timer->stop(t_trans);

  timer->start(t_vecset);
  boost::shared_ptr<gridpack::math::Vector> vecTemp(mac_ang_s0->clone());
  timer->stop(t_vecset);

  // Simulation related variables
  int simu_k;
  int t_step[20];
  double t_width[20];
  int flagF;
  int S_Steps;
  int last_S_Steps;
  int steps3, steps2, steps1;
  double h_sol1, h_sol2;
  int flagF1, flagF2;
  int I_Steps;

  const double sysFreq = 60.0;
  double pi = 4.0*atan(1.0);
  const double basrad = 2.0 * pi * sysFreq;
  gridpack::ComplexType jay(0.0, 1.0);

  // switch info is set up here 
  int nswtch = 4;
  static double sw1[4];
  static double sw7[4];
  sw1[0] = 0.0;
  sw1[1] = fault.start;
  sw1[2] = fault.end;
  sw1[3] = p_sim_time;
  sw7[0] = p_time_step;
  sw7[1] = fault.step;
  sw7[2] = p_time_step;
  sw7[3] = p_time_step;
  simu_k = 0; 
  for (int i = 0; i < nswtch-1; i++) {
    t_step[i] = (int) ((sw1[i+1] -sw1[i]) / sw7[i]);   
    t_width[i] = (sw1[i+1] - sw1[i]) / t_step[i];
    simu_k += t_step[i];
  }
  simu_k++;

  steps3 = t_step[0] + t_step[1] + t_step[2] - 1;
  steps2 = t_step[0] + t_step[1] - 1;
  steps1 = t_step[0] - 1;
  h_sol1 = t_width[0];
  h_sol2 = h_sol1;
  flagF1 = 0; 
  flagF2 = 0; 
  p_S_Steps = 1; 
  last_S_Steps = -1;

  if (p_generatorWatch) {
    p_generatorIO->header("t");
    p_generatorIO->write("watch_header");
    p_generatorIO->header("\n");
  }
  for (I_Steps = 0; I_Steps < simu_k+1; I_Steps++) {
    if (I_Steps < steps1) {
      p_S_Steps = I_Steps;
      flagF1 = 0;
      flagF2 = 0;
    } else if (I_Steps == steps1) { 
      p_S_Steps = I_Steps;
      flagF1 = 0;
      flagF2 = 1;
    } else if (I_Steps == steps1+1) {
      p_S_Steps = I_Steps;
      flagF1 = 1;
      flagF2 = 1;
    } else if ((I_Steps>steps1+1) && (I_Steps<steps2+1)) {
      p_S_Steps = I_Steps - 1;
      flagF1 = 1;
      flagF2 = 1;
    } else if (I_Steps==steps2+1) {
      p_S_Steps = I_Steps - 1;
      flagF1 = 1;
      flagF2 = 2;
    } else if (I_Steps==steps2+2) {
      p_S_Steps = I_Steps - 1;
      flagF1 = 2;
      flagF2 = 2;
    } else if (I_Steps>steps2+2) {
      p_S_Steps = I_Steps - 2;
      flagF1 = 2;
      flagF2 = 2;
    }

    if (I_Steps !=0 && last_S_Steps != p_S_Steps) {
      mac_ang_s0->equate(*mac_ang_s1); 
      mac_spd_s0->equate(*mac_spd_s1); 
      eprime_s0->equate(*eprime_s1); 
    }

    vecTemp->equate(*mac_ang_s0); 
    vecTemp->scale(jay); 
    vecTemp->exp(); 
    vecTemp->elementMultiply(*eqprime); 
    eprime_s0->equate(*vecTemp); 
     
    // ---------- CALL i_simu_innerloop(k,p_S_Steps,flagF1): ----------
    int t_trnsmul = timer->createCategory("Dynamic Simulation: Transpose Multiply");
    timer->start(t_trnsmul);
    if (flagF1 == 0) {
      curr.reset(multiply(*trans_prefy11, *eprime_s0)); //MatMultTranspose(prefy11, eprime_s0, curr);
      //transposeMultiply(*prefy11,*eprime_s0,*curr);
    } else if (flagF1 == 1) {
      curr.reset(multiply(*trans_fy11, *eprime_s0)); //MatMultTranspose(fy11, eprime_s0, curr);
      //transposeMultiply(*fy11,*eprime_s0,*curr);
    } else if (flagF1 == 2) {
      curr.reset(multiply(*trans_posfy11, *eprime_s0)); //MatMultTranspose(posfy11, eprime_s0, curr);
      //transposeMultiply(*posfy11,*eprime_s0,*curr);
    } 
    timer->stop(t_trnsmul);
    
    // ---------- CALL mac_em2(k,p_S_Steps): ----------
    // ---------- pelect: ----------
    curr->conjugate(); 
    vecTemp->equate(*eprime_s0);
    vecTemp->elementMultiply(*curr);
    pelect->equate(*vecTemp); 
    pelect->real(); //Get the real part of pelect
    // ---------- dmac_ang: ----------
    vecTemp->equate(*mac_spd_s0); 
    vecTemp->add(-1.0); 
    vecTemp->scale(basrad); 
    dmac_ang_s0->equate(*vecTemp); 
    // ---------- dmac_spd: ----------
    vecTemp->equate(*pelect);
    vecTemp->elementMultiply(*mva); 
    dmac_spd_s0->equate(*pmech); 
    dmac_spd_s0->add(*vecTemp, -1.0); 
    vecTemp->equate(*mac_spd_s0); 
    vecTemp->add(-1.0); 
    vecTemp->elementMultiply(*d0); 
    dmac_spd_s0->add(*vecTemp, -1.0); 
    vecTemp->equate(*h); 
    vecTemp->scale(2.0); 
    dmac_spd_s0->elementDivide(*vecTemp); 

    mac_ang_s1->equate(*mac_ang_s0); 
    vecTemp->equate(*dmac_ang_s0);
    mac_ang_s1->add(*dmac_ang_s0, h_sol1); 
    mac_spd_s1->equate(*mac_spd_s0); 
    vecTemp->equate(*dmac_spd_s0);
    mac_spd_s1->add(*vecTemp, h_sol1); 

    vecTemp->equate(*mac_ang_s1); 
    vecTemp->scale(jay); 
    vecTemp->exp(); 
    vecTemp->elementMultiply(*eqprime);
    eprime_s1->equate(*vecTemp); 

    // ---------- CALL i_simu_innerloop2(k,p_S_Steps+1,flagF2): ----------
    timer->start(t_trnsmul);
    if (flagF2 == 0) {
      curr.reset(multiply(*trans_prefy11, *eprime_s1)); //MatMultTranspose(prefy11, eprime_s1, curr);
      //transposeMultiply(*prefy11,*eprime_s1,*curr);
    } else if (flagF2 == 1) {
      curr.reset(multiply(*trans_fy11, *eprime_s1)); //MatMultTranspose(fy11, eprime_s1, curr);
      //transposeMultiply(*fy11,*eprime_s1,*curr);
    } else if (flagF2 == 2) {
      curr.reset(multiply(*trans_posfy11, *eprime_s1)); //MatMultTranspose(posfy11, eprime_s1, curr);
      //transposeMultiply(*posfy11,*eprime_s1,*curr);
    }
    timer->stop(t_trnsmul);

    // ---------- CALL mac_em2(k,p_S_Steps+1): ---------- 
    // ---------- pelect: ----------
    curr->conjugate(); 
    vecTemp->equate(*eprime_s1);
    vecTemp->elementMultiply(*curr); 
    pelect->equate(*vecTemp); 
    pelect->real(); //Get the real part of pelect
    // ---------- dmac_ang: ----------
    vecTemp->equate(*mac_spd_s1); 
    vecTemp->add(-1.0); 
    vecTemp->scale(basrad); 
    dmac_ang_s1->equate(*vecTemp); 
    // ---------- dmac_spd: ----------
    vecTemp->equate(*pelect);
    vecTemp->elementMultiply(*mva); 
    dmac_spd_s1->equate(*pmech); 
    dmac_spd_s1->add(*vecTemp, -1.0); 
    vecTemp->equate(*mac_spd_s1); 
    vecTemp->add(-1.0); 
    vecTemp->elementMultiply(*d0); 
    dmac_spd_s1->add(*vecTemp, -1.0); 
    vecTemp->equate(*h); 
    vecTemp->scale(2.0); 
    dmac_spd_s1->elementDivide(*vecTemp); 

    vecTemp->equate(*dmac_ang_s0); 
    vecTemp->add(*dmac_ang_s1); 
    vecTemp->scale(0.5); 
    mac_ang_s1->equate(*mac_ang_s0); 
    mac_ang_s1->add(*vecTemp, h_sol2); 
    vecTemp->equate(*dmac_spd_s0); 
    vecTemp->add(*dmac_spd_s1); 
    vecTemp->scale(0.5); 
    mac_spd_s1->equate(*mac_spd_s0); 
    mac_spd_s1->add(*vecTemp, h_sol2); 
    if (p_generatorWatch && I_Steps%p_watchFrequency == 0) {
      p_factory->setMode(init_mac_ang);
      XMap3.mapToBus(mac_ang_s1);
      p_factory->setMode(init_mac_spd);
      XMap3.mapToBus(mac_spd_s1);
      char tbuf[32];
      sprintf(tbuf,"%8.4f",static_cast<double>(I_Steps)*p_time_step);
      p_generatorIO->header(tbuf);
      p_generatorIO->write("watch");
      p_generatorIO->header("\n");
    }

    // Print to screen
    if (last_S_Steps != p_S_Steps) {
      //sprintf(ioBuf, "\n========================S_Steps = %d=========================\n", p_S_Steps);
      //p_busIO->header(ioBuf);
      //mac_ang_s0->print();  
      //mac_spd_s0->print();  
      //pmech->print();
      //pelect->print();
      //sprintf(ioBuf, "========================End of S_Steps = %d=========================\n\n", p_S_Steps);
      //p_busIO->header(ioBuf);
    }
    if (I_Steps == simu_k) {
      p_factory->setMode(init_mac_ang);
      XMap3.mapToBus(mac_ang_s1);
      p_factory->setMode(init_mac_spd);
      XMap3.mapToBus(mac_spd_s1);
      p_factory->setMode(init_pmech);
      XMap6.mapToBus(pmech);
      p_factory->setMode(init_pelect);
      XMap1.mapToBus(pelect);
      //mac_ang_s1->print();  
      //mac_spd_s1->print();  
      //pmech->print();
      //pelect->print();
    } // End of Print to screen 
    
    last_S_Steps = p_S_Steps;
  }
  closeGeneratorWatchFile();
  timer->stop(t_total);
#else
  timer->start(t_total);
  int t_matset = timer->createCategory("Matrix Setup");
  timer->start(t_matset);
  p_factory->setMode(YBUS);
  gridpack::mapper::FullMatrixMap<DSNetwork> ybusMap(p_network);
  timer->stop(t_matset);

  int t_trans = timer->createCategory("Matrix Transpose");
  // Construct matrix diagY_a using xd and ra extracted from gen data, 
  timer->start(t_matset);
  p_factory->setMode(YA);
  gridpack::mapper::FullMatrixMap<DSNetwork> yaMap(p_network);
  boost::shared_ptr<gridpack::math::Matrix> diagY_a = yaMap.mapToMatrix();
  // Convert diagY_a from sparse matrix to dense matrix Y_a so that SuperLU_DIST can solve
  gridpack::math::MatrixStorageType denseType = gridpack::math::Dense;
  boost::shared_ptr<gridpack::math::Matrix> Y_a(gridpack::math::storageType(*diagY_a, denseType));
  timer->stop(t_matset);

  int t_matmul = timer->createCategory("Matrix Multiply");
  // Construct Y_c as a dense matrix
  timer->start(t_matset);
  p_factory->setMode(YC);
  gridpack::mapper::FullMatrixMap<DSNetwork> cMap(p_network);
  boost::shared_ptr<gridpack::math::Matrix> Y_cDense = cMap.mapToMatrix(true);

  // Construct Y_b
  p_factory->setMode(YB);
  gridpack::mapper::FullMatrixMap<DSNetwork> bMap(p_network);
  boost::shared_ptr<gridpack::math::Matrix> Y_b = bMap.mapToMatrix();
  timer->stop(t_matset);
  
  timer->start(t_matset);
  p_factory->setMode(updateYbus);
  boost::shared_ptr<gridpack::math::Matrix> prefy11ybus = ybusMap.mapToMatrix();
  timer->stop(t_matset);

  // Solve linear equations ybus * X = Y_c
  int t_solve = timer->createCategory("Solve Linear Equation");
  timer->start(t_solve);
  gridpack::math::LinearMatrixSolver solver1(*prefy11ybus);
  boost::shared_ptr<gridpack::math::Matrix> prefy11X(solver1.solve(*Y_cDense));
  timer->stop(t_solve);
  
  //-----------------------------------------------------------------------
  // Compute prefy11
  //-----------------------------------------------------------------------
  // Form reduced admittance matrix prefy11: prefy11 = Y_b * X
  timer->start(t_matmul);
  boost::shared_ptr<gridpack::math::Matrix> prefy11(multiply(*Y_b, *prefy11X)); 
  timer->stop(t_matmul);
  // Update prefy11: prefy11 = Y_a + prefy11
  prefy11->add(*Y_a);

  //-----------------------------------------------------------------------
  // Compute fy11
  // Update ybus values at beginning of fault
  //-----------------------------------------------------------------------
  // Read the switch info from fault. Event from input.xml
  int sw2_2 = fault.from_idx - 1;
  int sw3_2 = fault.to_idx - 1;

  boost::shared_ptr<gridpack::math::Matrix> fy11ybus(prefy11ybus->clone());
  gridpack::ComplexType x(0.0, -1e7);
  timer->start(t_matset);
  p_factory->setEvent(fault);
  p_factory->setMode(onFY);
  ybusMap.overwriteMatrix(fy11ybus);
  timer->stop(t_matset);

  // Solve linear equations of fy11ybus * X = Y_c
  timer->start(t_solve);
  gridpack::math::LinearMatrixSolver solver2(*fy11ybus);
  boost::shared_ptr<gridpack::math::Matrix> fy11X(solver2.solve(*Y_cDense)); 
  timer->stop(t_solve);
  
  // Form reduced admittance matrix fy11: fy11 = Y_b * X
  timer->start(t_matmul);
  boost::shared_ptr<gridpack::math::Matrix> fy11(multiply(*Y_b, *fy11X)); 
  timer->stop(t_matmul);
  // Update fy11: fy11 = Y_a + fy11
  fy11->add(*Y_a);

  //-----------------------------------------------------------------------
  // Compute posfy11
  // Update ybus values at clear fault stage
  //-----------------------------------------------------------------------
  // Get the updating factor for posfy11 stage ybus
  timer->start(t_matset);
  boost::shared_ptr<gridpack::math::Matrix> posfy11ybus(prefy11ybus->clone());
  timer->stop(t_matset);
  timer->start(t_matset);
  p_factory->setMode(posFY);
  ybusMap.incrementMatrix(posfy11ybus);
  timer->stop(t_matset);
    
  // Solve linear equations of posfy11ybus * X = Y_c
  timer->start(t_solve);
  gridpack::math::LinearMatrixSolver solver3(*posfy11ybus);
  boost::shared_ptr<gridpack::math::Matrix> posfy11X(solver3.solve(*Y_cDense)); 
  timer->stop(t_solve);
  
  // Form reduced admittance matrix posfy11: posfy11 = Y_b * X
  timer->start(t_matmul);
  boost::shared_ptr<gridpack::math::Matrix> posfy11(multiply(*Y_b, *posfy11X)); 
  timer->stop(t_matmul);
  // Update posfy11: posfy11 = Y_a + posfy11
  posfy11->add(*Y_a);

  //-----------------------------------------------------------------------
  // Integration implementation (Modified Euler Method)
  //-----------------------------------------------------------------------
 
  p_factory->setDSParams();
  p_factory->setMode(Eprime0);
  // create vectors used in solution method
  gridpack::mapper::BusVectorMap<DSNetwork> Emap(p_network);
  boost::shared_ptr<gridpack::math::Vector> eprime_s0 = Emap.mapToVector();
  boost::shared_ptr<gridpack::math::Vector> eprime_s1(eprime_s0->clone());
  boost::shared_ptr<gridpack::math::Vector> curr(eprime_s0->clone());

  timer->start(t_trans);
  boost::shared_ptr<gridpack::math::Matrix> trans_prefy11(transpose(*prefy11));
  boost::shared_ptr<gridpack::math::Matrix> trans_fy11(transpose(*fy11));
  boost::shared_ptr<gridpack::math::Matrix> trans_posfy11(transpose(*posfy11));
  timer->stop(t_trans);

  // Simulation related variables
  int simu_k;
  int t_step[20];
  double t_width[20];
  int flagF;
  int S_Steps;
  int last_S_Steps;
  int steps3, steps2, steps1;
  double h_sol1, h_sol2;
  int flagF1, flagF2;
  int I_Steps;

  const double sysFreq = 60.0;
  double pi = 4.0*atan(1.0);
  const double basrad = 2.0 * pi * sysFreq;
  gridpack::ComplexType jay(0.0, 1.0);

  // switch info is set up here 
  int nswtch = 4;
  static double sw1[4];
  static double sw7[4];
  sw1[0] = 0.0;
  sw1[1] = fault.start;
  sw1[2] = fault.end;
  sw1[3] = p_sim_time;
  sw7[0] = p_time_step;
  sw7[1] = fault.step;
  sw7[2] = p_time_step;
  sw7[3] = p_time_step;
  simu_k = 0; 
  for (int i = 0; i < nswtch-1; i++) {
    t_step[i] = (int) ((sw1[i+1] -sw1[i]) / sw7[i]);   
    t_width[i] = (sw1[i+1] - sw1[i]) / t_step[i];
    simu_k += t_step[i];
  }
  simu_k++;

  steps3 = t_step[0] + t_step[1] + t_step[2] - 1;
  steps2 = t_step[0] + t_step[1] - 1;
  steps1 = t_step[0] - 1;
  h_sol1 = t_width[0];
  h_sol2 = h_sol1;
  flagF1 = 0; 
  flagF2 = 0; 
  S_Steps = 1; 
  last_S_Steps = -1;

  if (p_generatorWatch) {
    p_generatorIO->header("t");
    if (p_generatorWatch) p_generatorIO->write("watch_header");
    p_generatorIO->header("\n");
  }
  for (I_Steps = 0; I_Steps < simu_k+1; I_Steps++) {
    if (I_Steps < steps1) {
      S_Steps = I_Steps;
      flagF1 = 0;
      flagF2 = 0;
    } else if (I_Steps == steps1) { 
      S_Steps = I_Steps;
      flagF1 = 0;
      flagF2 = 1;
    } else if (I_Steps == steps1+1) {
      S_Steps = I_Steps;
      flagF1 = 1;
      flagF2 = 1;
    } else if ((I_Steps>steps1+1) && (I_Steps<steps2+1)) {
      S_Steps = I_Steps - 1;
      flagF1 = 1;
      flagF2 = 1;
    } else if (I_Steps==steps2+1) {
      S_Steps = I_Steps - 1;
      flagF1 = 1;
      flagF2 = 2;
    } else if (I_Steps==steps2+2) {
      S_Steps = I_Steps - 1;
      flagF1 = 2;
      flagF2 = 2;
    } else if (I_Steps>steps2+2) {
      S_Steps = I_Steps - 2;
      flagF1 = 2;
      flagF2 = 2;
    }

    if (I_Steps !=0 && last_S_Steps != S_Steps) {
      p_factory->initDSStep(false);
    } else {
      p_factory->initDSStep(true);
    }
    p_factory->setMode(Eprime0);
    Emap.mapToVector(eprime_s0);
     
    // ---------- CALL i_simu_innerloop(k,S_Steps,flagF1): ----------
    int t_trnsmul = timer->createCategory("Transpose Multiply");
    timer->start(t_trnsmul);
    if (flagF1 == 0) {
      curr.reset(multiply(*trans_prefy11, *eprime_s0)); //MatMultTranspose(prefy11, eprime_s0, curr);
      //transposeMultiply(*prefy11,*eprime_s0,*curr);
    } else if (flagF1 == 1) {
      curr.reset(multiply(*trans_fy11, *eprime_s0)); //MatMultTranspose(fy11, eprime_s0, curr);
      //transposeMultiply(*fy11,*eprime_s0,*curr);
    } else if (flagF1 == 2) {
      curr.reset(multiply(*trans_posfy11, *eprime_s0)); //MatMultTranspose(posfy11, eprime_s0, curr);
      //transposeMultiply(*posfy11,*eprime_s0,*curr);
    } 
    timer->stop(t_trnsmul);
    
    p_factory->setMode(Current);
    Emap.mapToBus(curr);
    p_factory->predDSStep(h_sol1);
    p_factory->setMode(Eprime1);
    Emap.mapToVector(eprime_s1);

    // ---------- CALL i_simu_innerloop2(k,S_Steps+1,flagF2): ----------
    timer->start(t_trnsmul);
    if (flagF2 == 0) {
      curr.reset(multiply(*trans_prefy11, *eprime_s1)); //MatMultTranspose(prefy11, eprime_s1, curr);
      //transposeMultiply(*prefy11,*eprime_s1,*curr);
    } else if (flagF2 == 1) {
      curr.reset(multiply(*trans_fy11, *eprime_s1)); //MatMultTranspose(fy11, eprime_s1, curr);
      //transposeMultiply(*fy11,*eprime_s1,*curr);
    } else if (flagF2 == 2) {
      curr.reset(multiply(*trans_posfy11, *eprime_s1)); //MatMultTranspose(posfy11, eprime_s1, curr);
      //transposeMultiply(*posfy11,*eprime_s1,*curr);
    }
    timer->stop(t_trnsmul);

    p_factory->setMode(Current);
    Emap.mapToBus(curr);
    p_factory->corrDSStep(h_sol2);

    if (p_generatorWatch && I_Steps%p_watchFrequency == 0) {
      char tbuf[32];
      sprintf(tbuf,"%8.4f",static_cast<double>(I_Steps)*p_time_step);
      p_generatorIO->header(tbuf);
      p_generatorIO->write("watch");
      p_generatorIO->header("\n");
    }
    // Print to screen
    if (I_Steps == simu_k) {
      char ioBuf[128];
      sprintf(ioBuf, "\n========================S_Steps = %d=========================\n",
          S_Steps+1);
      p_busIO->header(ioBuf);
      sprintf(ioBuf, "\n         Bus ID     Generator ID"
          "    mac_ang         mac_spd         mech            elect\n\n");
      p_busIO->header(ioBuf);
      p_busIO->write();
      sprintf(ioBuf, "\n========================End of S_Steps = %d=========================\n\n",
          S_Steps+1);
      p_busIO->header(ioBuf);
    } // End of Print to screen 
    
    last_S_Steps = S_Steps;
  }
  closeGeneratorWatchFile();
  timer->stop(t_total);
#endif
}
main(int argc, char **argv)
{
    int m;		/* number of constraints */
    int n;		/* number of variables */
    int nz;		/* number of nonzeros in sparse constraint matrix */
    int *ia; 		/* array row indices */
    int *ka; 		/* array of indices into ia and a */
    double *a;		/* array of nonzeros in the constraint matrix */
    double *b; 		/* right-hand side */
    double *c;          /* objective coefficients */
    double *c2;         /* objective coefficients */
    int     *basics;	/* list of basic variable indices */
    int     *nonbasics;	/* list of non-basic variable indices */
    int     *basicflag; /* neg if nonbasic, pos if basic */
    int     *freevars;  /* boolean indicator of free variables */
    double **X, **Y, **Z, **BETA0, **BETAhat, **TMP;
    time_t start_time, end_time;
    double elapsed_time;
    int knum = 100;
	int offset = atoi(argv[2]);
	int counter = offset * GAUSS_OFFSET ;
	int counter2 = offset * IDX_OFFSET ;

 
    int i, j, k, i1, i2, j1, j2, n1, n2, d1, d2, b_idx, n_idx;

    n1 = 33;
    n2 = 34;
    d1 = 141;
    d2 = atoi(argv[1]);


 FILE* file = fopen("rng_gauss.csv", "r");
   i = 0;
   j = 0;
   double num = 0;
   double rng_gauss[LEN_GAUSS];

   while(fscanf(file, "%lf,", &num) > 0)
   {
       rng_gauss[i++] = num;
      if (i>=LEN_GAUSS) break;
   }

   fclose(file);

   int num2 = 0;
	int rng_i[LEN_IDX];
   int rng_j[LEN_IDX];

   i = 0;
   file = fopen("rng_idx.csv", "r");
   while(fscanf(file, "%d,", &num2) > 0){
      rng_i[i] = (num2-1)/d2;
      rng_j[i] = (num2-1)%d2;

      i++;
      if (i>=LEN_IDX) break;
   }

   fclose(file);


    m = n1*d2 + n1*n2;
    n = 2*d1*d2 + n1*d2 + 2*n1*n2;
    nz = 2*n1*d1*d2 + d2*n1 + n2*d2*n1 + 2*n1*n2;

    CALLOC(        a, nz,  double );      
    CALLOC(       ia, nz,   int );      
    CALLOC(       ka, n+1,  int );      
    CALLOC(        b, m,   double );      
    CALLOC(        c, n,   double );      
    CALLOC(       c2, n,   double );      
    CALLOC(   basics, m,   int );      
    CALLOC(nonbasics, n-m, int );      
    CALLOC(basicflag, n,   int );      
    CALLOC(freevars,  n,   int );      

    CALLOC(        BETA0, d1,  double *);
    for (i=0; i<d1; i++) {
        CALLOC( BETA0[i], d2,  double );      
    }

    CALLOC(        BETAhat, d1,  double *);
    for (i=0; i<d1; i++) {
        CALLOC( BETAhat[i], d2,  double );      
    }

    CALLOC(        X, n1,  double *);
    for (i=0; i<n1; i++) {
        CALLOC( X[i], d1,  double);
    }

    CALLOC(        Z, n2,  double *);
    for (i=0; i<n2; i++) {
        CALLOC( Z[i], d2,  double);
    }

    CALLOC(        Y, n1,  double *);
    for (i=0; i<n1; i++) {
        CALLOC( Y[i], n2,  double);
    }

    CALLOC(        TMP, n1,  double *);
    for (i=0; i<n1; i++) {
        CALLOC( TMP[i], d2,  double );      
    }


    int kk;  
    for (kk=0; kk<knum; kk++) {
       j1 = rng_i[counter2];
       j2 = rng_j[counter2];
	counter2++;
	if(j1<d1 & j2<d2){
       if (BETA0[j1][j2]==0){
           BETA0[j1][j2] = 1.;
       } else{
          kk--;
          }
	if(counter2>=LEN_IDX) counter2 = 0;
    	}
    }

    for (j1=0; j1<d1; j1++) {
       for (i1=0; i1<n1; i1++) {
          X[i1][j1] = rng_gauss[counter++];
		if(counter>=LEN_GAUSS) counter = 0;
       }
    }
  
    for (j2=0; j2<d2; j2++) {
       for (i2=0; i2<n2; i2++) {
          Z[i2][j2] = rng_gauss[counter++];
		if(counter>=LEN_GAUSS) counter = 0;
       }
    }

    for (i1=0; i1<n1; i1++) {
       for (j2=0; j2<d2; j2++) {
          TMP[i1][j2] = 0;
          for (j=0; j<d1; j++) {
             TMP[i1][j2] += X[i1][j]*BETA0[j][j2];
          }
       }
    }

    for (i1=0; i1<n1; i1++) {
       for (j2=0; j2<n2; j2++) {
          Y[i1][j2] = 0;
          for (j=0; j<d2; j++) {
             Y[i1][j2] += TMP[i1][j]*Z[j2][j];
          }
       }
    }

    time(&start_time);

    /*****************************************************************
     * Structure of the problem:
     *
     *                  +          -                 +      -
     *              beta       beta       C       eps    eps
     *
     * zeta    =                                 -e^T   -e^T
     * zetabar =  -mu e^T   -mu e^T
     * ---------------------------------------------------------------
     *              X        -X      -I                       = 0      (n1)
     *               X        -X        -I                    = 0      (n1)
     *                .         .          .             
     *                 X        -X           -I               = 0      (n1)
     *
     *                               zI zI   zI   I     -I    = y_1    (n1)
     *                               zI zI   zI    I     -I   = y_2    (n1)
     *                                     .        .      .
     *                               zI zI   zI      I     -I = y_n2   (n1)
     *
     * NOTE:  C is free
     *
     ***************************************************************/

    k=0;
    for (j2=0; j2<d2; j2++) {
      for (j1=0; j1<d1; j1++) {
	j = d1*j2 + j1;
	ka[j] = k;
	for (i1=0; i1<n1; i1++) {
	    a[k] = X[i1][j1];
	    ia[k] = j2*n1 + i1;
	    k++;
	}
	c [j] =  0;
	c2[j] = -1;
      }
    }
    for (j2=0; j2<d2; j2++) {
      for (j1=0; j1<d1; j1++) {
	j = d1*d2 + d1*j2 + j1;
	ka[j] = k;
	for (i1=0; i1<n1; i1++) {
	    a[k] = -X[i1][j1];
	    ia[k] = j2*n1 + i1;
	    k++;
	}
	c [j] =  0;
	c2[j] = -1;
      }
    }
    for (j2=0; j2<d2; j2++) {
      for (i1=0; i1<n1; i1++) {
	j = 2*d1*d2 + j2*n1 + i1;
	freevars[j] = 1;
	ka[j] = k;
	i = j2*n1 + i1;
	a[k] = -1;
	ia[k] = i;
	k++;
	for (i2=0; i2<n2; i2++) {
	    i = d2*n1 + i2*n1 + i1;
	    a[k] = Z[i2][j2];
	    ia[k] = i;
	    k++;
	}
      }
    }
    i=n1*d2;
    for (j=2*d1*d2+n1*d2; j<2*d1*d2+n1*d2+n1*n2; j++) {
	ka[j] = k;
        a[k] = 1;
        ia[k] = i;
        k++;
	i++;
	c [j] = -1;
	c2[j] =  0;
    }
    i=n1*d2;
    for (j=2*d1*d2+n1*d2+n1*n2; j<2*d1*d2+n1*d2+2*n1*n2; j++) {
	ka[j] = k;
        a[k] = -1;
        ia[k] = i;
        k++;
	i++;
	c [j] = -1;
	c2[j] =  0;
    }
    ka[n] = k;


    for (i=0; i<n1*d2; i++) {
	b[i] = 0;
    }
    for (i2=0; i2<n2; i2++) {
      for (i1=0; i1<n1; i1++) {
	i = n1*d2 + i2*n1 + i1;
	b[i] = Y[i1][i2];
      }
    }

    b_idx = 0; n_idx = 0;
    for (j=0; j<2*d1*d2; j++) {
	nonbasics[n_idx] = j; basicflag[j] = -n_idx-1; n_idx++;
    }
    for (j=2*d1*d2; j<2*d1*d2+n1*d2; j++) {
	basics[b_idx] = j; basicflag[j] = b_idx; b_idx++;
    }
    for (i=0; i<n1*n2; i++) {
	j = 2*d1*d2+n1*d2+i;
	if (b[n1*d2 + i] >= 0) {
	    basics[b_idx] = j; basicflag[j] = b_idx; b_idx++;
	} else {
	    nonbasics[n_idx] = j; basicflag[j] = -n_idx-1; n_idx++;
	}
    }
    for (i=0; i<n1*n2; i++) {
	j = 2*d1*d2+n1*d2+n1*n2+i;
	if (b[n1*d2 + i] < 0) {
	    basics[b_idx] = j; basicflag[j] = b_idx; b_idx++;
	} else {
	    nonbasics[n_idx] = j; basicflag[j] = -n_idx-1; n_idx++;
	}
    }


    solver2(m,n,nz,ia,ka,a,b,c,c2,0,basics,nonbasics,basicflag,freevars,d1,d2,BETAhat);
    time(&end_time);
    elapsed_time  = difftime(end_time,start_time);

    /*printf("==================================================\n");*/
    double betahatsum = 0.0;
    /*printf("BETAhat: \n");*/
    for (i1=0; i1<d1; i1++){
       for (i2=0; i2<d2; i2++){
          /* if(ABS(BETAhat[i1][i2])>EPS0) printf("[%d,%d]: %6.2f, ",i1,i2,BETAhat[i1][i2]);*/
          betahatsum = betahatsum + ABS(BETAhat[i1][i2]);
       }
    }
    /*printf("Betahat sum: %f\n", betahatsum);*/
 

    double maxerror = 0.0;
    double l1error = 0.0;
    int happy = 1;
    double tmp = 0.;
    double maxBETA0 = 0.0;
    for (j1=0; j1<d1; j1++) {
       for (j2=0; j2<d2; j2++) {
          if (ABS(BETA0[j1][j2]) > maxBETA0) { maxBETA0 = ABS(BETA0[j1][j2]); }
       }
    }

    for (j1=0; j1<d1; j1++) {
       for (j2=0; j2<d2; j2++) {
          tmp = ABS(BETA0[j1][j2]-BETAhat[j1][j2]);
          l1error = l1error + tmp;
          if (tmp > maxerror) maxerror = tmp;
          if (tmp > 1e-5*maxBETA0) {
             happy = 0;
          }
       }
    }
    
  /*  printf("Max error: %f\n", maxerror);
    printf("L1 error: %f\n", l1error);

    if (happy) {
       printf("happy: ");
    } else {
       printf("unhappy: ");
    }
    
    printf("Solution time (seconds): %0.2lf \n", elapsed_time);*/

    printf("%d, %f, %f, %f\n",d2 , elapsed_time, maxerror, l1error);

    lu_clo();

    for (i=0; i<d1; i++){
       FREE(BETA0[i]);
       FREE(BETAhat[i]);
    }
    for (i=0; i<n1; i++){
       FREE(X[i]);
       FREE(Y[i]);
       FREE(TMP[i]);
    }
    for (i=0; i<n2; i++){
       FREE(Z[i]);
    }
    FREE(BETA0);
    FREE(BETAhat);
    FREE(X);
    FREE(Y);
    FREE(Z);
    FREE(TMP);

    FREE(a);
    FREE(ia); 
    FREE(ka);
    FREE(b);
    FREE(c);
    FREE(c2);
    FREE(basicflag);
    FREE(freevars);

    
    return 0;
}
Beispiel #4
0
/**
 * Execute application
 */
void gridpack::dynamic_simulation::DSApp::execute(int argc, char** argv)
{
  gridpack::utility::CoarseTimer *timer =
    gridpack::utility::CoarseTimer::instance();
  int t_total = timer->createCategory("Total Application");
  timer->start(t_total);
  gridpack::parallel::Communicator world;
  boost::shared_ptr<DSNetwork> network(new DSNetwork(world));

  int t_setup = timer->createCategory("Read in Data");
  timer->start(t_setup);
  // read configuration file
  gridpack::utility::Configuration *config = gridpack::utility::Configuration::configuration();
  if (argc >= 2 && argv[1] != NULL) {
    char inputfile[256];
    sprintf(inputfile,"%s",argv[1]);
    config->open(inputfile,world);
  } else {
    config->open("input.xml",world);
  }
  gridpack::utility::Configuration::CursorPtr cursor;
  cursor = config->getCursor("Configuration.Dynamic_simulation");
  std::string filename = cursor->get("networkConfiguration",
      "No network configuration specified");
  double sim_time = cursor->get("simulationTime",0.0);
  if (sim_time == 0.0) {
    // TODO: some kind of error
  }
  double time_step = cursor->get("timeStep",0.0);
  if (time_step == 0.0) {
    // TODO: some kind of error
  }

  // Read in information about fault events and store them in internal data
  // structure
  cursor = config->getCursor("Configuration.Dynamic_simulation.faultEvents");
  gridpack::utility::Configuration::ChildCursors events;
  if (cursor) cursor->children(events);
  std::vector<gridpack::dynamic_simulation::DSBranch::Event>
     faults = setFaultEvents(events); 

  // load input file
  gridpack::parser::PTI23_parser<DSNetwork> parser(network);
  parser.parse(filename.c_str());
  cursor = config->getCursor("Configuration.Dynamic_simulation");
  filename = cursor->get("generatorParameters","");
  timer->stop(t_setup);

  int t_part = timer->createCategory("Partition Network");
  timer->start(t_part);
  // partition network
  network->partition();
  timer->stop(t_part);
  if (filename.size() > 0) parser.externalParse(filename.c_str());

  // Create serial IO object to export data from buses or branches
  gridpack::serial_io::SerialBusIO<DSNetwork> busIO(2048, network);
  gridpack::serial_io::SerialBranchIO<DSNetwork> branchIO(128, network);
  char ioBuf[128];

  int t_config = timer->createCategory("Configure Network");
  timer->start(t_config);
  // create factory
  gridpack::dynamic_simulation::DSFactory factory(network);
  factory.load();

  // set network components using factory
  factory.setComponents();
  timer->stop(t_config);

  // set YBus components so that you can create Y matrix  
  factory.setYBus();

  if (!factory.checkGen()) {
    busIO.header("Missing generators on at least one processor\n");
    return;
  }

  int t_matset = timer->createCategory("Matrix Setup");
  timer->start(t_matset);
  factory.setMode(YBUS);
  gridpack::mapper::FullMatrixMap<DSNetwork> ybusMap(network);
  timer->stop(t_matset);

  int t_trans = timer->createCategory("Matrix Transpose");
  // Construct matrix Y_a using extracted xd and ra from gen data, 
  // and construct its diagonal matrix diagY_a
  timer->start(t_matset);
  factory.setMode(YA);
  gridpack::mapper::FullMatrixMap<DSNetwork> yaMap(network);
  boost::shared_ptr<gridpack::math::Matrix> diagY_a = yaMap.mapToMatrix();
  ///busIO.header("\n=== diagY_a: ============\n");
  ///diagY_a->print(); 
  // Convert diagY_a from sparse matrix to dense matrix Y_a so that SuperLU_DIST can solve
  gridpack::math::MatrixStorageType denseType = gridpack::math::Dense;
  boost::shared_ptr<gridpack::math::Matrix> Y_a(gridpack::math::storageType(*diagY_a, denseType));
  timer->stop(t_matset);

  // Construct matrix Ymod: Ymod = diagY_a * permTrans
  int t_matmul = timer->createCategory("Matrix Multiply");
  // Form matrix Y_b: Y_b(1:ngen, jg) = -Ymod, where jg represents the 
  // corresponding index sets of buses that the generators are connected to. 
  // Then construct Y_b's transposed matrix Y_c: Y_c = Y_b'
  // This two steps can be done by using a P matrix to get Y_c directly.
  timer->start(t_matset);
  factory.setMode(YC);
  gridpack::mapper::FullMatrixMap<DSNetwork> cMap(network);
  boost::shared_ptr<gridpack::math::Matrix> Y_cDense = cMap.mapToMatrix(true);

  factory.setMode(YB);
  gridpack::mapper::FullMatrixMap<DSNetwork> bMap(network);
  boost::shared_ptr<gridpack::math::Matrix> Y_b = bMap.mapToMatrix();
  timer->stop(t_matset);
  ///busIO.header("\n=== Y_b: ============\n");
  ///Y_b->print();
  
  timer->start(t_matset);
  factory.setMode(updateYbus);
  boost::shared_ptr<gridpack::math::Matrix> prefy11ybus = ybusMap.mapToMatrix();
  timer->stop(t_matset);
  ///branchIO.header("\n=== prefy11ybus: ============\n");
  ///prefy11ybus->print();

  // Solve linear equations of ybus * X = Y_c
  //gridpack::math::LinearSolver solver1(*prefy11ybus);
  //solver1.configure(cursor);
  int t_solve = timer->createCategory("Solve Linear Equation");
  timer->start(t_solve);
  gridpack::math::LinearMatrixSolver solver1(*prefy11ybus);
  boost::shared_ptr<gridpack::math::Matrix> prefy11X(solver1.solve(*Y_cDense));
  timer->stop(t_solve);
  ///branchIO.header("\n=== prefy11X: ============\n");
  ///prefy11X->print(); 
  
  //-----------------------------------------------------------------------
  // Compute prefy11
  //-----------------------------------------------------------------------
  // Form reduced admittance matrix prefy11: prefy11 = Y_b * X
  timer->start(t_matmul);
  boost::shared_ptr<gridpack::math::Matrix> prefy11(multiply(*Y_b, *prefy11X)); 
  timer->stop(t_matmul);
  // Update prefy11: prefy11 = Y_a + prefy11
  prefy11->add(*Y_a);
  ///branchIO.header("\n=== Reduced Ybus: prefy11: ============\n");
  ///prefy11->print();

  //-----------------------------------------------------------------------
  // Compute fy11
  // Update ybus values at fault stage
  //-----------------------------------------------------------------------
  // Read the switch info from faults Event from input.xml
  int sw2_2 = faults[0].from_idx - 1;
  int sw3_2 = faults[0].to_idx - 1;

  boost::shared_ptr<gridpack::math::Matrix> fy11ybus(prefy11ybus->clone());
  ///branchIO.header("\n=== fy11ybus(original): ============\n");
  ///fy11ybus->print();
  gridpack::ComplexType x(0.0, -1e7);
  timer->start(t_matset);
  factory.setEvent(faults[0]);
  factory.setMode(onFY);
  ybusMap.overwriteMatrix(fy11ybus);
  timer->stop(t_matset);
  ///branchIO.header("\n=== fy11ybus: ============\n");
  ///fy11ybus->print();

  // Solve linear equations of fy11ybus * X = Y_c
  timer->start(t_solve);
  gridpack::math::LinearMatrixSolver solver2(*fy11ybus);
  boost::shared_ptr<gridpack::math::Matrix> fy11X(solver2.solve(*Y_cDense)); 
  timer->stop(t_solve);
  ///branchIO.header("\n=== fy11X: ============\n");
  ///fy11X->print();
  
  // Form reduced admittance matrix fy11: fy11 = Y_b * X
  timer->start(t_matmul);
  boost::shared_ptr<gridpack::math::Matrix> fy11(multiply(*Y_b, *fy11X)); 
  timer->stop(t_matmul);
  // Update fy11: fy11 = Y_a + fy11
  fy11->add(*Y_a);
  ///branchIO.header("\n=== Reduced Ybus: fy11: ============\n");
  ///fy11->print();

  //-----------------------------------------------------------------------
  // Compute posfy11
  // Update ybus values at clear fault stage
  //-----------------------------------------------------------------------
  // Get the updating factor for posfy11 stage ybus
  timer->start(t_matset);
  boost::shared_ptr<gridpack::math::Matrix> posfy11ybus(prefy11ybus->clone());
  timer->stop(t_matset);
  ///branchIO.header("\n=== posfy11ybus (original): ============\n");
  ///posfy11ybus->print();
  timer->start(t_matset);
  factory.setMode(posFY);
  ybusMap.incrementMatrix(posfy11ybus);
  timer->stop(t_matset);
  ///branchIO.header("\n=== posfy11ybus: ============\n");
  ///posfy11ybus->print();
    
  // Solve linear equations of posfy11ybus * X = Y_c
  timer->start(t_solve);
  gridpack::math::LinearMatrixSolver solver3(*posfy11ybus);
  boost::shared_ptr<gridpack::math::Matrix> posfy11X(solver3.solve(*Y_cDense)); 
  timer->stop(t_solve);
  ///branchIO.header("\n=== posfy11X: ============\n");
  ///posfy11X->print();
  
  // Form reduced admittance matrix posfy11: posfy11 = Y_b * X
  timer->start(t_matmul);
  boost::shared_ptr<gridpack::math::Matrix> posfy11(multiply(*Y_b, *posfy11X)); 
  timer->stop(t_matmul);
  // Update posfy11: posfy11 = Y_a + posfy11
  posfy11->add(*Y_a);
  ///branchIO.header("\n=== Reduced Ybus: posfy11: ============\n");
  ///posfy11->print();

  //-----------------------------------------------------------------------
  // Integration implementation (Modified Euler Method)
  //-----------------------------------------------------------------------
 
  factory.setDSParams();
  factory.setMode(Eprime0);
  gridpack::mapper::BusVectorMap<DSNetwork> Emap(network);
  boost::shared_ptr<gridpack::math::Vector> eprime_s0 = Emap.mapToVector();
  boost::shared_ptr<gridpack::math::Vector> eprime_s1(eprime_s0->clone());
  boost::shared_ptr<gridpack::math::Vector> curr(eprime_s0->clone());

  timer->start(t_trans);
  boost::shared_ptr<gridpack::math::Matrix> trans_prefy11(transpose(*prefy11));
  boost::shared_ptr<gridpack::math::Matrix> trans_fy11(transpose(*fy11));
  boost::shared_ptr<gridpack::math::Matrix> trans_posfy11(transpose(*posfy11));
  timer->stop(t_trans);

  // Simulation related variables
  int simu_k;
  int t_step[20];
  double t_width[20];
  int flagF;
  int S_Steps;
  int last_S_Steps;
  int steps3, steps2, steps1;
  double h_sol1, h_sol2;
  int flagF1, flagF2;
  int I_Steps;

  const double sysFreq = 60.0;
  double pi = 4.0*atan(1.0);
  const double basrad = 2.0 * pi * sysFreq;
  gridpack::ComplexType jay(0.0, 1.0);

  // switch info is set up here 
  int nswtch = 4;
  static double sw1[4];
  static double sw7[4];
  sw1[0] = 0.0;
  sw1[1] = faults[0].start;
  sw1[2] = faults[0].end;
  sw1[3] = sim_time;
  sw7[0] = time_step;
  sw7[1] = faults[0].step;
  sw7[2] = time_step;
  sw7[3] = time_step;
  simu_k = 0; 
  for (int i = 0; i < nswtch-1; i++) {
    t_step[i] = (int) ((sw1[i+1] -sw1[i]) / sw7[i]);   
    t_width[i] = (sw1[i+1] - sw1[i]) / t_step[i];
    simu_k += t_step[i];
  }
  simu_k++;

  steps3 = t_step[0] + t_step[1] + t_step[2] - 1;
  steps2 = t_step[0] + t_step[1] - 1;
  steps1 = t_step[0] - 1;
  h_sol1 = t_width[0];
  h_sol2 = h_sol1;
  flagF1 = 0; 
  flagF2 = 0; 
  S_Steps = 1; 
  last_S_Steps = -1;

  for (I_Steps = 0; I_Steps < simu_k+1; I_Steps++) {
    if (I_Steps < steps1) {
      S_Steps = I_Steps;
      flagF1 = 0;
      flagF2 = 0;
    } else if (I_Steps == steps1) { 
      S_Steps = I_Steps;
      flagF1 = 0;
      flagF2 = 1;
    } else if (I_Steps == steps1+1) {
      S_Steps = I_Steps;
      flagF1 = 1;
      flagF2 = 1;
    } else if ((I_Steps>steps1+1) && (I_Steps<steps2+1)) {
      S_Steps = I_Steps - 1;
      flagF1 = 1;
      flagF2 = 1;
    } else if (I_Steps==steps2+1) {
      S_Steps = I_Steps - 1;
      flagF1 = 1;
      flagF2 = 2;
    } else if (I_Steps==steps2+2) {
      S_Steps = I_Steps - 1;
      flagF1 = 2;
      flagF2 = 2;
    } else if (I_Steps>steps2+2) {
      S_Steps = I_Steps - 2;
      flagF1 = 2;
      flagF2 = 2;
    }

    if (I_Steps !=0 && last_S_Steps != S_Steps) {
      factory.initDSStep(false);
    } else {
      factory.initDSStep(true);
    }
    factory.setMode(Eprime0);
    Emap.mapToVector(eprime_s0);
     
    // ---------- CALL i_simu_innerloop(k,S_Steps,flagF1): ----------
    int t_trnsmul = timer->createCategory("Transpose Multiply");
    timer->start(t_trnsmul);
    if (flagF1 == 0) {
      curr.reset(multiply(*trans_prefy11, *eprime_s0)); //MatMultTranspose(prefy11, eprime_s0, curr);
      //transposeMultiply(*prefy11,*eprime_s0,*curr);
    } else if (flagF1 == 1) {
      curr.reset(multiply(*trans_fy11, *eprime_s0)); //MatMultTranspose(fy11, eprime_s0, curr);
      //transposeMultiply(*fy11,*eprime_s0,*curr);
    } else if (flagF1 == 2) {
      curr.reset(multiply(*trans_posfy11, *eprime_s0)); //MatMultTranspose(posfy11, eprime_s0, curr);
      //transposeMultiply(*posfy11,*eprime_s0,*curr);
    } 
    timer->stop(t_trnsmul);
    
    factory.setMode(Current);
    Emap.mapToBus(curr);
    factory.predDSStep(h_sol1);
    factory.setMode(Eprime1);
    Emap.mapToVector(eprime_s1);

    // ---------- CALL i_simu_innerloop2(k,S_Steps+1,flagF2): ----------
    timer->start(t_trnsmul);
    if (flagF2 == 0) {
      curr.reset(multiply(*trans_prefy11, *eprime_s1)); //MatMultTranspose(prefy11, eprime_s1, curr);
      //transposeMultiply(*prefy11,*eprime_s1,*curr);
    } else if (flagF2 == 1) {
      curr.reset(multiply(*trans_fy11, *eprime_s1)); //MatMultTranspose(fy11, eprime_s1, curr);
      //transposeMultiply(*fy11,*eprime_s1,*curr);
    } else if (flagF2 == 2) {
      curr.reset(multiply(*trans_posfy11, *eprime_s1)); //MatMultTranspose(posfy11, eprime_s1, curr);
      //transposeMultiply(*posfy11,*eprime_s1,*curr);
    }
    timer->stop(t_trnsmul);

    factory.setMode(Current);
    Emap.mapToBus(curr);
    factory.corrDSStep(h_sol2);

    // Print to screen
    if (last_S_Steps != S_Steps) {
      //sprintf(ioBuf, "\n========================S_Steps = %d=========================\n", S_Steps);
      //busIO.header(ioBuf);
      //mac_ang_s0->print();  
      //mac_spd_s0->print();  
      //pmech->print();
      //pelect->print();
      //sprintf(ioBuf, "========================End of S_Steps = %d=========================\n\n", S_Steps);
      //busIO.header(ioBuf);
    }
    if (I_Steps == simu_k) {
      sprintf(ioBuf, "\n========================S_Steps = %d=========================\n",
          S_Steps+1);
      busIO.header(ioBuf);
      sprintf(ioBuf, "\n         Bus ID     Generator ID"
          "    mac_ang         mac_spd         mech            elect\n\n");
      busIO.header(ioBuf);
      //mac_ang_s1->print();  
      //mac_spd_s1->print();  
      //pmech->print();
      //pelect->print();
      busIO.write();
      sprintf(ioBuf, "\n========================End of S_Steps = %d=========================\n\n",
          S_Steps+1);
      busIO.header(ioBuf);
    } // End of Print to screen 
    
    last_S_Steps = S_Steps;
  }
  timer->stop(t_total);
  timer->dump();
}