void Demo() { const int nspins=2; const int nfreq=10; const double beta=5; // Construct the meshes: g::matsubara_positive_mesh m_mesh(beta, nfreq); g::momentum_index_mesh k_mesh(generate_momentum_mesh()); g::index_mesh s_mesh(nspins); // construct a GF using a pre-defined convenience type g::omega_k_sigma_gf gf(m_mesh, k_mesh, s_mesh); // initialize a GF to all-zeros gf.initialize(); // Make indices: g::matsubara_index omega; omega=4; g::momentum_index ii(2); g::index sigma(0); // Assign a GF element: gf(omega,ii,sigma)=std::complex<double>(3,4); // Density matrix as a double-valued GF // on momentum and integer-index space: typedef g::two_index_gf<double, g::momentum_index_mesh, g::index_mesh> density_matrix_type; // Construct the object: density_matrix_type denmat=density_matrix_type(k_mesh,s_mesh); // prepare diagonal matrix const double U=3.0; denmat.initialize(); // loop over first mesh index: for (g::momentum_index i=g::momentum_index(0); i<denmat.mesh1().extent(); ++i) { denmat(i,g::index(0))=0.5*U; denmat(i,g::index(1))=0.5*U; } // construct a tailed GF using predefined convenience type: g::omega_k_sigma_gf_with_tail gft(gf); gft.set_tail(0, denmat); // set the tail density_matrix_type gftail=gft.tail(0); // retrieve the tail // access the tailed GF element std::complex<double> x=gft(omega,ii,sigma); }
TEST_F(ThreeIndexTestGF, TailSaveLoad) { namespace g=alps::gf; typedef g::two_index_gf<double, g::momentum_index_mesh, g::index_mesh> density_matrix_type; density_matrix_type denmat=density_matrix_type(g::momentum_index_mesh(get_data_for_momentum_mesh()), g::index_mesh(nspins)); // prepare diagonal matrix double U=3.0; denmat.initialize(); for (g::momentum_index i=g::momentum_index(0); i<denmat.mesh1().extent(); ++i) { denmat(i,g::index(0))=0.5*U; denmat(i,g::index(1))=0.5*U; } // Attach a tail to the GF int order=0; // FIXME: TODO: gf.set_tail(min_order, max_order, denmat, ...); g::omega_k_sigma_gf_with_tail gft(gf); g::omega_k_sigma_gf_with_tail gft2(gft); EXPECT_EQ(g::TAIL_NOT_SET,gft.min_tail_order()); EXPECT_EQ(g::TAIL_NOT_SET,gft.max_tail_order()); gft.set_tail(order, denmat); EXPECT_EQ(0,gft.min_tail_order()); EXPECT_EQ(0,gft.max_tail_order()); EXPECT_EQ(0,(denmat-gft.tail(0)).norm()); { alps::hdf5::archive oar("gft.h5","w"); gft(g::matsubara_index(4),g::momentum_index(3), g::index(1))=std::complex<double>(7., 3.); gft.save(oar,"/gft"); } { alps::hdf5::archive iar("gft.h5"); gft2.load(iar,"/gft"); } EXPECT_EQ(gft2.tail().size(), gft.tail().size()) << "Tail size mismatch"; EXPECT_NEAR(0, (gft.tail(0)-gft2.tail(0)).norm(), 1E-8)<<"Tail loaded differs from tail stored"; EXPECT_EQ(7, gft2(g::matsubara_index(4),g::momentum_index(3), g::index(1)).real()) << "GF real part mismatch"; EXPECT_EQ(3, gft2(g::matsubara_index(4),g::momentum_index(3), g::index(1)).imag()) << "GF imag part mismatch"; }
TEST_F(GreensFunctionTailTest, TailSaveLoad) { typedef gfns::greenf<std::complex<double>, gfns::matsubara_mesh<gfns::mesh::POSITIVE_ONLY>, gfns::index_mesh> omega_sigma_gf; typedef gfns::gf_tail<omega_sigma_gf, gfns::greenf<double, gfns::index_mesh> > omega_sigma_gf_with_tail; typedef gfns::greenf<double, gfns::index_mesh> density_matrix_type; density_matrix_type denmat = density_matrix_type(gfns::index_mesh(nspins)); omega_sigma_gf gf(gfns::matsubara_positive_mesh(beta,nfreq), alps::gf::index_mesh(nspins)); // prepare diagonal matrix double U=3.0; denmat.initialize(); denmat(gfns::index(0))=0.5*U; denmat(gfns::index(1))=0.5*U; // Attach a tail to the GF int order=0; omega_sigma_gf_with_tail gft(gf); omega_sigma_gf_with_tail gft2(gft); EXPECT_EQ(gfns::TAIL_NOT_SET,gft.min_tail_order()); EXPECT_EQ(gfns::TAIL_NOT_SET,gft.max_tail_order()); gft.set_tail(order, denmat); EXPECT_EQ(0,gft.min_tail_order()); EXPECT_EQ(0,gft.max_tail_order()); EXPECT_EQ(0,(denmat - gft.tail(0)).norm()); { alps::hdf5::archive oar("gf_2i_tailsaveload.h5","w"); gft(gfns::matsubara_index(4),gfns::index(1))=std::complex<double>(7., 3.); oar["/gft"] << gft; } { alps::hdf5::archive iar("gf_2i_tailsaveload.h5"); iar["/gft"] >> gft2; } EXPECT_EQ(gft2.tail().size(), gft.tail().size()) << "Tail size mismatch"; EXPECT_NEAR(0, (gft.tail(0)-gft2.tail(0)).norm(), 1E-8)<<"Tail loaded differs from tail stored"; EXPECT_EQ(7, gft2(gfns::matsubara_index(4), gfns::index(1)).real()) << "GF real part mismatch"; EXPECT_EQ(3, gft2(gfns::matsubara_index(4), gfns::index(1)).imag()) << "GF imag part mismatch"; }
// Check incompatible broadcast of tails TEST_F(FourIndexGFTest,MpiWrongTailBroadcast) { namespace g=alps::gf; typedef g::three_index_gf<double, g::momentum_index_mesh, g::momentum_index_mesh, g::index_mesh> density_matrix_type; density_matrix_type denmat=density_matrix_type(g::momentum_index_mesh(get_data_for_momentum_mesh()), g::momentum_index_mesh(get_data_for_momentum_mesh()), g::index_mesh(this->nspins)); // Get the rank int rank; MPI_Comm_rank(MPI_COMM_WORLD, &rank); // prepare diagonal matrix double U=3.0; denmat.initialize(); for (g::momentum_index i=g::momentum_index(0); i<denmat.mesh1().extent(); ++i) { denmat(i,i,g::index(0))=0.5*U; denmat(i,i,g::index(1))=0.5*U; } g::omega_k1_k2_sigma_gf_with_tail gft(gf); int order=0; if (rank==MASTER) { // on master only // attach a tail to the GF: gft.set_tail(order, denmat); // change the GF gft(g::matsubara_index(4),g::momentum_index(3), g::momentum_index(2), g::index(1))=std::complex<double>(7., 3.); } // slaves do not have the tail attached to their GF. gft.broadcast(MASTER,MPI_COMM_WORLD); EXPECT_EQ(7, gft(g::matsubara_index(4),g::momentum_index(3), g::momentum_index(2), g::index(1)).real()) << "GF real part mismatch on rank " << rank; EXPECT_EQ(3, gft(g::matsubara_index(4),g::momentum_index(3), g::momentum_index(2), g::index(1)).imag()) << "GF imag part mismatch on rank " << rank; ASSERT_EQ(1, gft.tail().size()) << "Tail size mismatch on rank " << rank; EXPECT_NEAR(0, (gft.tail(0)-denmat).norm(), 1E-8) << "Tail broadcast differs from the received on rank " << rank; }
TEST_F(TwoIndexGFTest, TailSaveLoad) { namespace g=alps::gf; typedef g::one_index_gf<double, g::index_mesh> density_matrix_type; density_matrix_type denmat=density_matrix_type(g::index_mesh(nspins)); // prepare diagonal matrix double U=3.0; denmat.initialize(); denmat(g::index(0))=0.5*U; denmat(g::index(1))=0.5*U; // Attach a tail to the GF int order=0; g::omega_sigma_gf_with_tail gft(gf); g::omega_sigma_gf_with_tail gft2(gft); EXPECT_EQ(g::TAIL_NOT_SET,gft.min_tail_order()); EXPECT_EQ(g::TAIL_NOT_SET,gft.max_tail_order()); gft.set_tail(order, denmat); EXPECT_EQ(0,gft.min_tail_order()); EXPECT_EQ(0,gft.max_tail_order()); EXPECT_EQ(0,(denmat-gft.tail(0)).norm()); { alps::hdf5::archive oar("gft.h5","w"); gft(g::matsubara_index(4),g::index(1))=std::complex<double>(7., 3.); gft.save(oar,"/gft"); } { alps::hdf5::archive iar("gft.h5"); gft2.load(iar,"/gft"); } EXPECT_EQ(gft2.tail().size(), gft.tail().size()) << "Tail size mismatch"; EXPECT_NEAR(0, (gft.tail(0)-gft2.tail(0)).norm(), 1E-8)<<"Tail loaded differs from tail stored"; EXPECT_EQ(7, gft2(g::matsubara_index(4), g::index(1)).real()) << "GF real part mismatch"; EXPECT_EQ(3, gft2(g::matsubara_index(4), g::index(1)).imag()) << "GF imag part mismatch"; }
TEST_F(ThreeIndexTestGF, tail) { namespace g=alps::gf; typedef g::two_index_gf<double, g::momentum_index_mesh, g::index_mesh> density_matrix_type; density_matrix_type denmat=density_matrix_type(g::momentum_index_mesh(get_data_for_momentum_mesh()), g::index_mesh(nspins)); // prepare diagonal matrix double U=3.0; denmat.initialize(); for (g::momentum_index i=g::momentum_index(0); i<denmat.mesh1().extent(); ++i) { denmat(i,g::index(0))=0.5*U; denmat(i,g::index(1))=0.5*U; } // Attach a tail to the GF int order=0; // FIXME: TODO: gf.set_tail(min_order, max_order, denmat, ...); g::omega_k_sigma_gf_with_tail gft(gf); gft.set_tail(order, denmat) // .set_tail(order+1, other_gf) .... ; EXPECT_NEAR((denmat-gft.tail(order)).norm(), 0, 1.e-8); /* The following does not compile, as expected: typedef g::three_index_gf<double, g::momentum_index_mesh, g::momentum_index_mesh, g::index_mesh> some_matrix_type; typedef g::three_index_gf_with_tail<some_matrix_type, g::two_index_gf<double, g::momentum_index_mesh, g::index_mesh> > some_matrix_type_with_tail; some_matrix_type* ptr=0; some_matrix_type_with_tail wrong(*ptr); */ /* The following does not compile, as expected: typedef g::three_index_gf<double, g::itime_mesh, g::itime_mesh, g::index_mesh> some_gf_type; typedef g::three_index_gf_with_tail<some_gf_type, g::two_index_gf<double, g::momentum_index_mesh, g::index_mesh> > some_gf_type_with_tail; some_gf_type_with_tail wrong(*(some_gf_type*)0); */ }
TEST_F(TwoIndexGFTest, tail) { namespace g=alps::gf; typedef g::one_index_gf<double, g::index_mesh> density_matrix_type; density_matrix_type denmat=density_matrix_type(g::index_mesh(nspins)); // prepare diagonal matrix double U=3.0; denmat.initialize(); denmat(g::index(0))=0.5*U; denmat(g::index(1))=0.5*U; // Attach a tail to the GF int order=0; g::omega_sigma_gf_with_tail gft(gf); gft.set_tail(order, denmat); EXPECT_NEAR((denmat-gft.tail(order)).norm(), 0, 1.e-8); }
static void gftCallFunc(const iocshArgBuf *args) { gft(args[0].sval);}