Skip to content

Commit

Permalink
add some library examples and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
tjira committed Feb 6, 2024
1 parent e107bc8 commit bdb26fc
Show file tree
Hide file tree
Showing 16 changed files with 250 additions and 12 deletions.
38 changes: 38 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Test

on:
push:
branches:
- 'master'

permissions:
contents: write

env:
BUILD_TYPE: Release

jobs:
test_linux_x86-64:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: Install Packages
run: sudo apt install -y libboost-dev libeigen3-dev

- name: Build Libint
run: ./script/libint.sh

- name: Configure Acorn
run: cmake -B build -DBUILD_TESTING=ON -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_CXX_COMPILER=g++

- name: Build Acorn
run: |
export CPLUS_INCLUDE_PATH="$PWD/libint/install/include:$CPLUS_INCLUDE_PATH"
export LIBRARY_PATH="$PWD/libint/install/lib:$LIBRARY_PATH"
cmake --build build --parallel 2
- name: Run Tests
working-directory: build
run: ctest --verbose
25 changes: 25 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,28 @@ set_target_properties(acorn-exe PROPERTIES OUTPUT_NAME "acorn")

# create the header library
execute_process(COMMAND /bin/bash ${PROJECT_SOURCE_DIR}/script/headeronly.sh OUTPUT_FILE ${PROJECT_SOURCE_DIR}/bin/acorn.h)

# TESTING ==========================================================================================

# enable testing
enable_testing()

if (BUILD_TESTING)
# add test executables
add_executable(test_rhf test/rhf.cpp)
add_executable(test_mp2 test/mp2.cpp)
add_executable(test_fci test/fci.cpp)

# link the test executables to the library
target_link_libraries(test_rhf acorn)
target_link_libraries(test_mp2 acorn)
target_link_libraries(test_fci acorn)

# change the output folder for the test executables
set_target_properties(test_rhf PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin/test)
set_target_properties(test_mp2 PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin/test)
set_target_properties(test_fci PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin/test)
endif()

# include test file
include(CMakeTests.txt)
8 changes: 8 additions & 0 deletions CMakeTests.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
add_test(NAME water_0-1_mini_rhf_energy COMMAND ${PROJECT_SOURCE_DIR}/bin/test/test_rhf water sto-3g)
set_tests_properties(water_0-1_mini_rhf_energy PROPERTIES PASS_REGULAR_EXPRESSION "-74.96590119")

add_test(NAME water_0-1_mini_mp2_energy COMMAND ${PROJECT_SOURCE_DIR}/bin/test/test_mp2 water sto-3g)
set_tests_properties(water_0-1_mini_mp2_energy PROPERTIES PASS_REGULAR_EXPRESSION "-75.00485492")

add_test(NAME water_0-1_mini_fci_energy COMMAND ${PROJECT_SOURCE_DIR}/bin/test/test_fci water sto-3g)
set_tests_properties(water_0-1_mini_fci_energy PROPERTIES PASS_REGULAR_EXPRESSION "-75.02041033")
2 changes: 2 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

- [ ] Implement the analytical gradient for RHF
- [ ] Implement the unrestricted Hartree-Fock
- [ ] Modify restricted calculations to account for charge and multiplicity
- [x] Add some tests
- [x] Add the ability to export the atomic integrals
- [x] Add the ability to use orca to perform ground state dynamics
- [x] Check the correct working of the library before merging the fci branch
Expand Down
32 changes: 32 additions & 0 deletions example/library/fci.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include "acorn.h"

int main(int argc, char** argv) {
// get executable path for the executable to run from anywhere
auto path = std::filesystem::weakly_canonical(argv[0]).parent_path();

// create the molecule stream
std::ifstream mstream(path / "../molecule/water.xyz");

// create the molecule and integral container
System system(mstream, "sto-3g"); Integrals ints(true);

// calculate all the atomic integrals
ints.S = Integral::Overlap(system); ints.T = Integral::Kinetic(system);
ints.V = Integral::Nuclear(system); ints.J = Integral::Coulomb(system);

// run the restricted Hartree-Fock calculation
Result res = RestrictedHartreeFock().run(system, ints, {}, false);

// transform the one electron integrals to the MS basis
ints.Tms = Transform::SingleSpin(ints.T, res.rhf.C);
ints.Vms = Transform::SingleSpin(ints.V, res.rhf.C);

// transform the coulomb integrals to the MS basis
ints.Jms = Transform::CoulombSpin(ints.J, res.rhf.C);

// perform the FCI calculation
res = RestrictedConfigurationInteraction().run(system, ints, res, false);

// print the total energy
std::printf("%.8f\n", res.Etot);
}
28 changes: 28 additions & 0 deletions example/library/mp2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include "acorn.h"

int main(int argc, char** argv) {
// get executable path for the executable to run from anywhere
auto path = std::filesystem::weakly_canonical(argv[0]).parent_path();

// create the molecule stream
std::ifstream mstream(path / "../molecule/water.xyz");

// create the molecule and integral container
System system(mstream, "sto-3g"); Integrals ints(true);

// calculate all the atomic integrals
ints.S = Integral::Overlap(system); ints.T = Integral::Kinetic(system);
ints.V = Integral::Nuclear(system); ints.J = Integral::Coulomb(system);

// run the restricted Hartree-Fock calculation
Result res = RestrictedHartreeFock().run(system, ints, {}, false);

// transform the coulomb integrals to the MO basis
ints.Jmo = Transform::Coulomb(ints.J, res.rhf.C);

// perform the MP2 calculation
res = RestrictedMollerPlesset().run(system, ints, res, false);

// print the total energy
std::printf("%.8f\n", res.Etot);
}
11 changes: 7 additions & 4 deletions example/library/rhf.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
#include "acorn.h"

int main() {
int main(int argc, char** argv) {
// get executable path for the executable to run from anywhere
auto path = std::filesystem::weakly_canonical(argv[0]).parent_path();

// create the molecule stream
std::ifstream mstream("../molecule/water.xyz");
std::ifstream mstream(path / "../molecule/water.xyz");

// create the molecule and integral container
System system(mstream, "sto-3g"); Integrals ints(true);
Expand All @@ -14,6 +17,6 @@ int main() {
// run the restricted Hartree-Fock calculation
Result res = RestrictedHartreeFock().run(system, ints, {}, false);

// print the energy
std::cout << std::setprecision(14) << res.Etot << std::endl;
// print the total energy
std::printf("%.8f\n", res.Etot);
}
2 changes: 0 additions & 2 deletions include/constant.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,3 @@
#define BOHR2A 0.529177210903
#define BOLTZMANN 3.166811429e-6
#define CFREQ 5140.486777894163

inline int nthread = 1;
4 changes: 4 additions & 0 deletions include/eigen.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,9 @@ inline Vector<std::complex<double>> EigenFourier(const Vector<std::complex<doubl
// complamentary functions
inline bool VectorContains(const std::vector<int>& v, const int& e) {return std::find(v.begin(), v.end(), e) != v.end();}

// include necessities
#include <fstream>
#include <iomanip>

// number of threads
inline int nthread = 1;
2 changes: 1 addition & 1 deletion include/restrictedconfigurationinteraction.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class RestrictedConfigurationInteraction : public RestrictedMethod<RestrictedCon
};
public:
// constructors and destructors
RestrictedConfigurationInteraction(const RestrictedHartreeFock::Options& rhfopt, const Options& opt) : opt(opt), rhfopt(rhfopt) {}
RestrictedConfigurationInteraction(const RestrictedHartreeFock::Options& rhfopt = {}, const Options& opt = {}) : opt(opt), rhfopt(rhfopt) {}

// overriden virtual methods
Result run(const System& system, const Integrals& ints, Result res, bool print = true) const override;
Expand Down
2 changes: 1 addition & 1 deletion include/restrictedmollerplesset.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class RestrictedMollerPlesset : public RestrictedMethod<RestrictedMollerPlesset>
};
public:
// constructors and destructors
RestrictedMollerPlesset(const RestrictedHartreeFock::Options& rhfopt, const Options& opt) : opt(opt), rhfopt(rhfopt) {}
RestrictedMollerPlesset(const RestrictedHartreeFock::Options& rhfopt = {}, const Options& opt = {}) : opt(opt), rhfopt(rhfopt) {}

// overriden virtual methods
Result run(const System& system, const Integrals& ints, Result res, bool print = true) const override;
Expand Down
15 changes: 12 additions & 3 deletions script/headeronly.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
#!/bin/bash

cat << EndOfMessage
#pragma once
#define EIGEN_INITIALIZE_MATRICES_BY_ZERO
#include <unsupported/Eigen/MatrixFunctions>
#include <unsupported/Eigen/CXX11/Tensor>
#include <unsupported/Eigen/FFT>
#include <bits/stdc++.h>
EndOfMessage

tail -n +3 include/constant.h

cat \
include/constant.h \
include/eigen.h \
include/table.h \
include/system.h \
Expand All @@ -20,5 +30,4 @@ cat \
include/modelsystem.h \
include/modelsolver.h \
include/orca.h \
include/default.h \
| sed '/#pragma once/d ; /#include "/d'
| sed '/#pragma once/d ; /#include/d ; /\/\//d ; /^$/d'
2 changes: 1 addition & 1 deletion src/method.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ Result Method<M>::hessian(const System& system, const Integrals&, Result res, bo
// print the header
if (print) std::printf(" ELEM dE [Eh/Bohr] TIME\n");

#pragma omp parallel for num_threads(nthread)
#pragma omp parallel for num_threads(nthread) collapse(2)
for (int i = 0; i < res.H.rows(); i++) {
for (int j = i; j < res.H.cols(); j++) {
// start the timer
Expand Down
35 changes: 35 additions & 0 deletions test/fci.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "../bin/acorn.h"

int main(int argc, char** argv) {
// throw an error if the number of arguments is incorrect
if (argc != 3) throw std::runtime_error("INCORRECT NUMBER OF ARGUMENTS");

// get executable path for the executable to run from anywhere
auto path = std::filesystem::weakly_canonical(argv[0]).parent_path();

// create the molecule stream
std::ifstream mstream(path / "../../example/molecule" / (argv[1] + std::string(".xyz")));

// create the molecule and integral container
System system(mstream, argv[2]); Integrals ints(true);

// calculate all the atomic integrals
ints.S = Integral::Overlap(system); ints.T = Integral::Kinetic(system);
ints.V = Integral::Nuclear(system); ints.J = Integral::Coulomb(system);

// run the restricted Hartree-Fock calculation
Result res = RestrictedHartreeFock().run(system, ints, {}, false);

// transform the one electron integrals to the MS basis
ints.Tms = Transform::SingleSpin(ints.T, res.rhf.C);
ints.Vms = Transform::SingleSpin(ints.V, res.rhf.C);

// transform the coulomb integrals to the MS basis
ints.Jms = Transform::CoulombSpin(ints.J, res.rhf.C);

// perform the FCI calculation
res = RestrictedConfigurationInteraction().run(system, ints, res, false);

// print the total energy
std::printf("%.8f\n", res.Etot);
}
31 changes: 31 additions & 0 deletions test/mp2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include "../bin/acorn.h"

int main(int argc, char** argv) {
// throw an error if the number of arguments is incorrect
if (argc != 3) throw std::runtime_error("INCORRECT NUMBER OF ARGUMENTS");

// get executable path for the executable to run from anywhere
auto path = std::filesystem::weakly_canonical(argv[0]).parent_path();

// create the molecule stream
std::ifstream mstream(path / "../../example/molecule" / (argv[1] + std::string(".xyz")));

// create the molecule and integral container
System system(mstream, argv[2]); Integrals ints(true);

// calculate all the atomic integrals
ints.S = Integral::Overlap(system); ints.T = Integral::Kinetic(system);
ints.V = Integral::Nuclear(system); ints.J = Integral::Coulomb(system);

// run the restricted Hartree-Fock calculation
Result res = RestrictedHartreeFock().run(system, ints, {}, false);

// transform the coulomb integrals to the MO basis
ints.Jmo = Transform::Coulomb(ints.J, res.rhf.C);

// perform the MP2 calculation
res = RestrictedMollerPlesset().run(system, ints, res, false);

// print the total energy
std::printf("%.8f\n", res.Etot);
}
25 changes: 25 additions & 0 deletions test/rhf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include "../bin/acorn.h"

int main(int argc, char** argv) {
// throw an error if the number of arguments is incorrect
if (argc != 3) throw std::runtime_error("INCORRECT NUMBER OF ARGUMENTS");

// get executable path for the executable to run from anywhere
auto path = std::filesystem::weakly_canonical(argv[0]).parent_path();

// create the molecule stream
std::ifstream mstream(path / "../../example/molecule" / (argv[1] + std::string(".xyz")));

// create the molecule and integral container
System system(mstream, argv[2]); Integrals ints(true);

// calculate all the atomic integrals
ints.S = Integral::Overlap(system); ints.T = Integral::Kinetic(system);
ints.V = Integral::Nuclear(system); ints.J = Integral::Coulomb(system);

// run the restricted Hartree-Fock calculation
Result res = RestrictedHartreeFock().run(system, ints, {}, false);

// print the total energy
std::printf("%.8f\n", res.Etot);
}

0 comments on commit bdb26fc

Please sign in to comment.