/* only for Eigen3 matrix/vector */
void HDF5IO::saveVector(const std::string& GroupName,
  const std::string& Name, const RealVectorType& V)
{
    hsize_t Dim[1] = {hsize_t(V.size())};
    H5::DataSpace dspace(1,Dim);
    H5::Group FG = getGroup( GroupName );
    try{
      H5::Exception::dontPrint();
      H5::DataSet DataSet = FG.openDataSet(Name.c_str());
      DataSet.write(V.data(),H5::PredType::NATIVE_DOUBLE, dspace);
    } catch ( const H5::GroupIException not_found_error ){
      H5::DataSet DataSet = FG.createDataSet(Name.c_str(),
        H5::PredType::NATIVE_DOUBLE,dspace);
      DataSet.write(V.data(),H5::PredType::NATIVE_DOUBLE);
    }
    FG.close();
}
void HDF5IO::loadVector(const std::string& GroupName, const std::string& Name,
  RealVectorType& V)
{
  H5::Group FG = getGroup( GroupName );
  H5::DataSet DataSet = FG.openDataSet(Name.c_str());
  H5::DataSpace DataSpace = DataSet.getSpace();
  if(DataSpace.getSimpleExtentNdims() != 1)
	throw(H5::DataSpaceIException("HDF5IO::loadRealVector()",
    "Unexpected multidimentional dataspace."));
  V.resize(DataSpace.getSimpleExtentNpoints());
  try{
    DataSet.read(V.data(),H5::PredType::NATIVE_DOUBLE);
  }catch( H5::GroupIException not_found_error ){
    RUNTIME_ERROR("No dataset found in loadRealVector. ");
  }
  FG.close();
}
Beispiel #3
0
int main(int argc, char* argv[]) {
    boost::mpi::environment env(argc,argv);
    boost::mpi::communicator comm;

    print_section("Hubbard nxn");

    int size_x, size_y, wn;
    RealType t, mu, U, beta, reduce_tol, coeff_tol;
    bool calc_gf, calc_2pgf;
    int wf_max, wb_max;
    double eta, hbw, step; // for evaluation of GF on real axis

    try { // command line parser
        TCLAP::CmdLine cmd("Hubbard nxn diag", ' ', "");
        TCLAP::ValueArg<RealType> U_arg("U","U","Value of U",true,10.0,"RealType",cmd);
        TCLAP::ValueArg<RealType> mu_arg("","mu","Global chemical potential",false,0.0,"RealType",cmd);
        TCLAP::ValueArg<RealType> t_arg("t","t","Value of t",false,1.0,"RealType",cmd);

        TCLAP::ValueArg<RealType> beta_arg("b","beta","Inverse temperature",true,100.,"RealType");
        TCLAP::ValueArg<RealType> T_arg("T","T","Temperature",true,0.01,"RealType");
        cmd.xorAdd(beta_arg,T_arg);

        TCLAP::ValueArg<size_t> x_arg("x","x","Size over x",false,2,"int",cmd);
        TCLAP::ValueArg<size_t> y_arg("y","y","Size over y",false,2,"int",cmd);

        TCLAP::ValueArg<size_t> wn_arg("","wf","Number of positive fermionic Matsubara Freqs",false,64,"int",cmd);
        TCLAP::ValueArg<size_t> wb_arg("","wb","Number of positive bosonic Matsubara Freqs",false,1,"int",cmd);
        TCLAP::SwitchArg gf_arg("","calcgf","Calculate Green's functions",cmd, false);
        TCLAP::SwitchArg twopgf_arg("","calc2pgf","Calculate 2-particle Green's functions",cmd, false);
        TCLAP::ValueArg<RealType> reduce_tol_arg("","reducetol","Energy resonance resolution in 2pgf",false,1e-5,"RealType",cmd);
        TCLAP::ValueArg<RealType> coeff_tol_arg("","coefftol","Total weight tolerance",false,1e-12,"RealType",cmd);

        TCLAP::ValueArg<RealType> eta_arg("","eta","Offset from the real axis for Green's function calculation",false,0.05,"RealType",cmd);
        TCLAP::ValueArg<RealType> hbw_arg("D","hbw","Half-bandwidth. Default = U",false,0.0,"RealType",cmd);
        TCLAP::ValueArg<RealType> step_arg("","step","Step on a real axis. Default : 0.01",false,0.01,"RealType",cmd);

        cmd.parse( argc, argv );
        U = U_arg.getValue();
        mu = (mu_arg.isSet()?mu_arg.getValue():U/2);
        boost::tie(t, beta, calc_gf, calc_2pgf, reduce_tol, coeff_tol) = boost::make_tuple( t_arg.getValue(), beta_arg.getValue(),
                                                                                            gf_arg.getValue(), twopgf_arg.getValue(), reduce_tol_arg.getValue(), coeff_tol_arg.getValue());
        boost::tie(size_x, size_y) = boost::make_tuple(x_arg.getValue(), y_arg.getValue());
        boost::tie(wf_max, wb_max) = boost::make_tuple(wn_arg.getValue(), wb_arg.getValue());
        boost::tie(eta, hbw, step) = boost::make_tuple(eta_arg.getValue(), (hbw_arg.isSet()?hbw_arg.getValue():2.*U), step_arg.getValue());
        calc_gf = calc_gf || calc_2pgf;
        calc_gf = calc_gf || calc_2pgf;
    }
    catch (TCLAP::ArgException &e)  // catch parsing exceptions
    { std::cerr << "error: " << e.error() << " for arg " << e.argId() << std::endl; exit(1);}

    int L = size_x*size_y;
    INFO("Diagonalization of " << L << "=" << size_x << "*" << size_y << " sites");
    Lattice Lat;

    /* Add sites */
    std::vector<std::string> names(L);
    for (size_t y=0; y<size_y; y++)
        for (size_t x=0; x<size_x; x++)
        {
            size_t i = SiteIndexF(size_x, x, y);
            std::stringstream s; s << i;
            names[i]="S"+s.str();
            Lat.addSite(new Lattice::Site(names[i],1,2));
        };

    INFO("Sites");
    Lat.printSites();

    /* Add interaction on each site*/
    MelemType U_complex;
    U_complex = std::complex<double> (U,0);
    MelemType mu_complex;
    mu_complex = std::complex<double> (mu,0);
    for (size_t i=0; i<L; i++) LatticePresets::addCoulombS(&Lat, names[i], U_complex, -mu_complex);

    /* Add hopping */
    for (size_t y=0; y<size_y; y++) {
        for (size_t x=0; x<size_x; x++) {
            size_t pos = SiteIndexF(size_x, x,y);
            size_t pos_right = SiteIndexF(size_x, (x+1)%size_x,y); /*if (x == size_x - 1) pos_right = SiteIndexF(0,y); */
            size_t pos_up = SiteIndexF(size_x, x,(y+1)%size_y);

            if (size_x > 1) LatticePresets::addHopping(&Lat, std::min(names[pos], names[pos_right]), std::max(names[pos], names[pos_right]), -t);
            if (size_y > 1) LatticePresets::addHopping(&Lat, std::min(names[pos], names[pos_up]), std::max(names[pos], names[pos_up]), -t);
        };
    };

    int rank = comm.rank();
    if (!rank) {
        INFO("Terms with 2 operators");
        Lat.printTerms(2);

        INFO("Terms with 4 operators");
        Lat.printTerms(4);
    };

    IndexClassification IndexInfo(Lat.getSiteMap());
    IndexInfo.prepare(false); // Create index space
    if (!rank) { print_section("Indices"); IndexInfo.printIndices(); };
    int index_size = IndexInfo.getIndexSize();

    print_section("Matrix element storage");
    IndexHamiltonian Storage(&Lat,IndexInfo);
    Storage.prepare(); // Write down the Hamiltonian as a symbolic formula
    print_section("Terms");
    if (!rank) INFO(Storage);

    Symmetrizer Symm(IndexInfo, Storage);
    Symm.compute(); // Find symmetries of the problem

    StatesClassification S(IndexInfo,Symm); // Introduce Fock space and classify states to blocks
    S.compute();

    Hamiltonian H(IndexInfo, Storage, S); // Hamiltonian in the basis of Fock Space
    H.prepare(); // enter the Hamiltonian matrices
    H.compute(); // compute eigenvalues and eigenvectors

    RealVectorType evals (H.getEigenValues());
    std::sort(evals.data(), evals.data() + H.getEigenValues().size());
    savetxt("spectrum.dat", evals); // dump eigenvalues

    DensityMatrix rho(S,H,beta); // create Density Matrix
    rho.prepare();
    rho.compute(); // evaluate thermal weights with respect to ground energy, i.e exp(-beta(e-e_0))/Z

    INFO("<N> = " << rho.getAverageOccupancy()); // get average total particle number
    savetxt("N_T.dat",rho.getAverageOccupancy());

    // Green's function calculation starts here

    FieldOperatorContainer Operators(IndexInfo, S, H); // Create a container for c and c^+ in the eigenstate basis

    if (calc_gf) {

        INFO("1-particle Green's functions calc");
        std::set<ParticleIndex> f;
        std::set<IndexCombination2> indices2;
        ParticleIndex d0 = IndexInfo.getIndex("S0", 0, down);
        ParticleIndex u0 = IndexInfo.getIndex("S0", 0, up);
        f.insert(u0);
        f.insert(d0);
        for (size_t x = 0; x < size_x; x++) {
            ParticleIndex ind = IndexInfo.getIndex(names[SiteIndexF(size_x, x, 0)], 0, down);
            f.insert(ind);
            indices2.insert(IndexCombination2(d0, ind));
        };

        Operators.prepareAll(f);
        Operators.computeAll(); // evaluate c, c^+ for chosen indices

        GFContainer G(IndexInfo, S, H, rho, Operators);

        G.prepareAll(indices2); // identify all non-vanishing block connections in the Green's function
        G.computeAll(); // Evaluate all GF terms, i.e. resonances and weights of expressions in Lehmans representation of the Green's function

        if (!comm.rank()) { // dump gf into a file
            std::set<IndexCombination2>::iterator ind2;
            for (ind2 = indices2.begin(); ind2 !=
                                          indices2.end(); ++ind2) { // loops over all components (pairs of indices) of the Green's function
                // Save Matsubara GF from pi/beta to pi/beta*(4*wf_max + 1)
                std::cout << "Saving imfreq G" << *ind2 << " on " << 4 * wf_max << " Matsubara freqs. " << std::endl;

                std::stringstream fname;
                fname << "gw_imag" << (*ind2).Index1 << (*ind2).Index2 << ".dat";
                std::ofstream gw_im(fname.str().c_str());

                const GreensFunction &GF = G(*ind2);
                for (int wn = 0; wn < wf_max * 4; wn++) {
                    ComplexType val = GF(
                            I * FMatsubara(wn, beta)); // this comes from Pomerol - see GreensFunction::operator()
                    gw_im << std::scientific << std::setprecision(12) << FMatsubara(wn, beta) << "   " << real(val) <<
                    " " << imag(val) << std::endl;
                };
                gw_im.close();
            }
        }
    }

    return 0;
}