Пример #1
0
void EigsGen::findMatchedIndex(const Eigen::VectorXcd &target,
                               const Eigen::VectorXcd &collection,
                               Eigen::VectorXi &result)
{
    int nfound = 0;
    int maxn = target.size();
    if(result.size() < maxn)
        result.resize(maxn);
    for(int i = 0; i < collection.size(); i++)
    {
        int j;
        for(j = 0; j < maxn; j++)
        {
            if(abs(collection[i] - target[j]) < 1e-8 * abs(target[j]))
                break;
        }
        if(j < maxn)
        {
            result[nfound] = i;
            nfound++;
            if(collection[i].imag() != 0)
            {
                i++;
                result[nfound] = i;
                nfound++;
            }
        }
        if(nfound >= maxn)  break;
    }
    if(result.size() > nfound)
        result.conservativeResize(nfound);
}
Пример #2
0
Файл: A1.cpp Проект: nMerlin/CP
//Main-Function
int main () {
	double xiMax = 10;
	double xiMin = -10;
	double deltaXi = 0.1;
	double deltaT = 0.05;
	double mittelWert = 0, mittelWert2 = 0;
	double impuls = 0, impuls2 = 0;
	int cn = floor(10./deltaT+0.5);
	int iN = 0;
	std::complex<double> c_i = (0,1);
	
	Eigen::MatrixXcd Sh = S_H(deltaT, &H, deltaXi, xiMax, xiMin);
	Eigen::VectorXcd xi = init(xiMax, xiMin, deltaXi);
	Eigen::VectorXcd xi_n = xi;
	Eigen::VectorXcd xi_temp;
	
	//Dateistreams für geforderte Ausgabe-Plots
	std::ofstream datei("A1d_Normierung.dat");
	std::ofstream datei2("A1f.dat");
	
	//Anwenden des Zeitentwicklungsoperators bis t=10
	for (int i = 0; i < cn; i++) {
		xi_n = Sh*xi_n;
		datei << i*deltaT << " " << Norm(xi_n) << std::endl;
		
		//Animationssequenz
		//if (i%2 == 0) {
		//	SchreibeZustand(xi_n, "A1d_Animation_"+convertInt(i/2));
		//}
		
		//Mittelwert des Ortes und des Impulses
		for (int j = 0; j < xi.size(); j++) {
			iN = j - floor(xi.size()/2);
			mittelWert += iN*deltaXi*abs(xi_n(j))*abs(xi_n(j));
			mittelWert2 += (iN*deltaXi)*(iN*deltaXi)*abs(xi_n(j))*abs(xi_n(j));
			impuls += abs(xi_n(j)*(-c_i)*Ableitung(xi_n, j, deltaXi));
			impuls2 += abs(xi_n(j)*(-1.)*Ableitung2(xi_n, j, deltaXi));
		}
		datei2 << i*deltaT << " " << mittelWert << " " << (mittelWert2 - mittelWert*mittelWert) << " " << impuls << " " << impuls2 << std::endl;
		mittelWert = 0;
		mittelWert2 = 0;
		impuls = 0;
		impuls2 = 0;
	}
	
	datei.close();
	datei2.close();
	
	SchreibeZustand(xi_n, "A1d_Zustand");
	
	return 0;	
}
Пример #3
0
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void LapH::OperatorsForMesons::build_vdaggerv(const std::string& filename) {

  clock_t t2 = clock();
  const size_t dim_row = 3*Lx*Ly*Lz;
  const size_t id_unity = operator_lookuptable.index_of_unity;

  // resizing each matrix in vdaggerv
  // TODO: check if it is better to use for_each and resize instead of std::fill
  std::fill(vdaggerv.origin(), vdaggerv.origin() + vdaggerv.num_elements(), 
            Eigen::MatrixXcd::Zero(nb_ev, nb_ev));

#pragma omp parallel
{
  Eigen::VectorXcd mom = Eigen::VectorXcd::Zero(dim_row);
  LapH::EigenVector V_t(1, dim_row, nb_ev);// each thread needs its own copy
  #pragma omp for schedule(dynamic)
  for(size_t t = 0; t < Lt; ++t){

    // creating full filename for eigenvectors and reading them in
    char inter_name[200];
    sprintf(inter_name, "%s%03d", filename.c_str(), (int) t);
    //avoid reading eigenvectors for now, since no displacement or momentum is
    //used
    //V_t.read_eigen_vector(inter_name, 0, 0); // reading eigenvectors

    // VdaggerV is independent of the gamma structure and momenta connected by
    // sign flip are related by adjoining VdaggerV. Thus the expensive 
    // calculation must only be performed for a subset of quantum numbers given
    // in op_VdaggerV.
    for(const auto& op : operator_lookuptable.vdaggerv_lookup){
      // For zero momentum and displacement VdaggerV is the unit matrix, thus
      // the calculation is not performed
      if(op.id != id_unity){
        // momentum vector contains exp(-i p x). Divisor 3 for colour index. 
        // All three colours on same lattice site get the same momentum.
        for(size_t x = 0; x < dim_row; ++x) {
          mom(x) = momentum[op.id][x/3];
        }
        vdaggerv[op.id][t] = V_t[0].adjoint() * mom.asDiagonal() * V_t[0];
      }
      else // zero momentum
        vdaggerv[op.id][t] = Eigen::MatrixXcd::Identity(nb_ev, nb_ev);
    }
  } // loop over time
}// pragma omp parallel ends here

  t2 = clock() - t2;
  std::cout << std::setprecision(1) << "\t\t\tSUCCESS - " << std::fixed 
    << ((float) t2)/CLOCKS_PER_SEC << " seconds" << std::endl;
  is_vdaggerv_set = true;

}
Пример #4
0
Файл: A1.cpp Проект: nMerlin/CP
//Norm eines Zustands
double Norm(Eigen::VectorXcd xi) {
	double summe = 0;
	int n_max = xi.size();
	for (int i = 0; i < n_max; i++) {
		summe += abs(xi(i))*abs(xi(i));	
	}
	return summe;	
}
Пример #5
0
Файл: A1.cpp Проект: nMerlin/CP
//Zustandsvektor in Datei schreiben
void SchreibeZustand(Eigen::VectorXcd xi, std::string name) {
	int n_max = xi.size();
	std::ofstream datei(name + ".dat");
	for (int i = 0; i < n_max; i++) {
		datei << (i - floor(n_max/2)) << " " << abs(xi(i))*abs(xi(i)) << std::endl;	
	}
	datei.close();
}
Пример #6
0
// Calculates U_mu^dagger(x-\hat{mu})V(x-\hat{\mu})
Eigen::MatrixXcd GaugeField::backward_uv(const Eigen::VectorXcd &v,
                                         const ssize_t t,
                                         const int spatial_ind,
                                         const int direction) const {
  int down_ind = idown[spatial_ind][direction];

  return (tslices.at(t))[down_ind][direction].adjoint() * v.segment(3 * down_ind, 3);
}
Пример #7
0
// Calculates U_mu(x)V(x+\hat{\mu})
Eigen::MatrixXcd GaugeField::forward_uv(const Eigen::VectorXcd &v,
                                        const ssize_t t,
                                        const int spatial_ind,
                                        const int direction) const {
  int up_ind = iup[spatial_ind][direction];

  return (tslices.at(t))[spatial_ind][direction] * v.segment(3 * up_ind, 3);
}
Пример #8
0
Файл: A1.cpp Проект: nMerlin/CP
//Ableitung der Wellenfunktion an der Stelle n
std::complex<double> Ableitung(Eigen::VectorXcd xi, int n, double deltaXi) {
	int laenge = xi.size();
	
	if (n == 0) {
		return (xi(1)-xi(0))/(deltaXi);
	} else if (n == (laenge-1)) {
		return (xi(laenge-1) - xi(laenge-2))/(deltaXi);
	} else {
		return (xi(n+1)-xi(n-1))/(2.*deltaXi);
	}	
}
Пример #9
0
unsigned int Model::check_feedback_matrix(Eigen::MatrixXd &S) {

  Eigen::VectorXcd eigenvalues = S.eigenvalues();
  Eigen::VectorXd real = eigenvalues.real();
  Eigen::VectorXd imag = eigenvalues.imag();

  double magnitude, max_magnitude = 0;
  for (unsigned int i = 0; i < n_alternatives; i++) {
    magnitude = sqrt(real(i) * real(i) + imag(i) * imag(i));
    if (magnitude > max_magnitude) {
      max_magnitude = magnitude;
    }
  }

  // unsigned int res = 1;
  unsigned int res = 0;
  if (max_magnitude < 1) {
    res = 0;
  }

  return res;
}
Пример #10
0
// partial reorthogonalization
double                  EigenTriangle::solve(int maxIter, double tol)
{
    int n = graph -> VertexCount();
    srand(time(0));
    if (maxIter > n)
        maxIter = n;
    double na = adjMatrix.norm();
    double phi = tol * na;
    double delta = tol * sqrt(na);
    vector<Triplet<double> > omega_vector;
    //MatrixXd omega = MatrixXd::Zero(n + 2, n + 2);
    for (int i = 0; i < n + 2; i ++)
    {
        //omega(i, i - 1) = phi;
        if (i > 0)
            omega_vector.push_back(Triplet<double>(i, i - 1, phi)); 
        omega_vector.push_back(Triplet<double>(i, i, 1));
    }
    omega.resize(n + 2, n + 2);
    omega.setFromTriplets(omega_vector.begin(), omega_vector.end());
    //std::cout << omega << std::endl; 
    vector<SparseVector<double> > v;
    //v.push_back(SparseVector::Random(n));
    SparseVector<double> firstV(n);
    for (int i = 0; i < 100; i ++)
        firstV.coeffRef(i % n) = i;
    v.push_back(firstV);
    v[0] /= v[0].norm();
    VectorXd alpha(n);
    VectorXd beta(n + 1);
    beta[0] = 0;
    SparseVector<double> w;
    bool flag = false;
    int num = 0;    // reorthogonalization times
    int last = -1;
    for (int i = 0; i < maxIter; i ++)
    {
        if ((i + 1) * 100 / maxIter > last)
        {
            last = (i + 1) * 100 / maxIter;
            std::cout << "\r" << "[EigenTriangle] Processing " << last << "% ..." << std::flush;
        }
        //printf("== Iter %d ===\n", i);
        w = adjMatrix * v[i];
        alpha.coeffRef(i) = w.dot(v[i]);
        if (i == maxIter - 1)
            break;
        w -= alpha[i] * v[i];
        if (i > 0)
            w -= beta[i] * v[i - 1];
        beta[i + 1] = w.norm();
        v.push_back(w / beta[i + 1]);
        if (flag)
        {
            flag = false;
            for (int j = 0; j <= i; j ++)
                v[i + 1] -= v[j].dot(v[i + 1]) * v[j];
            for (int j = 0; j <= i; j ++)
                omega.coeffRef(i + 1, j) = phi;
            //for (int j = 0; j <= i; j ++)
            //    printf("%.5lf\n", v[i + 1].dot(v[j]));
        }
        else
        {
            omega.coeffRef(i + 1, 0) = 0.0;
            if (i > 0)
            {
                omega.coeffRef(i + 1, 0) = 1.0 / beta(i) * ((alpha(0) - alpha(i)) * omega.coeffRef(i, 0) - beta(i - 1) * omega.coeffRef(i - 1, 0)) + delta;
            }
            for (int j = 1; j <= i; j ++)
            {
                omega.coeffRef(i + 1, j) = 1.0 / beta(i) * (beta(j) * omega.coeffRef(i, j + 1) + (alpha(j) - alpha(i)) * omega.coeffRef(i, j) - beta(j - 1) * omega.coeffRef(i, j - 1) - beta(i - 1) * omega.coeffRef(i - 1, j)) + delta;
            }
        }
        double mx = 0.0;
        for (int j = 0; j <= i; j ++)
            if (mx < fabs(omega.coeffRef(i + 1, j)))
                mx = fabs(omega.coeffRef(i + 1, j));
        if (mx > sqrt(tol))
        {
            for (int j = 0; j <= i; j ++)
                omega.coeffRef(i + 1, j) = phi;
            num ++;
            for (int j = 0; j <= i; j ++)
                v[i + 1] -= v[i + 1].dot(v[j]) * v[j];
            flag = true;
        }
    }
    printf("\n");
    int k = maxIter;
    MatrixXd T = MatrixXd::Zero(k, k);
    for (int i = 0; i < k; i ++)
    {
        T(i, i) = alpha[i];
        if (i < k - 1)
            T(i, i + 1) = beta[i + 1];
        if (i > 0)
            T(i, i - 1) = beta[i];
    }
    //std::cout << T << std::endl;

    Eigen::EigenSolver<MatrixXd> eigenSolver;
    eigenSolver.compute(T, false);
    Eigen::VectorXcd eigens = eigenSolver.eigenvalues();
    double res = 0;
    for (int i = 0; i < eigens.size(); i ++)
    {
        std::complex<double> tmp = eigens[i];
        res += pow(tmp.real(), 3) / 6;
        std::cout << i << ": " << tmp << std::endl;
    }
    //res /= 6;
    return res;
}
Пример #11
0
// full reorthogonalization
double                  EigenTriangle::solve(int maxIter)
{
    int n = graph -> VertexCount();
    srand(time(0));
    // check if rows == cols()
    if (maxIter > n)
        maxIter = n;
    vector<VectorXd> v;
    v.push_back(VectorXd::Random(n));
    v[0] = v[0] / v[0].norm();
    VectorXd alpha(n);
    VectorXd beta(n + 1);
    beta[0] = 0;
    VectorXd w;
    int last = 0;
    printf("%d\n", maxIter);
    for (int i = 0; i < maxIter; i ++)
    {
        if (i * 100 / maxIter > last + 10 || i == maxIter - 1)
        {
            last = (i + 1) * 100 / maxIter;
            std::cout << "\r" << "[EigenTriangle] Processing " << last << "% ..." << std::flush;
        }
        w = adjMatrix * v[i];
        alpha[i] = w.dot(v[i]);
        if (i == maxIter - 1)
            break;
        w -= alpha[i] * v[i];
        if (i > 0)
            w -= beta[i] * v[i - 1];
        beta[i + 1] = w.norm();
        v.push_back(w / beta[i + 1]);
        for (int j = 0; j <= i; j ++)
        {
            v[i + 1] = v[i + 1] - v[i + 1].dot(v[j]) * v[j];
        }
    }
    printf("\n");
    int k = maxIter;
    MatrixXd T = MatrixXd::Zero(k, k);
    for (int i = 0; i < k; i ++)
    {
        T(i, i) = alpha[i];
        if (i < k - 1)
            T(i, i + 1) = beta[i + 1];
        if (i > 0)
            T(i, i - 1) = beta[i];
    }
    //std::cout << T << std::endl;

    Eigen::EigenSolver<MatrixXd> eigenSolver;
    eigenSolver.compute(T, /* computeEigenvectors = */ false);
    Eigen::VectorXcd eigens = eigenSolver.eigenvalues();
    double res = 0;
    for (int i = 0; i < eigens.size(); i ++)
    {
        std::complex<double> tmp = eigens[i];
        res += pow(tmp.real(), 3);
        printf("%.5lf\n", tmp.real());
    }
    res /= 6;
    return res;
}
Пример #12
0
 inline int size_zeta() const { return zeta_iz.rows(); }
void propa_2d()
{
    trace.beginBlock("2d propagation");

    typedef DiscreteExteriorCalculus<2, 2, EigenLinearAlgebraBackend> Calculus;
		typedef DiscreteExteriorCalculusFactory<EigenLinearAlgebraBackend> CalculusFactory;

    {
        trace.beginBlock("solving time dependent equation");

        const Calculus::Scalar cc = 8; // px/s
        trace.info() << "cc = " << cc << endl;

        const Z2i::Domain domain(Z2i::Point(0,0), Z2i::Point(29,29));
        const Calculus calculus = CalculusFactory::createFromDigitalSet(generateDiskSet(domain), false);

        //! [time_laplace]
        const Calculus::DualIdentity0 laplace = calculus.laplace<DUAL>() + 1e-8 * calculus.identity<0, DUAL>();
        //! [time_laplace]
        trace.info() << "laplace = " << laplace << endl;

        trace.beginBlock("finding eigen pairs");
        //! [time_eigen]
        typedef Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> EigenSolverMatrix;
        const EigenSolverMatrix eigen_solver(laplace.myContainer);

        const Eigen::VectorXd eigen_values = eigen_solver.eigenvalues();
        const Eigen::MatrixXd eigen_vectors = eigen_solver.eigenvectors();
        //! [time_eigen]
        trace.info() << "eigen_values_range = " << eigen_values.minCoeff() << "/" << eigen_values.maxCoeff() << endl;
        trace.endBlock();

        //! [time_omega]
        const Eigen::VectorXd angular_frequencies = cc * eigen_values.array().sqrt();
        //! [time_omega]

        Eigen::VectorXcd initial_wave = Eigen::VectorXcd::Zero(calculus.kFormLength(0, DUAL));
        //set_initial_phase_null(calculus, initial_wave);
        set_initial_phase_dir_yy(calculus, initial_wave);

        {
            Board2D board;
            board << domain;
            board << CustomStyle("KForm", new KFormStyle2D(-1, 1));
            board << Calculus::DualForm0(calculus, initial_wave.real());
            board.saveSVG("propagation_time_wave_initial_coarse.svg");
        }

        //! [time_init_proj]
        Eigen::VectorXcd initial_projections = eigen_vectors.transpose() * initial_wave;
        //! [time_init_proj]

        // low pass
        //! [time_low_pass]
        const Calculus::Scalar lambda_cutoff = 4.5;
        const Calculus::Scalar angular_frequency_cutoff = 2*M_PI * cc / lambda_cutoff;
        int cutted = 0;
        for (int kk=0; kk<initial_projections.rows(); kk++)
        {
            const Calculus::Scalar angular_frequency = angular_frequencies(kk);
            if (angular_frequency < angular_frequency_cutoff) continue;
            initial_projections(kk) = 0;
            cutted ++;
        }
        //! [time_low_pass]
        trace.info() << "cutted = " << cutted << "/" << initial_projections.rows() << endl;

        {
            const Eigen::VectorXcd wave = eigen_vectors * initial_projections;
            Board2D board;
            board << domain;
            board << CustomStyle("KForm", new KFormStyle2D(-1, 1));
            board << Calculus::DualForm0(calculus, wave.real());
            board.saveSVG("propagation_time_wave_initial_smoothed.svg");
        }

        const int kk_max = 60;
        trace.progressBar(0,kk_max);
        for (int kk=0; kk<kk_max; kk++)
        {
            //! [time_solve_time]
            const Calculus::Scalar time = kk/20.;
            const Eigen::VectorXcd current_projections = (angular_frequencies * std::complex<double>(0,time)).array().exp() * initial_projections.array();
            const Eigen::VectorXcd current_wave = eigen_vectors * current_projections;
            //! [time_solve_time]

            std::stringstream ss;
            ss << "propagation_time_wave_solution_" << std::setfill('0') << std::setw(3) << kk << ".svg";

            Board2D board;
            board << domain;
            board << CustomStyle("KForm", new KFormStyle2D(-1, 1));
            board << Calculus::DualForm0(calculus, current_wave.real());
            board.saveSVG(ss.str().c_str());

            trace.progressBar(kk+1,kk_max);
        }
        trace.info() << endl;

        trace.endBlock();
    }

    {
        trace.beginBlock("forced oscillations");

        const Z2i::Domain domain(Z2i::Point(0,0), Z2i::Point(50,50));
        const Calculus calculus = CalculusFactory::createFromDigitalSet(generateDiskSet(domain), false);

        const Calculus::DualIdentity0 laplace = calculus.laplace<DUAL>();
        trace.info() << "laplace = " << laplace << endl;

        trace.beginBlock("finding eigen pairs");
        typedef Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> EigenSolverMatrix;
        const EigenSolverMatrix eigen_solver(laplace.myContainer);

        const Eigen::VectorXd laplace_eigen_values = eigen_solver.eigenvalues();
        const Eigen::MatrixXd laplace_eigen_vectors = eigen_solver.eigenvectors();
        trace.info() << "eigen_values_range = " << laplace_eigen_values.minCoeff() << "/" << laplace_eigen_values.maxCoeff() << endl;
        trace.endBlock();

        Calculus::DualForm0 concentration(calculus);
        {
            const Z2i::Point point(25,25);
            const Calculus::Cell cell = calculus.myKSpace.uSpel(point);
            const Calculus::Index index = calculus.getCellIndex(cell);
            concentration.myContainer(index) = 1;
        }

        {
            Board2D board;
            board << domain;
            board << concentration;
            board.saveSVG("propagation_forced_concentration.svg");
        }

        for (int ll=0; ll<6; ll++)
        {
            //! [forced_lambda]
            const Calculus::Scalar lambda = 4*20.75/(1+2*ll);
            //! [forced_lambda]
            trace.info() << "lambda = " << lambda << endl;

            //! [forced_dalembert_eigen]
            const Eigen::VectorXd dalembert_eigen_values = (laplace_eigen_values.array() - (2*M_PI/lambda)*(2*M_PI/lambda)).array().inverse();
            const Eigen::MatrixXd concentration_to_wave = laplace_eigen_vectors * dalembert_eigen_values.asDiagonal() * laplace_eigen_vectors.transpose();
            //! [forced_dalembert_eigen]

            //! [forced_wave]
            Calculus::DualForm0 wave(calculus, concentration_to_wave * concentration.myContainer);
            //! [forced_wave]
            wave.myContainer /= wave.myContainer(calculus.getCellIndex(calculus.myKSpace.uSpel(Z2i::Point(25,25))));

            {
                trace.info() << "saving samples" << endl;
                const Calculus::Properties properties = calculus.getProperties();
                {
                    std::stringstream ss;
                    ss << "propagation_forced_samples_hv_" << ll << ".dat";
                    std::ofstream handle(ss.str().c_str());
                    for (int kk=0; kk<=50; kk++)
                    {
                        const Z2i::Point point_horizontal(kk,25);
                        const Z2i::Point point_vertical(25,kk);
                        const Calculus::Scalar xx = 2 * (kk/50. - .5);
                        handle << xx << " ";
                        handle << sample_dual_0_form<Calculus>(properties, wave, point_horizontal) << " ";
                        handle << sample_dual_0_form<Calculus>(properties, wave, point_vertical) << endl;
                    }
                }

                {
                    std::stringstream ss;
                    ss << "propagation_forced_samples_diag_" << ll << ".dat";
                    std::ofstream handle(ss.str().c_str());
                    for (int kk=0; kk<=50; kk++)
                    {
                        const Z2i::Point point_diag_pos(kk,kk);
                        const Z2i::Point point_diag_neg(kk,50-kk);
                        const Calculus::Scalar xx = 2 * sqrt(2) * (kk/50. - .5);
                        handle << xx << " ";
                        handle << sample_dual_0_form<Calculus>(properties, wave, point_diag_pos) << " ";
                        handle << sample_dual_0_form<Calculus>(properties, wave, point_diag_neg) << endl;
                    }
                }
            }

            {
                std::stringstream ss;
                ss << "propagation_forced_wave_" << ll << ".svg";
                Board2D board;
                board << domain;
                board << CustomStyle("KForm", new KFormStyle2D(-.5, 1));
                board << wave;
                board.saveSVG(ss.str().c_str());
            }
        }

        trace.endBlock();
    }
    trace.endBlock();
}
Пример #14
0
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void LapH::OperatorsForMesons::build_vdaggerv(const std::string& filename,
                                              const int config) {

  clock_t t2 = clock();
  const size_t dim_row = 3*Lx*Ly*Lz;
  const int id_unity = operator_lookuptable.index_of_unity;

  // prepare full path for writing
  char dummy_path[200];
  sprintf(dummy_path, "/%s/cnfg%04d/", path_vdaggerv.c_str(), config);
  const std::string full_path(dummy_path);
  // check if directory exists
  if(handling_vdaggerv == "write" && access(full_path.c_str(), 0 ) != 0) {
    std::cout << "\tdirectory " << full_path.c_str() 
              << " does not exist and will be created";
    boost::filesystem::path dir(full_path.c_str());
    if(!boost::filesystem::create_directories(dir))
      std::cout << "\tSuccess" << std::endl;
    else
      std::cout << "\tFailure" << std::endl;
  }

  // resizing each matrix in vdaggerv
  // TODO: check if it is better to use for_each and resize instead of std::fill
  std::fill(vdaggerv.origin(), vdaggerv.origin() + vdaggerv.num_elements(), 
            Eigen::MatrixXcd::Zero(nb_ev, nb_ev));


#pragma omp parallel
{
  Eigen::VectorXcd mom = Eigen::VectorXcd::Zero(dim_row);
  LapH::EigenVector V_t(1, dim_row, nb_ev);// each thread needs its own copy
  #pragma omp for schedule(dynamic)
  for(size_t t = 0; t < Lt; ++t){

    // creating full filename for eigenvectors and reading them in
    if(!(operator_lookuptable.vdaggerv_lookup.size() == 1 &&
       operator_lookuptable.vdaggerv_lookup[0].id == id_unity)){
      char inter_name[200];
      sprintf(inter_name, "%s%03d", filename.c_str(), (int) t);
      V_t.read_eigen_vector(inter_name, 0, 0); // reading eigenvectors
    }

    // VdaggerV is independent of the gamma structure and momenta connected by
    // sign flip are related by adjoining VdaggerV. Thus the expensive 
    // calculation must only be performed for a subset of quantum numbers given
    // in op_VdaggerV.
    for(const auto& op : operator_lookuptable.vdaggerv_lookup){
      // For zero momentum and displacement VdaggerV is the unit matrix, thus
      // the calculation is not performed
      if(op.id != id_unity){
        // momentum vector contains exp(-i p x). Divisor 3 for colour index. 
        // All three colours on same lattice site get the same momentum.
        for(size_t x = 0; x < dim_row; ++x) {
          mom(x) = momentum[op.id][x/3];
        }
        vdaggerv[op.id][t] = V_t[0].adjoint() * mom.asDiagonal() * V_t[0];
        // writing vdaggerv to disk
        if(handling_vdaggerv == "write"){
          char dummy2[200];
          sprintf(dummy2, "operators.%04d.p_", config);
          std::string dummy = std::string(dummy2) + 
                              std::to_string(op.momentum[0]) + 
                              std::to_string(op.momentum[1]) + 
                              std::to_string(op.momentum[2]);
          char outfile[200];
          sprintf(outfile, "%s_.t_%03d", dummy.c_str(), (int) t);
          write_vdaggerv(full_path, std::string(outfile), vdaggerv[op.id][t]);
        }
      }
      else // zero momentum
        vdaggerv[op.id][t] = Eigen::MatrixXcd::Identity(nb_ev, nb_ev);
    }
  } // loop over time
}// pragma omp parallel ends here

  t2 = clock() - t2;
  std::cout << std::setprecision(1) << "\t\t\tSUCCESS - " << std::fixed 
    << ((float) t2)/CLOCKS_PER_SEC << " seconds" << std::endl;
  is_vdaggerv_set = true;

}