Example #1
0
/*b_prime copies the arrays pointed to by *x and *y to std::vectors iks, yps of type
Eigen::Vector3cd, respectively
After this the Multiplication of the Laplace takes place. Result is stored
in yps, which then is written to the array at *y again. */
static void b_prime(int nx,const PetscScalar *x,PetscScalar *y) {
  const int V3 = pars -> get_int("V3");
  const double LAM_L = pars -> get_float("lambda_l");
  //define vectors
  std::vector<Eigen::Vector3cd> iks(V3, Eigen::Vector3cd::Zero());
  std::vector<Eigen::Vector3cd> yps(V3, Eigen::Vector3cd::Zero());

  #pragma omp parallel
  {
    Eigen::Vector3cd tmp_x, tmp_y;
    //copy read in vectors x and y to vectors of 3cd vectors
    #pragma omp for
    for(unsigned i = 0; i < V3; ++i) {
      tmp_x << x[3*i], x[3*i+1], x[3*i+2];
      tmp_y << y[3*i], y[3*i+1], y[3*i+2];
      iks[i] = tmp_x;
      yps[i] = tmp_y;
    }
    //constants used often: c := -2/lambda_L
    //a := -1.
    register const double c = -2./(LAM_L);
    register const double a = -1.;
    #pragma omp for
    for ( int k = 0; k < V3; ++k) {
      yps[k] = c * ( (ts -> get_gauge(k,0)) * iks.at( lookup -> get_up(k,0) )
               + ( (ts -> get_gauge( lookup -> get_dn(k,0), 0)).adjoint())
               * iks.at( lookup -> get_dn(k,0) ) 
               + (ts -> get_gauge(k,1)) * iks.at( lookup -> get_up(k,1) )
               + (ts -> get_gauge( lookup -> get_dn(k,1),1).adjoint()) 
               * iks.at( lookup -> get_dn(k,1) )
               + ts -> get_gauge(k,2) * iks.at( lookup -> get_up(k,2) )
               + (ts -> get_gauge( lookup -> get_dn(k, 2), 2).adjoint())
               * iks.at( lookup -> get_dn(k,2) )
               - 6.0 * (iks.at(k))) + a * (iks.at(k));
    }
    //copy vectors back to Petsc-arrays
    #pragma omp for
    for(unsigned j = 0; j < V3; ++j) {
      y[3*j] = (yps[j])(0);
      y[3*j+1] = (yps[j])(1);
      y[3*j+2] = (yps[j])(2);
    }
  }
}
Example #2
0
/*tv copies the arrays pointed to by *x and *y to std::vectors iks, yps of type
Eigen::Vector3cd, respectively
After this the Multiplication of the Laplace takes place. Result is stored
in yps, which then is written to the array at *y again. */
static void tv2(int nx,const PetscScalar *x,PetscScalar *y) {
  const int V3 = pars -> get_int("V3");
  const double LAM_L = pars -> get_float("lambda_l");
  const double LAM_C = pars -> get_float("lambda_c");
  //define vectors
  std::vector<Eigen::Vector3cd> iks(V3, Eigen::Vector3cd::Zero());
  std::vector<Eigen::Vector3cd> yps(V3, Eigen::Vector3cd::Zero());
  //iks.clear();
  //yps.clear();
  //Eigen::Vector3cd tmp_x, tmp_y;
  omp_set_num_threads(pars -> get_int("OMP_THRDS"));
  //std::cout << "Calculating with " << omp_get_num_threads() << " threads" << std::endl;
  #pragma omp parallel
  {
  Eigen::Vector3cd tmp_x, tmp_y;
  //copy read in vectors x and y to vectors of 3cd vectors
  #pragma omp for
  for(unsigned i = 0; i < V3; ++i) {
    tmp_x << x[3*i], x[3*i+1], x[3*i+2];
    tmp_y << y[3*i], y[3*i+1], y[3*i+2];
    iks[i] = tmp_x;
    yps[i] = tmp_y;
  }
//  for (unsigned i = 0; (i+3) <= 3*V3 ; i += 3){
//    //Eigen::Vector3cd tmp_x;
//    //Eigen::Vector3cd tmp_y;
//    tmp_x << x[i], x[i+1], x[i+2];
//    tmp_y << y[i], y[i+1], y[i+2];
//    iks.push_back(tmp_x);
//    yps.push_back(tmp_y);
//  }
  //constants used often: c := 2/ (lambda_L - lambda_C) 
  //a := 1+2*lambda_C / (lambda_L - lambda_C)
  register const double c = 2./(LAM_L - LAM_C);
  register const double a = 1 + c * LAM_C;
  //these disable chebyshev acceleration:
  //register const double c = 1;
  //register const double a = 0;
  //Laplace times vector in terms of Eigen::3cd
  //for ( int k = 0; k < V3; ++k ) yps.at(k) = Eigen::Vector3cd::Zero();
  #pragma omp for
//  {
  for ( int k = 0; k < V3; ++k) {
    /*if (k == 0) {
      yps.at(k) = -(U[k][0]*iks.at( up_3d[k][0] ) + (U[ down_3d[k][0] ][0].adjoint())
                  * iks.at( down_3d[k][0] ) + U[k][1] * iks.at( up_3d[k][1] )
                  + (U[ down_3d[k][1] ][1].adjoint()) * iks.at( down_3d[k][1] )
                  + U[k][2] * iks.at( up_3d[k][2] )
                  + (U[ down_3d[k][2] ][2].adjoint()) * iks.at( down_3d[k][2] )
                  - 200.0 * (iks.at(k)));
    }*/
    //else {
    yps[k] = c * ( (ts -> get_gauge(k,0)) * iks.at( lookup -> get_up(k,0) )
             + ( (ts -> get_gauge( lookup -> get_dn(k,0), 0)).adjoint())
             * iks.at( lookup -> get_dn(k,0) ) 
             + (ts -> get_gauge(k,1)) * iks.at( lookup -> get_up(k,1) )
             + (ts -> get_gauge( lookup -> get_dn(k,1),1).adjoint()) 
             * iks.at( lookup -> get_dn(k,1) )
             + ts -> get_gauge(k,2) * iks.at( lookup -> get_up(k,2) )
             + (ts -> get_gauge( lookup -> get_dn(k, 2), 2).adjoint())
             * iks.at( lookup -> get_dn(k,2) )
             - 6.0 * (iks.at(k))) + a * (iks.at(k));
//    yps.at(k) = c * (eigen_timeslice[k][0]*iks.at( up_3d[k][0] ) + (eigen_timeslice[ down_3d[k][0] ][0].adjoint())
//              * iks.at( down_3d[k][0] ) + eigen_timeslice[k][1] * iks.at( up_3d[k][1] )
//              + (eigen_timeslice[ down_3d[k][1] ][1].adjoint()) * iks.at( down_3d[k][1] )
//              + eigen_timeslice[k][2] * iks.at( up_3d[k][2] )
//              + (eigen_timeslice[ down_3d[k][2] ][2].adjoint()) * iks.at( down_3d[k][2] )
//              - 6.0 * (iks.at(k))) + a * (iks.at(k));
//    std::cout << U[k][0] << " " << down_3d[k][0] << " " << up_3d[k][1] << " " << down_3d[k][1] << " " << up_3d[k][2] << " " << down_3d[k][2] << std::endl;
    //}
  }
//  }
  //copy vectors back to Petsc-arrays
  #pragma omp for
  for(unsigned j = 0; j < V3; ++j) {
    y[3*j] = (yps[j])(0);
    y[3*j+1] = (yps[j])(1);
    y[3*j+2] = (yps[j])(2);
  }
  }
//  int k = 0;
//  for (int j = 0; j < V3; j++) {
//    y[k] = (yps.at(j))(0);
//    y[k+1] = (yps.at(j))(1);
//    y[k+2] = (yps.at(j))(2);
//    k += 3;
//  }
}