@Override
 public void printInputData(String fileName) {
   try {
     lpsolver.writeLp(fileName);
     OPFLogger.getLogger().info("The input data model has been saved to: " + fileName);
   } catch (LpSolveException e) {
     OPFLogger.getLogger().severe(e.toString());
     // e.printStackTrace();
   }
 }
 @Override
 public void debug(String file) {
   OPFLogger.getLogger().info("Running DCOPF debug mode for LP solver...");
   this.build(cstContainer);
   try {
     outputMatrix(file);
     OPFLogger.getLogger().info("Output file for debug purpose has been saved to: " + file);
   } catch (Exception e) {
     OPFLogger.getLogger().severe(e.toString());
     // e.printStackTrace();
   }
 }
  @Override
  public void build(List<OpfConstraint> cstContainer) {

    new ActivePowerEqnConstraintCollector(opfNet, cstContainer).collectConstraint();

    new LineMwFlowConstraintCollector(opfNet, cstContainer).collectConstraint();

    new GenMwOutputConstraintCollector(opfNet, cstContainer).collectConstraint();

    new BusMinAngleConstraintCollector(opfNet, cstContainer, BusAngleLimit).collectConstraint();

    lpsolver.setAddRowmode(true);

    new LpsolveSolverInputBuilder(cstContainer).buildInput(lpsolver);

    LpsolveSolverObjectiveFunctionCollector objBuilder =
        new LpsolveSolverObjectiveFunctionCollector(opfNet);
    try {
      objBuilder.processGenCostFunction(lpsolver);
      // int refineNum = 2;
      objBuilder.genCostFunctionRefinement(lpsolver);
    } catch (LpSolveException e) {
      OPFLogger.getLogger().severe(e.toString());
      e.printStackTrace();
    }

    lpsolver.setAddRowmode(false);
  }
  private void writeMatlabInputFile(
      String file,
      ArrayRealVector f,
      Array2DRowRealMatrix Aeq,
      ArrayRealVector beq,
      Array2DRowRealMatrix Aiq,
      ArrayRealVector biq,
      ArrayRealVector ub,
      ArrayRealVector lb)
      throws IOException {

    FileWriter fstream = new FileWriter(file);
    BufferedWriter out = new BufferedWriter(fstream);
    try {
      helper.writeVector(out, f, "f=[ ");
      helper.writeMatrix(out, Aeq, "Aeq=[");
      helper.writeVector(out, beq, "beq=[ ");
      helper.writeMatrix(out, Aiq, "Aiq=[");
      helper.writeVector(out, biq, "biq=[ ");
      helper.writeVector(out, lb, "lb=[ ");
      helper.writeVector(out, ub, "ub=[ ");
      String linprog = "x = linprog(f,Aiq,biq,Aeq,beq,lb,ub);";
      out.append(linprog);
    } catch (Exception e) {
      OPFLogger.getLogger().severe(e.toString());
      // e.printStackTrace();
    }

    out.close();
  }
 private void setVarName(LpSolve lpsolver) {
   int busIdx = 1;
   int genIndex = 1;
   try {
     for (Bus b : opfNet.getBusList()) {
       lpsolver.setColName(busIdx + this.numOfGen, "x" + (b.getSortNumber() + 1));
       if (opfNet.isOpfGenBus(b)) {
         lpsolver.setColName(genIndex, "Pg" + (b.getSortNumber() + 1));
         lpsolver.setColName(genIndex + this.numOfVar, "y" + (b.getSortNumber() + 1));
         genIndex++;
       }
       busIdx++;
     }
   } catch (LpSolveException e) {
     OPFLogger.getLogger().severe(e.toString());
   }
 }
  @Override
  public void calLMP() {
    int cnt = 1;
    int numOfConstraint = lpsolver.getNorigRows();
    int numOfVar = lpsolver.getNcolumns();
    double[] shadowPrice = new double[numOfConstraint + numOfVar + 1];
    try {
      lpsolver.getDualSolution(shadowPrice);
    } catch (LpSolveException e) {
      OPFLogger.getLogger().severe(e.toString());
    }

    double baseMVA = opfNet.getBaseKva() / 1000.0;
    double lmp = 0;
    for (Bus b : opfNet.getBusList()) {
      OpfBus bus1 = (OpfBus) b;
      lmp = Math.abs(shadowPrice[cnt++]);
      bus1.setLMP(lmp / baseMVA);
    }
  }
  @Override
  public boolean solve() {
    OPFLogger.getLogger().info("Running DC Optimal Power Flow Using LP solver....");
    Long startTime = System.currentTimeMillis();
    this.build(cstContainer);
    int ret = 0;
    lpsolver.setMinim();
    lpsolver.setVerbose(LpSolve.IMPORTANT);

    try {
      ret = lpsolver.solve();
    } catch (LpSolveException e) {
      OPFLogger.getLogger().severe(e.toString());
    }

    if (ret == LpSolve.OPTIMAL) ret = 0;
    else OPFLogger.getLogger().severe(this.retriveSolutionInfo(ret));

    if (ret == 0) {
      this.isSolved = true;
      Long endTime = System.currentTimeMillis();
      Long duration = endTime - startTime;
      OPFLogger.getLogger().info("Optimization terminated.");
      OPFLogger.getLogger()
          .info("Converged in " + OpfDataHelper.round(duration, 3) + " milliseconds.");
      try {
        ofv = lpsolver.getObjective(); // in $/(pu*h)			
        int xsize = lpsolver.getNcolumns();
        optimX = new double[xsize];
        lpsolver.getVariables(optimX);
        // attach result to network
        this.attachedResult();
        this.calLMP();
      } catch (LpSolveException e) {
        OPFLogger.getLogger().severe(e.toString());
      }
    }
    return isSolved;
  }