From f98e8f013294add7b7ed32c74379f0f5d749d0e9 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 23 Jul 2023 03:28:52 +0000 Subject: [PATCH 01/10] Feature: add a class for sparse matrix io in CSR format --- source/module_io/CMakeLists.txt | 1 + source/module_io/sparse_matrix.cpp | 128 +++++++++++ source/module_io/sparse_matrix.h | 101 +++++++++ source/module_io/test/CMakeLists.txt | 6 + source/module_io/test/sparse_matrix_test.cpp | 225 +++++++++++++++++++ 5 files changed, 461 insertions(+) create mode 100644 source/module_io/sparse_matrix.cpp create mode 100644 source/module_io/sparse_matrix.h create mode 100644 source/module_io/test/sparse_matrix_test.cpp diff --git a/source/module_io/CMakeLists.txt b/source/module_io/CMakeLists.txt index a324d94bf29..823f66512c9 100644 --- a/source/module_io/CMakeLists.txt +++ b/source/module_io/CMakeLists.txt @@ -50,6 +50,7 @@ if(ENABLE_LCAO) dos_nao.cpp output_dm.cpp output_dm1.cpp + sparse_matrix.cpp ) list(APPEND objects_advanced unk_overlap_lcao.cpp diff --git a/source/module_io/sparse_matrix.cpp b/source/module_io/sparse_matrix.cpp new file mode 100644 index 00000000000..35ba53f2bde --- /dev/null +++ b/source/module_io/sparse_matrix.cpp @@ -0,0 +1,128 @@ +#include "sparse_matrix.h" + +#include + +#include "module_base/tool_quit.h" + +namespace ModuleIO +{ + +/** + * @brief Add value to the matrix with row and column indices + */ +template +void SparseMatrix::addValue(int row, int col, T value) +{ + if (row < 0 || row >= _rows || col < 0 || col >= _cols) + { + ModuleBase::WARNING_QUIT("SparseMatrix::addValue", "row or col index out of range"); + } + data.push_back(std::make_tuple(row, col, value)); +} + +/** + * @brief Convert to CSR format + */ +template +void SparseMatrix::convertToCSR(double threshold) +{ + // Filter elements greater than the threshold + auto it = std::remove_if(data.begin(), data.end(), [threshold](const std::tuple& elem) { + return std::abs(std::get<2>(elem)) <= threshold; + }); + data.erase(it, data.end()); + + // Sort data by row, then by column + std::sort(data.begin(), data.end(), [](const std::tuple& a, const std::tuple& b) { + if (std::get<0>(a) == std::get<0>(b)) + { + return std::get<1>(a) < std::get<1>(b); + } + return std::get<0>(a) < std::get<0>(b); + }); + + // Initialize the CSR arrays + csr_row_ptr.assign(_rows + 1, 0); + csr_col_ind.clear(); + csr_values.clear(); + + // Fill the CSR arrays + for (const auto& elem: data) + { + int row = std::get<0>(elem); + int col = std::get<1>(elem); + T value = std::get<2>(elem); + + csr_col_ind.push_back(col); + csr_values.push_back(value); + csr_row_ptr[row + 1]++; + } + + // Compute the row pointers + for (int i = 1; i <= _rows; i++) + { + csr_row_ptr[i] += csr_row_ptr[i - 1]; + } +} + +/** + * @brief Print data in CSR format + */ +template +void SparseMatrix::printCSR(std::ostream& ofs, int precision) +{ + for (int i = 0; i < csr_values.size(); i++) + { + ofs << " " << std::fixed << std::scientific << std::setprecision(precision) << csr_values[i]; + } + ofs << std::endl; + for (int i = 0; i < csr_col_ind.size(); i++) + { + ofs << " " << csr_col_ind[i]; + } + ofs << std::endl; + for (int i = 0; i < csr_row_ptr.size(); i++) + { + ofs << " " << csr_row_ptr[i]; + } + ofs << std::endl; +} + +/** + * @brief Read CSR data from arrays + */ +template +void SparseMatrix::readCSR(const std::vector& values, + const std::vector& col_ind, + const std::vector& row_ptr) +{ + if (row_ptr.size() != static_cast(_rows) + 1) + { + ModuleBase::WARNING_QUIT("SparseMatrix::readCSR", "Invalid row_ptr size"); + } + if (col_ind.size() != values.size()) + { + ModuleBase::WARNING_QUIT("SparseMatrix::readCSR", "Column indices and values size mismatch"); + } + + csr_row_ptr = row_ptr; + csr_col_ind = col_ind; + csr_values = values; + + data.clear(); + for (int row = 0; row < _rows; row++) + { + for (int idx = csr_row_ptr[row]; idx < csr_row_ptr[row + 1]; idx++) + { + int col = csr_col_ind[idx]; + T value = csr_values[idx]; + data.push_back(std::make_tuple(row, col, value)); + } + } +} + +// Explicit instantiation of template classes +template class SparseMatrix; +template class SparseMatrix>; + +} // namespace ModuleIO \ No newline at end of file diff --git a/source/module_io/sparse_matrix.h b/source/module_io/sparse_matrix.h new file mode 100644 index 00000000000..e13d8b0bb6e --- /dev/null +++ b/source/module_io/sparse_matrix.h @@ -0,0 +1,101 @@ +#ifndef SPARSE_MATRIX_H +#define SPARSE_MATRIX_H + +#include +#include +#include +#include + +namespace ModuleIO +{ + +/** + * @brief Sparse matrix class + * + * @tparam T + */ +template +class SparseMatrix +{ + public: + // Default constructor + SparseMatrix() : _rows(0), _cols(0) + { + } + + SparseMatrix(int rows, int cols) : _rows(rows), _cols(cols) + { + } + + // add value to the matrix with row and column indices + void addValue(int row, int col, T value); + + // get data vector + const std::vector>& getData() const + { + return data; + } + + // get CSR_values + const std::vector& getCSRValues() const + { + return csr_values; + } + + // get CSR_col_ind + const std::vector& getCSRColInd() const + { + return csr_col_ind; + } + + // get CSR_row_ptr + const std::vector& getCSRRowPtr() const + { + return csr_row_ptr; + } + + // convert to CSR format + void convertToCSR(double threshold); + + // print data in CSR format CSR: Compressed Sparse Row + void printCSR(std::ostream& ofs, int precision = 8); + + // read CSR data from arrays + void readCSR(const std::vector& values, const std::vector& col_ind, const std::vector& row_ptr); + + // set number of rows + void setRows(int rows) + { + _rows = rows; + } + + // set number of columns + void setCols(int cols) + { + _cols = cols; + } + + // get number of rows + int getRows() const + { + return _rows; + } + + // get number of columns + int getCols() const + { + return _cols; + } + + private: + int _rows; + int _cols; + std::vector> data; + std::vector csr_row_ptr; + std::vector csr_col_ind; + std::vector csr_values; +}; // class SparseMatrix + +} // namespace ModuleIO + +#endif // SPARSE_MATRIX_H \ No newline at end of file diff --git a/source/module_io/test/CMakeLists.txt b/source/module_io/test/CMakeLists.txt index 71511cbe35e..69bd6ff41c0 100644 --- a/source/module_io/test/CMakeLists.txt +++ b/source/module_io/test/CMakeLists.txt @@ -122,4 +122,10 @@ AddTest( TARGET io_output_log_test LIBS base ${math_libs} device SOURCES ../output_log.cpp outputlog_test.cpp +) + +AddTest( + TARGET io_sparse_matrix_test + LIBS base ${math_libs} device + SOURCES sparse_matrix_test.cpp ../sparse_matrix.cpp ) \ No newline at end of file diff --git a/source/module_io/test/sparse_matrix_test.cpp b/source/module_io/test/sparse_matrix_test.cpp new file mode 100644 index 00000000000..4ccd1e5a78a --- /dev/null +++ b/source/module_io/test/sparse_matrix_test.cpp @@ -0,0 +1,225 @@ +#include "module_io/sparse_matrix.h" + +#include + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +/************************************************ + * unit test of sparse_matrix.cpp + ***********************************************/ + +/** + * - Tested Functions: + * - addValue() + * - Add value to the matrix with row and column indices + * - convertToCSR() + * - Convert to CSR format + * - printCSR() + * - Print data in CSR format + * - readCSR() + * - Read CSR data from arrays + */ + +class SparseMatrixTest : public testing::Test +{ + protected: + ModuleIO::SparseMatrix> smc0; + ModuleIO::SparseMatrix smd = ModuleIO::SparseMatrix(4, 4); + ModuleIO::SparseMatrix> smc = ModuleIO::SparseMatrix>(4, 4); + std::string output; +}; + +TEST_F(SparseMatrixTest, AddValueDouble) +{ + // Add a value to the matrix with row and column indices + smd.addValue(2, 2, 3.0); + smd.addValue(3, 3, 4.0); + + EXPECT_EQ(smd.getData().size(), 2); + EXPECT_EQ(smd.getCols(), 4); + EXPECT_EQ(smd.getRows(), 4); + + // Check if the value was added correctly + EXPECT_EQ(std::make_tuple(2, 2, 3.0), smd.getData()[0]); + EXPECT_EQ(std::make_tuple(3, 3, 4.0), smd.getData()[1]); +} + +TEST_F(SparseMatrixTest, AddValueDoubleWarning) +{ + // case 1 + testing::internal::CaptureStdout(); + EXPECT_EXIT(smd.addValue(2, -1, 3.0), ::testing::ExitedWithCode(0), ""); + output = testing::internal::GetCapturedStdout(); + // test output on screen + EXPECT_THAT(output, testing::HasSubstr("row or col index out of range")); + // case 2 + testing::internal::CaptureStdout(); + EXPECT_EXIT(smd.addValue(-1, 0, 3.0), ::testing::ExitedWithCode(0), ""); + output = testing::internal::GetCapturedStdout(); + // test output on screen + EXPECT_THAT(output, testing::HasSubstr("row or col index out of range")); + // case 3 + testing::internal::CaptureStdout(); + EXPECT_EXIT(smd.addValue(2, 4, 3.0), ::testing::ExitedWithCode(0), ""); + output = testing::internal::GetCapturedStdout(); + // test output on screen + EXPECT_THAT(output, testing::HasSubstr("row or col index out of range")); + // case 4 + testing::internal::CaptureStdout(); + EXPECT_EXIT(smd.addValue(4, 2, 3.0), ::testing::ExitedWithCode(0), ""); + output = testing::internal::GetCapturedStdout(); + // test output on screen + EXPECT_THAT(output, testing::HasSubstr("row or col index out of range")); +} + +TEST_F(SparseMatrixTest, AddValueComplex) +{ + // Add a value to the matrix with row and column indices + smc.addValue(2, 2, std::complex(1.0, 0.0)); + smc.addValue(3, 3, std::complex(0.0, 0.2)); + + EXPECT_EQ(smc.getData().size(), 2); + EXPECT_EQ(smc.getCols(), 4); + EXPECT_EQ(smc.getRows(), 4); + + // Check if the value was added correctly + EXPECT_EQ(std::make_tuple(2, 2, std::complex(1.0, 0.0)), smc.getData()[0]); + EXPECT_EQ(std::make_tuple(3, 3, std::complex(0.0, 0.2)), smc.getData()[1]); +} + +TEST_F(SparseMatrixTest, AddValueComplexWarning) +{ + // case 1 + testing::internal::CaptureStdout(); + EXPECT_EXIT(smc.addValue(2, -1, std::complex(1.0, 0.0)), ::testing::ExitedWithCode(0), ""); + output = testing::internal::GetCapturedStdout(); + // test output on screen + EXPECT_THAT(output, testing::HasSubstr("row or col index out of range")); + // case 2 + testing::internal::CaptureStdout(); + EXPECT_EXIT(smc.addValue(-1, 0, std::complex(1.0, 0.0)), ::testing::ExitedWithCode(0), ""); + output = testing::internal::GetCapturedStdout(); + // test output on screen + EXPECT_THAT(output, testing::HasSubstr("row or col index out of range")); + // case 3 + testing::internal::CaptureStdout(); + EXPECT_EXIT(smc.addValue(2, 4, std::complex(1.0, 0.0)), ::testing::ExitedWithCode(0), ""); + output = testing::internal::GetCapturedStdout(); + // test output on screen + EXPECT_THAT(output, testing::HasSubstr("row or col index out of range")); + // case 4 + testing::internal::CaptureStdout(); + EXPECT_EXIT(smc.addValue(4, 2, std::complex(1.0, 0.0)), ::testing::ExitedWithCode(0), ""); + output = testing::internal::GetCapturedStdout(); + // test output on screen + EXPECT_THAT(output, testing::HasSubstr("row or col index out of range")); +} + +TEST_F(SparseMatrixTest, CSRDouble) +{ + // test the printCSR function for the following matrix + // 1.0 2.0 0.0 0.0 0.0 0.0 + // 0.0 3.0 0.0 4.0 0.0 0.0 + // 0.0 0.0 5.0 6.0 7.0 0.0 + // 0.0 0.0 0.0 0.0 0.0 8.0 + // the expect output is + // csr_values = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0] + // csr_col_ind = [0, 1, 1, 3, 2, 3, 4, 5] + // csr_row_ptr = [0, 2, 4, 7, 8] + ModuleIO::SparseMatrix smd0; + ModuleIO::SparseMatrix smd1; + smd0.setRows(4); + smd0.setCols(6); + smd0.addValue(0, 0, 1.0); + smd0.addValue(0, 1, 2.0); + smd0.addValue(1, 1, 3.0); + smd0.addValue(1, 3, 4.0); + smd0.addValue(2, 2, 5.0); + smd0.addValue(2, 3, 6.0); + smd0.addValue(2, 4, 7.0); + smd0.addValue(3, 5, 8.0); + smd0.convertToCSR(0.0); + testing::internal::CaptureStdout(); + smd0.printCSR(std::cout, 2); + output = testing::internal::GetCapturedStdout(); + EXPECT_THAT(output, testing::HasSubstr("1.00e+00 2.00e+00 3.00e+00 4.00e+00 5.00e+00 6.00e+00 7.00e+00 8.00e+00")); + EXPECT_THAT(output, testing::HasSubstr("0 1 1 3 2 3 4 5")); + EXPECT_THAT(output, testing::HasSubstr("0 2 4 7 8")); + + std::vector expected_csr_values = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0}; + std::vector expected_csr_col_ind = {0, 1, 1, 3, 2, 3, 4, 5}; + std::vector expected_csr_row_ptr = {0, 2, 4, 7, 8}; + + smd1.setRows(4); + smd1.setCols(6); + smd1.readCSR(expected_csr_values, expected_csr_col_ind, expected_csr_row_ptr); + + for (int i = 0; i < 8; i++) + { + EXPECT_DOUBLE_EQ(smd0.getCSRValues()[i], smd1.getCSRValues()[i]); + EXPECT_EQ(smd0.getCSRColInd()[i], smd1.getCSRColInd()[i]); + } + for (int i = 0; i < 5; i++) + { + EXPECT_EQ(smd0.getCSRRowPtr()[i], smd1.getCSRRowPtr()[i]); + } +} + +TEST_F(SparseMatrixTest, CSRComplex) +{ + // test the printCSR function for the following matrix + // 1.0 2.0 0.0 0.0 0.0 0.0 + // 0.0 3.0 0.0 4.0 0.0 0.0 + // 0.0 0.0 5.0 6.0 7.0 0.0 + // 0.0 0.0 0.0 0.0 0.0 8.0 + // the expect output is + // csr_values = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0] + // csr_col_ind = [0, 1, 1, 3, 2, 3, 4, 5] + // csr_row_ptr = [0, 2, 4, 7, 8] + ModuleIO::SparseMatrix> smc0; + ModuleIO::SparseMatrix> smc1; + smc0.setRows(4); + smc0.setCols(6); + smc0.addValue(0, 0, std::complex(1.0, 0.0)); + smc0.addValue(0, 1, std::complex(2.0, 0.0)); + smc0.addValue(1, 1, std::complex(3.0, 0.0)); + smc0.addValue(1, 3, std::complex(4.0, 0.0)); + smc0.addValue(2, 2, std::complex(5.0, 0.0)); + smc0.addValue(2, 3, std::complex(6.0, 0.0)); + smc0.addValue(2, 4, std::complex(7.0, 0.0)); + smc0.addValue(3, 5, std::complex(8.0, 0.0)); + smc0.convertToCSR(0.5); + testing::internal::CaptureStdout(); + smc0.printCSR(std::cout, 1); + output = testing::internal::GetCapturedStdout(); + EXPECT_THAT(output, testing::HasSubstr("(1.0e+00,0.0e+00) (2.0e+00,0.0e+00) (3.0e+00,0.0e+00) (4.0e+00,0.0e+00) (5.0e+00,0.0e+00) (6.0e+00,0.0e+00) (7.0e+00,0.0e+00) (8.0e+00,0.0e+00)")); + EXPECT_THAT(output, testing::HasSubstr("0 1 1 3 2 3 4 5")); + EXPECT_THAT(output, testing::HasSubstr("0 2 4 7 8")); + + std::vector> expected_csr_values = {std::complex(1.0, 0.0), + std::complex(2.0, 0.0), + std::complex(3.0, 0.0), + std::complex(4.0, 0.0), + std::complex(5.0, 0.0), + std::complex(6.0, 0.0), + std::complex(7.0, 0.0), + std::complex(8.0, 0.0)}; + std::vector expected_csr_col_ind = {0, 1, 1, 3, 2, 3, 4, 5}; + std::vector expected_csr_row_ptr = {0, 2, 4, 7, 8}; + + smc1.setRows(4); + smc1.setCols(6); + smc1.readCSR(expected_csr_values, expected_csr_col_ind, expected_csr_row_ptr); + + for (int i = 0; i < 8; i++) + { + EXPECT_DOUBLE_EQ(smc0.getCSRValues()[i].real(), smc1.getCSRValues()[i].real()); + EXPECT_DOUBLE_EQ(smc0.getCSRValues()[i].imag(), smc1.getCSRValues()[i].imag()); + EXPECT_EQ(smc0.getCSRColInd()[i], smc1.getCSRColInd()[i]); + } + for (int i = 0; i < 5; i++) + { + EXPECT_EQ(smc0.getCSRRowPtr()[i], smc1.getCSRRowPtr()[i]); + } +} \ No newline at end of file From 8df0ce82a21e3e8c298fd1be8e6571dc5e51091e Mon Sep 17 00:00:00 2001 From: root Date: Sun, 23 Jul 2023 03:32:19 +0000 Subject: [PATCH 02/10] remove a unused line --- source/module_io/test/sparse_matrix_test.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/source/module_io/test/sparse_matrix_test.cpp b/source/module_io/test/sparse_matrix_test.cpp index 4ccd1e5a78a..d1fa2943951 100644 --- a/source/module_io/test/sparse_matrix_test.cpp +++ b/source/module_io/test/sparse_matrix_test.cpp @@ -24,7 +24,6 @@ class SparseMatrixTest : public testing::Test { protected: - ModuleIO::SparseMatrix> smc0; ModuleIO::SparseMatrix smd = ModuleIO::SparseMatrix(4, 4); ModuleIO::SparseMatrix> smc = ModuleIO::SparseMatrix>(4, 4); std::string output; From dfe36827d45c894c5fca55231265f01b8b57b13c Mon Sep 17 00:00:00 2001 From: root Date: Sun, 23 Jul 2023 03:46:35 +0000 Subject: [PATCH 03/10] refine tests --- source/module_io/test/sparse_matrix_test.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/source/module_io/test/sparse_matrix_test.cpp b/source/module_io/test/sparse_matrix_test.cpp index d1fa2943951..d24f8ad539c 100644 --- a/source/module_io/test/sparse_matrix_test.cpp +++ b/source/module_io/test/sparse_matrix_test.cpp @@ -163,6 +163,12 @@ TEST_F(SparseMatrixTest, CSRDouble) { EXPECT_EQ(smd0.getCSRRowPtr()[i], smd1.getCSRRowPtr()[i]); } + for (int i = 0; i < 8; i++) + { + EXPECT_EQ(std::get<0>(smd0.getData()[i]), std::get<0>(smd1.getData()[i])); + EXPECT_EQ(std::get<1>(smd0.getData()[i]), std::get<1>(smd1.getData()[i])); + EXPECT_DOUBLE_EQ(std::get<2>(smd0.getData()[i]), std::get<2>(smd1.getData()[i])); + } } TEST_F(SparseMatrixTest, CSRComplex) @@ -221,4 +227,11 @@ TEST_F(SparseMatrixTest, CSRComplex) { EXPECT_EQ(smc0.getCSRRowPtr()[i], smc1.getCSRRowPtr()[i]); } + for (int i = 0; i < 8; i++) + { + EXPECT_EQ(std::get<0>(smc0.getData()[i]), std::get<0>(smc1.getData()[i])); + EXPECT_EQ(std::get<1>(smc0.getData()[i]), std::get<1>(smc1.getData()[i])); + EXPECT_DOUBLE_EQ((std::get<2>(smc0.getData()[i])).real(), (std::get<2>(smc1.getData()[i])).real()); + EXPECT_DOUBLE_EQ((std::get<2>(smc0.getData()[i])).imag(), (std::get<2>(smc1.getData()[i])).imag()); + } } \ No newline at end of file From f3188b5ddb5c9ba42b49544300fa71b328c032e5 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 24 Jul 2023 03:49:44 +0000 Subject: [PATCH 04/10] Feature: add a output interface for hcontainer --- source/module_io/CMakeLists.txt | 1 + source/module_io/output_hcontainer.cpp | 111 ++++++++++++ source/module_io/output_hcontainer.h | 43 +++++ source/module_io/test/CMakeLists.txt | 6 + .../module_io/test/output_hcontainer_test.cpp | 161 ++++++++++++++++++ source/module_io/test/tmp_mocks.cpp | 46 +++++ 6 files changed, 368 insertions(+) create mode 100644 source/module_io/output_hcontainer.cpp create mode 100644 source/module_io/output_hcontainer.h create mode 100644 source/module_io/test/output_hcontainer_test.cpp create mode 100644 source/module_io/test/tmp_mocks.cpp diff --git a/source/module_io/CMakeLists.txt b/source/module_io/CMakeLists.txt index 823f66512c9..5e544565469 100644 --- a/source/module_io/CMakeLists.txt +++ b/source/module_io/CMakeLists.txt @@ -51,6 +51,7 @@ if(ENABLE_LCAO) output_dm.cpp output_dm1.cpp sparse_matrix.cpp + output_hcontainer.cpp ) list(APPEND objects_advanced unk_overlap_lcao.cpp diff --git a/source/module_io/output_hcontainer.cpp b/source/module_io/output_hcontainer.cpp new file mode 100644 index 00000000000..c11009973e8 --- /dev/null +++ b/source/module_io/output_hcontainer.cpp @@ -0,0 +1,111 @@ +#include "module_io/output_hcontainer.h" + +#include + +#include "module_io/sparse_matrix.h" + +namespace ModuleIO +{ + +template +Output_HContainer::Output_HContainer(hamilt::HContainer* hcontainer, + const Parallel_Orbitals* ParaV, + const UnitCell& ucell, + std::ostream& ofs, + double sparse_threshold, + int precision) + : _hcontainer(hcontainer), + _ParaV(ParaV), + _ucell(ucell), + _ofs(ofs), + _sparse_threshold(sparse_threshold), + _precision(precision) +{ +} + +template +void Output_HContainer::write() +{ + int size_for_loop_R = this->_hcontainer->size_R_loop(); + int rx, ry, rz; + for (int iR = 0; iR < size_for_loop_R; iR++) + { + this->_hcontainer->loop_R(iR, rx, ry, rz); + this->write_single_R(rx, ry, rz); + } +} + +template +void Output_HContainer::write(int rx_in, int ry_in, int rz_in) +{ + int size_for_loop_R = this->_hcontainer->size_R_loop(); + int rx, ry, rz; + int find_R = 0; + for (int iR = 0; iR < size_for_loop_R; iR++) + { + this->_hcontainer->loop_R(iR, rx, ry, rz); + if (rx == rx_in && ry == ry_in && rz == rz_in) + { + find_R += 1; + this->write_single_R(rx, ry, rz); + break; + } + } + if (find_R == 0) + { + ModuleBase::WARNING_QUIT("Output_HContainer::write", "Cannot find the R vector from the HContaine"); + } +} + +template +void Output_HContainer::write_single_R(int rx, int ry, int rz) +{ + this->_hcontainer->fix_R(rx, ry, rz); + ModuleIO::SparseMatrix sparse_matrix = ModuleIO::SparseMatrix(this->_ParaV->nrow, this->_ParaV->ncol); + int nonzero = 0; + for (int iap = 0; iap < this->_hcontainer->size_atom_pairs(); ++iap) + { + auto atom_pair = this->_hcontainer->get_atom_pair(iap); + int iat1 = atom_pair.get_atom_i(); + int iat2 = atom_pair.get_atom_j(); + int T1 = _ucell.iat2it[iat1]; + int T2 = _ucell.iat2it[iat2]; + int I1 = _ucell.iat2ia[iat1]; + int I2 = _ucell.iat2ia[iat2]; + const int start1 = _ucell.itiaiw2iwt(T1, I1, 0); + const int start2 = _ucell.itiaiw2iwt(T2, I2, 0); + int size1 = _ucell.atoms[T1].nw; + int size2 = _ucell.atoms[T2].nw; + for (int iw1 = 0; iw1 < size1; ++iw1) + { + const int global_index1 = start1 + iw1; + for (int iw2 = 0; iw2 < size2; ++iw2) + { + const int global_index2 = start2 + iw2; + + T tmp_matrix_value = atom_pair.get_matrix_value(global_index1, global_index2); + + if (std::abs(tmp_matrix_value) > _sparse_threshold) + { + nonzero++; + sparse_matrix.addValue(global_index1, global_index2, tmp_matrix_value); + // to do: consider 2D block-cyclic distribution + } + } + } + } + if (nonzero != 0) + { + _ofs << rx << " " << ry << " " << rz << " " << nonzero << std::endl; + sparse_matrix.convertToCSR(_sparse_threshold); + sparse_matrix.printCSR(_ofs, _precision); + } + this->_hcontainer->unfix_R(); +} + +// explicit instantiation of template class with double type +template class Output_HContainer; +// to do: explicit instantiation of template class with std::complex type +// template class Output_HContainer>; + +} // namespace ModuleIO \ No newline at end of file diff --git a/source/module_io/output_hcontainer.h b/source/module_io/output_hcontainer.h new file mode 100644 index 00000000000..cd2e8498841 --- /dev/null +++ b/source/module_io/output_hcontainer.h @@ -0,0 +1,43 @@ +#ifndef OUTPUT_HCONTAINER_H +#define OUTPUT_HCONTAINER_H + +#include "module_cell/unitcell.h" +#include "module_hamilt_lcao/module_hcontainer/hcontainer.h" +#include "module_io/output_interface.h" + +namespace ModuleIO +{ + +template +class Output_HContainer : public Output_Interface +{ + public: + Output_HContainer(hamilt::HContainer* hcontainer, + const Parallel_Orbitals* ParaV, + const UnitCell& ucell, + std::ostream& ofs, + double sparse_threshold, + int precision); + // write the matrices of all R vectors to the output stream + void write() override; + + // write the matrix of a single R vector to the output stream + // rx_in, ry_in, rz_in: the R vector from the input + void write(int rx_in, int ry_in, int rz_in); + + // write the matrix of a single R vector to the output stream + // rx, ry, rz: the R vector from the HContainer + void write_single_R(int rx, int ry, int rz); + + private: + hamilt::HContainer* _hcontainer; + const UnitCell& _ucell; + const Parallel_Orbitals* _ParaV; + std::ostream& _ofs; + double _sparse_threshold; + int _precision; +}; + +} // namespace ModuleIO + +#endif // OUTPUT_HCONTAINER_H \ No newline at end of file diff --git a/source/module_io/test/CMakeLists.txt b/source/module_io/test/CMakeLists.txt index 54fd360095b..bf4efe93cc2 100644 --- a/source/module_io/test/CMakeLists.txt +++ b/source/module_io/test/CMakeLists.txt @@ -120,4 +120,10 @@ AddTest( TARGET io_sparse_matrix_test LIBS base ${math_libs} device SOURCES sparse_matrix_test.cpp ../sparse_matrix.cpp +) + +AddTest( + TARGET io_output_hcontainer_test + LIBS base ${math_libs} device hcontainer + SOURCES output_hcontainer_test.cpp ../output_hcontainer.cpp ../../module_basis/module_ao/parallel_2d.cpp ../../module_basis/module_ao/parallel_orbitals.cpp ../sparse_matrix.cpp tmp_mocks.cpp ) \ No newline at end of file diff --git a/source/module_io/test/output_hcontainer_test.cpp b/source/module_io/test/output_hcontainer_test.cpp new file mode 100644 index 00000000000..48c24230f14 --- /dev/null +++ b/source/module_io/test/output_hcontainer_test.cpp @@ -0,0 +1,161 @@ +#include "module_io/output_hcontainer.h" + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "module_cell/unitcell.h" +#include "module_hamilt_lcao/module_hcontainer/hcontainer.h" + +/************************************************ + * unit test of output_hcontainer.cpp + ***********************************************/ + +/** + * - Tested Functions: + * - write() + * - write the matrices of all R vectors to the output stream + * - write(int rx_in, int ry_in, int rz_in) + * - write the matrix of a single R vector to the output stream + * - write_single_R(int rx, int ry, int rz) + * - write the matrix of a single R vector to the output stream + */ + +class OutputHContainerTest : public testing::Test +{ + protected: + UnitCell ucell; + std::string output; + void SetUp() override + { + ucell.ntype = 1; + ucell.nat = 2; + ucell.atoms = new Atom[ucell.ntype]; + ucell.iat2it = new int[ucell.nat]; + ucell.iat2ia = new int[ucell.nat]; + for (int iat = 0; iat < ucell.nat; iat++) + { + ucell.iat2ia[iat] = iat; + ucell.iat2it[iat] = 0; + } + ucell.atoms[0].nw = 2; + ucell.iwt2iat = new int[4]; + ucell.iwt2iw = new int[4]; + ucell.itia2iat.create(ucell.ntype, ucell.nat); + ucell.iat2iwt.resize(ucell.nat); + ucell.iat2iwt[0] = 0; + ucell.iat2iwt[1] = 2; + ucell.itia2iat(0, 0) = 0; + ucell.itia2iat(0, 1) = 1; + ucell.iwt2iat[0] = 0; + ucell.iwt2iat[1] = 0; + ucell.iwt2iat[2] = 1; + ucell.iwt2iat[3] = 1; + ucell.iwt2iw[0] = 0; + ucell.iwt2iw[1] = 1; + ucell.iwt2iw[2] = 0; + ucell.iwt2iw[3] = 1; + } + void TearDown() override + { + delete[] ucell.atoms; + delete[] ucell.iat2it; + delete[] ucell.iwt2iat; + delete[] ucell.iwt2iw; + } +}; + +TEST_F(OutputHContainerTest, Write) +{ + Parallel_Orbitals ParaV; + ParaV.atom_begin_row.resize(2); + ParaV.atom_begin_col.resize(2); + for (int i = 0; i < 2; i++) + { + ParaV.atom_begin_row[i] = i * 2; + ParaV.atom_begin_col[i] = i * 2; + } + ParaV.nrow = 4; + ParaV.ncol = 4; + std::ofstream ofs("output_hcontainer.log"); + ParaV.set_global2local(4, 4, false, ofs); + // std::cout << "ParaV.global2local_row = " << ParaV.global2local_row(0) << " " << ParaV.global2local_row(1) << " " + // << ParaV.global2local_row(2) << " " << ParaV.global2local_row(3) << std::endl; + // std::cout << "ParaV.global2local_col = " << ParaV.global2local_col(0) << " " << ParaV.global2local_col(1) << " " + // << ParaV.global2local_col(2) << " " << ParaV.global2local_col(3) << std::endl; + ofs.close(); + remove("output_hcontainer.log"); + hamilt::HContainer HR(&ParaV); + double correct_array[16] = {1, 2, 0, 4, 5, 0, 7, 0, 3, 0, 5, 6, 7, 8, 0, 10}; + // correct_array represent a matrix of + // 1 2 0 4 + // 5 0 7 0 + // 3 0 5 6 + // 7 8 0 10 + hamilt::AtomPair ap1(0, 1, 0, 1, 1, &ParaV, correct_array); + hamilt::AtomPair ap2(1, 1, 0, 0, 0, &ParaV, correct_array); + HR.insert_pair(ap1); + HR.insert_pair(ap2); + for (int ir = 0; ir < HR.size_R_loop(); ++ir) + { + int rx, ry, rz; + HR.loop_R(ir, rx, ry, rz); + HR.fix_R(rx, ry, rz); + // std::cout << "rx = " << rx << " ry = " << ry << " rz = " << rz << std::endl; + for (int iap = 0; iap < HR.size_atom_pairs(); ++iap) + { + hamilt::AtomPair& tmp_ap = HR.get_atom_pair(iap); + if (rx == 0 && ry == 1 && rz == 1) + { + EXPECT_DOUBLE_EQ(tmp_ap.get_value(0, 0), 0); + EXPECT_DOUBLE_EQ(tmp_ap.get_value(0, 1), 4); + EXPECT_DOUBLE_EQ(tmp_ap.get_value(1, 0), 7); + EXPECT_DOUBLE_EQ(tmp_ap.get_value(1, 1), 0); + EXPECT_DOUBLE_EQ(tmp_ap.get_matrix_value(0, 2), 0); + EXPECT_DOUBLE_EQ(tmp_ap.get_matrix_value(0, 3), 4); + EXPECT_DOUBLE_EQ(tmp_ap.get_matrix_value(1, 2), 7); + EXPECT_DOUBLE_EQ(tmp_ap.get_matrix_value(1, 3), 0); + } + else if (rx == 0 && ry == 0 && rz == 0) + { + EXPECT_DOUBLE_EQ(tmp_ap.get_value(0, 0), 5); + EXPECT_DOUBLE_EQ(tmp_ap.get_value(0, 1), 6); + EXPECT_DOUBLE_EQ(tmp_ap.get_value(1, 0), 0); + EXPECT_DOUBLE_EQ(tmp_ap.get_value(1, 1), 10); + EXPECT_DOUBLE_EQ(tmp_ap.get_matrix_value(2, 2), 5); + EXPECT_DOUBLE_EQ(tmp_ap.get_matrix_value(2, 3), 6); + EXPECT_DOUBLE_EQ(tmp_ap.get_matrix_value(3, 2), 0); + EXPECT_DOUBLE_EQ(tmp_ap.get_matrix_value(3, 3), 10); + } + } + HR.unfix_R(); + } + double sparse_threshold = 0.1; + ModuleIO::Output_HContainer output_HR(&HR, &ParaV, ucell, std::cout, sparse_threshold, 2); + // the first R + testing::internal::CaptureStdout(); + output_HR.write(0, 1, 1); + output = testing::internal::GetCapturedStdout(); + EXPECT_THAT(output, testing::HasSubstr("0 1 1 2")); + EXPECT_THAT(output, testing::HasSubstr(" 4.00e+00 7.00e+00")); + EXPECT_THAT(output, testing::HasSubstr(" 3 2")); + EXPECT_THAT(output, testing::HasSubstr(" 0 1 2 2 2")); + // the second R + testing::internal::CaptureStdout(); + output_HR.write(0, 0, 0); + output = testing::internal::GetCapturedStdout(); + EXPECT_THAT(output, testing::HasSubstr("0 0 0 3")); + EXPECT_THAT(output, testing::HasSubstr(" 5.00e+00 6.00e+00 1.00e+01")); + EXPECT_THAT(output, testing::HasSubstr(" 2 3 3")); + EXPECT_THAT(output, testing::HasSubstr(" 0 0 0 2 3")); + // output all R + testing::internal::CaptureStdout(); + output_HR.write(); + output = testing::internal::GetCapturedStdout(); + EXPECT_THAT(output, testing::HasSubstr("0 1 1 2")); + EXPECT_THAT(output, testing::HasSubstr(" 4.00e+00 7.00e+00")); + EXPECT_THAT(output, testing::HasSubstr(" 3 2")); + EXPECT_THAT(output, testing::HasSubstr(" 0 1 2 2 2")); + EXPECT_THAT(output, testing::HasSubstr("0 0 0 3")); + EXPECT_THAT(output, testing::HasSubstr(" 5.00e+00 6.00e+00 1.00e+01")); + EXPECT_THAT(output, testing::HasSubstr(" 2 3 3")); + EXPECT_THAT(output, testing::HasSubstr(" 0 0 0 2 3")); +} \ No newline at end of file diff --git a/source/module_io/test/tmp_mocks.cpp b/source/module_io/test/tmp_mocks.cpp new file mode 100644 index 00000000000..e3d27368b99 --- /dev/null +++ b/source/module_io/test/tmp_mocks.cpp @@ -0,0 +1,46 @@ + +#include "module_cell/unitcell.h" + +// constructor of Atom +Atom::Atom() +{ +} +Atom::~Atom() +{ +} + +Atom_pseudo::Atom_pseudo() +{ +} +Atom_pseudo::~Atom_pseudo() +{ +} + +Magnetism::Magnetism() +{ +} +Magnetism::~Magnetism() +{ +} + +InfoNonlocal::InfoNonlocal() +{ +} +InfoNonlocal::~InfoNonlocal() +{ +} + +pseudo_nc::pseudo_nc() +{ +} +pseudo_nc::~pseudo_nc() +{ +} + +// constructor of UnitCell +UnitCell::UnitCell() +{ +} +UnitCell::~UnitCell() +{ +} From bad8a50da63f56c1cf5bae33ee5aba2cf4c8c061 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 24 Jul 2023 04:47:48 +0000 Subject: [PATCH 05/10] try to fix error --- source/module_io/test/CMakeLists.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/module_io/test/CMakeLists.txt b/source/module_io/test/CMakeLists.txt index bf4efe93cc2..8cb915e0add 100644 --- a/source/module_io/test/CMakeLists.txt +++ b/source/module_io/test/CMakeLists.txt @@ -124,6 +124,7 @@ AddTest( AddTest( TARGET io_output_hcontainer_test - LIBS base ${math_libs} device hcontainer - SOURCES output_hcontainer_test.cpp ../output_hcontainer.cpp ../../module_basis/module_ao/parallel_2d.cpp ../../module_basis/module_ao/parallel_orbitals.cpp ../sparse_matrix.cpp tmp_mocks.cpp + LIBS base ${math_libs} device + SOURCES output_hcontainer_test.cpp ../output_hcontainer.cpp ../../module_basis/module_ao/parallel_2d.cpp ../../module_basis/module_ao/parallel_orbitals.cpp ../sparse_matrix.cpp tmp_mocks.cpp ../../module_hamilt_lcao/module_hcontainer/hcontainer.cpp + ../../module_hamilt_lcao/module_hcontainer/atom_pair.cpp ../../module_hamilt_lcao/module_hcontainer/base_matrix.cpp ) \ No newline at end of file From 3f838ce659ba32040a9e3137281b4cd9e8743c8a Mon Sep 17 00:00:00 2001 From: root Date: Mon, 24 Jul 2023 05:29:21 +0000 Subject: [PATCH 06/10] fix error --- source/module_hamilt_lcao/module_hcontainer/CMakeLists.txt | 1 + .../module_hcontainer}/output_hcontainer.cpp | 6 +++--- .../module_hcontainer}/output_hcontainer.h | 7 +++---- .../module_hcontainer/test/CMakeLists.txt | 6 ++++++ .../module_hcontainer}/test/output_hcontainer_test.cpp | 6 +++--- source/module_io/CMakeLists.txt | 1 - source/module_io/test/CMakeLists.txt | 7 ------- 7 files changed, 16 insertions(+), 18 deletions(-) rename source/{module_io => module_hamilt_lcao/module_hcontainer}/output_hcontainer.cpp (97%) rename source/{module_io => module_hamilt_lcao/module_hcontainer}/output_hcontainer.h (89%) rename source/{module_io => module_hamilt_lcao/module_hcontainer}/test/output_hcontainer_test.cpp (96%) diff --git a/source/module_hamilt_lcao/module_hcontainer/CMakeLists.txt b/source/module_hamilt_lcao/module_hcontainer/CMakeLists.txt index 56a2ada86fa..6eb2cac6ec1 100644 --- a/source/module_hamilt_lcao/module_hcontainer/CMakeLists.txt +++ b/source/module_hamilt_lcao/module_hcontainer/CMakeLists.txt @@ -2,6 +2,7 @@ list(APPEND objects base_matrix.cpp atom_pair.cpp hcontainer.cpp + output_hcontainer.cpp ) add_library( diff --git a/source/module_io/output_hcontainer.cpp b/source/module_hamilt_lcao/module_hcontainer/output_hcontainer.cpp similarity index 97% rename from source/module_io/output_hcontainer.cpp rename to source/module_hamilt_lcao/module_hcontainer/output_hcontainer.cpp index c11009973e8..0963f6f2222 100644 --- a/source/module_io/output_hcontainer.cpp +++ b/source/module_hamilt_lcao/module_hcontainer/output_hcontainer.cpp @@ -1,10 +1,10 @@ -#include "module_io/output_hcontainer.h" +#include "output_hcontainer.h" #include #include "module_io/sparse_matrix.h" -namespace ModuleIO +namespace hamilt { template @@ -108,4 +108,4 @@ template class Output_HContainer; // to do: explicit instantiation of template class with std::complex type // template class Output_HContainer>; -} // namespace ModuleIO \ No newline at end of file +} // namespace hamilt \ No newline at end of file diff --git a/source/module_io/output_hcontainer.h b/source/module_hamilt_lcao/module_hcontainer/output_hcontainer.h similarity index 89% rename from source/module_io/output_hcontainer.h rename to source/module_hamilt_lcao/module_hcontainer/output_hcontainer.h index cd2e8498841..0c19e374189 100644 --- a/source/module_io/output_hcontainer.h +++ b/source/module_hamilt_lcao/module_hcontainer/output_hcontainer.h @@ -3,13 +3,12 @@ #include "module_cell/unitcell.h" #include "module_hamilt_lcao/module_hcontainer/hcontainer.h" -#include "module_io/output_interface.h" -namespace ModuleIO +namespace hamilt { template -class Output_HContainer : public Output_Interface +class Output_HContainer { public: Output_HContainer(hamilt::HContainer* hcontainer, @@ -19,7 +18,7 @@ class Output_HContainer : public Output_Interface double sparse_threshold, int precision); // write the matrices of all R vectors to the output stream - void write() override; + void write(); // write the matrix of a single R vector to the output stream // rx_in, ry_in, rz_in: the R vector from the input diff --git a/source/module_hamilt_lcao/module_hcontainer/test/CMakeLists.txt b/source/module_hamilt_lcao/module_hcontainer/test/CMakeLists.txt index f3a52a683d5..3f801ee2973 100644 --- a/source/module_hamilt_lcao/module_hcontainer/test/CMakeLists.txt +++ b/source/module_hamilt_lcao/module_hcontainer/test/CMakeLists.txt @@ -20,4 +20,10 @@ AddTest( SOURCES test_hcontainer_time.cpp ../base_matrix.cpp ../hcontainer.cpp ../atom_pair.cpp ../../../module_basis/module_ao/parallel_2d.cpp ../../../module_basis/module_ao/parallel_orbitals.cpp tmp_mocks.cpp ) + +AddTest( + TARGET test_output_hcontainer + LIBS base ${math_libs} device + SOURCES output_hcontainer_test.cpp ../output_hcontainer.cpp ../../../module_basis/module_ao/parallel_2d.cpp ../../../module_basis/module_ao/parallel_orbitals.cpp ../../../module_io/sparse_matrix.cpp ../base_matrix.cpp ../hcontainer.cpp ../atom_pair.cpp tmp_mocks.cpp +) endif() \ No newline at end of file diff --git a/source/module_io/test/output_hcontainer_test.cpp b/source/module_hamilt_lcao/module_hcontainer/test/output_hcontainer_test.cpp similarity index 96% rename from source/module_io/test/output_hcontainer_test.cpp rename to source/module_hamilt_lcao/module_hcontainer/test/output_hcontainer_test.cpp index 48c24230f14..4872946777c 100644 --- a/source/module_io/test/output_hcontainer_test.cpp +++ b/source/module_hamilt_lcao/module_hcontainer/test/output_hcontainer_test.cpp @@ -1,9 +1,9 @@ -#include "module_io/output_hcontainer.h" +#include "../output_hcontainer.h" +#include "../hcontainer.h" #include "gmock/gmock.h" #include "gtest/gtest.h" #include "module_cell/unitcell.h" -#include "module_hamilt_lcao/module_hcontainer/hcontainer.h" /************************************************ * unit test of output_hcontainer.cpp @@ -129,7 +129,7 @@ TEST_F(OutputHContainerTest, Write) HR.unfix_R(); } double sparse_threshold = 0.1; - ModuleIO::Output_HContainer output_HR(&HR, &ParaV, ucell, std::cout, sparse_threshold, 2); + hamilt::Output_HContainer output_HR(&HR, &ParaV, ucell, std::cout, sparse_threshold, 2); // the first R testing::internal::CaptureStdout(); output_HR.write(0, 1, 1); diff --git a/source/module_io/CMakeLists.txt b/source/module_io/CMakeLists.txt index 5e544565469..823f66512c9 100644 --- a/source/module_io/CMakeLists.txt +++ b/source/module_io/CMakeLists.txt @@ -51,7 +51,6 @@ if(ENABLE_LCAO) output_dm.cpp output_dm1.cpp sparse_matrix.cpp - output_hcontainer.cpp ) list(APPEND objects_advanced unk_overlap_lcao.cpp diff --git a/source/module_io/test/CMakeLists.txt b/source/module_io/test/CMakeLists.txt index 8cb915e0add..54fd360095b 100644 --- a/source/module_io/test/CMakeLists.txt +++ b/source/module_io/test/CMakeLists.txt @@ -120,11 +120,4 @@ AddTest( TARGET io_sparse_matrix_test LIBS base ${math_libs} device SOURCES sparse_matrix_test.cpp ../sparse_matrix.cpp -) - -AddTest( - TARGET io_output_hcontainer_test - LIBS base ${math_libs} device - SOURCES output_hcontainer_test.cpp ../output_hcontainer.cpp ../../module_basis/module_ao/parallel_2d.cpp ../../module_basis/module_ao/parallel_orbitals.cpp ../sparse_matrix.cpp tmp_mocks.cpp ../../module_hamilt_lcao/module_hcontainer/hcontainer.cpp - ../../module_hamilt_lcao/module_hcontainer/atom_pair.cpp ../../module_hamilt_lcao/module_hcontainer/base_matrix.cpp ) \ No newline at end of file From 9cfc22224b6f5921c8e7890272720d3888e4a025 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 25 Jul 2023 07:26:39 +0000 Subject: [PATCH 07/10] remove csr_values and csr_col_inds --- .../module_hcontainer/output_hcontainer.cpp | 7 ++- .../module_hcontainer/output_hcontainer.h | 15 ++++-- source/module_io/sparse_matrix.cpp | 49 ++++++------------- source/module_io/sparse_matrix.h | 27 +--------- source/module_io/test/sparse_matrix_test.cpp | 25 +--------- 5 files changed, 35 insertions(+), 88 deletions(-) diff --git a/source/module_hamilt_lcao/module_hcontainer/output_hcontainer.cpp b/source/module_hamilt_lcao/module_hcontainer/output_hcontainer.cpp index 0963f6f2222..d60421c8d54 100644 --- a/source/module_hamilt_lcao/module_hcontainer/output_hcontainer.cpp +++ b/source/module_hamilt_lcao/module_hcontainer/output_hcontainer.cpp @@ -7,6 +7,10 @@ namespace hamilt { +/** + * @brief Constructor of Output_HContainer + * @attention ofs should be open outside of this interface + */ template Output_HContainer::Output_HContainer(hamilt::HContainer* hcontainer, const Parallel_Orbitals* ParaV, @@ -97,8 +101,7 @@ void Output_HContainer::write_single_R(int rx, int ry, int rz) if (nonzero != 0) { _ofs << rx << " " << ry << " " << rz << " " << nonzero << std::endl; - sparse_matrix.convertToCSR(_sparse_threshold); - sparse_matrix.printCSR(_ofs, _precision); + sparse_matrix.printToCSR(_ofs, _sparse_threshold, _precision); } this->_hcontainer->unfix_R(); } diff --git a/source/module_hamilt_lcao/module_hcontainer/output_hcontainer.h b/source/module_hamilt_lcao/module_hcontainer/output_hcontainer.h index 0c19e374189..3a8152a409f 100644 --- a/source/module_hamilt_lcao/module_hcontainer/output_hcontainer.h +++ b/source/module_hamilt_lcao/module_hcontainer/output_hcontainer.h @@ -7,6 +7,9 @@ namespace hamilt { +/** + * @brief A class to output the HContainer + */ template class Output_HContainer { @@ -20,12 +23,16 @@ class Output_HContainer // write the matrices of all R vectors to the output stream void write(); - // write the matrix of a single R vector to the output stream - // rx_in, ry_in, rz_in: the R vector from the input + /** + * write the matrix of a single R vector to the output stream + * rx_in, ry_in, rz_in: the R vector from the input + */ void write(int rx_in, int ry_in, int rz_in); - // write the matrix of a single R vector to the output stream - // rx, ry, rz: the R vector from the HContainer + /** + * write the matrix of a single R vector to the output stream + * rx, ry, rz: the R vector from the HContainer + */ void write_single_R(int rx, int ry, int rz); private: diff --git a/source/module_io/sparse_matrix.cpp b/source/module_io/sparse_matrix.cpp index 35ba53f2bde..e0359428baf 100644 --- a/source/module_io/sparse_matrix.cpp +++ b/source/module_io/sparse_matrix.cpp @@ -21,10 +21,10 @@ void SparseMatrix::addValue(int row, int col, T value) } /** - * @brief Convert to CSR format + * @brief Print to CSR format */ template -void SparseMatrix::convertToCSR(double threshold) +void SparseMatrix::printToCSR(std::ostream& ofs, double threshold, int precision) { // Filter elements greater than the threshold auto it = std::remove_if(data.begin(), data.end(), [threshold](const std::tuple& elem) { @@ -43,44 +43,29 @@ void SparseMatrix::convertToCSR(double threshold) // Initialize the CSR arrays csr_row_ptr.assign(_rows + 1, 0); - csr_col_ind.clear(); - csr_values.clear(); - // Fill the CSR arrays - for (const auto& elem: data) + // print the CSR values + for (int i = 0; i < data.size(); i++) { - int row = std::get<0>(elem); - int col = std::get<1>(elem); - T value = std::get<2>(elem); - - csr_col_ind.push_back(col); - csr_values.push_back(value); + ofs << " " << std::fixed << std::scientific << std::setprecision(precision) << std::get<2>(data[i]); + } + ofs << std::endl; + // print the CSR column indices + for (int i = 0; i < data.size(); i++) + { + ofs << " " << std::get<1>(data[i]); + int row = std::get<0>(data[i]); csr_row_ptr[row + 1]++; } + ofs << std::endl; // Compute the row pointers for (int i = 1; i <= _rows; i++) { csr_row_ptr[i] += csr_row_ptr[i - 1]; } -} -/** - * @brief Print data in CSR format - */ -template -void SparseMatrix::printCSR(std::ostream& ofs, int precision) -{ - for (int i = 0; i < csr_values.size(); i++) - { - ofs << " " << std::fixed << std::scientific << std::setprecision(precision) << csr_values[i]; - } - ofs << std::endl; - for (int i = 0; i < csr_col_ind.size(); i++) - { - ofs << " " << csr_col_ind[i]; - } - ofs << std::endl; + // print the CSR row pointers for (int i = 0; i < csr_row_ptr.size(); i++) { ofs << " " << csr_row_ptr[i]; @@ -106,17 +91,13 @@ void SparseMatrix::readCSR(const std::vector& values, } csr_row_ptr = row_ptr; - csr_col_ind = col_ind; - csr_values = values; data.clear(); for (int row = 0; row < _rows; row++) { for (int idx = csr_row_ptr[row]; idx < csr_row_ptr[row + 1]; idx++) { - int col = csr_col_ind[idx]; - T value = csr_values[idx]; - data.push_back(std::make_tuple(row, col, value)); + data.push_back(std::make_tuple(row, col_ind[idx], values[idx])); } } } diff --git a/source/module_io/sparse_matrix.h b/source/module_io/sparse_matrix.h index e13d8b0bb6e..1ab370694fa 100644 --- a/source/module_io/sparse_matrix.h +++ b/source/module_io/sparse_matrix.h @@ -36,29 +36,8 @@ class SparseMatrix return data; } - // get CSR_values - const std::vector& getCSRValues() const - { - return csr_values; - } - - // get CSR_col_ind - const std::vector& getCSRColInd() const - { - return csr_col_ind; - } - - // get CSR_row_ptr - const std::vector& getCSRRowPtr() const - { - return csr_row_ptr; - } - - // convert to CSR format - void convertToCSR(double threshold); - - // print data in CSR format CSR: Compressed Sparse Row - void printCSR(std::ostream& ofs, int precision = 8); + // print data in CSR (Compressed Sparse Row) format + void printToCSR(std::ostream& ofs, double threshold, int precision = 8); // read CSR data from arrays void readCSR(const std::vector& values, const std::vector& col_ind, const std::vector& row_ptr); @@ -92,8 +71,6 @@ class SparseMatrix int _cols; std::vector> data; std::vector csr_row_ptr; - std::vector csr_col_ind; - std::vector csr_values; }; // class SparseMatrix } // namespace ModuleIO diff --git a/source/module_io/test/sparse_matrix_test.cpp b/source/module_io/test/sparse_matrix_test.cpp index d24f8ad539c..28a6d5ec41f 100644 --- a/source/module_io/test/sparse_matrix_test.cpp +++ b/source/module_io/test/sparse_matrix_test.cpp @@ -138,9 +138,8 @@ TEST_F(SparseMatrixTest, CSRDouble) smd0.addValue(2, 3, 6.0); smd0.addValue(2, 4, 7.0); smd0.addValue(3, 5, 8.0); - smd0.convertToCSR(0.0); testing::internal::CaptureStdout(); - smd0.printCSR(std::cout, 2); + smd0.printToCSR(std::cout, 0.0, 2); output = testing::internal::GetCapturedStdout(); EXPECT_THAT(output, testing::HasSubstr("1.00e+00 2.00e+00 3.00e+00 4.00e+00 5.00e+00 6.00e+00 7.00e+00 8.00e+00")); EXPECT_THAT(output, testing::HasSubstr("0 1 1 3 2 3 4 5")); @@ -154,15 +153,6 @@ TEST_F(SparseMatrixTest, CSRDouble) smd1.setCols(6); smd1.readCSR(expected_csr_values, expected_csr_col_ind, expected_csr_row_ptr); - for (int i = 0; i < 8; i++) - { - EXPECT_DOUBLE_EQ(smd0.getCSRValues()[i], smd1.getCSRValues()[i]); - EXPECT_EQ(smd0.getCSRColInd()[i], smd1.getCSRColInd()[i]); - } - for (int i = 0; i < 5; i++) - { - EXPECT_EQ(smd0.getCSRRowPtr()[i], smd1.getCSRRowPtr()[i]); - } for (int i = 0; i < 8; i++) { EXPECT_EQ(std::get<0>(smd0.getData()[i]), std::get<0>(smd1.getData()[i])); @@ -194,9 +184,8 @@ TEST_F(SparseMatrixTest, CSRComplex) smc0.addValue(2, 3, std::complex(6.0, 0.0)); smc0.addValue(2, 4, std::complex(7.0, 0.0)); smc0.addValue(3, 5, std::complex(8.0, 0.0)); - smc0.convertToCSR(0.5); testing::internal::CaptureStdout(); - smc0.printCSR(std::cout, 1); + smc0.printToCSR(std::cout, 0.5, 1); output = testing::internal::GetCapturedStdout(); EXPECT_THAT(output, testing::HasSubstr("(1.0e+00,0.0e+00) (2.0e+00,0.0e+00) (3.0e+00,0.0e+00) (4.0e+00,0.0e+00) (5.0e+00,0.0e+00) (6.0e+00,0.0e+00) (7.0e+00,0.0e+00) (8.0e+00,0.0e+00)")); EXPECT_THAT(output, testing::HasSubstr("0 1 1 3 2 3 4 5")); @@ -217,16 +206,6 @@ TEST_F(SparseMatrixTest, CSRComplex) smc1.setCols(6); smc1.readCSR(expected_csr_values, expected_csr_col_ind, expected_csr_row_ptr); - for (int i = 0; i < 8; i++) - { - EXPECT_DOUBLE_EQ(smc0.getCSRValues()[i].real(), smc1.getCSRValues()[i].real()); - EXPECT_DOUBLE_EQ(smc0.getCSRValues()[i].imag(), smc1.getCSRValues()[i].imag()); - EXPECT_EQ(smc0.getCSRColInd()[i], smc1.getCSRColInd()[i]); - } - for (int i = 0; i < 5; i++) - { - EXPECT_EQ(smc0.getCSRRowPtr()[i], smc1.getCSRRowPtr()[i]); - } for (int i = 0; i < 8; i++) { EXPECT_EQ(std::get<0>(smc0.getData()[i]), std::get<0>(smc1.getData()[i])); From 7d6c0d74f5425bd658d1da81b5563236e1487df3 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 25 Jul 2023 08:04:59 +0000 Subject: [PATCH 08/10] simplify further --- source/module_io/sparse_matrix.cpp | 5 ++--- source/module_io/sparse_matrix.h | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/source/module_io/sparse_matrix.cpp b/source/module_io/sparse_matrix.cpp index e0359428baf..1781d09bcf3 100644 --- a/source/module_io/sparse_matrix.cpp +++ b/source/module_io/sparse_matrix.cpp @@ -42,6 +42,7 @@ void SparseMatrix::printToCSR(std::ostream& ofs, double threshold, int precis }); // Initialize the CSR arrays + std::vector csr_row_ptr; csr_row_ptr.assign(_rows + 1, 0); // print the CSR values @@ -90,12 +91,10 @@ void SparseMatrix::readCSR(const std::vector& values, ModuleBase::WARNING_QUIT("SparseMatrix::readCSR", "Column indices and values size mismatch"); } - csr_row_ptr = row_ptr; - data.clear(); for (int row = 0; row < _rows; row++) { - for (int idx = csr_row_ptr[row]; idx < csr_row_ptr[row + 1]; idx++) + for (int idx = row_ptr[row]; idx < row_ptr[row + 1]; idx++) { data.push_back(std::make_tuple(row, col_ind[idx], values[idx])); } diff --git a/source/module_io/sparse_matrix.h b/source/module_io/sparse_matrix.h index 1ab370694fa..40ef07bdeca 100644 --- a/source/module_io/sparse_matrix.h +++ b/source/module_io/sparse_matrix.h @@ -70,7 +70,6 @@ class SparseMatrix int _rows; int _cols; std::vector> data; - std::vector csr_row_ptr; }; // class SparseMatrix } // namespace ModuleIO From 4544be4eacefc21854e81b5a613942641324553d Mon Sep 17 00:00:00 2001 From: root Date: Tue, 25 Jul 2023 10:51:30 +0000 Subject: [PATCH 09/10] fix bug --- .../module_hcontainer/test/output_hcontainer_test.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/source/module_hamilt_lcao/module_hcontainer/test/output_hcontainer_test.cpp b/source/module_hamilt_lcao/module_hcontainer/test/output_hcontainer_test.cpp index 4872946777c..1f7b02bd6a9 100644 --- a/source/module_hamilt_lcao/module_hcontainer/test/output_hcontainer_test.cpp +++ b/source/module_hamilt_lcao/module_hcontainer/test/output_hcontainer_test.cpp @@ -58,6 +58,7 @@ class OutputHContainerTest : public testing::Test { delete[] ucell.atoms; delete[] ucell.iat2it; + delete[] ucell.iat2ia; delete[] ucell.iwt2iat; delete[] ucell.iwt2iw; } From d4208d2cd042f4ce9ac706134a102e2e96b207a1 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 25 Jul 2023 11:57:42 +0000 Subject: [PATCH 10/10] try to fix error --- .../module_hcontainer/test/output_hcontainer_test.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/module_hamilt_lcao/module_hcontainer/test/output_hcontainer_test.cpp b/source/module_hamilt_lcao/module_hcontainer/test/output_hcontainer_test.cpp index 1f7b02bd6a9..f4d870c1fd4 100644 --- a/source/module_hamilt_lcao/module_hcontainer/test/output_hcontainer_test.cpp +++ b/source/module_hamilt_lcao/module_hcontainer/test/output_hcontainer_test.cpp @@ -95,6 +95,7 @@ TEST_F(OutputHContainerTest, Write) hamilt::AtomPair ap2(1, 1, 0, 0, 0, &ParaV, correct_array); HR.insert_pair(ap1); HR.insert_pair(ap2); + /* for (int ir = 0; ir < HR.size_R_loop(); ++ir) { int rx, ry, rz; @@ -129,6 +130,7 @@ TEST_F(OutputHContainerTest, Write) } HR.unfix_R(); } + */ double sparse_threshold = 0.1; hamilt::Output_HContainer output_HR(&HR, &ParaV, ucell, std::cout, sparse_threshold, 2); // the first R