void SPHSolver::SetupCUDASolver()
{
	//Generate the CUDA buffer
	GenerateCUDABuffer();
	//Setup an CUDA stuff
	SetupCUDA(mTotalParticles,sizeof(Fluid));
    SetupSolver(mSmoothRadius, mTotalParticles);
	//Transfer to CUDA
	TransferToCUDA(mPartBuffer,mTotalParticles,sizeof(Fluid));

}
//=======================================================
int EpetraExt_HypreIJMatrix::Solve(bool Upper, bool transpose, bool UnitDiagonal, const Epetra_MultiVector & X, Epetra_MultiVector & Y) const {
  bool SameVectors = false;
  int NumVectors = X.NumVectors();
  if (NumVectors != Y.NumVectors()) return -1;  // X and Y must have same number of vectors
  if(X.Pointers() == Y.Pointers()){
    SameVectors = true;
  }
  if(SolveOrPrec_ == Solver){
    if(IsSolverSetup_[0] == false){
      SetupSolver();
    }
  } else {
    if(IsPrecondSetup_[0] == false){
      SetupPrecond();
    }
  }
  for(int VecNum = 0; VecNum < NumVectors; VecNum++) {
    //Get values for current vector in multivector.
    double * x_values;
    EPETRA_CHK_ERR((*X(VecNum)).ExtractView(&x_values));
    double * y_values;
    if(!SameVectors){
      EPETRA_CHK_ERR((*Y(VecNum)).ExtractView(&y_values));
    } else {
      y_values = new double[X.MyLength()];
    }
    // Temporarily make a pointer to data in Hypre for end
    double *x_temp = x_local->data; 
    // Replace data in Hypre vectors with epetra values
    x_local->data = x_values;
    double *y_temp = y_local->data;
    y_local->data = y_values;
    
    EPETRA_CHK_ERR(HYPRE_ParVectorSetConstantValues(par_y, 0.0));
    if(transpose && !TransposeSolve_){
      // User requested a transpose solve, but the solver selected doesn't provide one
      EPETRA_CHK_ERR(-1);
    }
    if(SolveOrPrec_ == Solver){
      // Use the solver methods
      EPETRA_CHK_ERR(SolverSolvePtr_(Solver_, ParMatrix_, par_x, par_y));
    } else {
      // Apply the preconditioner
      EPETRA_CHK_ERR(PrecondSolvePtr_(Preconditioner_, ParMatrix_, par_x, par_y));
    }
    if(SameVectors){
      int NumEntries = Y.MyLength();
      std::vector<double> new_values; new_values.resize(NumEntries);
      std::vector<int> new_indices; new_indices.resize(NumEntries);
      for(int i = 0; i < NumEntries; i++){
        new_values[i] = y_values[i];
        new_indices[i] = i;
      }
      EPETRA_CHK_ERR((*Y(VecNum)).ReplaceMyValues(NumEntries, &new_values[0], &new_indices[0]));
      delete[] y_values;
    }
    x_local->data = x_temp;
    y_local->data = y_temp;
  }
  double flops = (double) NumVectors * (double) NumGlobalNonzeros();
  UpdateFlops(flops);
  return 0;
} //Solve()